From 9aa9dc1b4c2cb102acdeb154b534e5e25e09672b Mon Sep 17 00:00:00 2001 From: Parvesh Monu Date: Tue, 16 Apr 2024 20:30:24 +0530 Subject: [PATCH] Redirect to community channel when following universal link (#19566) --- src/status_im/common/router.cljs | 20 +++++-- src/status_im/common/router_test.cljs | 2 + .../common/shared_urls/data_store.cljs | 20 +++++++ src/status_im/common/shared_urls/events.cljs | 33 +++++++++++ src/status_im/common/universal_links.cljs | 12 ++-- .../contexts/communities/events.cljs | 55 +++++++++++-------- src/status_im/events.cljs | 1 + 7 files changed, 110 insertions(+), 33 deletions(-) create mode 100644 src/status_im/common/shared_urls/data_store.cljs create mode 100644 src/status_im/common/shared_urls/events.cljs diff --git a/src/status_im/common/router.cljs b/src/status_im/common/router.cljs index 08d7f4d97b7..06e8cbaaae4 100644 --- a/src/status_im/common/router.cljs +++ b/src/status_im/common/router.cljs @@ -100,7 +100,7 @@ ens? (assoc-in [:route-params :ens-name] fragment) - (and (or (= handler :community) (= handler :community-chat)) compressed-key?) + (and (= handler :community) compressed-key?) (assoc-in [:route-params :community-id] fragment) (and equal-end-of-base64url (= handler :community) (:community-data route-params)) @@ -119,6 +119,13 @@ (re-find constants/regx-starts-with-uuid (:community-data route-params))) (assoc-in [:route-params :community-channel-id] (:community-data route-params)) + (and fragment + (= handler :community-chat) + (:community-data route-params) + (string? (:community-data route-params)) + (not (re-find constants/regx-starts-with-uuid (:community-data route-params)))) + (assoc-in [:route-params :community-encoded-data?] true) + (and equal-end-of-base64url (= handler :user) (:user-data route-params)) (update-in [:route-params :user-data] #(str % equal-end-of-base64url)) @@ -203,6 +210,10 @@ (cb {:type :private-chat :error :invalid-chat-id}))))) +(defn parse-shared-url + [uri] + (re-frame/dispatch [:shared-urls/parse-shared-url uri])) + (defn match-community-channel-async [{:keys [community-channel-id community-id]} cb] (if (validators/valid-compressed-key? community-id) @@ -307,9 +318,10 @@ (and (= handler :community-chat) (:community-channel-id route-params) (:community-id route-params)) (match-community-channel-async route-params cb) - (and (= handler :community-chat) (:community-id route-params)) - (cb {:type :community - :community-id (:community-id route-params)}) + (and (= handler :community-chat) + (:community-encoded-data? route-params) + (:community-id route-params)) + (parse-shared-url uri) ;; NOTE: removed in `match-uri`, might need this in the future (= handler :wallet-account) diff --git a/src/status_im/common/router_test.cljs b/src/status_im/common/router_test.cljs index b9832602cd3..7a8c8915d6e 100644 --- a/src/status_im/common/router_test.cljs +++ b/src/status_im/common/router_test.cljs @@ -42,12 +42,14 @@ [:community-chat {:community-data "G54AAKwObLdpiGjXnckYzRcOSq0QQAS_CURGfqVU42ceGHCObstUIknTTZDOKF3E8y2MSicncpO7fTskXnoACiPKeejvjtLTGWNxUhlT7fyQS7Jrr33UVHluxv_PLjV2ePGw5GQ33innzeK34pInIgUGs5RjdQifMVmURalxxQKwiuoY5zwIjixWWRHqjHM=" + :community-encoded-data? true :community-id "zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11"}] "status-app://cc/G54AAKwObLdpiGjXnckYzRcOSq0QQAS_CURGfqVU42ceGHCObstUIknTTZDOKF3E8y2MSicncpO7fTskXnoACiPKeejvjtLTGWNxUhlT7fyQS7Jrr33UVHluxv_PLjV2ePGw5GQ33innzeK34pInIgUGs5RjdQifMVmURalxxQKwiuoY5zwIjixWWRHqjHM=#zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11" [:community-chat {:community-data "G54AAKwObLdpiGjXnckYzRcOSq0QQAS_CURGfqVU42ceGHCObstUIknTTZDOKF3E8y2MSicncpO7fTskXnoACiPKeejvjtLTGWNxUhlT7fyQS7Jrr33UVHluxv_PLjV2ePGw5GQ33innzeK34pInIgUGs5RjdQifMVmURalxxQKwiuoY5zwIjixWWRHqjHM=" + :community-encoded-data? true :community-id "zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11"}] "https://status.app/cc/c432709e-fc73-440d-bb67-cb3a0929dfda#zQ3shZL6dXiFCbDyxnXxwQa9v8QFC2q19subFtyxd7kVszMVo" diff --git a/src/status_im/common/shared_urls/data_store.cljs b/src/status_im/common/shared_urls/data_store.cljs new file mode 100644 index 00000000000..f929d713d00 --- /dev/null +++ b/src/status_im/common/shared_urls/data_store.cljs @@ -0,0 +1,20 @@ +(ns status-im.common.shared-urls.data-store + (:require + [clojure.set :as set])) + +(defn <-rpc + [{:keys [community channel contact]}] + {:community (set/rename-keys + community + {:communityId :community-id + :displayName :display-name + :membersCount :members-count + :tagIndices :tag-indices}) + :channel (set/rename-keys + channel + {:displayName :display-name + :channelUuid :channel-uuid}) + :contact (set/rename-keys + contact + {:displayName :display-name + :publicKey :public-key})}) diff --git a/src/status_im/common/shared_urls/events.cljs b/src/status_im/common/shared_urls/events.cljs new file mode 100644 index 00000000000..f5c626d2ad0 --- /dev/null +++ b/src/status_im/common/shared_urls/events.cljs @@ -0,0 +1,33 @@ +(ns status-im.common.shared-urls.events + (:require + [clojure.string :as string] + [re-frame.core :as re-frame] + [status-im.common.shared-urls.data-store :as data-store] + [taoensso.timbre :as log] + [utils.re-frame :as rf])) + +(defn parse-shared-url-success + [url response] + (let [parsed-data (data-store/<-rpc response) + cb #(rf/dispatch [:universal-links/match-value url %])] + (cond + (:channel parsed-data) + (cb {:type :community-chat + :chat-id (str (get-in parsed-data [:community :community-id]) + (get-in parsed-data [:channel :channel-uuid])) + :community-id (get-in parsed-data [:community :community-id])}) + + (:community parsed-data) + (cb {:type :community :community-id (get-in parsed-data [:community :community-id])})))) + +(defn parse-shared-url + [_ [uri]] + (let [url (string/replace uri #"status-app:/" "https://status.app")] + {:json-rpc/call + [{:method "wakuext_parseSharedURL" + :params [url] + :on-success #(parse-shared-url-success url %) + :on-error (fn [err] + (log/error "failed to parse shared url" {:error err :url url}))}]})) + +(re-frame/reg-event-fx :shared-urls/parse-shared-url parse-shared-url) diff --git a/src/status_im/common/universal_links.cljs b/src/status_im/common/universal_links.cljs index 425eee08f2c..549162c10ae 100644 --- a/src/status_im/common/universal_links.cljs +++ b/src/status_im/common/universal_links.cljs @@ -116,14 +116,16 @@ (log/debug "universal-links: no url"))) (rf/defn on-handle - {:events [::match-value]} - [cofx url {:keys [type chat-id] :as data}] + {:events [:universal-links/match-value]} + [cofx url {:keys [type chat-id community-id] :as data}] (case type :group-chat (handle-group-chat cofx data) :private-chat (handle-private-chat cofx data) :community-requests (handle-community-requests cofx data) - :community (communities.events/navigate-to-serialized-community cofx data) - :community-chat {:dispatch [:communities/navigate-to-community-chat chat-id :pop-to-root]} + :community (communities.events/navigate-to-community-overview cofx [community-id]) + :community-chat (communities.events/navigate-to-community-chat cofx + [chat-id :pop-to-root + community-id]) :contact (handle-view-profile cofx data) :browser (handle-browse cofx data) :eip681 (handle-eip681 cofx data) @@ -136,7 +138,7 @@ {:router/handle-uri {:chain (chain/chain-keyword db) :chats (:chats db) :uri url - :cb #(re-frame/dispatch [::match-value url %])}}) + :cb #(re-frame/dispatch [:universal-links/match-value url %])}}) (rf/defn store-url-for-later "Store the url in the db to be processed on login" diff --git a/src/status_im/contexts/communities/events.cljs b/src/status_im/contexts/communities/events.cljs index 2bc04c269bf..4ed775dc34d 100644 --- a/src/status_im/contexts/communities/events.cljs +++ b/src/status_im/contexts/communities/events.cljs @@ -325,8 +325,8 @@ (rf/reg-event-fx :chat.ui/spectate-community spectate-community) -(rf/defn navigate-to-serialized-community - [_ {:keys [community-id]}] +(defn navigate-to-serialized-community + [community-id] {:serialization/deserialize-and-compress-key {:serialized-key community-id :on-success #(rf/dispatch [:communities/navigate-to-community-overview %]) @@ -334,27 +334,30 @@ :error % :community-id community-id})}}) -(rf/reg-event-fx :communities/navigate-to-community-overview - (fn [{:keys [db] :as cofx} [deserialized-key]] - (let [current-view-id (:view-id db)] - (if (string/starts-with? deserialized-key constants/serialization-key) - (navigate-to-serialized-community cofx deserialized-key) - (rf/merge - cofx - {:fx [[:dispatch - [:communities/fetch-community - {:community-id deserialized-key - :update-last-opened-at? true}]] - [:dispatch [:navigate-to :community-overview deserialized-key]] - (when (get-in db [:communities deserialized-key :joined]) - [:dispatch - [:activity-center.notifications/dismiss-community-overview deserialized-key]])]} - (when-not (or (= current-view-id :shell) (= current-view-id :communities-stack)) - (navigation/pop-to-root :shell-stack))))))) - -(rf/reg-event-fx :communities/navigate-to-community-chat - (fn [{:keys [db]} [chat-id pop-to-root?]] - (let [{:keys [community-id]} (get-in db [:chats chat-id])] +(rf/defn navigate-to-community-overview + [{:keys [db] :as cofx} [community-id]] + (let [current-view-id (:view-id db)] + (if (string/starts-with? community-id constants/serialization-key) + (navigate-to-serialized-community community-id) + (rf/merge + cofx + {:fx [[:dispatch + [:communities/fetch-community + {:community-id community-id + :update-last-opened-at? true}]] + [:dispatch [:navigate-to :community-overview community-id]] + (when (get-in db [:communities community-id :joined]) + [:dispatch + [:activity-center.notifications/dismiss-community-overview community-id]])]} + (when-not (or (= current-view-id :shell) (= current-view-id :communities-stack)) + (navigation/pop-to-root :shell-stack)))))) + +(rf/reg-event-fx :communities/navigate-to-community-overview navigate-to-community-overview) + +(defn navigate-to-community-chat + [{:keys [db]} [chat-id pop-to-root? community-id]] + (let [community-id (or community-id (get-in db [:chats chat-id :community-id]))] + (merge {:fx [(when community-id [:dispatch [:communities/fetch-community @@ -362,7 +365,11 @@ :update-last-opened-at? true}]]) (if pop-to-root? [:dispatch [:chat/pop-to-root-and-navigate-to-chat chat-id]] - [:dispatch [:chat/navigate-to-chat chat-id]])]}))) + [:dispatch [:chat/navigate-to-chat chat-id]])]} + (when-not (get-in db [:chats chat-id :community-id]) + {:db (assoc-in db [:chats chat-id :community-id] community-id)})))) + +(rf/reg-event-fx :communities/navigate-to-community-chat navigate-to-community-chat) (defn get-revealed-accounts [{:keys [db]} [community-id on-success]] diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index 23641cf36b6..920720a83af 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -10,6 +10,7 @@ [status-im.common.json-rpc.events] status-im.common.log status-im.common.password-authentication.events + status-im.common.shared-urls.events status-im.common.signals.events status-im.common.theme.events [status-im.common.toasts.events]