From de6a736c10069265b7dbd1ead7e02026f4af75bd Mon Sep 17 00:00:00 2001 From: Jamie Caprani Date: Tue, 14 Mar 2023 23:14:37 +0000 Subject: [PATCH] feat: add ability to cancel a request to join a community (#14973) https://github.com/status-im/status-go/compare/80d350ad...5d818669 --- src/status_im/communities/core.cljs | 100 +++++++++++++++--- src/status_im/multiaccounts/login/core.cljs | 1 + src/status_im2/constants.cljs | 8 +- .../community_options/component_spec.cljs | 61 ++++++----- .../menus/community_options/view.cljs | 26 ++--- .../communities/menus/generic_menu/view.cljs | 7 +- .../communities/menus/leave/view.cljs | 28 ++++- .../menus/request_to_join/view.cljs | 6 +- .../communities/menus/see_rules/view.cljs | 7 +- .../contexts/communities/overview/view.cljs | 39 ++++--- src/status_im2/subs/communities.cljs | 24 +++-- src/status_im2/subs/communities_test.cljs | 33 ++++++ src/status_im2/subs/root.cljs | 1 + translations/en.json | 3 + 14 files changed, 256 insertions(+), 88 deletions(-) diff --git a/src/status_im/communities/core.cljs b/src/status_im/communities/core.cljs index ec5f83a748..5233fc3064 100644 --- a/src/status_im/communities/core.cljs +++ b/src/status_im/communities/core.cljs @@ -4,6 +4,7 @@ [clojure.walk :as walk] [quo.design-system.colors :as colors] [re-frame.core :as re-frame] + [status-im.utils.types :as types] [status-im.async-storage.core :as async-storage] [status-im.ui.components.emoji-thumbnail.styles :as emoji-thumbnail-styles] [status-im.utils.universal-links.core :as universal-links] @@ -36,9 +37,9 @@ :chatId :chat-id})) (defn <-requests-to-join-community-rpc - [requests] + [requests key-fn] (reduce (fn [acc r] - (assoc acc (:id r) (<-request-to-join-community-rpc r))) + (assoc acc (key-fn r) (<-request-to-join-community-rpc r))) {} requests)) @@ -80,14 +81,28 @@ (update :chats <-chats-rpc) (update :categories <-categories-rpc))) -(defn fetch-community-id-input +(defn- fetch-community-id-input [{:keys [db]}] (:communities/community-id-input db)) +(defn- handle-my-request + [db {:keys [community-id state] :as request}] + {:db (if (= constants/community-request-to-join-state-pending state) + (assoc-in db [:communities/my-pending-requests-to-join community-id] request) + (update-in db [:communities/my-pending-requests-to-join] dissoc community-id))}) + +(defn handle-admin-request + [db {:keys [id community-id] :as request}] + {:db (assoc-in db [:communities/requests-to-join community-id id] request)}) + (rf/defn handle-request-to-join [{:keys [db]} r] - (let [{:keys [id community-id] :as request} (<-request-to-join-community-rpc r)] - {:db (assoc-in db [:communities/requests-to-join community-id id] request)})) + (let [my-public-key (get-in db [:multiaccount :public-key]) + {:keys [id community-id public-key] :as request} (<-request-to-join-community-rpc r) + my-request? (= my-public-key public-key)] + (if my-request? + (handle-my-request db request) + (handle-admin-request db request)))) (rf/defn handle-removed-chats [{:keys [db]} chat-ids] @@ -109,6 +124,14 @@ db communities)}) +(rf/defn handle-my-pending-requests-to-join + {:events [:communities/fetched-my-communities-requests-to-join]} + [{:keys [db]} my-requests] + {:db (assoc db + :communities/my-pending-requests-to-join + (<-requests-to-join-community-rpc (types/js->clj my-requests) + :communityId))}) + (rf/defn handle-response [_ response-js] {:dispatch [:sanitize-messages-and-process-response response-js]}) @@ -130,6 +153,7 @@ [cofx response-js] (let [[event-name _] (:event cofx) community-name (aget response-js "communities" 0 "name")] + (js/console.log "event-name") (rf/merge cofx (handle-response cofx response-js) (toasts/upsert {:icon :correct @@ -139,9 +163,31 @@ :t/requested-to-join-community) {:community community-name})})))) +(rf/defn requested-to-join + {:events [:communities/requested-to-join]} + [cofx response-js] + (let [community-name (aget response-js "communities" 0 "name")] + (rf/merge cofx + (handle-response cofx response-js) + (toasts/upsert {:icon :correct + :icon-color (:positive-01 @colors/theme) + :text (i18n/label + :t/requested-to-join-community + {:community community-name})})))) + +(rf/defn cancelled-requested-to-join + {:events [:communities/cancelled-request-to-join]} + [cofx response-js] + (rf/merge cofx + (handle-response cofx response-js) + (toasts/upsert {:icon :correct + :icon-color (:positive-01 @colors/theme) + :text (i18n/label + :t/you-canceled-the-request)}))) + (rf/defn export {:events [::export-pressed]} - [cofx community-id] + [_ community-id] {:json-rpc/call [{:method "wakuext_exportCommunity" :params [community-id] :on-success #(re-frame/dispatch [:show-popover @@ -175,14 +221,35 @@ (rf/defn request-to-join {:events [:communities/request-to-join]} - [cofx community-id] + [_ community-id] {:json-rpc/call [{:method "wakuext_requestToJoinCommunity" :params [{:communityId community-id}] :js-response true - :on-success #(re-frame/dispatch [::requested-to-join %]) - :on-error #(do - (log/error "failed to request to join community" community-id %) - (re-frame/dispatch [::failed-to-request-to-join %]))}]}) + :on-success #(re-frame/dispatch [:communities/requested-to-join %]) + :on-error (fn [] + (log/error "failed to request to join community" community-id) + (re-frame/dispatch [::failed-to-request-to-join]))}]}) + +(rf/defn get-user-requests-to-join + {:events [:communities/get-user-requests-to-join]} + [_] + {:json-rpc/call [{:method "wakuext_myPendingRequestsToJoin" + :params [] + :js-response true + :on-success #(re-frame/dispatch + [:communities/fetched-my-communities-requests-to-join %]) + :on-error #(log/error "failed to get requests to join community")}]}) + +(rf/defn cancel-request-to-join + {:events [:communities/cancel-request-to-join]} + [_ request-to-join-id] + {:json-rpc/call [{:method "wakuext_cancelRequestToJoinCommunity" + :params [{:id request-to-join-id}] + :on-success #(re-frame/dispatch [:communities/cancelled-request-to-join %]) + :js-response true + :on-error #(log/error "failed to cancel request to join community" + request-to-join-id + %)}]}) (rf/defn leave {:events [:communities/leave]} @@ -196,11 +263,10 @@ :params [community-id] :js-response true :on-success #(re-frame/dispatch [::left %]) - :on-error #(do - (log/error "failed to leave community" - community-id - %) - (re-frame/dispatch [::failed-to-leave %]))}]})) + :on-error (fn [] + (log/error "failed to leave community" + community-id) + (re-frame/dispatch [::failed-to-leave]))}]})) (rf/defn status-tag-pressed {:events [:communities/status-tag-pressed]} @@ -555,7 +621,7 @@ [{:keys [db]} community-id requests] {:db (assoc-in db [:communities/requests-to-join community-id] - (<-requests-to-join-community-rpc requests))}) + (<-requests-to-join-community-rpc requests :id))}) (rf/defn fetch-requests-to-join {:events [::fetch-requests-to-join]} diff --git a/src/status_im/multiaccounts/login/core.cljs b/src/status_im/multiaccounts/login/core.cljs index 2cd21547fd..8fcc5371e2 100644 --- a/src/status_im/multiaccounts/login/core.cljs +++ b/src/status_im/multiaccounts/login/core.cljs @@ -405,6 +405,7 @@ (data-store.chats/fetch-chats-rpc {:on-success #(do (re-frame/dispatch [:chats-list/load-success %]) + (rf/dispatch [:communities/get-user-requests-to-join]) (re-frame/dispatch [::get-chats-callback]))}) (initialize-appearance) (initialize-communities-enabled) diff --git a/src/status_im2/constants.cljs b/src/status_im2/constants.cljs index 8a5c90a3ac..ff7b4c8d35 100644 --- a/src/status_im2/constants.cljs +++ b/src/status_im2/constants.cljs @@ -121,6 +121,7 @@ (def ^:const status-create-address "status_createaddress") +(def ^:const community-unknown-membership-access 0) (def ^:const community-no-membership-access 1) (def ^:const community-invitation-only-access 2) (def ^:const community-on-request-access 3) @@ -132,7 +133,12 @@ (def ^:const community-channel-access-invitation-only 2) (def ^:const community-channel-access-on-request 3) -; BIP44 Wallet Root Key, the extended key from which any wallet can be derived +(def ^:const community-request-to-join-state-pending 1) +(def ^:const community-request-to-join-state-declined 2) +(def ^:const community-request-to-join-state-accepted 3) +(def ^:const community-request-to-join-state-cancelled 4) + + ; BIP44 Wallet Root Key, the extended key from which any wallet can be derived (def ^:const path-wallet-root "m/44'/60'/0'/0") ; EIP1581 Root Key, the extended key from which any whisper key/encryption key can be derived (def ^:const path-eip1581 "m/43'/60'/1581'") diff --git a/src/status_im2/contexts/communities/menus/community_options/component_spec.cljs b/src/status_im2/contexts/communities/menus/community_options/component_spec.cljs index 59bb1501e7..d0ce24a1df 100644 --- a/src/status_im2/contexts/communities/menus/community_options/component_spec.cljs +++ b/src/status_im2/contexts/communities/menus/community_options/component_spec.cljs @@ -2,24 +2,19 @@ (ns status-im2.contexts.communities.menus.community-options.component-spec (:require [re-frame.core :as re-frame] [test-helpers.component :as h] - [utils.i18n :as i18n] - [status-im2.setup.i18n-resources :as i18n-resources] [status-im2.contexts.communities.menus.community-options.view :as options])) -(defn init - [] - (i18n/set-language "en") - (i18n-resources/load-language "en")) - -(defn setup-sub - [opts] - (re-frame/reg-sub - :communities/community - (fn [_] opts))) +(defn setup-subs + [subs] + (doseq [keyval subs] + (re-frame/reg-sub + (key keyval) + (fn [_] (val keyval))))) (h/describe "community options for bottom sheets" (h/test "joined options - Non token Gated" - (setup-sub {:joined true}) + (setup-subs {:communities/my-pending-request-to-join nil + :communities/community {:joined true}}) (h/render [options/community-options-bottom-sheet {:id "test"}]) (-> (h/expect (h/get-by-translation-text :view-members)) (.toBeTruthy)) @@ -41,8 +36,9 @@ (.toBeTruthy))) (h/test "joined options - Token Gated" - (setup-sub {:joined true - :token-gated? true}) + (setup-subs {:communities/my-pending-request-to-join nil + :communities/community {:joined true + :token-gated? true}}) (h/render [options/community-options-bottom-sheet {:id "test"}]) (-> (h/expect (h/get-by-translation-text :view-members)) (.toBeTruthy)) @@ -66,7 +62,8 @@ (.toBeTruthy))) (h/test "admin options - Non token Gated" - (setup-sub {:admin true}) + (setup-subs {:communities/my-pending-request-to-join nil + :communities/community {:admin true}}) (h/render [options/community-options-bottom-sheet {:id "test"}]) (-> (h/expect (h/get-by-translation-text :view-members)) (.toBeTruthy)) @@ -88,8 +85,9 @@ (.toBeTruthy))) (h/test "admin options - Token Gated" - (setup-sub {:admin true - :token-gated? true}) + (setup-subs {:communities/my-pending-request-to-join nil + :communities/community {:admin true + :token-gated? true}}) (h/render [options/community-options-bottom-sheet {:id "test"}]) (-> (h/expect (h/get-by-translation-text :view-members)) (.toBeTruthy)) @@ -111,7 +109,8 @@ (.toBeTruthy))) (h/test "request sent options - Non token Gated" - (setup-sub {:requested-to-join-at true}) + (setup-subs {:communities/my-pending-request-to-join "mock-id" + :communities/community {}}) (h/render [options/community-options-bottom-sheet {:id "test"}]) (-> (h/expect (h/get-by-translation-text :view-members)) (.toBeTruthy)) @@ -127,8 +126,8 @@ (.toBeTruthy))) (h/test "request sent options - Token Gated" - (setup-sub {:requested-to-join-at 100 - :token-gated? true}) + (setup-subs {:communities/my-pending-request-to-join "mock-id" + :communities/community {:token-gated? true}}) (h/render [options/community-options-bottom-sheet {:id "test"}]) (-> (h/expect (h/get-by-translation-text :invite-people-from-contacts)) (.toBeTruthy)) @@ -142,7 +141,8 @@ (.toBeTruthy))) (h/test "banned options - Non token Gated" - (setup-sub {:banList true}) + (setup-subs {:communities/my-pending-request-to-join nil + :communities/community {:banList true}}) (h/render [options/community-options-bottom-sheet {:id "test"}]) (-> (h/expect (h/get-by-translation-text :view-members)) (.toBeTruthy)) @@ -156,8 +156,9 @@ (.toBeTruthy))) (h/test "banned options - Token Gated" - (setup-sub {:banList 100 - :token-gated? true}) + (setup-subs {:communities/my-pending-request-to-join nil + :communities/community {:banList 100 + :token-gated? true}}) (h/render [options/community-options-bottom-sheet {:id "test"}]) (-> (h/expect (h/get-by-translation-text :invite-people-from-contacts)) (.toBeTruthy)) @@ -169,8 +170,9 @@ (.toBeTruthy))) (h/test "banned options - Token Gated" - (setup-sub {:banList 100 - :token-gated? true}) + (setup-subs {:communities/my-pending-request-to-join nil + :communities/community {:banList 100 + :token-gated? true}}) (h/render [options/community-options-bottom-sheet {:id "test"}]) (-> (h/expect (h/get-by-translation-text :invite-people-from-contacts)) (.toBeTruthy)) @@ -182,9 +184,10 @@ (.toBeTruthy))) (h/test "joined and muted community" - (setup-sub {:joined true - :muted true - :token-gated? true}) + (setup-subs {:communities/my-pending-request-to-join nil + :communities/community {:joined true + :muted true + :token-gated? true}}) (h/render [options/community-options-bottom-sheet {:id "test"}]) (-> (h/expect (h/get-by-translation-text :unmute-community)) (.toBeTruthy)))) diff --git a/src/status_im2/contexts/communities/menus/community_options/view.cljs b/src/status_im2/contexts/communities/menus/community_options/view.cljs index 7bfe531054..635077f091 100644 --- a/src/status_im2/contexts/communities/menus/community_options/view.cljs +++ b/src/status_im2/contexts/communities/menus/community_options/view.cljs @@ -85,19 +85,21 @@ {:icon :i/log-out :label (i18n/label :t/leave-community) :accessibility-label :leave-community - :danger? true :on-press #(rf/dispatch [:bottom-sheet/show-sheet {:content (constantly [leave-menu/leave-sheet id]) :content-height 400}])}) (defn cancel-request-to-join - [id] + [id request-id] {:icon :i/block :label (i18n/label :t/cancel-request-to-join) :accessibility-label :cancel-request-to-join :danger? true - :on-press #(js/alert (str "implement action" id))}) + :on-press #(rf/dispatch [:bottom-sheet/show-sheet + {:content (constantly [leave-menu/cancel-request-sheet id + request-id]) + :content-height 400}])}) (defn edit-community [id] @@ -117,9 +119,9 @@ (share-community id)]]) (defn join-request-sent-options - [id token-gated?] + [id token-gated? request-id] [(conj (first (not-joined-options id token-gated?)) - (assoc (cancel-request-to-join id) :add-divider? true))]) + (assoc (cancel-request-to-join id request-id) :add-divider? true))]) (defn banned-options [id token-gated?] @@ -153,15 +155,15 @@ (defn get-context-drawers [{:keys [id]}] - (let [{:keys [token-gated? admin joined requested-to-join-at + (let [{:keys [token-gated? admin joined muted banList]} (rf/sub [:communities/community id]) - request-sent? (pos? requested-to-join-at)] + request-id (rf/sub [:communities/my-pending-request-to-join id])] (cond - admin (owner-options id token-gated? muted) - joined (joined-options id token-gated? muted) - request-sent? (join-request-sent-options id token-gated?) - banList (banned-options id token-gated?) - :else (not-joined-options id token-gated?)))) + admin (owner-options id token-gated? muted) + joined (joined-options id token-gated? muted) + request-id (join-request-sent-options id token-gated? request-id) + banList (banned-options id token-gated?) + :else (not-joined-options id token-gated?)))) (defn community-options-bottom-sheet [id] diff --git a/src/status_im2/contexts/communities/menus/generic_menu/view.cljs b/src/status_im2/contexts/communities/menus/generic_menu/view.cljs index dbf97c1fa8..58c37f700a 100644 --- a/src/status_im2/contexts/communities/menus/generic_menu/view.cljs +++ b/src/status_im2/contexts/communities/menus/generic_menu/view.cljs @@ -1,12 +1,11 @@ (ns status-im2.contexts.communities.menus.generic-menu.view - (:require [utils.i18n :as i18n] - [quo2.core :as quo] + (:require [quo2.core :as quo] [status-im2.contexts.communities.menus.generic-menu.style :as style] [react-native.core :as rn] [utils.re-frame :as rf])) (defn view - [id children] + [{:keys [id title]} children] (let [{:keys [name images]} (rf/sub [:communities/community id])] [rn/view {:style style/container} [rn/view {:style style/inner-container} @@ -14,7 +13,7 @@ {:accessibility-label :communities-join-community :weight :semi-bold :size :heading-1} - (i18n/label :t/leave-community?)]] + title]] [quo/context-tag {:style style/context-tag} (:thumbnail images) name] diff --git a/src/status_im2/contexts/communities/menus/leave/view.cljs b/src/status_im2/contexts/communities/menus/leave/view.cljs index 18e91802b7..2e36669fcf 100644 --- a/src/status_im2/contexts/communities/menus/leave/view.cljs +++ b/src/status_im2/contexts/communities/menus/leave/view.cljs @@ -14,7 +14,8 @@ (defn leave-sheet [id] [generic-menu/view - id + {:id id + :title (i18n/label :t/leave-community?)} [:<> [quo/text {:accessibility-label :communities-join-community @@ -32,3 +33,28 @@ {:on-press #(hide-sheet-and-dispatch [:communities/leave id]) :style style/action-button} (i18n/label :t/leave-community)]]]]) + +(defn cancel-request-sheet + [id request-id] + [generic-menu/view + {:id id + :title (i18n/label :t/cancel-request?)} + [:<> + [quo/text + {:accessibility-label :communities-join-community + :size :paragraph-1 + :style style/text} + (i18n/label :t/if-you-cancel)] + [rn/view + {:style style/button-container} + [quo/button + {:accessibility-label :cancel-button + :on-press #(rf/dispatch [:bottom-sheet/hide]) + :type :grey + :style style/cancel-button} + (i18n/label :t/close)] + [quo/button + {:accessibility-label :confirm-button + :on-press #(hide-sheet-and-dispatch [:communities/cancel-request-to-join request-id]) + :style style/action-button} + (i18n/label :t/confirm)]]]]) diff --git a/src/status_im2/contexts/communities/menus/request_to_join/view.cljs b/src/status_im2/contexts/communities/menus/request_to_join/view.cljs index 19fe469a17..9e488d729a 100644 --- a/src/status_im2/contexts/communities/menus/request_to_join/view.cljs +++ b/src/status_im2/contexts/communities/menus/request_to_join/view.cljs @@ -23,7 +23,9 @@ can-join? can-request-access? requested-to-join-at]}] - (let [agreed-to-rules? (reagent/atom false)] + (let [agreed-to-rules? (reagent/atom false) + pending? (rf/sub [:communities/my-pending-request-to-join id]) + ] [safe-area/consumer (fn [insets] [:f> @@ -73,7 +75,7 @@ (rf/dispatch [:communities/join id]) (rf/dispatch [:bottom-sheet/hide])) (do (and can-request-access? - (not (pos? requested-to-join-at)) + (not pending?) (requests/can-request-access-again? requested-to-join-at)) (rf/dispatch [:communities/request-to-join id]) diff --git a/src/status_im2/contexts/communities/menus/see_rules/view.cljs b/src/status_im2/contexts/communities/menus/see_rules/view.cljs index 8e91bbd3db..f14a242d6f 100644 --- a/src/status_im2/contexts/communities/menus/see_rules/view.cljs +++ b/src/status_im2/contexts/communities/menus/see_rules/view.cljs @@ -1,9 +1,12 @@ (ns status-im2.contexts.communities.menus.see-rules.view (:require [status-im2.contexts.communities.menus.generic-menu.view :as generic-menu] - [status-im2.contexts.communities.menus.community-rules-list.view :as community-rules])) + [status-im2.contexts.communities.menus.community-rules-list.view :as community-rules] + [utils.i18n :as i18n])) (defn view [id] [generic-menu/view - id + {:id id + :title (i18n/label :t/community-rules) + } [community-rules/view community-rules/rules]]) diff --git a/src/status_im2/contexts/communities/overview/view.cljs b/src/status_im2/contexts/communities/overview/view.cljs index 99c6ba799c..8ed62c3bf2 100644 --- a/src/status_im2/contexts/communities/overview/view.cljs +++ b/src/status_im2/contexts/communities/overview/view.cljs @@ -107,15 +107,25 @@ (i18n/label :t/join-open-community) (i18n/label :t/request-to-join-community))) +(defn get-access-type + [access] + (case access + constants/community-no-membership-access :open + constants/community-invitation-only-access :invite-only + constants/community-on-request-access :request-access + :unknown-access)) + (defn join-community - [{:keys [joined can-join? requested-to-join-at + [{:keys [joined can-join? community-color permissions] - :as community}] - (let [pending? (pos? requested-to-join-at) - is-open? (not= constants/community-channel-access-on-request (:access permissions)) - node-offline? (and can-join? (not joined) (pos? requested-to-join-at))] + :as community} pending?] + (let [access-type (get-access-type (:access permissions)) + unknown-access? (= access-type :unknown-access) + invite-only? (= access-type :invite-only) + is-open? (= access-type :open) + node-offline? (and can-join? (not joined) pending?)] [:<> - (when-not (or joined pending?) + (when-not (or joined pending? invite-only? unknown-access?) [quo/button {:on-press #(rf/dispatch [:bottom-sheet/show-sheet @@ -210,12 +220,11 @@ (defn community-content [{:keys [name description locked joined images - status tokens tags requested-to-join-at id] - :as community} + status tokens tags id] + :as community} pending? {:keys [on-categories-heights-changed on-first-channel-height-changed]}] - (let [pending? (pos? requested-to-join-at) - thumbnail-image (get-in images [:thumbnail]) + (let [thumbnail-image (:thumbnail images) chats-by-category (rf/sub [:communities/categorized-channels id]) users (rf/sub [:communities/users id])] [rn/view @@ -253,7 +262,7 @@ [rn/view {:margin-top 12}] [quo/community-tags tags] [preview-user-list users] - [join-community community]] + [join-community community pending?]] [channel-list-component {:on-categories-heights-changed #(on-categories-heights-changed %) :on-first-channel-height-changed #(on-first-channel-height-changed %)} @@ -290,7 +299,7 @@ scroll-height (reagent/atom 0) cover {:uri (get-in images [:banner :uri])} logo {:uri (get-in images [:thumbnail :uri])}] - (fn [community] + (fn [community pending?] [scroll-page/scroll-page {:cover-image cover :logo logo @@ -312,16 +321,18 @@ @categories-heights))}] [community-content community + pending? {:on-categories-heights-changed #(reset! categories-heights %) :on-first-channel-height-changed #(reset! first-channel-height %)}]]))) (defn overview [] (let [id (rf/sub [:get-screen-params :community-overview]) - community (rf/sub [:communities/community id])] + community (rf/sub [:communities/community id]) + pending? (rf/sub [:communities/my-pending-request-to-join id])] [rn/view {:style style/community-overview-container} - [community-card-page-view community] + [community-card-page-view community pending?] [floating-shell-button/floating-shell-button {:jump-to {:on-press #(rf/dispatch [:shell/navigate-to-jump-to]) :label (i18n/label :t/jump-to)}} diff --git a/src/status_im2/subs/communities.cljs b/src/status_im2/subs/communities.cljs index e80ee75c13..6cfbf53b55 100644 --- a/src/status_im2/subs/communities.cljs +++ b/src/status_im2/subs/communities.cljs @@ -123,14 +123,20 @@ (re-frame/reg-sub :communities/grouped-by-status :<- [:communities/communities] - (fn [communities] + :<- [:communities/my-pending-requests-to-join] + ;; Return communities splitted by level of user participation. Some communities user + ;; already joined, to some of them join request sent and others were opened one day + ;; and their data remained in app-db. + ;; Result map has form: {:joined [id1, id2] :pending [id3, id5] :opened [id4]}" + (fn [[communities requests]] (reduce (fn [acc community] - (let [joined? (:joined community) - requested? (pos? (:requested-to-join-at community))] ;; this looks suspicious + (let [joined? (:joined community) + community-id (:id community) + pending? (boolean (get requests community-id))] (cond - joined? (update acc :joined conj community) - requested? (update acc :pending conj community) - :else (update acc :opened conj community)))) + joined? (update acc :joined conj community) + pending? (update acc :pending conj community) + :else (update acc :opened conj community)))) {:joined [] :pending [] :opened []} communities))) @@ -152,6 +158,12 @@ (get communities identity) counts))) +(re-frame/reg-sub + :communities/my-pending-request-to-join + :<- [:communities/my-pending-requests-to-join] + (fn [requests [_ community-id]] + (:id (get requests community-id)))) + (re-frame/reg-sub :communities/edited-community :<- [:communities] diff --git a/src/status_im2/subs/communities_test.cljs b/src/status_im2/subs/communities_test.cljs index 00ed8c7966..f0ec230896 100644 --- a/src/status_im2/subs/communities_test.cljs +++ b/src/status_im2/subs/communities_test.cljs @@ -156,3 +156,36 @@ [{:name "chat1" :emoji nil :locked? false :id "0x1" :unread-messages? true :mentions-count 2} {:name "chat2" :emoji nil :locked? true :id "0x2" :unread-messages? false :mentions-count 0}]} (rf/sub [sub-name "0x1"]))))) + +(h/deftest-sub :communities/my-pending-requests-to-join + [sub-name] + (testing "no requests" + (swap! rf-db/app-db assoc + :communities/my-pending-requests-to-join + {}) + (is (= {} + (rf/sub [sub-name])))) + (testing "users requests to join different communities" + (swap! rf-db/app-db assoc + :communities/my-pending-requests-to-join + {:community-id-1 {:id :request-id-1} + :community-id-2 {:id :request-id-2}}) + (is (= {:community-id-1 {:id :request-id-1} + :community-id-2 {:id :request-id-2}} + (rf/sub [sub-name]))))) + +(h/deftest-sub :communities/my-pending-request-to-join + [sub-name] + (testing "no request for community" + (swap! rf-db/app-db assoc + :communities/my-pending-requests-to-join + {}) + (is (= nil + (rf/sub [sub-name :community-id-1])))) + (testing "users request to join a specific communities" + (swap! rf-db/app-db assoc + :communities/my-pending-requests-to-join + {:community-id-1 {:id :request-id-1} + :community-id-2 {:id :request-id-2}}) + (is (= :request-id-1 + (rf/sub [sub-name :community-id-1]))))) diff --git a/src/status_im2/subs/root.cljs b/src/status_im2/subs/root.cljs index 14482d2ba1..b8e9889dca 100644 --- a/src/status_im2/subs/root.cljs +++ b/src/status_im2/subs/root.cljs @@ -245,6 +245,7 @@ (reg-root-key-sub :communities/community-id-input :communities/community-id-input) (reg-root-key-sub :communities/enabled? :communities/enabled?) (reg-root-key-sub :communities/resolve-community-info :communities/resolve-community-info) +(reg-root-key-sub :communities/my-pending-requests-to-join :communities/my-pending-requests-to-join) (reg-root-key-sub :activity-center :activity-center) diff --git a/translations/en.json b/translations/en.json index f786be2e33..fff0540eb4 100644 --- a/translations/en.json +++ b/translations/en.json @@ -127,6 +127,7 @@ "can-not-add-yourself": "That's you, to start a chat choose someone else", "cancel": "Cancel", "cancel-keycard-setup": "Cancel Keycard setup", + "cancel-request?": "Cancel request?", "cancel-request-to-join": "Cancel request to join", "cannot-read-card": "Can't read card.\nPlease hold it to the back of your phone", "cannot-use-default-pin": "Passcode 000000 is not allowed.\nPlease use another number", @@ -663,6 +664,7 @@ "home": "Home", "hooks": "Hooks", "identifier": "Identifier", + "if-you-cancel": "If you cancel, you can request to join this community at any point.", "image-remove-current": "Remove current photo", "image-source-gallery": "Select from gallery", "image-source-make-photo": "Capture", @@ -1466,6 +1468,7 @@ "you-are-all-set": "You’re all set!", "you-are-all-set-description": "If you lose your phone, you can now access your funds and chat key using your seed phrase", "you-can-change-account": "You can change the account name and color to what you wish", + "you-canceled-the-request": "You canceled the request to join", "you-dont-have-stickers": "You don’t have any stickers yet", "you-dont-have-contacts-invite-friends": "You don’t have any contacts yet.\nInvite your friends to start chatting.", "your-contact-code": "Granting access authorizes this DApp to retrieve your chat key",