From a7fc05fcd35a6250076ed430f6d3f845d9890943 Mon Sep 17 00:00:00 2001 From: Andrea Maria Piana Date: Thu, 28 Jun 2018 13:03:34 +0200 Subject: [PATCH] Add support for browse dapps Signed-off-by: Andrea Maria Piana --- src/status_im/chat/events.cljs | 10 ------ src/status_im/ui/components/dialog.cljs | 3 +- .../ui/components/list_selection.cljs | 6 ++++ src/status_im/ui/screens/browser/events.cljs | 15 ++++++++ src/status_im/ui/screens/events.cljs | 33 +++++++++-------- src/status_im/utils/universal_links/core.cljs | 35 ++++++++++++++----- test/cljs/status_im/test/runner.cljs | 2 ++ .../status_im/test/ui/screens/events.cljs | 10 ++++++ .../test/utils/universal_links/core.cljs | 28 ++++++++++++++- 9 files changed, 108 insertions(+), 34 deletions(-) create mode 100644 test/cljs/status_im/test/ui/screens/events.cljs diff --git a/src/status_im/chat/events.cljs b/src/status_im/chat/events.cljs index d817a6b5e5..b7b6f52379 100644 --- a/src/status_im/chat/events.cljs +++ b/src/status_im/chat/events.cljs @@ -8,7 +8,6 @@ [status-im.chat.models.message :as models.message] [status-im.chat.console :as console] [status-im.commands.events.loading :as events.loading] - [status-im.ui.components.list-selection :as list-selection] [status-im.ui.screens.navigation :as navigation] [status-im.utils.handlers :as handlers] [status-im.utils.handlers-macro :as handlers-macro] @@ -30,10 +29,6 @@ ;;;; Effects -(re-frame/reg-fx - :browse - (fn [link] - (list-selection/browse link))) (re-frame/reg-fx :show-cooldown-warning @@ -202,11 +197,6 @@ (group-chat-messages) (add-default-contacts))))) -(handlers/register-handler-fx - :browse-link-from-message - (fn [_ [_ link]] - {:browse link})) - (defn- send-messages-seen [chat-id message-ids {:keys [db] :as cofx}] (when (and (not (get-in db [:chats chat-id :public?])) (not (models/bot-only-chat? db chat-id))) diff --git a/src/status_im/ui/components/dialog.cljs b/src/status_im/ui/components/dialog.cljs index dcf310f76d..3a851c9c17 100644 --- a/src/status_im/ui/components/dialog.cljs +++ b/src/status_im/ui/components/dialog.cljs @@ -7,9 +7,10 @@ (when-let [handler (:action (nth options index))] (handler))))) -(defn- show [{:keys [title options]}] +(defn- show [{:keys [title options cancel-text]}] (let [dialog (new rn-dependencies/dialogs)] (.set dialog (clj->js {:title title + :negativeText cancel-text :items (mapv :label options) :itemsCallback (callback options)})) (.show dialog))) diff --git a/src/status_im/ui/components/list_selection.cljs b/src/status_im/ui/components/list_selection.cljs index d9f4d0bafd..11563a60c1 100644 --- a/src/status_im/ui/components/list_selection.cljs +++ b/src/status_im/ui/components/list_selection.cljs @@ -35,3 +35,9 @@ {:label (i18n/label :t/browsing-open-in-web-browser) :action #(.openURL react/linking (http/normalize-url link))}] :cancel-text (i18n/label :t/browsing-cancel)})) + +(defn browse-dapp [link] + (show {:title (i18n/label :t/browsing-title) + :options [{:label (i18n/label :t/browsing-open-in-browser) + :action #(re-frame/dispatch [:open-browser {:url link}])}] + :cancel-text (i18n/label :t/browsing-cancel)})) diff --git a/src/status_im/ui/screens/browser/events.cljs b/src/status_im/ui/screens/browser/events.cljs index e84d6ec408..21bfa6dfe8 100644 --- a/src/status_im/ui/screens/browser/events.cljs +++ b/src/status_im/ui/screens/browser/events.cljs @@ -4,6 +4,8 @@ [re-frame.core :as re-frame] [status-im.utils.random :as random] [status-im.i18n :as i18n] + [status-im.ui.components.list-selection :as list-selection] + [status-im.utils.universal-links.core :as utils.universal-links] [status-im.data-store.browser :as browser-store] [status-im.utils.http :as http])) @@ -14,6 +16,19 @@ (let [browsers (into {} (map #(vector (:browser-id %) %) all-stored-browsers))] {:db (assoc db :browser/browsers browsers)}))) +(re-frame/reg-fx + :browse + (fn [link] + (if (utils.universal-links/universal-link? link) + (do + (utils.universal-links/open! link)) + (list-selection/browse link)))) + +(handlers/register-handler-fx + :browse-link-from-message + (fn [_ [_ link]] + {:browse link})) + (defn get-new-browser [browser now] (cond-> browser true diff --git a/src/status_im/ui/screens/events.cljs b/src/status_im/ui/screens/events.cljs index 426985891f..6c20e32cbd 100644 --- a/src/status_im/ui/screens/events.cljs +++ b/src/status_im/ui/screens/events.cljs @@ -272,22 +272,27 @@ (transport/stop-whisper))) {:get-encryption-key [this-event]}))) +(defn initialize-db [encryption-key + {{:universal-links/keys [url] + :keys [status-module-initialized? status-node-started? + network-status network peers-count peers-summary device-UUID] + :or {network (get app-db :network)}} :db}] + {::init-store encryption-key + :db (assoc app-db + :contacts/contacts {} + :network-status network-status + :peers-count (or peers-count 0) + :peers-summary (or peers-summary []) + :status-module-initialized? (or platform/ios? js/goog.DEBUG status-module-initialized?) + :status-node-started? status-node-started? + :network network + :universal-links/url url + :device-UUID device-UUID)}) + (handlers/register-handler-fx :initialize-db - (fn [{{:keys [status-module-initialized? status-node-started? - network-status network peers-count peers-summary device-UUID] - :or {network (get app-db :network)}} :db} - [_ encryption-key]] - {::init-store encryption-key - :db (assoc app-db - :contacts/contacts {} - :network-status network-status - :peers-count (or peers-count 0) - :peers-summary (or peers-summary []) - :status-module-initialized? (or platform/ios? js/goog.DEBUG status-module-initialized?) - :status-node-started? status-node-started? - :network network - :device-UUID device-UUID)})) + (fn [cofx [_ encryption-key]] + (initialize-db encryption-key cofx))) (handlers/register-handler-db :initialize-account-db diff --git a/src/status_im/utils/universal_links/core.cljs b/src/status_im/utils/universal_links/core.cljs index 0aa3282c05..5160502be6 100644 --- a/src/status_im/utils/universal_links/core.cljs +++ b/src/status_im/utils/universal_links/core.cljs @@ -5,26 +5,42 @@ [status-im.utils.config :as config] [status-im.chat.events :as chat.events] [status-im.models.account :as models.account] + [status-im.ui.components.list-selection :as list-selection] [status-im.ui.components.react :as react])) (def public-chat-regex #".*/chat/public/(.*)$") (def profile-regex #".*/user/(.*)$") +(def browse-regex #".*/browse/(.*)$") + +(defn match-url [url regex] + (some->> url + (re-matches regex) + peek)) + +(defn universal-link? [url] + (boolean + (re-matches #"^(app|http|https)://get.status.im/.*$" url))) + +(defn open! [url] + (log/info "universal-links: opening " url) + (if-let [dapp-url (match-url url browse-regex)] + (list-selection/browse-dapp dapp-url) + (.openURL react/linking url))) + +(defn handle-browse [url cofx] + (log/info "universal-links: handling browse " url) + {:browse url}) (defn handle-public-chat [public-chat cofx] (log/info "universal-links: handling public chat " public-chat) (chat.events/create-new-public-chat public-chat cofx)) (defn handle-view-profile [profile-id cofx] - (log/info "universal links: handling view profile" profile-id) + (log/info "universal-links: handling view profile" profile-id) (chat.events/show-profile profile-id cofx)) (defn handle-not-found [full-url] - (log/info "universal links: no handler for " full-url)) - -(defn match-url [url regex] - (some->> url - (re-matches regex) - peek)) + (log/info "universal-links: no handler for " full-url)) (defn stored-url-event "Return an event description for processing a url if in the database" @@ -37,7 +53,7 @@ [url] (if-not (nil? url) (re-frame/dispatch [:handle-universal-link url]) - (log/debug "universal links: no url"))) + (log/debug "universal-links: no url"))) (defn store-url-for-later "Store the url in the db to be processed on login" @@ -59,6 +75,9 @@ (match-url url profile-regex) (handle-view-profile (match-url url profile-regex) cofx) + (match-url url browse-regex) + (handle-browse url cofx) + :else (handle-not-found url))) (defn handle-url diff --git a/test/cljs/status_im/test/runner.cljs b/test/cljs/status_im/test/runner.cljs index 0f123cd372..a197cf4bb7 100644 --- a/test/cljs/status_im/test/runner.cljs +++ b/test/cljs/status_im/test/runner.cljs @@ -43,6 +43,7 @@ [status-im.test.utils.prices] [status-im.test.utils.keychain.core] [status-im.test.utils.universal-links.core] + [status-im.test.ui.screens.events] [status-im.test.ui.screens.accounts.login.events])) (enable-console-print!) @@ -97,4 +98,5 @@ 'status-im.test.utils.prices 'status-im.test.utils.keychain.core 'status-im.test.utils.universal-links.core + 'status-im.test.ui.screens.events 'status-im.test.ui.screens.accounts.login.events) diff --git a/test/cljs/status_im/test/ui/screens/events.cljs b/test/cljs/status_im/test/ui/screens/events.cljs new file mode 100644 index 0000000000..8e07f4ce13 --- /dev/null +++ b/test/cljs/status_im/test/ui/screens/events.cljs @@ -0,0 +1,10 @@ +(ns status-im.test.ui.screens.events + (:require [cljs.test :refer-macros [deftest is testing]] + [status-im.ui.screens.events :as events])) + +(deftest initialize-db + (testing "it preserves universal-links/url" + (is (= "some-url" (get-in (events/initialize-db "blah" + {:db + {:universal-links/url "some-url"}}) + [:db :universal-links/url]))))) diff --git a/test/cljs/status_im/test/utils/universal_links/core.cljs b/test/cljs/status_im/test/utils/universal_links/core.cljs index 3ee21366c7..7362bb1c77 100644 --- a/test/cljs/status_im/test/utils/universal_links/core.cljs +++ b/test/cljs/status_im/test/utils/universal_links/core.cljs @@ -20,6 +20,13 @@ (is (get-in (links/handle-url "app://get.status.im/chat/public/status" {:db db}) [:db :chats "status"])))) + + (testing "a browse dapp link" + (testing "it open the dapps" + (is + (= "app://get.status.im/browse/www.cryptokitties.co" + (:browse (links/handle-url "app://get.status.im/browse/www.cryptokitties.co" + {:db db})))))) (testing "a user profile link" (testing "it loads the profile" (let [actual (links/handle-url "app://get.status.im/user/profile-id" @@ -45,6 +52,26 @@ (links/url-event-listener #js {}) (is (= nil @actual))))))) +(deftest universal-link-test + (testing "app://get.status.im/blah" + (testing "it returns true" + (is (links/universal-link? "app://get.status.im/blah")))) + (testing "http://get.status.im/blah" + (testing "it returns true" + (is (links/universal-link? "http://get.status.im/blah")))) + (testing "https://get.status.im/blah" + (testing "it returns true" + (is (links/universal-link? "https://get.status.im/blah")))) + (testing "app://not.status.im/blah" + (testing "it returns false" + (is (not (links/universal-link? "https://not.status.im/blah"))))) + (testing "http://not.status.im/blah" + (testing "it returns false" + (is (not (links/universal-link? "https://not.status.im/blah"))))) + (testing "https://not.status.im/blah" + (testing "it returns false" + (is (not (links/universal-link? "https://not.status.im/blah")))))) + (deftest stored-url-event (testing "the url is in the database" (testing "it returns the event" @@ -54,4 +81,3 @@ (testing "it returns nil" (= nil (links/stored-url-event {:db {}}))))) -