feat: add ability to cancel a request to join a community (#14973)

80d350ad...5d818669
This commit is contained in:
Jamie Caprani 2023-03-14 23:14:37 +00:00 committed by GitHub
parent 61600a534b
commit de6a736c10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 256 additions and 88 deletions

View File

@ -4,6 +4,7 @@
[clojure.walk :as walk] [clojure.walk :as walk]
[quo.design-system.colors :as colors] [quo.design-system.colors :as colors]
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[status-im.utils.types :as types]
[status-im.async-storage.core :as async-storage] [status-im.async-storage.core :as async-storage]
[status-im.ui.components.emoji-thumbnail.styles :as emoji-thumbnail-styles] [status-im.ui.components.emoji-thumbnail.styles :as emoji-thumbnail-styles]
[status-im.utils.universal-links.core :as universal-links] [status-im.utils.universal-links.core :as universal-links]
@ -36,9 +37,9 @@
:chatId :chat-id})) :chatId :chat-id}))
(defn <-requests-to-join-community-rpc (defn <-requests-to-join-community-rpc
[requests] [requests key-fn]
(reduce (fn [acc r] (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)) requests))
@ -80,14 +81,28 @@
(update :chats <-chats-rpc) (update :chats <-chats-rpc)
(update :categories <-categories-rpc))) (update :categories <-categories-rpc)))
(defn fetch-community-id-input (defn- fetch-community-id-input
[{:keys [db]}] [{:keys [db]}]
(:communities/community-id-input 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 (rf/defn handle-request-to-join
[{:keys [db]} r] [{:keys [db]} r]
(let [{:keys [id community-id] :as request} (<-request-to-join-community-rpc r)] (let [my-public-key (get-in db [:multiaccount :public-key])
{:db (assoc-in db [:communities/requests-to-join community-id id] request)})) {: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 (rf/defn handle-removed-chats
[{:keys [db]} chat-ids] [{:keys [db]} chat-ids]
@ -109,6 +124,14 @@
db db
communities)}) 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 (rf/defn handle-response
[_ response-js] [_ response-js]
{:dispatch [:sanitize-messages-and-process-response response-js]}) {:dispatch [:sanitize-messages-and-process-response response-js]})
@ -130,6 +153,7 @@
[cofx response-js] [cofx response-js]
(let [[event-name _] (:event cofx) (let [[event-name _] (:event cofx)
community-name (aget response-js "communities" 0 "name")] community-name (aget response-js "communities" 0 "name")]
(js/console.log "event-name")
(rf/merge cofx (rf/merge cofx
(handle-response cofx response-js) (handle-response cofx response-js)
(toasts/upsert {:icon :correct (toasts/upsert {:icon :correct
@ -139,9 +163,31 @@
:t/requested-to-join-community) :t/requested-to-join-community)
{:community community-name})})))) {: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 (rf/defn export
{:events [::export-pressed]} {:events [::export-pressed]}
[cofx community-id] [_ community-id]
{:json-rpc/call [{:method "wakuext_exportCommunity" {:json-rpc/call [{:method "wakuext_exportCommunity"
:params [community-id] :params [community-id]
:on-success #(re-frame/dispatch [:show-popover :on-success #(re-frame/dispatch [:show-popover
@ -175,14 +221,35 @@
(rf/defn request-to-join (rf/defn request-to-join
{:events [:communities/request-to-join]} {:events [:communities/request-to-join]}
[cofx community-id] [_ community-id]
{:json-rpc/call [{:method "wakuext_requestToJoinCommunity" {:json-rpc/call [{:method "wakuext_requestToJoinCommunity"
:params [{:communityId community-id}] :params [{:communityId community-id}]
:js-response true :js-response true
:on-success #(re-frame/dispatch [::requested-to-join %]) :on-success #(re-frame/dispatch [:communities/requested-to-join %])
:on-error #(do :on-error (fn []
(log/error "failed to request to join community" community-id %) (log/error "failed to request to join community" community-id)
(re-frame/dispatch [::failed-to-request-to-join %]))}]}) (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 (rf/defn leave
{:events [:communities/leave]} {:events [:communities/leave]}
@ -196,11 +263,10 @@
:params [community-id] :params [community-id]
:js-response true :js-response true
:on-success #(re-frame/dispatch [::left %]) :on-success #(re-frame/dispatch [::left %])
:on-error #(do :on-error (fn []
(log/error "failed to leave community" (log/error "failed to leave community"
community-id community-id)
%) (re-frame/dispatch [::failed-to-leave]))}]}))
(re-frame/dispatch [::failed-to-leave %]))}]}))
(rf/defn status-tag-pressed (rf/defn status-tag-pressed
{:events [:communities/status-tag-pressed]} {:events [:communities/status-tag-pressed]}
@ -555,7 +621,7 @@
[{:keys [db]} community-id requests] [{:keys [db]} community-id requests]
{:db (assoc-in db {:db (assoc-in db
[:communities/requests-to-join community-id] [: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 (rf/defn fetch-requests-to-join
{:events [::fetch-requests-to-join]} {:events [::fetch-requests-to-join]}

View File

@ -405,6 +405,7 @@
(data-store.chats/fetch-chats-rpc (data-store.chats/fetch-chats-rpc
{:on-success {:on-success
#(do (re-frame/dispatch [:chats-list/load-success %]) #(do (re-frame/dispatch [:chats-list/load-success %])
(rf/dispatch [:communities/get-user-requests-to-join])
(re-frame/dispatch [::get-chats-callback]))}) (re-frame/dispatch [::get-chats-callback]))})
(initialize-appearance) (initialize-appearance)
(initialize-communities-enabled) (initialize-communities-enabled)

View File

@ -121,6 +121,7 @@
(def ^:const status-create-address "status_createaddress") (def ^:const status-create-address "status_createaddress")
(def ^:const community-unknown-membership-access 0)
(def ^:const community-no-membership-access 1) (def ^:const community-no-membership-access 1)
(def ^:const community-invitation-only-access 2) (def ^:const community-invitation-only-access 2)
(def ^:const community-on-request-access 3) (def ^:const community-on-request-access 3)
@ -132,7 +133,12 @@
(def ^:const community-channel-access-invitation-only 2) (def ^:const community-channel-access-invitation-only 2)
(def ^:const community-channel-access-on-request 3) (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") (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 ; EIP1581 Root Key, the extended key from which any whisper key/encryption key can be derived
(def ^:const path-eip1581 "m/43'/60'/1581'") (def ^:const path-eip1581 "m/43'/60'/1581'")

View File

@ -2,24 +2,19 @@
(ns status-im2.contexts.communities.menus.community-options.component-spec (ns status-im2.contexts.communities.menus.community-options.component-spec
(:require [re-frame.core :as re-frame] (:require [re-frame.core :as re-frame]
[test-helpers.component :as h] [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])) [status-im2.contexts.communities.menus.community-options.view :as options]))
(defn init (defn setup-subs
[] [subs]
(i18n/set-language "en") (doseq [keyval subs]
(i18n-resources/load-language "en"))
(defn setup-sub
[opts]
(re-frame/reg-sub (re-frame/reg-sub
:communities/community (key keyval)
(fn [_] opts))) (fn [_] (val keyval)))))
(h/describe "community options for bottom sheets" (h/describe "community options for bottom sheets"
(h/test "joined options - Non token Gated" (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/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :view-members)) (-> (h/expect (h/get-by-translation-text :view-members))
(.toBeTruthy)) (.toBeTruthy))
@ -41,8 +36,9 @@
(.toBeTruthy))) (.toBeTruthy)))
(h/test "joined options - Token Gated" (h/test "joined options - Token Gated"
(setup-sub {:joined true (setup-subs {:communities/my-pending-request-to-join nil
:token-gated? true}) :communities/community {:joined true
:token-gated? true}})
(h/render [options/community-options-bottom-sheet {:id "test"}]) (h/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :view-members)) (-> (h/expect (h/get-by-translation-text :view-members))
(.toBeTruthy)) (.toBeTruthy))
@ -66,7 +62,8 @@
(.toBeTruthy))) (.toBeTruthy)))
(h/test "admin options - Non token Gated" (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/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :view-members)) (-> (h/expect (h/get-by-translation-text :view-members))
(.toBeTruthy)) (.toBeTruthy))
@ -88,8 +85,9 @@
(.toBeTruthy))) (.toBeTruthy)))
(h/test "admin options - Token Gated" (h/test "admin options - Token Gated"
(setup-sub {:admin true (setup-subs {:communities/my-pending-request-to-join nil
:token-gated? true}) :communities/community {:admin true
:token-gated? true}})
(h/render [options/community-options-bottom-sheet {:id "test"}]) (h/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :view-members)) (-> (h/expect (h/get-by-translation-text :view-members))
(.toBeTruthy)) (.toBeTruthy))
@ -111,7 +109,8 @@
(.toBeTruthy))) (.toBeTruthy)))
(h/test "request sent options - Non token Gated" (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/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :view-members)) (-> (h/expect (h/get-by-translation-text :view-members))
(.toBeTruthy)) (.toBeTruthy))
@ -127,8 +126,8 @@
(.toBeTruthy))) (.toBeTruthy)))
(h/test "request sent options - Token Gated" (h/test "request sent options - Token Gated"
(setup-sub {:requested-to-join-at 100 (setup-subs {:communities/my-pending-request-to-join "mock-id"
:token-gated? true}) :communities/community {:token-gated? true}})
(h/render [options/community-options-bottom-sheet {:id "test"}]) (h/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts)) (-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
(.toBeTruthy)) (.toBeTruthy))
@ -142,7 +141,8 @@
(.toBeTruthy))) (.toBeTruthy)))
(h/test "banned options - Non token Gated" (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/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :view-members)) (-> (h/expect (h/get-by-translation-text :view-members))
(.toBeTruthy)) (.toBeTruthy))
@ -156,8 +156,9 @@
(.toBeTruthy))) (.toBeTruthy)))
(h/test "banned options - Token Gated" (h/test "banned options - Token Gated"
(setup-sub {:banList 100 (setup-subs {:communities/my-pending-request-to-join nil
:token-gated? true}) :communities/community {:banList 100
:token-gated? true}})
(h/render [options/community-options-bottom-sheet {:id "test"}]) (h/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts)) (-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
(.toBeTruthy)) (.toBeTruthy))
@ -169,8 +170,9 @@
(.toBeTruthy))) (.toBeTruthy)))
(h/test "banned options - Token Gated" (h/test "banned options - Token Gated"
(setup-sub {:banList 100 (setup-subs {:communities/my-pending-request-to-join nil
:token-gated? true}) :communities/community {:banList 100
:token-gated? true}})
(h/render [options/community-options-bottom-sheet {:id "test"}]) (h/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts)) (-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
(.toBeTruthy)) (.toBeTruthy))
@ -182,9 +184,10 @@
(.toBeTruthy))) (.toBeTruthy)))
(h/test "joined and muted community" (h/test "joined and muted community"
(setup-sub {:joined true (setup-subs {:communities/my-pending-request-to-join nil
:communities/community {:joined true
:muted true :muted true
:token-gated? true}) :token-gated? true}})
(h/render [options/community-options-bottom-sheet {:id "test"}]) (h/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :unmute-community)) (-> (h/expect (h/get-by-translation-text :unmute-community))
(.toBeTruthy)))) (.toBeTruthy))))

View File

@ -85,19 +85,21 @@
{:icon :i/log-out {:icon :i/log-out
:label (i18n/label :t/leave-community) :label (i18n/label :t/leave-community)
:accessibility-label :leave-community :accessibility-label :leave-community
:danger? true :danger? true
:on-press #(rf/dispatch [:bottom-sheet/show-sheet :on-press #(rf/dispatch [:bottom-sheet/show-sheet
{:content (constantly [leave-menu/leave-sheet id]) {:content (constantly [leave-menu/leave-sheet id])
:content-height 400}])}) :content-height 400}])})
(defn cancel-request-to-join (defn cancel-request-to-join
[id] [id request-id]
{:icon :i/block {:icon :i/block
:label (i18n/label :t/cancel-request-to-join) :label (i18n/label :t/cancel-request-to-join)
:accessibility-label :cancel-request-to-join :accessibility-label :cancel-request-to-join
:danger? true :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 (defn edit-community
[id] [id]
@ -117,9 +119,9 @@
(share-community id)]]) (share-community id)]])
(defn join-request-sent-options (defn join-request-sent-options
[id token-gated?] [id token-gated? request-id]
[(conj (first (not-joined-options id token-gated?)) [(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 (defn banned-options
[id token-gated?] [id token-gated?]
@ -153,13 +155,13 @@
(defn get-context-drawers (defn get-context-drawers
[{:keys [id]}] [{: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]) 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 (cond
admin (owner-options id token-gated? muted) admin (owner-options id token-gated? muted)
joined (joined-options id token-gated? muted) joined (joined-options id token-gated? muted)
request-sent? (join-request-sent-options id token-gated?) request-id (join-request-sent-options id token-gated? request-id)
banList (banned-options id token-gated?) banList (banned-options id token-gated?)
:else (not-joined-options id token-gated?)))) :else (not-joined-options id token-gated?))))

View File

@ -1,12 +1,11 @@
(ns status-im2.contexts.communities.menus.generic-menu.view (ns status-im2.contexts.communities.menus.generic-menu.view
(:require [utils.i18n :as i18n] (:require [quo2.core :as quo]
[quo2.core :as quo]
[status-im2.contexts.communities.menus.generic-menu.style :as style] [status-im2.contexts.communities.menus.generic-menu.style :as style]
[react-native.core :as rn] [react-native.core :as rn]
[utils.re-frame :as rf])) [utils.re-frame :as rf]))
(defn view (defn view
[id children] [{:keys [id title]} children]
(let [{:keys [name images]} (rf/sub [:communities/community id])] (let [{:keys [name images]} (rf/sub [:communities/community id])]
[rn/view {:style style/container} [rn/view {:style style/container}
[rn/view {:style style/inner-container} [rn/view {:style style/inner-container}
@ -14,7 +13,7 @@
{:accessibility-label :communities-join-community {:accessibility-label :communities-join-community
:weight :semi-bold :weight :semi-bold
:size :heading-1} :size :heading-1}
(i18n/label :t/leave-community?)]] title]]
[quo/context-tag [quo/context-tag
{:style style/context-tag} {:style style/context-tag}
(:thumbnail images) name] (:thumbnail images) name]

View File

@ -14,7 +14,8 @@
(defn leave-sheet (defn leave-sheet
[id] [id]
[generic-menu/view [generic-menu/view
id {:id id
:title (i18n/label :t/leave-community?)}
[:<> [:<>
[quo/text [quo/text
{:accessibility-label :communities-join-community {:accessibility-label :communities-join-community
@ -32,3 +33,28 @@
{:on-press #(hide-sheet-and-dispatch [:communities/leave id]) {:on-press #(hide-sheet-and-dispatch [:communities/leave id])
:style style/action-button} :style style/action-button}
(i18n/label :t/leave-community)]]]]) (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)]]]])

View File

@ -23,7 +23,9 @@
can-join? can-join?
can-request-access? can-request-access?
requested-to-join-at]}] 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 [safe-area/consumer
(fn [insets] (fn [insets]
[:f> [:f>
@ -73,7 +75,7 @@
(rf/dispatch [:communities/join id]) (rf/dispatch [:communities/join id])
(rf/dispatch [:bottom-sheet/hide])) (rf/dispatch [:bottom-sheet/hide]))
(do (and can-request-access? (do (and can-request-access?
(not (pos? requested-to-join-at)) (not pending?)
(requests/can-request-access-again? (requests/can-request-access-again?
requested-to-join-at)) requested-to-join-at))
(rf/dispatch [:communities/request-to-join id]) (rf/dispatch [:communities/request-to-join id])

View File

@ -1,9 +1,12 @@
(ns status-im2.contexts.communities.menus.see-rules.view (ns status-im2.contexts.communities.menus.see-rules.view
(:require [status-im2.contexts.communities.menus.generic-menu.view :as generic-menu] (: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 (defn view
[id] [id]
[generic-menu/view [generic-menu/view
id {:id id
:title (i18n/label :t/community-rules)
}
[community-rules/view community-rules/rules]]) [community-rules/view community-rules/rules]])

View File

@ -107,15 +107,25 @@
(i18n/label :t/join-open-community) (i18n/label :t/join-open-community)
(i18n/label :t/request-to-join-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 (defn join-community
[{:keys [joined can-join? requested-to-join-at [{:keys [joined can-join?
community-color permissions] community-color permissions]
:as community}] :as community} pending?]
(let [pending? (pos? requested-to-join-at) (let [access-type (get-access-type (:access permissions))
is-open? (not= constants/community-channel-access-on-request (:access permissions)) unknown-access? (= access-type :unknown-access)
node-offline? (and can-join? (not joined) (pos? requested-to-join-at))] 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 [quo/button
{:on-press #(rf/dispatch {:on-press #(rf/dispatch
[:bottom-sheet/show-sheet [:bottom-sheet/show-sheet
@ -210,12 +220,11 @@
(defn community-content (defn community-content
[{:keys [name description locked joined images [{:keys [name description locked joined images
status tokens tags requested-to-join-at id] status tokens tags id]
:as community} :as community} pending?
{:keys [on-categories-heights-changed {:keys [on-categories-heights-changed
on-first-channel-height-changed]}] on-first-channel-height-changed]}]
(let [pending? (pos? requested-to-join-at) (let [thumbnail-image (:thumbnail images)
thumbnail-image (get-in images [:thumbnail])
chats-by-category (rf/sub [:communities/categorized-channels id]) chats-by-category (rf/sub [:communities/categorized-channels id])
users (rf/sub [:communities/users id])] users (rf/sub [:communities/users id])]
[rn/view [rn/view
@ -253,7 +262,7 @@
[rn/view {:margin-top 12}] [rn/view {:margin-top 12}]
[quo/community-tags tags] [quo/community-tags tags]
[preview-user-list users] [preview-user-list users]
[join-community community]] [join-community community pending?]]
[channel-list-component [channel-list-component
{:on-categories-heights-changed #(on-categories-heights-changed %) {:on-categories-heights-changed #(on-categories-heights-changed %)
:on-first-channel-height-changed #(on-first-channel-height-changed %)} :on-first-channel-height-changed #(on-first-channel-height-changed %)}
@ -290,7 +299,7 @@
scroll-height (reagent/atom 0) scroll-height (reagent/atom 0)
cover {:uri (get-in images [:banner :uri])} cover {:uri (get-in images [:banner :uri])}
logo {:uri (get-in images [:thumbnail :uri])}] logo {:uri (get-in images [:thumbnail :uri])}]
(fn [community] (fn [community pending?]
[scroll-page/scroll-page [scroll-page/scroll-page
{:cover-image cover {:cover-image cover
:logo logo :logo logo
@ -312,16 +321,18 @@
@categories-heights))}] @categories-heights))}]
[community-content [community-content
community community
pending?
{:on-categories-heights-changed #(reset! categories-heights %) {:on-categories-heights-changed #(reset! categories-heights %)
:on-first-channel-height-changed #(reset! first-channel-height %)}]]))) :on-first-channel-height-changed #(reset! first-channel-height %)}]])))
(defn overview (defn overview
[] []
(let [id (rf/sub [:get-screen-params :community-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 [rn/view
{:style style/community-overview-container} {:style style/community-overview-container}
[community-card-page-view community] [community-card-page-view community pending?]
[floating-shell-button/floating-shell-button [floating-shell-button/floating-shell-button
{:jump-to {:on-press #(rf/dispatch [:shell/navigate-to-jump-to]) {:jump-to {:on-press #(rf/dispatch [:shell/navigate-to-jump-to])
:label (i18n/label :t/jump-to)}} :label (i18n/label :t/jump-to)}}

View File

@ -123,13 +123,19 @@
(re-frame/reg-sub (re-frame/reg-sub
:communities/grouped-by-status :communities/grouped-by-status
:<- [:communities/communities] :<- [: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] (reduce (fn [acc community]
(let [joined? (:joined community) (let [joined? (:joined community)
requested? (pos? (:requested-to-join-at community))] ;; this looks suspicious community-id (:id community)
pending? (boolean (get requests community-id))]
(cond (cond
joined? (update acc :joined conj community) joined? (update acc :joined conj community)
requested? (update acc :pending conj community) pending? (update acc :pending conj community)
:else (update acc :opened conj community)))) :else (update acc :opened conj community))))
{:joined [] :pending [] :opened []} {:joined [] :pending [] :opened []}
communities))) communities)))
@ -152,6 +158,12 @@
(get communities identity) (get communities identity)
counts))) 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 (re-frame/reg-sub
:communities/edited-community :communities/edited-community
:<- [:communities] :<- [:communities]

View File

@ -156,3 +156,36 @@
[{:name "chat1" :emoji nil :locked? false :id "0x1" :unread-messages? true :mentions-count 2} [{: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}]} {:name "chat2" :emoji nil :locked? true :id "0x2" :unread-messages? false :mentions-count 0}]}
(rf/sub [sub-name "0x1"]))))) (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])))))

View File

@ -245,6 +245,7 @@
(reg-root-key-sub :communities/community-id-input :communities/community-id-input) (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/enabled? :communities/enabled?)
(reg-root-key-sub :communities/resolve-community-info :communities/resolve-community-info) (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) (reg-root-key-sub :activity-center :activity-center)

View File

@ -127,6 +127,7 @@
"can-not-add-yourself": "That's you, to start a chat choose someone else", "can-not-add-yourself": "That's you, to start a chat choose someone else",
"cancel": "Cancel", "cancel": "Cancel",
"cancel-keycard-setup": "Cancel Keycard setup", "cancel-keycard-setup": "Cancel Keycard setup",
"cancel-request?": "Cancel request?",
"cancel-request-to-join": "Cancel request to join", "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-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", "cannot-use-default-pin": "Passcode 000000 is not allowed.\nPlease use another number",
@ -663,6 +664,7 @@
"home": "Home", "home": "Home",
"hooks": "Hooks", "hooks": "Hooks",
"identifier": "Identifier", "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-remove-current": "Remove current photo",
"image-source-gallery": "Select from gallery", "image-source-gallery": "Select from gallery",
"image-source-make-photo": "Capture", "image-source-make-photo": "Capture",
@ -1466,6 +1468,7 @@
"you-are-all-set": "Youre all set!", "you-are-all-set": "Youre 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-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-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 dont have any stickers yet", "you-dont-have-stickers": "You dont have any stickers yet",
"you-dont-have-contacts-invite-friends": "You dont have any contacts yet.\nInvite your friends to start chatting.", "you-dont-have-contacts-invite-friends": "You dont have any contacts yet.\nInvite your friends to start chatting.",
"your-contact-code": "Granting access authorizes this DApp to retrieve your chat key", "your-contact-code": "Granting access authorizes this DApp to retrieve your chat key",