Account selection: Implement features related to editing shared addresses (#19177)
* Fix schema error
* Implement feature to edit shared addresses
* fix: show tokens when sharing all future addresses toggled
* fix: eligibility not checked when toggling all addresses
* Revert "fix: show tokens when sharing all future addresses toggled"
This reverts commit 8443a3432e
.
* fix: don't fetch balances on mount if toggled share all
---------
Co-authored-by: Cristian Lungu <lungucristian95@gmail.com>
This commit is contained in:
parent
6c5242b3e0
commit
7948582e46
|
@ -59,4 +59,15 @@
|
||||||
:button-one-label "Request to join"}])
|
:button-one-label "Request to join"}])
|
||||||
(h/is-truthy (h/get-by-text "Eligible to join as"))
|
(h/is-truthy (h/get-by-text "Eligible to join as"))
|
||||||
(h/is-truthy (h/get-by-text "Admin"))
|
(h/is-truthy (h/get-by-text "Admin"))
|
||||||
|
(h/is-truthy (h/get-by-text "Request to join")))
|
||||||
|
|
||||||
|
(h/test "render with top description with custom text & 1 action"
|
||||||
|
(render [bottom-actions/view
|
||||||
|
{:description :top
|
||||||
|
:role :admin
|
||||||
|
:actions :one-action
|
||||||
|
:description-top-text "You'll be an"
|
||||||
|
:button-one-label "Request to join"}])
|
||||||
|
(h/is-truthy (h/get-by-text "You'll be an"))
|
||||||
|
(h/is-truthy (h/get-by-text "Admin"))
|
||||||
(h/is-truthy (h/get-by-text "Request to join"))))
|
(h/is-truthy (h/get-by-text "Request to join"))))
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
[:actions [:maybe [:enum :one-action :two-actions]]]
|
[:actions [:maybe [:enum :one-action :two-actions]]]
|
||||||
[:description {:optional true} [:maybe [:enum :top :bottom :top-error]]]
|
[:description {:optional true} [:maybe [:enum :top :bottom :top-error]]]
|
||||||
[:description-text {:optional true} [:maybe :string]]
|
[:description-text {:optional true} [:maybe :string]]
|
||||||
|
[:description-top-text {:optional true} [:maybe :string]]
|
||||||
[:error-message {:optional true} [:maybe :string]]
|
[:error-message {:optional true} [:maybe :string]]
|
||||||
[:role {:optional true} [:maybe [:enum :admin :member :token-master :owner]]]
|
[:role {:optional true} [:maybe [:enum :admin :member :token-master :owner]]]
|
||||||
[:button-one-label {:optional true} [:maybe :string]]
|
[:button-one-label {:optional true} [:maybe :string]]
|
||||||
|
@ -38,8 +39,8 @@
|
||||||
:owner :i/crown})
|
:owner :i/crown})
|
||||||
|
|
||||||
(defn- view-internal
|
(defn- view-internal
|
||||||
[{:keys [actions description description-text error-message role button-one-label button-two-label
|
[{:keys [actions description description-text description-top-text error-message role button-one-label
|
||||||
blur? button-one-props button-two-props theme scroll? container-style]}]
|
button-two-label blur? button-one-props button-two-props theme scroll? container-style]}]
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style (merge (style/container scroll? blur? theme) container-style)}
|
{:style (merge (style/container scroll? blur? theme) container-style)}
|
||||||
(when (= description :top-error)
|
(when (= description :top-error)
|
||||||
|
@ -54,12 +55,11 @@
|
||||||
error-message]])
|
error-message]])
|
||||||
|
|
||||||
(when (and (= description :top) role)
|
(when (and (= description :top) role)
|
||||||
[rn/view
|
[rn/view {:style style/description-top}
|
||||||
{:style style/description-top}
|
|
||||||
[text/text
|
[text/text
|
||||||
{:size :paragraph-2
|
{:size :paragraph-2
|
||||||
:style (style/description-top-text scroll? blur? theme)}
|
:style (style/description-top-text scroll? blur? theme)}
|
||||||
(i18n/label :t/eligible-to-join-as)]
|
(or description-top-text (i18n/label :t/eligible-to-join-as))]
|
||||||
[context-tag/view
|
[context-tag/view
|
||||||
{:type :icon
|
{:type :icon
|
||||||
:size 24
|
:size 24
|
||||||
|
|
|
@ -5,6 +5,14 @@
|
||||||
(def ^:private ?cofx
|
(def ^:private ?cofx
|
||||||
[:map])
|
[:map])
|
||||||
|
|
||||||
|
(def ^:private ?event
|
||||||
|
[:and
|
||||||
|
[:vector {:min 1} :any]
|
||||||
|
[:catn
|
||||||
|
[:event-id keyword?]
|
||||||
|
[:event-args [:* :any]]]])
|
||||||
|
|
||||||
(defn register-schemas
|
(defn register-schemas
|
||||||
[]
|
[]
|
||||||
(registry/register ::cofx ?cofx))
|
(registry/register ::cofx ?cofx)
|
||||||
|
(registry/register ::event ?event))
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
(ns status-im.contexts.communities.actions.accounts-selection.effects
|
||||||
|
(:require
|
||||||
|
[promesa.core :as p]
|
||||||
|
[schema.core :as schema]
|
||||||
|
[status-im.common.json-rpc.events :as rpc]
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(defn- generate-requests-for-signing
|
||||||
|
[pub-key community-id addresses-to-reveal]
|
||||||
|
(p/create
|
||||||
|
(fn [p-resolve p-reject]
|
||||||
|
(rpc/call
|
||||||
|
{:method :wakuext_generateJoiningCommunityRequestsForSigning
|
||||||
|
:params [pub-key community-id addresses-to-reveal]
|
||||||
|
:on-success p-resolve
|
||||||
|
:on-error #(p-reject (str "failed to generate requests for signing\n" %))}))))
|
||||||
|
|
||||||
|
(defn- sign-data
|
||||||
|
[sign-params password]
|
||||||
|
(p/create
|
||||||
|
(fn [p-resolve p-reject]
|
||||||
|
(rpc/call
|
||||||
|
{:method :wakuext_signData
|
||||||
|
:params [(map #(assoc % :password password) sign-params)]
|
||||||
|
:on-success p-resolve
|
||||||
|
:on-error #(p-reject (str "failed to sign data\n" %))}))))
|
||||||
|
|
||||||
|
(defn- edit-shared-addresses-for-community
|
||||||
|
[community-id signatures addresses-to-reveal airdrop-address]
|
||||||
|
(p/create
|
||||||
|
(fn [p-resolve p-reject]
|
||||||
|
(rpc/call
|
||||||
|
{:method :wakuext_editSharedAddressesForCommunity
|
||||||
|
:params [{:communityId community-id
|
||||||
|
:signatures signatures
|
||||||
|
:addressesToReveal addresses-to-reveal
|
||||||
|
:airdropAddress airdrop-address}]
|
||||||
|
:js-response true
|
||||||
|
:on-success p-resolve
|
||||||
|
:on-error p-reject}))))
|
||||||
|
|
||||||
|
(defn- request-to-join
|
||||||
|
[community-id signatures addresses-to-reveal airdrop-address]
|
||||||
|
(p/create
|
||||||
|
(fn [p-resolve p-reject]
|
||||||
|
(rpc/call
|
||||||
|
{:method :wakuext_requestToJoinCommunity
|
||||||
|
:params [{:communityId community-id
|
||||||
|
:signatures signatures
|
||||||
|
:addressesToReveal addresses-to-reveal
|
||||||
|
:airdropAddress airdrop-address}]
|
||||||
|
:js-response true
|
||||||
|
:on-success p-resolve
|
||||||
|
:on-error p-reject}))))
|
||||||
|
|
||||||
|
(defn- run-callback-or-event
|
||||||
|
[callback-or-event result]
|
||||||
|
(cond (fn? callback-or-event)
|
||||||
|
(callback-or-event result)
|
||||||
|
|
||||||
|
(vector? callback-or-event)
|
||||||
|
(rf/dispatch (conj callback-or-event result))))
|
||||||
|
|
||||||
|
(defn- sign-and-call-endpoint
|
||||||
|
[{:keys [community-id password pub-key
|
||||||
|
addresses-to-reveal airdrop-address
|
||||||
|
on-success on-error
|
||||||
|
callback]}]
|
||||||
|
(-> (p/let [sign-params (generate-requests-for-signing pub-key community-id addresses-to-reveal)
|
||||||
|
signatures (sign-data sign-params password)
|
||||||
|
result (callback community-id
|
||||||
|
signatures
|
||||||
|
addresses-to-reveal
|
||||||
|
airdrop-address)]
|
||||||
|
(run-callback-or-event on-success result))
|
||||||
|
(p/catch #(run-callback-or-event on-error %))))
|
||||||
|
|
||||||
|
(schema/=> sign-and-call-endpoint
|
||||||
|
[:=>
|
||||||
|
[:cat
|
||||||
|
[:map {:closed true}
|
||||||
|
[:community-id string?]
|
||||||
|
[:password string?]
|
||||||
|
[:pub-key string?]
|
||||||
|
[:addresses-to-reveal
|
||||||
|
[:or [:set string?]
|
||||||
|
[:sequential string?]]]
|
||||||
|
[:airdrop-address string?]
|
||||||
|
[:on-success [:or fn? :schema.re-frame/event]]
|
||||||
|
[:on-error [:or fn? :schema.re-frame/event]]
|
||||||
|
[:callback fn?]]]
|
||||||
|
:any])
|
||||||
|
|
||||||
|
(rf/reg-fx :effects.community/edit-shared-addresses
|
||||||
|
(fn [opts]
|
||||||
|
(sign-and-call-endpoint
|
||||||
|
(assoc opts :callback edit-shared-addresses-for-community))))
|
||||||
|
|
||||||
|
(rf/reg-fx :effects.community/request-to-join
|
||||||
|
(fn [opts]
|
||||||
|
(sign-and-call-endpoint
|
||||||
|
(assoc opts :callback request-to-join))))
|
|
@ -0,0 +1,103 @@
|
||||||
|
(ns status-im.contexts.communities.actions.accounts-selection.events
|
||||||
|
(:require
|
||||||
|
status-im.contexts.communities.actions.accounts-selection.effects
|
||||||
|
[status-im.contexts.communities.utils :as utils]
|
||||||
|
[taoensso.timbre :as log]
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(defn initialize-permission-addresses
|
||||||
|
[{:keys [db]} [community-id]]
|
||||||
|
(let [{:keys [joined]} (get-in db [:communities community-id])
|
||||||
|
pending-requests (get-in db [:communities/my-pending-requests-to-join community-id])
|
||||||
|
init-using-revealed-accounts? (or joined (seq pending-requests))]
|
||||||
|
{:fx [(if init-using-revealed-accounts?
|
||||||
|
[:dispatch
|
||||||
|
[:communities/get-revealed-accounts community-id
|
||||||
|
[:communities/do-init-permission-addresses community-id]]]
|
||||||
|
[:dispatch [:communities/do-init-permission-addresses community-id]])]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/initialize-permission-addresses initialize-permission-addresses)
|
||||||
|
|
||||||
|
(defn do-init-permission-addresses
|
||||||
|
[{:keys [db]} [community-id revealed-accounts]]
|
||||||
|
(let [wallet-accounts (utils/sorted-non-watch-only-accounts db)
|
||||||
|
addresses-to-reveal (if (seq revealed-accounts)
|
||||||
|
(set (keys revealed-accounts))
|
||||||
|
;; Reveal all addresses as fallback.
|
||||||
|
(set (map :address wallet-accounts)))
|
||||||
|
|
||||||
|
;; When there are no revealed addresses, such as when joining a
|
||||||
|
;; community, use first address for airdrops.
|
||||||
|
airdrop-address (or (->> revealed-accounts
|
||||||
|
vals
|
||||||
|
(filter :airdrop-address?)
|
||||||
|
first
|
||||||
|
:address)
|
||||||
|
(->> wallet-accounts
|
||||||
|
first
|
||||||
|
:address))]
|
||||||
|
{:db (-> db
|
||||||
|
;; Set to false by default while we don't persist the user's choice
|
||||||
|
;; in status-go, otherwise whenever the view is mounted, the choice
|
||||||
|
;; of selected addresses won't be respected.
|
||||||
|
(assoc-in [:communities/selected-share-all-addresses community-id] false)
|
||||||
|
(assoc-in [:communities/all-addresses-to-reveal community-id] addresses-to-reveal)
|
||||||
|
(assoc-in [:communities/all-airdrop-addresses community-id] airdrop-address))
|
||||||
|
:fx [[:dispatch
|
||||||
|
[:communities/check-permissions-to-join-community
|
||||||
|
community-id addresses-to-reveal :based-on-client-selection]]
|
||||||
|
;; Pre-fetch permissions check so that when first opening the
|
||||||
|
;; Addresses for Permissions screen the highest permission role is
|
||||||
|
;; already available and no incorrect information flashes on screen.
|
||||||
|
[:dispatch
|
||||||
|
[:communities/check-permissions-to-join-during-selection community-id
|
||||||
|
addresses-to-reveal]]]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/do-init-permission-addresses do-init-permission-addresses)
|
||||||
|
|
||||||
|
(defn edit-shared-addresses
|
||||||
|
"This event will effectively persist the choice of addresses and airdrop address
|
||||||
|
in status-go. It can either take addresses to share AND an airdrop address, or
|
||||||
|
just addresses to share OR an airdrop address. This is because when the user
|
||||||
|
is selecting an airdrop address, we must submit to status-go the current
|
||||||
|
choice of addresses to share, and vice-versa. If we omit addresses to share,
|
||||||
|
status-go will default to all available."
|
||||||
|
[{:keys [db]} [{:keys [community-id password on-success addresses airdrop-address]}]]
|
||||||
|
(let [pub-key (get-in db [:profile/profile :public-key])
|
||||||
|
wallet-accounts (utils/sorted-non-watch-only-accounts db)
|
||||||
|
addresses-to-reveal (if (seq addresses)
|
||||||
|
(set addresses)
|
||||||
|
(get-in db [:communities/all-addresses-to-reveal community-id]))
|
||||||
|
new-airdrop-address (if (contains? addresses-to-reveal airdrop-address)
|
||||||
|
airdrop-address
|
||||||
|
(->> wallet-accounts
|
||||||
|
(filter #(contains? addresses-to-reveal (:address %)))
|
||||||
|
first
|
||||||
|
:address))]
|
||||||
|
{:fx [[:effects.community/edit-shared-addresses
|
||||||
|
{:community-id community-id
|
||||||
|
:password password
|
||||||
|
:pub-key pub-key
|
||||||
|
:addresses-to-reveal addresses-to-reveal
|
||||||
|
:airdrop-address new-airdrop-address
|
||||||
|
:on-success (fn []
|
||||||
|
(when (fn? on-success)
|
||||||
|
(on-success addresses-to-reveal new-airdrop-address))
|
||||||
|
(rf/dispatch [:communities/edit-shared-addresses-success
|
||||||
|
community-id addresses-to-reveal airdrop-address]))
|
||||||
|
:on-error [:communities/edit-shared-addresses-failure community-id]}]]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/edit-shared-addresses edit-shared-addresses)
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/edit-shared-addresses-success
|
||||||
|
(fn [_ [community-id addresses-to-reveal airdrop-address]]
|
||||||
|
{:fx [[:dispatch [:communities/set-airdrop-address community-id airdrop-address]]
|
||||||
|
[:dispatch [:communities/set-addresses-to-reveal community-id addresses-to-reveal]]]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/edit-shared-addresses-failure
|
||||||
|
(fn [{:keys [db]} [community-id error]]
|
||||||
|
(log/error "failed to edit shared addresses"
|
||||||
|
{:event :communities/edit-shared-addresses
|
||||||
|
:community-id community-id
|
||||||
|
:error error})
|
||||||
|
{:db (assoc-in db [:password-authentication :error] error)}))
|
|
@ -0,0 +1,169 @@
|
||||||
|
(ns status-im.contexts.communities.actions.accounts-selection.events-test
|
||||||
|
(:require [cljs.test :refer [deftest is testing]]
|
||||||
|
matcher-combinators.test
|
||||||
|
[status-im.contexts.communities.actions.accounts-selection.events :as sut]))
|
||||||
|
|
||||||
|
(def community-id "0x99")
|
||||||
|
(def password "password")
|
||||||
|
|
||||||
|
(def wallet-accounts
|
||||||
|
{"0xA" {:address "0xA"
|
||||||
|
:watch-only? true
|
||||||
|
:position 2
|
||||||
|
:color :red
|
||||||
|
:emoji "🦇"}
|
||||||
|
"0xB" {:address "0xB"
|
||||||
|
:position 0
|
||||||
|
:color :blue
|
||||||
|
:emoji "🐈"}
|
||||||
|
"0xC" {:address "0xC"
|
||||||
|
:position 1
|
||||||
|
:color :orange
|
||||||
|
:emoji "🛏️"}})
|
||||||
|
|
||||||
|
(def permissioned-accounts
|
||||||
|
[{:address "0xB"
|
||||||
|
:position 0
|
||||||
|
:color :blue
|
||||||
|
:emoji "🐈"
|
||||||
|
:airdrop-address? true
|
||||||
|
:reveal? true}
|
||||||
|
{:address "0xC"
|
||||||
|
:position 1
|
||||||
|
:color :orange
|
||||||
|
:emoji "🛏️"
|
||||||
|
:airdrop-address? false
|
||||||
|
:reveal? false}])
|
||||||
|
|
||||||
|
(deftest initialize-permission-addresses-test
|
||||||
|
(testing "fetches revealed accounts when pending and not joined"
|
||||||
|
(let [cofx {:db {:communities {community-id {:joined false}}
|
||||||
|
:communities/my-pending-requests-to-join {community-id [:anything]}}}]
|
||||||
|
(is (match?
|
||||||
|
{:fx [[:dispatch
|
||||||
|
[:communities/get-revealed-accounts community-id
|
||||||
|
[:communities/do-init-permission-addresses community-id]]]]}
|
||||||
|
(sut/initialize-permission-addresses cofx [community-id])))))
|
||||||
|
|
||||||
|
(testing "fetches revealed accounts when not pending and joined"
|
||||||
|
(let [cofx {:db {:communities {community-id {:joined true}}
|
||||||
|
:communities/my-pending-requests-to-join {}}}]
|
||||||
|
(is (match?
|
||||||
|
{:fx [[:dispatch
|
||||||
|
[:communities/get-revealed-accounts community-id
|
||||||
|
[:communities/do-init-permission-addresses community-id]]]]}
|
||||||
|
(sut/initialize-permission-addresses cofx [community-id])))))
|
||||||
|
|
||||||
|
(testing "does not fetch revealed accounts when not pending and not joined"
|
||||||
|
(let [cofx {:db {:communities {community-id {:joined false}}
|
||||||
|
:communities/my-pending-requests-to-join {}}}]
|
||||||
|
(is (match?
|
||||||
|
{:fx [[:dispatch [:communities/do-init-permission-addresses community-id]]]}
|
||||||
|
(sut/initialize-permission-addresses cofx [community-id]))))))
|
||||||
|
|
||||||
|
(deftest do-init-permission-addresses-test
|
||||||
|
(testing "uses already revealed accounts to initialize shareable accounts"
|
||||||
|
(let [cofx {:db {:wallet {:accounts wallet-accounts}}}
|
||||||
|
revealed-accounts {"0xC" {:address "0xC"
|
||||||
|
:airdrop-address? true
|
||||||
|
:position 1}}
|
||||||
|
airdrop-address "0xC"
|
||||||
|
addresses-to-reveal #{"0xC"}]
|
||||||
|
(is
|
||||||
|
(match?
|
||||||
|
{:db (-> (:db cofx)
|
||||||
|
(assoc-in [:communities/selected-share-all-addresses community-id] false)
|
||||||
|
(assoc-in [:communities/all-addresses-to-reveal community-id] addresses-to-reveal)
|
||||||
|
(assoc-in [:communities/all-airdrop-addresses community-id] airdrop-address))
|
||||||
|
:fx [[:dispatch
|
||||||
|
[:communities/check-permissions-to-join-community
|
||||||
|
community-id addresses-to-reveal :based-on-client-selection]]
|
||||||
|
;; Pre-fetch permissions check so that when first opening the
|
||||||
|
;; Addresses for Permissions screen the highest permission role is
|
||||||
|
;; already available and no incorrect information flashes on screen.
|
||||||
|
[:dispatch
|
||||||
|
[:communities/check-permissions-to-join-during-selection community-id
|
||||||
|
addresses-to-reveal]]]}
|
||||||
|
(sut/do-init-permission-addresses cofx [community-id revealed-accounts])))))
|
||||||
|
|
||||||
|
;; Expect to mark all addresses to be revealed and first one to receive
|
||||||
|
;; airdrops when no addresses were previously revealed.
|
||||||
|
(testing "handles case where there are no previously revealed addresses"
|
||||||
|
(let [cofx {:db {:wallet {:accounts wallet-accounts}}}
|
||||||
|
addresses-to-reveal #{"0xB" "0xC"}
|
||||||
|
revealed-accounts []]
|
||||||
|
(is
|
||||||
|
(match?
|
||||||
|
{:db (-> (:db cofx)
|
||||||
|
(assoc-in [:communities/selected-share-all-addresses community-id] false)
|
||||||
|
(assoc-in [:communities/all-addresses-to-reveal community-id] addresses-to-reveal))
|
||||||
|
:fx [[:dispatch
|
||||||
|
[:communities/check-permissions-to-join-community
|
||||||
|
community-id addresses-to-reveal :based-on-client-selection]]
|
||||||
|
[:dispatch
|
||||||
|
[:communities/check-permissions-to-join-during-selection community-id
|
||||||
|
addresses-to-reveal]]]}
|
||||||
|
(sut/do-init-permission-addresses cofx [community-id revealed-accounts]))))))
|
||||||
|
|
||||||
|
(deftest edit-shared-addresses-test
|
||||||
|
(testing
|
||||||
|
"when airdrop address is passed, but addresses to reveal is not, then
|
||||||
|
fallback to all wallet addresses"
|
||||||
|
(let [pub-key "abcdef"
|
||||||
|
revealed-addresses #{"0xB" "0xC"}
|
||||||
|
cofx {:db {:profile/profile {:public-key pub-key}
|
||||||
|
:communities/all-addresses-to-reveal {community-id revealed-addresses}}}
|
||||||
|
airdrop-address "0xB"
|
||||||
|
|
||||||
|
actual
|
||||||
|
(sut/edit-shared-addresses
|
||||||
|
cofx
|
||||||
|
[{:community-id community-id
|
||||||
|
:password password
|
||||||
|
:airdrop-address airdrop-address
|
||||||
|
:on-success (fn [new-addresses-to-reveal]
|
||||||
|
(is (match? revealed-addresses new-addresses-to-reveal)))}])
|
||||||
|
|
||||||
|
on-success-wrapper (-> actual :fx first second :on-success)]
|
||||||
|
(is (match?
|
||||||
|
{:fx [[:effects.community/edit-shared-addresses
|
||||||
|
{:community-id community-id
|
||||||
|
:password password
|
||||||
|
:pub-key pub-key
|
||||||
|
:addresses-to-reveal revealed-addresses
|
||||||
|
:airdrop-address airdrop-address
|
||||||
|
:on-success fn?
|
||||||
|
:on-error [:communities/edit-shared-addresses-failure community-id]}]]}
|
||||||
|
actual))
|
||||||
|
|
||||||
|
(on-success-wrapper)))
|
||||||
|
|
||||||
|
(testing "when addresses to reveal are passed, but airdrop address is not"
|
||||||
|
(let [pub-key "abcdef"
|
||||||
|
cofx {:db {:profile/profile {:public-key pub-key}
|
||||||
|
:wallet {:accounts wallet-accounts}
|
||||||
|
:communities/all-addresses-to-reveal {community-id #{"0xB" "0xC"}}}}
|
||||||
|
|
||||||
|
actual (sut/edit-shared-addresses
|
||||||
|
cofx
|
||||||
|
[{:community-id community-id
|
||||||
|
:password password
|
||||||
|
:addresses ["0xC"]
|
||||||
|
:on-success (fn [new-addresses-to-reveal new-airdrop-address]
|
||||||
|
(is (= #{"0xC"} new-addresses-to-reveal))
|
||||||
|
(is (= "0xC" new-airdrop-address)))}])
|
||||||
|
|
||||||
|
on-success-wrapper
|
||||||
|
(-> actual :fx first second :on-success)]
|
||||||
|
(is (match?
|
||||||
|
{:fx [[:effects.community/edit-shared-addresses
|
||||||
|
{:community-id community-id
|
||||||
|
:password password
|
||||||
|
:pub-key pub-key
|
||||||
|
:addresses-to-reveal #{"0xC"}
|
||||||
|
:airdrop-address "0xC"
|
||||||
|
:on-success fn?
|
||||||
|
:on-error [:communities/edit-shared-addresses-failure community-id]}]]}
|
||||||
|
actual))
|
||||||
|
|
||||||
|
(on-success-wrapper))))
|
|
@ -15,32 +15,51 @@
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
(let [{id :community-id} (rf/sub [:get-screen-params])
|
(let [{id :community-id} (rf/sub [:get-screen-params])
|
||||||
show-addresses-for-permissions (fn []
|
{:keys [name color images joined]} (rf/sub [:communities/community id])
|
||||||
(rf/dispatch [:show-bottom-sheet
|
|
||||||
{:community-id id
|
|
||||||
:content addresses-for-permissions/view}]))
|
|
||||||
show-airdrop-addresses (fn []
|
|
||||||
(rf/dispatch [:show-bottom-sheet
|
|
||||||
{:community-id id
|
|
||||||
:content airdrop-addresses/view}]))
|
|
||||||
navigate-back #(rf/dispatch [:navigate-back])
|
|
||||||
join-and-go-back (fn []
|
|
||||||
(rf/dispatch [:password-authentication/show
|
|
||||||
{:content (fn [] [password-authentication/view])}
|
|
||||||
{:label (i18n/label :t/join-open-community)
|
|
||||||
:on-press
|
|
||||||
#(rf/dispatch
|
|
||||||
[:communities/request-to-join-with-addresses
|
|
||||||
{:community-id id :password %}])}])
|
|
||||||
(navigate-back))]
|
|
||||||
(fn []
|
|
||||||
(let [{:keys [name color images]} (rf/sub [:communities/community id])
|
|
||||||
airdrop-account (rf/sub [:communities/airdrop-account id])
|
airdrop-account (rf/sub [:communities/airdrop-account id])
|
||||||
selected-accounts (rf/sub [:communities/selected-permission-accounts id])
|
revealed-accounts (rf/sub [:communities/accounts-to-reveal id])
|
||||||
{:keys [highest-permission-role]} (rf/sub [:community/token-gated-overview id])
|
{:keys [highest-permission-role]} (rf/sub [:community/token-gated-overview id])
|
||||||
highest-role-text (i18n/label (communities.utils/role->translation-key
|
highest-role-text (i18n/label (communities.utils/role->translation-key
|
||||||
highest-permission-role
|
highest-permission-role
|
||||||
:t/member))]
|
:t/member))
|
||||||
|
can-edit-addresses? (rf/sub [:communities/can-edit-shared-addresses? id])
|
||||||
|
navigate-back (rn/use-callback #(rf/dispatch [:navigate-back]))
|
||||||
|
|
||||||
|
show-addresses-for-permissions
|
||||||
|
(rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(if can-edit-addresses?
|
||||||
|
(rf/dispatch [:open-modal :addresses-for-permissions {:community-id id}])
|
||||||
|
(rf/dispatch [:show-bottom-sheet
|
||||||
|
{:community-id id
|
||||||
|
:content (fn [] [addresses-for-permissions/view])}])))
|
||||||
|
[can-edit-addresses?])
|
||||||
|
|
||||||
|
show-airdrop-addresses
|
||||||
|
(rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(if can-edit-addresses?
|
||||||
|
(rf/dispatch [:open-modal :address-for-airdrop {:community-id id}])
|
||||||
|
(rf/dispatch [:show-bottom-sheet
|
||||||
|
{:community-id id
|
||||||
|
:content (fn [] [airdrop-addresses/view])}])))
|
||||||
|
[can-edit-addresses?])
|
||||||
|
|
||||||
|
confirm-choices
|
||||||
|
(rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(rf/dispatch
|
||||||
|
[:password-authentication/show
|
||||||
|
{:content (fn [] [password-authentication/view])}
|
||||||
|
{:label (i18n/label :t/join-open-community)
|
||||||
|
:on-press (fn [password]
|
||||||
|
(rf/dispatch [:communities/request-to-join-with-addresses
|
||||||
|
{:community-id id :password password}]))}])
|
||||||
|
(navigate-back)))]
|
||||||
|
(rn/use-mount
|
||||||
|
(fn []
|
||||||
|
(rf/dispatch [:communities/initialize-permission-addresses id])))
|
||||||
|
|
||||||
[rn/safe-area-view {:style style/container}
|
[rn/safe-area-view {:style style/container}
|
||||||
[quo/page-nav
|
[quo/page-nav
|
||||||
{:text-align :left
|
{:text-align :left
|
||||||
|
@ -48,7 +67,9 @@
|
||||||
:on-press navigate-back
|
:on-press navigate-back
|
||||||
:accessibility-label :back-button}]
|
:accessibility-label :back-button}]
|
||||||
[quo/page-top
|
[quo/page-top
|
||||||
{:title (i18n/label :t/request-to-join)
|
{:title (if can-edit-addresses?
|
||||||
|
(i18n/label :t/edit-shared-addresses)
|
||||||
|
(i18n/label :t/request-to-join))
|
||||||
:description :context-tag
|
:description :context-tag
|
||||||
:context-tag {:type :community
|
:context-tag {:type :community
|
||||||
:size 24
|
:size 24
|
||||||
|
@ -56,21 +77,24 @@
|
||||||
:community-name name}}]
|
:community-name name}}]
|
||||||
[gesture/scroll-view
|
[gesture/scroll-view
|
||||||
[:<>
|
[:<>
|
||||||
|
(when-not can-edit-addresses?
|
||||||
[quo/text
|
[quo/text
|
||||||
{:style style/section-title
|
{:style style/section-title
|
||||||
:accessibility-label :community-rules-title
|
:accessibility-label :community-rules-title
|
||||||
:weight :semi-bold
|
:weight :semi-bold
|
||||||
:size :paragraph-1}
|
:size :paragraph-1}
|
||||||
(i18n/label :t/address-to-share)]
|
(i18n/label :t/address-to-share)])
|
||||||
[quo/category
|
[quo/category
|
||||||
{:list-type :settings
|
{:list-type :settings
|
||||||
:data [{:title (i18n/label :t/join-as-a {:role highest-role-text})
|
:data [{:title (if joined
|
||||||
|
(i18n/label :t/you-are-a-role {:role highest-role-text})
|
||||||
|
(i18n/label :t/join-as-a {:role highest-role-text}))
|
||||||
:on-press show-addresses-for-permissions
|
:on-press show-addresses-for-permissions
|
||||||
:description :text
|
:description :text
|
||||||
:action :arrow
|
:action :arrow
|
||||||
:label :preview
|
:label :preview
|
||||||
:label-props {:type :accounts
|
:label-props {:type :accounts
|
||||||
:data selected-accounts}
|
:data revealed-accounts}
|
||||||
:description-props {:text (i18n/label :t/all-addresses)}}
|
:description-props {:text (i18n/label :t/all-addresses)}}
|
||||||
{:title (i18n/label :t/for-airdrops)
|
{:title (i18n/label :t/for-airdrops)
|
||||||
:on-press show-airdrop-addresses
|
:on-press show-airdrop-addresses
|
||||||
|
@ -80,17 +104,20 @@
|
||||||
:label-props {:type :accounts
|
:label-props {:type :accounts
|
||||||
:data [airdrop-account]}
|
:data [airdrop-account]}
|
||||||
:description-props {:text (:name airdrop-account)}}]}]
|
:description-props {:text (:name airdrop-account)}}]}]
|
||||||
|
(when-not can-edit-addresses?
|
||||||
[quo/text
|
[quo/text
|
||||||
{:style style/section-title
|
{:style style/section-title
|
||||||
:accessibility-label :community-rules-title
|
:accessibility-label :community-rules-title
|
||||||
:weight :semi-bold
|
:weight :semi-bold
|
||||||
:size :paragraph-1}
|
:size :paragraph-1}
|
||||||
(i18n/label :t/community-rules)]
|
(i18n/label :t/community-rules)])
|
||||||
[community-rules/view id]]]
|
(when-not can-edit-addresses?
|
||||||
|
[community-rules/view id])]]
|
||||||
|
(when-not can-edit-addresses?
|
||||||
[rn/view {:style (style/bottom-actions)}
|
[rn/view {:style (style/bottom-actions)}
|
||||||
[quo/slide-button
|
[quo/slide-button
|
||||||
{:size :size-48
|
{:size :size-48
|
||||||
:track-text (i18n/label :t/slide-to-request-to-join)
|
:track-text (i18n/label :t/slide-to-request-to-join)
|
||||||
:track-icon :i/face-id
|
:track-icon :i/face-id
|
||||||
:customization-color color
|
:customization-color color
|
||||||
:on-complete join-and-go-back}]]]))))
|
:on-complete confirm-choices}]])]))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns status-im.contexts.communities.actions.addresses-for-permissions.events
|
(ns status-im.contexts.communities.actions.addresses-for-permissions.events
|
||||||
(:require
|
(:require
|
||||||
[schema.core :as schema]
|
[schema.core :as schema]
|
||||||
|
[status-im.contexts.communities.utils :as utils]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
@ -56,3 +57,97 @@
|
||||||
map?])
|
map?])
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/get-permissioned-balances-success get-permissioned-balances-success)
|
(rf/reg-event-fx :communities/get-permissioned-balances-success get-permissioned-balances-success)
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/addresses-for-permissions-cancel-request
|
||||||
|
(fn [_ [request-id]]
|
||||||
|
{:fx [[:dispatch [:communities/cancel-request-to-join request-id]]
|
||||||
|
[:dispatch [:pop-to-root :shell-stack]]
|
||||||
|
[:dispatch [:hide-bottom-sheet]]]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/addresses-for-permissions-leave
|
||||||
|
(fn [_ [community-id]]
|
||||||
|
{:fx [[:dispatch [:communities/leave community-id]]
|
||||||
|
[:dispatch [:hide-bottom-sheet]]
|
||||||
|
[:dispatch [:dismiss-modal :addresses-for-permissions]]
|
||||||
|
[:dispatch [:pop-to-root :shell-stack]]]}))
|
||||||
|
|
||||||
|
(defn check-permissions-to-join-for-selection
|
||||||
|
[{:keys [db]} [community-id addresses]]
|
||||||
|
(if (empty? addresses)
|
||||||
|
;; When there are no addresses we can't just check permissions, otherwise
|
||||||
|
;; status-go will consider all possible addresses and the user will see the
|
||||||
|
;; incorrect highest permission role.
|
||||||
|
{:db (update db :communities/permissions-checks-for-selection dissoc community-id)}
|
||||||
|
(let [{:keys [checking?]} (get-in db [:communities/permissions-checks-for-selection community-id])]
|
||||||
|
(when-not checking?
|
||||||
|
{:db (assoc-in db [:communities/permissions-checks-for-selection community-id :checking?] true)
|
||||||
|
:fx [[:json-rpc/call
|
||||||
|
[{:method :wakuext_checkPermissionsToJoinCommunity
|
||||||
|
:params [{:communityId community-id :addresses addresses}]
|
||||||
|
:on-success [:communities/check-permissions-to-join-during-selection-success
|
||||||
|
community-id]
|
||||||
|
:on-error [:communities/check-permissions-to-join-during-selection-failure
|
||||||
|
community-id addresses]}]]]}))))
|
||||||
|
|
||||||
|
;; This event should be used to check permissions temporarily because it won't
|
||||||
|
;; mutate the state `:communities/permissions-check` (used by many other
|
||||||
|
;; screens).
|
||||||
|
(rf/reg-event-fx :communities/check-permissions-to-join-during-selection
|
||||||
|
check-permissions-to-join-for-selection)
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/check-permissions-to-join-during-selection-success
|
||||||
|
(fn [{:keys [db]} [community-id result]]
|
||||||
|
{:db (assoc-in db
|
||||||
|
[:communities/permissions-checks-for-selection community-id]
|
||||||
|
{:checking? false
|
||||||
|
:based-on-client-selection? true
|
||||||
|
:check result})}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/check-permissions-to-join-during-selection-failure
|
||||||
|
(fn [_ [community-id addresses error]]
|
||||||
|
(log/error "failed to check permissions for currently selected addresses"
|
||||||
|
{:event :communities/check-permissions-to-join-during-selection
|
||||||
|
:community-id community-id
|
||||||
|
:addresses addresses
|
||||||
|
:error error})))
|
||||||
|
|
||||||
|
(defn set-permissioned-accounts
|
||||||
|
[{:keys [db]} [community-id addresses-to-reveal]]
|
||||||
|
(let [addresses-to-reveal (set addresses-to-reveal)
|
||||||
|
wallet-accounts (utils/sorted-non-watch-only-accounts db)
|
||||||
|
current-airdrop-address (get-in db [:communities/all-airdrop-addresses community-id])
|
||||||
|
new-airdrop-address (if (contains? addresses-to-reveal current-airdrop-address)
|
||||||
|
current-airdrop-address
|
||||||
|
(->> wallet-accounts
|
||||||
|
(filter #(contains? addresses-to-reveal (:address %)))
|
||||||
|
first
|
||||||
|
:address))]
|
||||||
|
{:db (-> db
|
||||||
|
(assoc-in [:communities/all-addresses-to-reveal community-id] addresses-to-reveal)
|
||||||
|
(assoc-in [:communities/all-airdrop-addresses community-id] new-airdrop-address))
|
||||||
|
:fx [[:dispatch
|
||||||
|
[:communities/check-permissions-to-join-community
|
||||||
|
community-id addresses-to-reveal :based-on-client-selection]]
|
||||||
|
[:dispatch [:hide-bottom-sheet]]]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/set-addresses-to-reveal set-permissioned-accounts)
|
||||||
|
|
||||||
|
(defn set-share-all-addresses
|
||||||
|
[{:keys [db]} [community-id new-value]]
|
||||||
|
(let [current-addresses (get-in db [:communities/all-addresses-to-reveal community-id])
|
||||||
|
addresses-to-reveal (if new-value
|
||||||
|
(->> (utils/sorted-non-watch-only-accounts db)
|
||||||
|
(map :address)
|
||||||
|
set)
|
||||||
|
current-addresses)]
|
||||||
|
{:db (-> db
|
||||||
|
(assoc-in [:communities/selected-share-all-addresses community-id] new-value)
|
||||||
|
(assoc-in [:communities/all-addresses-to-reveal community-id] addresses-to-reveal))
|
||||||
|
;; We should check permissions again because the flag is being enabled and
|
||||||
|
;; different addresses will be revealed.
|
||||||
|
:fx [(when new-value
|
||||||
|
[:dispatch
|
||||||
|
[:communities/check-permissions-to-join-during-selection
|
||||||
|
community-id addresses-to-reveal]])]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/set-share-all-addresses set-share-all-addresses)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
(ns status-im.contexts.communities.actions.addresses-for-permissions.events-test
|
(ns status-im.contexts.communities.actions.addresses-for-permissions.events-test
|
||||||
(:require
|
(:require
|
||||||
[cljs.test :refer [deftest is]]
|
[cljs.test :refer [deftest is testing]]
|
||||||
[status-im.contexts.communities.actions.addresses-for-permissions.events :as sut]))
|
[status-im.contexts.communities.actions.addresses-for-permissions.events :as sut]))
|
||||||
|
|
||||||
(def community-id "0x1")
|
(def community-id "0x1")
|
||||||
|
@ -13,3 +13,101 @@
|
||||||
:on-success [:communities/get-permissioned-balances-success community-id]
|
:on-success [:communities/get-permissioned-balances-success community-id]
|
||||||
:on-error fn?}]]]}
|
:on-error fn?}]]]}
|
||||||
(sut/get-permissioned-balances cofx [community-id])))))
|
(sut/get-permissioned-balances cofx [community-id])))))
|
||||||
|
|
||||||
|
(deftest set-permissioned-accounts-test
|
||||||
|
(testing "new accounts contain the current airdrop address"
|
||||||
|
(let [cofx {:db {:communities/all-addresses-to-reveal
|
||||||
|
{community-id #{"0xA" "0xB"}}}}
|
||||||
|
addresses-to-reveal ["0xA"]
|
||||||
|
expected-addresses-to-reveal (set addresses-to-reveal)]
|
||||||
|
(is (match?
|
||||||
|
{:db {:communities/all-addresses-to-reveal
|
||||||
|
{community-id expected-addresses-to-reveal}}
|
||||||
|
:fx [[:dispatch
|
||||||
|
[:communities/check-permissions-to-join-community
|
||||||
|
community-id expected-addresses-to-reveal :based-on-client-selection]]
|
||||||
|
[:dispatch [:hide-bottom-sheet]]]}
|
||||||
|
(sut/set-permissioned-accounts cofx [community-id addresses-to-reveal])))))
|
||||||
|
|
||||||
|
(testing "new accounts do not contain the current airdrop address"
|
||||||
|
(let [cofx
|
||||||
|
{:db {:communities/all-addresses-to-reveal {community-id #{"0xA" "0xB" "0xC"}}
|
||||||
|
:communities/all-airdrop-addresses {community-id "0xB"}
|
||||||
|
:wallet {:accounts {"0xB" {:address "0xB" :position 0}
|
||||||
|
"0xA" {:address "0xA" :position 1}
|
||||||
|
"0xC" {:address "0xC" :position 2}}}}}
|
||||||
|
addresses-to-reveal ["0xA" "0xC"]]
|
||||||
|
(is (match?
|
||||||
|
{:db {:communities/all-addresses-to-reveal
|
||||||
|
{community-id (set addresses-to-reveal)}
|
||||||
|
:communities/all-airdrop-addresses
|
||||||
|
{community-id "0xA"}}
|
||||||
|
:fx [[:dispatch
|
||||||
|
[:communities/check-permissions-to-join-community
|
||||||
|
community-id (set addresses-to-reveal) :based-on-client-selection]]
|
||||||
|
[:dispatch [:hide-bottom-sheet]]]}
|
||||||
|
(sut/set-permissioned-accounts cofx [community-id addresses-to-reveal]))))))
|
||||||
|
|
||||||
|
(deftest set-share-all-addresses-test
|
||||||
|
(testing "sets flag from false -> true will mark all addresses to be revealed"
|
||||||
|
(let [cofx {:db
|
||||||
|
{:wallet
|
||||||
|
{:accounts {"0xB" {:address "0xB" :position 0}
|
||||||
|
"0xA" {:address "0xA" :position 1}
|
||||||
|
"0xC" {:address "0xC" :position 2}}}
|
||||||
|
:communities/all-addresses-to-reveal {community-id #{"0xA"}}
|
||||||
|
:communities/selected-share-all-addresses {community-id false}}}
|
||||||
|
addresses-to-reveal #{"0xA" "0xB" "0xC"}]
|
||||||
|
(is (match?
|
||||||
|
{:db {:communities/selected-share-all-addresses {community-id true}
|
||||||
|
:communities/all-addresses-to-reveal
|
||||||
|
{community-id addresses-to-reveal}}
|
||||||
|
:fx [[:dispatch
|
||||||
|
[:communities/check-permissions-to-join-during-selection
|
||||||
|
community-id addresses-to-reveal]]]}
|
||||||
|
(sut/set-share-all-addresses cofx [community-id true])))))
|
||||||
|
|
||||||
|
(testing "sets flag from true -> false will not change addresses to be revealed"
|
||||||
|
(let [cofx {:db {:communities/all-addresses-to-reveal {community-id #{"0xA"}}}}]
|
||||||
|
(is (match?
|
||||||
|
{:db {:communities/selected-share-all-addresses {community-id false}
|
||||||
|
:communities/all-addresses-to-reveal {community-id #{"0xA"}}}
|
||||||
|
:fx [nil]}
|
||||||
|
(sut/set-share-all-addresses cofx [community-id false]))))))
|
||||||
|
|
||||||
|
(deftest check-permissions-to-join-for-selection-test
|
||||||
|
(testing "when no addresses are passed don't check permissions"
|
||||||
|
(let [addresses []
|
||||||
|
cofx {:db {:foo :bar
|
||||||
|
:communities/permissions-checks-for-selection
|
||||||
|
{"0xC" :another-check
|
||||||
|
community-id :some-check}}}]
|
||||||
|
(is (match?
|
||||||
|
{:db {:foo :bar
|
||||||
|
:communities/permissions-checks-for-selection {"0xC" :another-check}}}
|
||||||
|
(sut/check-permissions-to-join-for-selection cofx [community-id addresses])))))
|
||||||
|
|
||||||
|
(testing "when there are addresses to check permissions and not currently checking"
|
||||||
|
(let [addresses ["0xA"]
|
||||||
|
cofx {:db {:communities/permissions-checks-for-selection
|
||||||
|
{"other-comm-id" {}
|
||||||
|
community-id {:checking? false}}}}]
|
||||||
|
(is (match?
|
||||||
|
{:db {:communities/permissions-checks-for-selection
|
||||||
|
{"other-comm-id" {}
|
||||||
|
community-id {:checking? true}}}
|
||||||
|
:fx [[:json-rpc/call
|
||||||
|
[{:method :wakuext_checkPermissionsToJoinCommunity
|
||||||
|
:params [{:communityId community-id :addresses addresses}]
|
||||||
|
:on-success [:communities/check-permissions-to-join-during-selection-success
|
||||||
|
community-id]
|
||||||
|
:on-error [:communities/check-permissions-to-join-during-selection-failure
|
||||||
|
community-id addresses]}]]]}
|
||||||
|
(sut/check-permissions-to-join-for-selection cofx [community-id addresses])))))
|
||||||
|
|
||||||
|
(testing "when there are addresses to check permissions, but currently checking, then skip the check"
|
||||||
|
(let [addresses ["0xA"]
|
||||||
|
cofx {:db {:communities/permissions-checks-for-selection
|
||||||
|
{"other-comm-id" {}
|
||||||
|
community-id {:checking? true}}}}]
|
||||||
|
(is (nil? (sut/check-permissions-to-join-for-selection cofx [community-id addresses]))))))
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
(ns status-im.contexts.communities.actions.addresses-for-permissions.style)
|
||||||
|
|
||||||
|
(def drawer-body
|
||||||
|
{:padding-top 4
|
||||||
|
:padding-horizontal 20
|
||||||
|
:padding-bottom 12})
|
|
@ -1,8 +1,13 @@
|
||||||
(ns status-im.contexts.communities.actions.addresses-for-permissions.view
|
(ns status-im.contexts.communities.actions.addresses-for-permissions.view
|
||||||
(:require [quo.core :as quo]
|
(:require
|
||||||
|
[clojure.string :as string]
|
||||||
|
[quo.core :as quo]
|
||||||
|
[react-native.core :as rn]
|
||||||
[react-native.gesture :as gesture]
|
[react-native.gesture :as gesture]
|
||||||
[status-im.common.not-implemented :as not-implemented]
|
[status-im.common.not-implemented :as not-implemented]
|
||||||
|
[status-im.common.password-authentication.view :as password-authentication]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
|
[status-im.contexts.communities.actions.addresses-for-permissions.style :as style]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.money :as money]
|
[utils.money :as money]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
@ -36,44 +41,139 @@
|
||||||
:token (:symbol balance)
|
:token (:symbol balance)
|
||||||
:token-img-src (images-by-symbol sym)))))
|
:token-img-src (images-by-symbol sym)))))
|
||||||
|
|
||||||
|
(defn- cancel-join-request-drawer
|
||||||
|
[community-id]
|
||||||
|
(let [{:keys [name logo color]} (rf/sub [:communities/for-context-tag community-id])
|
||||||
|
request-id (rf/sub [:communities/my-pending-request-to-join community-id])]
|
||||||
|
[:<>
|
||||||
|
[quo/drawer-top
|
||||||
|
{:type :context-tag
|
||||||
|
:context-tag-type :community
|
||||||
|
:title (i18n/label :t/cancel-request?)
|
||||||
|
:community-name name
|
||||||
|
:community-logo logo
|
||||||
|
:customization-color color}]
|
||||||
|
[rn/view {:style style/drawer-body}
|
||||||
|
[quo/text (i18n/label :t/pending-join-request-farewell)]]
|
||||||
|
[quo/bottom-actions
|
||||||
|
{:actions :two-actions
|
||||||
|
|
||||||
|
:button-one-label (i18n/label :t/confirm-and-cancel)
|
||||||
|
:button-one-props {:customization-color color
|
||||||
|
:on-press
|
||||||
|
(fn []
|
||||||
|
(rf/dispatch [:communities/addresses-for-permissions-cancel-request
|
||||||
|
request-id]))}
|
||||||
|
|
||||||
|
:button-two-label (i18n/label :t/cancel)
|
||||||
|
:button-two-props {:type :grey
|
||||||
|
:on-press #(rf/dispatch [:hide-bottom-sheet])}}]]))
|
||||||
|
|
||||||
|
(defn- confirm-discard-drawer
|
||||||
|
[community-id]
|
||||||
|
(let [{:keys [name logo color]} (rf/sub [:communities/for-context-tag community-id])]
|
||||||
|
[:<>
|
||||||
|
[quo/drawer-top
|
||||||
|
{:type :context-tag
|
||||||
|
:context-tag-type :community
|
||||||
|
:title (i18n/label :t/discard-changes?)
|
||||||
|
:community-name name
|
||||||
|
:community-logo logo
|
||||||
|
:customization-color color}]
|
||||||
|
[rn/view {:style style/drawer-body}
|
||||||
|
[quo/text (i18n/label :t/all-changes-will-be-discarded)]]
|
||||||
|
[quo/bottom-actions
|
||||||
|
{:actions :two-actions
|
||||||
|
|
||||||
|
:button-one-label (i18n/label :t/discard)
|
||||||
|
:button-one-props {:customization-color color
|
||||||
|
:on-press
|
||||||
|
(fn []
|
||||||
|
(rf/dispatch [:dismiss-modal :addresses-for-permissions])
|
||||||
|
(rf/dispatch [:hide-bottom-sheet]))}
|
||||||
|
|
||||||
|
:button-two-label (i18n/label :t/cancel)
|
||||||
|
:button-two-props {:type :grey
|
||||||
|
:on-press #(rf/dispatch [:hide-bottom-sheet])}}]]))
|
||||||
|
|
||||||
|
(defn- leave-community-drawer
|
||||||
|
[community-id outro-message]
|
||||||
|
(let [{:keys [name logo color]} (rf/sub [:communities/for-context-tag community-id])]
|
||||||
|
[:<>
|
||||||
|
[quo/drawer-top
|
||||||
|
{:type :context-tag
|
||||||
|
:context-tag-type :community
|
||||||
|
:title (i18n/label :t/leave-community?)
|
||||||
|
:community-name name
|
||||||
|
:community-logo logo
|
||||||
|
:customization-color color}]
|
||||||
|
[rn/view {:style style/drawer-body}
|
||||||
|
[quo/text
|
||||||
|
(if (string/blank? outro-message)
|
||||||
|
(i18n/label :t/leave-community-farewell)
|
||||||
|
outro-message)]]
|
||||||
|
[quo/bottom-actions
|
||||||
|
{:actions :two-actions
|
||||||
|
|
||||||
|
:button-one-label (i18n/label :t/confirm-and-leave)
|
||||||
|
:button-one-props {:customization-color color
|
||||||
|
:on-press
|
||||||
|
#(rf/dispatch [:communities/addresses-for-permissions-leave community-id])}
|
||||||
|
|
||||||
|
:button-two-label (i18n/label :t/cancel)
|
||||||
|
:button-two-props {:type :grey
|
||||||
|
:on-press #(rf/dispatch [:hide-bottom-sheet])}}]]))
|
||||||
|
|
||||||
(defn- account-item
|
(defn- account-item
|
||||||
[{:keys [color address name emoji]} _ _
|
[{:keys [customization-color address name emoji]} _ _
|
||||||
{:keys [selected-addresses community-id share-all-addresses? community-color]}]
|
[addresses-to-reveal set-addresses-to-reveal community-id community-color share-all-addresses?]]
|
||||||
(let [balances (rf/sub [:communities/permissioned-balances-by-address community-id address])
|
(let [balances (rf/sub [:communities/permissioned-balances-by-address community-id address])
|
||||||
images-by-symbol (rf/sub [:communities/token-images-by-symbol community-id])]
|
images-by-symbol (rf/sub [:communities/token-images-by-symbol community-id])
|
||||||
|
checked? (contains? addresses-to-reveal address)
|
||||||
|
toggle-address (fn []
|
||||||
|
(let [new-addresses (if checked?
|
||||||
|
(disj addresses-to-reveal address)
|
||||||
|
(conj addresses-to-reveal address))]
|
||||||
|
(set-addresses-to-reveal new-addresses)))]
|
||||||
[quo/account-permissions
|
[quo/account-permissions
|
||||||
{:account {:name name
|
{:account {:name name
|
||||||
:address address
|
:address address
|
||||||
:emoji emoji
|
:emoji emoji
|
||||||
:customization-color color}
|
:customization-color customization-color}
|
||||||
:token-details (balances->components-props balances images-by-symbol)
|
:token-details (when-not share-all-addresses?
|
||||||
:checked? (contains? selected-addresses address)
|
(balances->components-props balances images-by-symbol))
|
||||||
|
:checked? checked?
|
||||||
:disabled? share-all-addresses?
|
:disabled? share-all-addresses?
|
||||||
:on-change #(rf/dispatch [:communities/toggle-selected-permission-address
|
:on-change toggle-address
|
||||||
address community-id])
|
|
||||||
:container-style {:margin-bottom 8}
|
:container-style {:margin-bottom 8}
|
||||||
:customization-color community-color}]))
|
:customization-color community-color}]))
|
||||||
|
|
||||||
(defn view
|
(defn- page-top
|
||||||
[]
|
[{:keys [community-id identical-choices? can-edit-addresses?]}]
|
||||||
(let [{id :community-id} (rf/sub [:get-screen-params])
|
(let [{:keys [name logo color]} (rf/sub [:communities/for-context-tag community-id])
|
||||||
toggle-share-all-addresses #(rf/dispatch [:communities/toggle-share-all-addresses id])
|
confirm-discard-changes (rn/use-callback
|
||||||
update-previous-addresses (fn []
|
|
||||||
(rf/dispatch [:communities/update-previous-permission-addresses id])
|
|
||||||
(rf/dispatch [:hide-bottom-sheet]))
|
|
||||||
reset-selected-addresses (fn []
|
|
||||||
(rf/dispatch [:communities/reset-selected-permission-addresses id])
|
|
||||||
(rf/dispatch [:hide-bottom-sheet]))]
|
|
||||||
(rf/dispatch [:communities/get-permissioned-balances id])
|
|
||||||
(fn []
|
(fn []
|
||||||
(let [{:keys [name color images]} (rf/sub [:communities/community id])
|
(if identical-choices?
|
||||||
{:keys [checking?
|
(rf/dispatch [:dismiss-modal :addresses-for-permissions])
|
||||||
highest-permission-role]} (rf/sub [:community/token-gated-overview id])
|
(rf/dispatch [:show-bottom-sheet
|
||||||
accounts (rf/sub [:wallet/accounts-without-watched-accounts])
|
{:content (fn [] [confirm-discard-drawer
|
||||||
selected-addresses (rf/sub [:communities/selected-permission-addresses id])
|
community-id])}])))
|
||||||
share-all-addresses? (rf/sub [:communities/share-all-addresses? id])
|
[identical-choices?])]
|
||||||
unsaved-address-changes? (rf/sub [:communities/unsaved-address-changes? id])]
|
|
||||||
[:<>
|
[:<>
|
||||||
|
(when can-edit-addresses?
|
||||||
|
[quo/page-nav
|
||||||
|
{:type :no-title
|
||||||
|
:icon-name :i/arrow-left
|
||||||
|
:on-press confirm-discard-changes}])
|
||||||
|
|
||||||
|
(if can-edit-addresses?
|
||||||
|
[quo/page-top
|
||||||
|
{:title (i18n/label :t/addresses-for-permissions)
|
||||||
|
:title-accessibility-label :title-label
|
||||||
|
:description :context-tag
|
||||||
|
:context-tag {:type :community
|
||||||
|
:community-logo logo
|
||||||
|
:community-name name}}]
|
||||||
[quo/drawer-top
|
[quo/drawer-top
|
||||||
{:type :context-tag
|
{:type :context-tag
|
||||||
:title (i18n/label :t/addresses-for-permissions)
|
:title (i18n/label :t/addresses-for-permissions)
|
||||||
|
@ -82,15 +182,102 @@
|
||||||
:button-icon :i/info
|
:button-icon :i/info
|
||||||
:button-type :grey
|
:button-type :grey
|
||||||
:on-button-press not-implemented/alert
|
:on-button-press not-implemented/alert
|
||||||
:community-logo (get-in images [:thumbnail :uri])
|
:community-logo logo
|
||||||
:customization-color color}]
|
:customization-color color}])]))
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[]
|
||||||
|
(let [{id :community-id} (rf/sub [:get-screen-params])
|
||||||
|
{:keys [color joined] outro-message :outroMessage} (rf/sub [:communities/community id])
|
||||||
|
|
||||||
|
highest-role (rf/sub [:communities/highest-role-for-selection id])
|
||||||
|
[unmodified-role _] (rn/use-state highest-role)
|
||||||
|
|
||||||
|
can-edit-addresses? (rf/sub [:communities/can-edit-shared-addresses? id])
|
||||||
|
pending? (boolean (rf/sub [:communities/my-pending-request-to-join id]))
|
||||||
|
|
||||||
|
wallet-accounts (rf/sub [:wallet/accounts-without-watched-accounts])
|
||||||
|
unmodified-addresses-to-reveal (rf/sub [:communities/addresses-to-reveal id])
|
||||||
|
[addresses-to-reveal set-addresses-to-reveal] (rn/use-state unmodified-addresses-to-reveal)
|
||||||
|
|
||||||
|
unmodified-flag-share-all-addresses (rf/sub [:communities/share-all-addresses? id])
|
||||||
|
[flag-share-all-addresses
|
||||||
|
set-flag-share-all-addresses] (rn/use-state unmodified-flag-share-all-addresses)
|
||||||
|
|
||||||
|
identical-choices? (and (= unmodified-addresses-to-reveal addresses-to-reveal)
|
||||||
|
(= unmodified-flag-share-all-addresses flag-share-all-addresses))
|
||||||
|
|
||||||
|
toggle-flag-share-all-addresses
|
||||||
|
(fn []
|
||||||
|
(let [new-value (not flag-share-all-addresses)]
|
||||||
|
(set-flag-share-all-addresses new-value)
|
||||||
|
(when new-value
|
||||||
|
(set-addresses-to-reveal (set (map :address wallet-accounts))))))
|
||||||
|
|
||||||
|
cancel-join-request
|
||||||
|
(rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(rf/dispatch [:show-bottom-sheet
|
||||||
|
{:content (fn [] [cancel-join-request-drawer id])}])))
|
||||||
|
|
||||||
|
leave-community
|
||||||
|
(rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(rf/dispatch [:show-bottom-sheet
|
||||||
|
{:content (fn [] [leave-community-drawer id outro-message])}]))
|
||||||
|
[outro-message])
|
||||||
|
|
||||||
|
cancel-selection
|
||||||
|
(fn []
|
||||||
|
(rf/dispatch [:communities/check-permissions-to-join-community
|
||||||
|
id
|
||||||
|
unmodified-addresses-to-reveal
|
||||||
|
:based-on-client-selection])
|
||||||
|
(rf/dispatch [:hide-bottom-sheet]))
|
||||||
|
|
||||||
|
confirm-changes
|
||||||
|
(fn []
|
||||||
|
(if can-edit-addresses?
|
||||||
|
(rf/dispatch
|
||||||
|
[:password-authentication/show
|
||||||
|
{:content (fn [] [password-authentication/view])}
|
||||||
|
{:label (i18n/label :t/enter-password)
|
||||||
|
:on-press (fn [password]
|
||||||
|
(rf/dispatch
|
||||||
|
[:communities/edit-shared-addresses
|
||||||
|
{:community-id id
|
||||||
|
:password password
|
||||||
|
:addresses addresses-to-reveal
|
||||||
|
:on-success (fn []
|
||||||
|
(rf/dispatch [:dismiss-modal :addresses-for-permissions])
|
||||||
|
(rf/dispatch [:hide-bottom-sheet]))}]))}])
|
||||||
|
(do
|
||||||
|
(rf/dispatch [:communities/set-share-all-addresses id flag-share-all-addresses])
|
||||||
|
(rf/dispatch [:communities/set-addresses-to-reveal id addresses-to-reveal]))))]
|
||||||
|
|
||||||
|
(rn/use-mount
|
||||||
|
(fn []
|
||||||
|
(when-not flag-share-all-addresses
|
||||||
|
(rf/dispatch [:communities/get-permissioned-balances id]))))
|
||||||
|
|
||||||
|
(rn/use-effect
|
||||||
|
(fn []
|
||||||
|
(rf/dispatch [:communities/check-permissions-to-join-during-selection id addresses-to-reveal]))
|
||||||
|
[id addresses-to-reveal])
|
||||||
|
|
||||||
|
[:<>
|
||||||
|
[page-top
|
||||||
|
{:community-id id
|
||||||
|
:identical-choices? identical-choices?
|
||||||
|
:can-edit-addresses? can-edit-addresses?}]
|
||||||
|
|
||||||
[gesture/flat-list
|
[gesture/flat-list
|
||||||
{:render-fn account-item
|
{:render-fn account-item
|
||||||
:render-data {:selected-addresses selected-addresses
|
:render-data [addresses-to-reveal
|
||||||
:community-id id
|
set-addresses-to-reveal
|
||||||
:share-all-addresses? share-all-addresses?
|
id
|
||||||
:community-color color}
|
color
|
||||||
|
flag-share-all-addresses]
|
||||||
:header [quo/category
|
:header [quo/category
|
||||||
{:list-type :settings
|
{:list-type :settings
|
||||||
:data [{:title
|
:data [{:title
|
||||||
|
@ -98,34 +285,72 @@
|
||||||
:t/share-all-current-and-future-addresses)
|
:t/share-all-current-and-future-addresses)
|
||||||
:action :selector
|
:action :selector
|
||||||
:action-props
|
:action-props
|
||||||
{:on-change toggle-share-all-addresses
|
{:on-change toggle-flag-share-all-addresses
|
||||||
:customization-color color
|
:customization-color color
|
||||||
:checked? share-all-addresses?}}]
|
:checked? flag-share-all-addresses}}]
|
||||||
:container-style {:padding-bottom 16 :padding-horizontal 0}}]
|
:container-style {:padding-bottom 16 :padding-horizontal 0}}]
|
||||||
:content-container-style {:padding-horizontal 20}
|
:content-container-style {:padding-horizontal 20}
|
||||||
:key-fn :address
|
:key-fn :address
|
||||||
:data accounts}]
|
:data wallet-accounts}]
|
||||||
|
|
||||||
[quo/bottom-actions
|
[quo/bottom-actions
|
||||||
{:actions :two-actions
|
(cond-> {:role (role-keyword highest-role)
|
||||||
:button-one-label (i18n/label :t/confirm-changes)
|
:description (if highest-role
|
||||||
|
:top
|
||||||
|
:top-error)
|
||||||
:button-one-props {:customization-color color
|
:button-one-props {:customization-color color
|
||||||
:disabled? (or checking?
|
:on-press confirm-changes
|
||||||
(empty? selected-addresses)
|
:disabled? (or (empty? addresses-to-reveal)
|
||||||
(not highest-permission-role)
|
(not highest-role)
|
||||||
(not unsaved-address-changes?))
|
identical-choices?)}}
|
||||||
:on-press update-previous-addresses}
|
can-edit-addresses?
|
||||||
|
(->
|
||||||
|
(assoc :actions :one-action
|
||||||
|
:button-one-label (cond
|
||||||
|
(and pending? (not highest-role))
|
||||||
|
(i18n/label :t/cancel-request)
|
||||||
|
|
||||||
|
(and joined (not highest-role))
|
||||||
|
(i18n/label :t/leave-community)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(i18n/label :t/confirm-changes))
|
||||||
|
:description-top-text (cond
|
||||||
|
(and pending? highest-role)
|
||||||
|
(i18n/label :t/eligible-to-join-as)
|
||||||
|
|
||||||
|
(and joined (= highest-role unmodified-role))
|
||||||
|
(i18n/label :t/you-are-a)
|
||||||
|
|
||||||
|
(and joined (not= highest-role unmodified-role))
|
||||||
|
(i18n/label :t/you-will-be-a))
|
||||||
|
:error-message (cond
|
||||||
|
(and pending? (not highest-role))
|
||||||
|
(i18n/label :t/community-join-requirements-not-met)
|
||||||
|
|
||||||
|
(and joined (not highest-role))
|
||||||
|
(i18n/label :t/membership-requirements-not-met)))
|
||||||
|
(update :button-one-props
|
||||||
|
merge
|
||||||
|
(cond (and pending? (not highest-role))
|
||||||
|
{:type :danger
|
||||||
|
:disabled? false
|
||||||
|
:on-press cancel-join-request}
|
||||||
|
|
||||||
|
(and joined (not highest-role))
|
||||||
|
{:type :danger
|
||||||
|
:disabled? false
|
||||||
|
:on-press leave-community})))
|
||||||
|
|
||||||
|
(not can-edit-addresses?)
|
||||||
|
(assoc :actions :two-actions
|
||||||
|
:button-one-label (i18n/label :t/confirm-changes)
|
||||||
:button-two-label (i18n/label :t/cancel)
|
:button-two-label (i18n/label :t/cancel)
|
||||||
:button-two-props {:type :grey
|
:button-two-props {:type :grey
|
||||||
:on-press reset-selected-addresses}
|
:on-press cancel-selection}
|
||||||
:description (if (or (empty? selected-addresses)
|
|
||||||
(not highest-permission-role))
|
|
||||||
:top-error
|
|
||||||
:top)
|
|
||||||
:role (when-not checking? (role-keyword highest-permission-role))
|
|
||||||
:error-message (cond
|
:error-message (cond
|
||||||
(empty? selected-addresses)
|
(empty? addresses-to-reveal)
|
||||||
(i18n/label :t/no-addresses-selected)
|
(i18n/label :t/no-addresses-selected)
|
||||||
|
|
||||||
(not highest-permission-role)
|
(not highest-role)
|
||||||
(i18n/label :t/addresses-dont-contain-tokens-needed))}]]))))
|
(i18n/label :t/addresses-dont-contain-tokens-needed))))]]))
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
(ns status-im.contexts.communities.actions.airdrop-addresses.events
|
||||||
|
(:require
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(defn set-airdrop-address
|
||||||
|
[{:keys [db]} [community-id airdrop-address]]
|
||||||
|
{:db (assoc-in db [:communities/all-airdrop-addresses community-id] airdrop-address)})
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/set-airdrop-address set-airdrop-address)
|
|
@ -0,0 +1,18 @@
|
||||||
|
(ns status-im.contexts.communities.actions.airdrop-addresses.events-test
|
||||||
|
(:require
|
||||||
|
[cljs.test :refer [deftest is testing]]
|
||||||
|
[status-im.contexts.communities.actions.airdrop-addresses.events :as sut]))
|
||||||
|
|
||||||
|
(def community-id "community-id")
|
||||||
|
|
||||||
|
(deftest set-airdrop-address-test
|
||||||
|
(testing "updates all reveal? flags"
|
||||||
|
(let [new-airdrop-address "0xA"
|
||||||
|
cofx {:db {:communities/all-airdrop-addresses
|
||||||
|
{"another-community" "0xF"
|
||||||
|
community-id "0xB"}}}]
|
||||||
|
(is (match?
|
||||||
|
(assoc-in cofx
|
||||||
|
[:db :communities/all-airdrop-addresses community-id]
|
||||||
|
new-airdrop-address)
|
||||||
|
(sut/set-airdrop-address cofx [community-id new-airdrop-address]))))))
|
|
@ -1,29 +1,68 @@
|
||||||
(ns status-im.contexts.communities.actions.airdrop-addresses.view
|
(ns status-im.contexts.communities.actions.airdrop-addresses.view
|
||||||
(:require
|
(:require
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
|
[react-native.core :as rn]
|
||||||
[react-native.gesture :as gesture]
|
[react-native.gesture :as gesture]
|
||||||
[status-im.common.not-implemented :as not-implemented]
|
[status-im.common.not-implemented :as not-implemented]
|
||||||
|
[status-im.common.password-authentication.view :as password-authentication]
|
||||||
[status-im.contexts.communities.actions.airdrop-addresses.style :as style]
|
[status-im.contexts.communities.actions.airdrop-addresses.style :as style]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(defn- render-item
|
(defn- account-item
|
||||||
[item _ _ [airdrop-address community-id]]
|
[{:keys [address emoji] :as account}
|
||||||
|
_ _
|
||||||
|
[community-id airdrop-address can-edit-addresses?]]
|
||||||
|
(let [airdrop-address? (= address airdrop-address)
|
||||||
|
on-press
|
||||||
|
(when-not airdrop-address?
|
||||||
|
(fn []
|
||||||
|
(if can-edit-addresses?
|
||||||
|
(rf/dispatch
|
||||||
|
[:password-authentication/show
|
||||||
|
{:content (fn [] [password-authentication/view])}
|
||||||
|
{:label (i18n/label :t/enter-password)
|
||||||
|
:on-press (fn [password]
|
||||||
|
(rf/dispatch
|
||||||
|
[:communities/edit-shared-addresses
|
||||||
|
{:community-id community-id
|
||||||
|
:password password
|
||||||
|
:airdrop-address address
|
||||||
|
:on-success (fn []
|
||||||
|
(rf/dispatch [:dismiss-modal :address-for-airdrop])
|
||||||
|
(rf/dispatch [:hide-bottom-sheet]))}]))}])
|
||||||
|
(do
|
||||||
|
(rf/dispatch [:communities/set-airdrop-address community-id address])
|
||||||
|
(rf/dispatch [:hide-bottom-sheet])))))]
|
||||||
[quo/account-item
|
[quo/account-item
|
||||||
{:account-props item
|
{:account-props account
|
||||||
:state (when (= airdrop-address (:address item)) :selected)
|
:emoji emoji
|
||||||
:on-press (fn []
|
:state (if airdrop-address? :selected :default)
|
||||||
(rf/dispatch [:communities/set-airdrop-address (:address item) community-id])
|
:on-press on-press}]))
|
||||||
(rf/dispatch [:hide-bottom-sheet]))
|
|
||||||
:emoji (:emoji item)}])
|
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
(let [{id :community-id} (rf/sub [:get-screen-params])
|
(let [{id :community-id} (rf/sub [:get-screen-params])
|
||||||
{:keys [name images color]} (rf/sub [:communities/community id])
|
{:keys [name logo color]} (rf/sub [:communities/for-context-tag id])
|
||||||
selected-accounts (rf/sub [:communities/selected-permission-accounts id])
|
accounts (rf/sub [:communities/accounts-to-reveal id])
|
||||||
airdrop-address (rf/sub [:communities/airdrop-address id])]
|
airdrop-address (rf/sub [:communities/airdrop-address id])
|
||||||
|
can-edit-addresses? (rf/sub [:communities/can-edit-shared-addresses? id])
|
||||||
|
go-back (rn/use-callback #(rf/dispatch [:dismiss-modal :address-for-airdrop]))]
|
||||||
[:<>
|
[:<>
|
||||||
|
(when can-edit-addresses?
|
||||||
|
[quo/page-nav
|
||||||
|
{:type :no-title
|
||||||
|
:icon-name :i/arrow-left
|
||||||
|
:on-press go-back}])
|
||||||
|
|
||||||
|
(if can-edit-addresses?
|
||||||
|
[quo/page-top
|
||||||
|
{:title (i18n/label :t/airdrop-addresses)
|
||||||
|
:title-accessibility-label :title-label
|
||||||
|
:description :context-tag
|
||||||
|
:context-tag {:type :community
|
||||||
|
:community-logo logo
|
||||||
|
:community-name name}}]
|
||||||
[quo/drawer-top
|
[quo/drawer-top
|
||||||
{:type :context-tag
|
{:type :context-tag
|
||||||
:context-tag-type :community
|
:context-tag-type :community
|
||||||
|
@ -31,11 +70,12 @@
|
||||||
:community-name name
|
:community-name name
|
||||||
:button-icon :i/info
|
:button-icon :i/info
|
||||||
:on-button-press not-implemented/alert
|
:on-button-press not-implemented/alert
|
||||||
:community-logo (get-in images [:thumbnail :uri])
|
:community-logo logo
|
||||||
:customization-color color}]
|
:customization-color color}])
|
||||||
|
|
||||||
[gesture/flat-list
|
[gesture/flat-list
|
||||||
{:data selected-accounts
|
{:data accounts
|
||||||
:render-fn render-item
|
:render-fn account-item
|
||||||
:render-data [airdrop-address id]
|
:render-data [id airdrop-address can-edit-addresses?]
|
||||||
:content-container-style style/account-list-container
|
:content-container-style style/account-list-container
|
||||||
:key-fn :address}]]))
|
:key-fn :address}]]))
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
[status-im.contexts.communities.actions.leave.view :as leave-menu]
|
[status-im.contexts.communities.actions.leave.view :as leave-menu]
|
||||||
[status-im.contexts.communities.actions.see-rules.view :as see-rules]
|
[status-im.contexts.communities.actions.see-rules.view :as see-rules]
|
||||||
[status-im.contexts.communities.actions.token-gating.view :as token-gating]
|
[status-im.contexts.communities.actions.token-gating.view :as token-gating]
|
||||||
|
[status-im.feature-flags :as ff]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
@ -41,6 +42,15 @@
|
||||||
{:content (fn [] [token-gating/token-requirements id])}])
|
{:content (fn [] [token-gating/token-requirements id])}])
|
||||||
:label (i18n/label :t/view-token-gating)})
|
:label (i18n/label :t/view-token-gating)})
|
||||||
|
|
||||||
|
(defn edit-shared-addresses
|
||||||
|
[id]
|
||||||
|
{:icon :i/wallet
|
||||||
|
:right-icon :i/chevron-right
|
||||||
|
:accessibility-label :edit-shared-addresses
|
||||||
|
:on-press (fn []
|
||||||
|
(rf/dispatch [:open-modal :community-account-selection {:community-id id}]))
|
||||||
|
:label (i18n/label :t/edit-shared-addresses)})
|
||||||
|
|
||||||
(defn mark-as-read
|
(defn mark-as-read
|
||||||
[id]
|
[id]
|
||||||
{:icon :i/up-to-date
|
{:icon :i/up-to-date
|
||||||
|
@ -119,28 +129,33 @@
|
||||||
request-id])}])})
|
request-id])}])})
|
||||||
|
|
||||||
(defn not-joined-options
|
(defn not-joined-options
|
||||||
[id token-gated?]
|
[id token-gated? pending?]
|
||||||
[[(when-not token-gated? (view-members id))
|
[[(when-not token-gated? (view-members id))
|
||||||
(when-not token-gated? (view-rules id))
|
(when-not token-gated? (view-rules id))
|
||||||
(invite-contacts id)
|
(invite-contacts id)
|
||||||
(when token-gated? (view-token-gating id))
|
(when token-gated? (view-token-gating id))
|
||||||
|
(when (and pending? (ff/enabled? ::ff/community.edit-account-selection))
|
||||||
|
(edit-shared-addresses id))
|
||||||
(show-qr id)
|
(show-qr id)
|
||||||
(share-community id)]])
|
(share-community id)]])
|
||||||
|
|
||||||
(defn join-request-sent-options
|
(defn join-request-sent-options
|
||||||
[id token-gated? request-id]
|
[id token-gated? request-id]
|
||||||
[(conj (first (not-joined-options id token-gated?))
|
[(conj (first (not-joined-options id token-gated? request-id))
|
||||||
(assoc (cancel-request-to-join id request-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?]
|
||||||
(not-joined-options id token-gated?))
|
(let [pending? false]
|
||||||
|
(not-joined-options id token-gated? pending?)))
|
||||||
|
|
||||||
(defn joined-options
|
(defn joined-options
|
||||||
[id token-gated? muted? muted-till]
|
[id token-gated? muted? muted-till]
|
||||||
[[(view-members id)
|
[[(view-members id)
|
||||||
(view-rules id)
|
(view-rules id)
|
||||||
(when token-gated? (view-token-gating id))
|
(when token-gated? (view-token-gating id))
|
||||||
|
(when (ff/enabled? ::ff/community.edit-account-selection)
|
||||||
|
(edit-shared-addresses id))
|
||||||
(mark-as-read id)
|
(mark-as-read id)
|
||||||
(mute-community id muted? muted-till)
|
(mute-community id muted? muted-till)
|
||||||
(community-notification-settings id)
|
(community-notification-settings id)
|
||||||
|
@ -171,7 +186,7 @@
|
||||||
joined (joined-options id token-permissions muted muted-till)
|
joined (joined-options id token-permissions muted muted-till)
|
||||||
request-id (join-request-sent-options id token-permissions request-id)
|
request-id (join-request-sent-options id token-permissions request-id)
|
||||||
banList (banned-options id token-permissions)
|
banList (banned-options id token-permissions)
|
||||||
:else (not-joined-options id token-permissions))))
|
:else (not-joined-options id token-permissions request-id))))
|
||||||
|
|
||||||
(defn community-options-bottom-sheet
|
(defn community-options-bottom-sheet
|
||||||
[id]
|
[id]
|
||||||
|
|
|
@ -29,10 +29,11 @@
|
||||||
{:type :positive
|
{:type :positive
|
||||||
:text (i18n/label :t/left-community {:community community-name})}]]
|
:text (i18n/label :t/left-community {:community community-name})}]]
|
||||||
[:dispatch [:activity-center.notifications/fetch-unread-count]]
|
[:dispatch [:activity-center.notifications/fetch-unread-count]]
|
||||||
|
[:dispatch [:hide-bottom-sheet]]
|
||||||
[:dispatch [:navigate-back]]]})))
|
[:dispatch [:navigate-back]]]})))
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/leave
|
(rf/reg-event-fx :communities/leave
|
||||||
(fn [{:keys [db]} [community-id]]
|
(fn [{:keys [db]} [community-id on-success]]
|
||||||
(let [community-chat-ids (map #(str community-id %)
|
(let [community-chat-ids (map #(str community-id %)
|
||||||
(keys (get-in db [:communities community-id :chats])))]
|
(keys (get-in db [:communities community-id :chats])))]
|
||||||
{:effects/push-notifications-clear-message-notifications community-chat-ids
|
{:effects/push-notifications-clear-message-notifications community-chat-ids
|
||||||
|
@ -41,5 +42,8 @@
|
||||||
[{:method "wakuext_leaveCommunity"
|
[{:method "wakuext_leaveCommunity"
|
||||||
:params [community-id]
|
:params [community-id]
|
||||||
:js-response true
|
:js-response true
|
||||||
:on-success #(rf/dispatch [:communities/left %])
|
:on-success (fn [^js response]
|
||||||
|
(when (fn? on-success)
|
||||||
|
(on-success))
|
||||||
|
(rf/dispatch [:communities/left response]))
|
||||||
:on-error #(log/error "failed to leave community" community-id %)}]})))
|
:on-error #(log/error "failed to leave community" community-id %)}]})))
|
||||||
|
|
|
@ -9,10 +9,11 @@
|
||||||
[schema.core :as schema]
|
[schema.core :as schema]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[status-im.contexts.chat.messenger.messages.link-preview.events :as link-preview.events]
|
[status-im.contexts.chat.messenger.messages.link-preview.events :as link-preview.events]
|
||||||
|
status-im.contexts.communities.actions.accounts-selection.events
|
||||||
status-im.contexts.communities.actions.addresses-for-permissions.events
|
status-im.contexts.communities.actions.addresses-for-permissions.events
|
||||||
|
status-im.contexts.communities.actions.airdrop-addresses.events
|
||||||
status-im.contexts.communities.actions.community-options.events
|
status-im.contexts.communities.actions.community-options.events
|
||||||
status-im.contexts.communities.actions.leave.events
|
status-im.contexts.communities.actions.leave.events
|
||||||
[status-im.contexts.communities.utils :as utils]
|
|
||||||
[status-im.navigation.events :as navigation]
|
[status-im.navigation.events :as navigation]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
|
@ -29,13 +30,10 @@
|
||||||
{:db (assoc-in db
|
{:db (assoc-in db
|
||||||
[:communities id]
|
[:communities id]
|
||||||
(assoc community :last-opened-at (max last-opened-at previous-last-opened-at)))
|
(assoc community :last-opened-at (max last-opened-at previous-last-opened-at)))
|
||||||
:fx [[:dispatch [:communities/initialize-permission-addresses id]]
|
:fx [(when (not joined)
|
||||||
(when (not joined)
|
|
||||||
[:dispatch [:chat.ui/spectate-community id]])
|
[:dispatch [:chat.ui/spectate-community id]])
|
||||||
(when (nil? token-permissions-check)
|
(when (nil? token-permissions-check)
|
||||||
[:dispatch [:communities/check-permissions-to-join-community id]])
|
[:dispatch [:communities/check-permissions-to-join-community id]])]}))))
|
||||||
(when joined
|
|
||||||
[:dispatch [:communities/get-revealed-accounts id]])]}))))
|
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/handle-community handle-community)
|
(rf/reg-event-fx :communities/handle-community handle-community)
|
||||||
|
|
||||||
|
@ -157,97 +155,6 @@
|
||||||
:on-success #(rf/dispatch [:communities/fetched-collapsed-categories-success %])
|
:on-success #(rf/dispatch [:communities/fetched-collapsed-categories-success %])
|
||||||
:on-error #(log/error "failed to fetch collapsed community categories" %)}]}))
|
:on-error #(log/error "failed to fetch collapsed community categories" %)}]}))
|
||||||
|
|
||||||
(defn initialize-permission-addresses
|
|
||||||
[{:keys [db]} [community-id]]
|
|
||||||
(when community-id
|
|
||||||
(let [accounts (utils/sorted-non-watch-only-accounts db)
|
|
||||||
addresses (set (map :address accounts))]
|
|
||||||
{:db (update-in db
|
|
||||||
[:communities community-id]
|
|
||||||
assoc
|
|
||||||
:previous-share-all-addresses? true
|
|
||||||
:share-all-addresses? true
|
|
||||||
:previous-permission-addresses addresses
|
|
||||||
:selected-permission-addresses addresses
|
|
||||||
:airdrop-address (:address (first accounts)))})))
|
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/initialize-permission-addresses
|
|
||||||
initialize-permission-addresses)
|
|
||||||
|
|
||||||
(defn update-previous-permission-addresses
|
|
||||||
[{:keys [db]} [community-id]]
|
|
||||||
(when community-id
|
|
||||||
(let [accounts (utils/sorted-non-watch-only-accounts db)
|
|
||||||
selected-permission-addresses (get-in db
|
|
||||||
[:communities community-id
|
|
||||||
:selected-permission-addresses])
|
|
||||||
selected-accounts (filter #(contains? selected-permission-addresses (:address %))
|
|
||||||
accounts)
|
|
||||||
current-airdrop-address (get-in db [:communities community-id :airdrop-address])
|
|
||||||
share-all-addresses? (get-in db [:communities community-id :share-all-addresses?])]
|
|
||||||
{:db (update-in db
|
|
||||||
[:communities community-id]
|
|
||||||
assoc
|
|
||||||
:previous-share-all-addresses? share-all-addresses?
|
|
||||||
:previous-permission-addresses selected-permission-addresses
|
|
||||||
:airdrop-address (if (contains? selected-permission-addresses
|
|
||||||
current-airdrop-address)
|
|
||||||
current-airdrop-address
|
|
||||||
(:address (first selected-accounts))))})))
|
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/update-previous-permission-addresses
|
|
||||||
update-previous-permission-addresses)
|
|
||||||
|
|
||||||
(defn toggle-selected-permission-address
|
|
||||||
[{:keys [db]} [address community-id]]
|
|
||||||
(let [selected-permission-addresses
|
|
||||||
(get-in db [:communities community-id :selected-permission-addresses])
|
|
||||||
updated-selected-permission-addresses
|
|
||||||
(if (contains? selected-permission-addresses address)
|
|
||||||
(disj selected-permission-addresses address)
|
|
||||||
(conj selected-permission-addresses address))]
|
|
||||||
{:db (assoc-in db
|
|
||||||
[:communities community-id :selected-permission-addresses]
|
|
||||||
updated-selected-permission-addresses)
|
|
||||||
:fx [(when community-id
|
|
||||||
[:dispatch
|
|
||||||
[:communities/check-permissions-to-join-community community-id
|
|
||||||
updated-selected-permission-addresses :based-on-client-selection]])]}))
|
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/toggle-selected-permission-address
|
|
||||||
toggle-selected-permission-address)
|
|
||||||
|
|
||||||
(defn toggle-share-all-addresses
|
|
||||||
[{:keys [db]} [community-id]]
|
|
||||||
(let [share-all-addresses? (get-in db [:communities community-id :share-all-addresses?])
|
|
||||||
next-share-all-addresses? (not share-all-addresses?)
|
|
||||||
accounts (utils/sorted-non-watch-only-accounts db)
|
|
||||||
addresses (set (map :address accounts))]
|
|
||||||
{:db (update-in db
|
|
||||||
[:communities community-id]
|
|
||||||
assoc
|
|
||||||
:share-all-addresses? next-share-all-addresses?
|
|
||||||
:selected-permission-addresses addresses)
|
|
||||||
:fx [(when (and community-id next-share-all-addresses?)
|
|
||||||
[:dispatch
|
|
||||||
[:communities/check-permissions-to-join-community community-id
|
|
||||||
addresses :based-on-client-selection]])]}))
|
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/toggle-share-all-addresses
|
|
||||||
toggle-share-all-addresses)
|
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/reset-selected-permission-addresses
|
|
||||||
(fn [{:keys [db]} [community-id]]
|
|
||||||
(when community-id
|
|
||||||
{:db (update-in db
|
|
||||||
[:communities community-id]
|
|
||||||
assoc
|
|
||||||
:selected-permission-addresses
|
|
||||||
(get-in db [:communities community-id :previous-permission-addresses])
|
|
||||||
:share-all-addresses?
|
|
||||||
(get-in db [:communities community-id :previous-share-all-addresses?]))
|
|
||||||
:fx [[:dispatch [:communities/check-permissions-to-join-community community-id]]]})))
|
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/get-community-channel-share-data
|
(rf/reg-event-fx :communities/get-community-channel-share-data
|
||||||
(fn [_ [chat-id on-success]]
|
(fn [_ [chat-id on-success]]
|
||||||
(let [{:keys [community-id channel-id]} (data-store.chats/decode-chat-id chat-id)]
|
(let [{:keys [community-id channel-id]} (data-store.chats/decode-chat-id chat-id)]
|
||||||
|
@ -286,10 +193,6 @@
|
||||||
:url %}])]
|
:url %}])]
|
||||||
{:fx [[:dispatch [:communities/get-community-channel-share-data chat-id on-success]]]})))
|
{:fx [[:dispatch [:communities/get-community-channel-share-data chat-id on-success]]]})))
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/set-airdrop-address
|
|
||||||
(fn [{:keys [db]} [address community-id]]
|
|
||||||
{:db (assoc-in db [:communities community-id :airdrop-address] address)}))
|
|
||||||
|
|
||||||
(defn community-fetched
|
(defn community-fetched
|
||||||
[{:keys [db]} [community-id community]]
|
[{:keys [db]} [community-id community]]
|
||||||
(when community
|
(when community
|
||||||
|
@ -425,16 +328,17 @@
|
||||||
[:dispatch [:chat/navigate-to-chat chat-id]])]})))
|
[:dispatch [:chat/navigate-to-chat chat-id]])]})))
|
||||||
|
|
||||||
(defn get-revealed-accounts
|
(defn get-revealed-accounts
|
||||||
[{:keys [db]} [community-id]]
|
[{:keys [db]} [community-id on-success]]
|
||||||
(let [{:keys [joined fetching-revealed-accounts]
|
(let [{:keys [joined fetching-revealed-accounts]
|
||||||
:as community} (get-in db [:communities community-id])]
|
:as community} (get-in db [:communities community-id])
|
||||||
(when (and community joined (not fetching-revealed-accounts))
|
pending? (get-in db [:communities/my-pending-requests-to-join community-id])]
|
||||||
|
(when (and community (or pending? joined) (not fetching-revealed-accounts))
|
||||||
{:db (assoc-in db [:communities community-id :fetching-revealed-accounts] true)
|
{:db (assoc-in db [:communities community-id :fetching-revealed-accounts] true)
|
||||||
:json-rpc/call
|
:json-rpc/call
|
||||||
[{:method "wakuext_getRevealedAccounts"
|
[{:method "wakuext_getRevealedAccounts"
|
||||||
:params [community-id (get-in db [:profile/profile :public-key])]
|
:params [community-id (get-in db [:profile/profile :public-key])]
|
||||||
:js-response true
|
:js-response true
|
||||||
:on-success [:communities/get-revealed-accounts-success community-id]
|
:on-success [:communities/get-revealed-accounts-success community-id on-success]
|
||||||
:on-error (fn [err]
|
:on-error (fn [err]
|
||||||
(log/error {:message "failed to fetch revealed accounts"
|
(log/error {:message "failed to fetch revealed accounts"
|
||||||
:community-id community-id
|
:community-id community-id
|
||||||
|
@ -448,19 +352,22 @@
|
||||||
[:catn
|
[:catn
|
||||||
[:cofx :schema.re-frame/cofx]
|
[:cofx :schema.re-frame/cofx]
|
||||||
[:args
|
[:args
|
||||||
[:schema [:catn [:community-id [:? :string]]]]]]
|
[:schema
|
||||||
|
[:catn
|
||||||
|
[:community-id [:? :string]]
|
||||||
|
[:on-success [:? :schema.re-frame/event]]]]]]
|
||||||
[:maybe
|
[:maybe
|
||||||
[:map
|
[:map
|
||||||
[:db map?]
|
[:db map?]
|
||||||
[:json-rpc/call :schema.common/rpc-call]]]])
|
[:json-rpc/call :schema.common/rpc-call]]]])
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/get-revealed-accounts-success
|
(rf/reg-event-fx :communities/get-revealed-accounts-success
|
||||||
(fn [{:keys [db]} [community-id revealed-accounts-js]]
|
(fn [{:keys [db]} [community-id on-success revealed-accounts-js]]
|
||||||
(when-let [community (get-in db [:communities community-id])]
|
(when-let [community (get-in db [:communities community-id])]
|
||||||
(let [revealed-accounts
|
(let [revealed-accounts
|
||||||
(reduce
|
(reduce
|
||||||
(fn [acc {:keys [address] :as revealed-account}]
|
(fn [acc {:keys [address] :as revealed-account}]
|
||||||
(assoc acc address (dissoc revealed-account :address)))
|
(assoc acc address revealed-account))
|
||||||
{}
|
{}
|
||||||
(data-store.communities/<-revealed-accounts-rpc revealed-accounts-js))
|
(data-store.communities/<-revealed-accounts-rpc revealed-accounts-js))
|
||||||
|
|
||||||
|
@ -468,7 +375,9 @@
|
||||||
(-> community
|
(-> community
|
||||||
(assoc :revealed-accounts revealed-accounts)
|
(assoc :revealed-accounts revealed-accounts)
|
||||||
(dissoc :fetching-revealed-accounts))]
|
(dissoc :fetching-revealed-accounts))]
|
||||||
{:db (assoc-in db [:communities community-id] community-with-revealed-accounts)}))))
|
{:db (assoc-in db [:communities community-id] community-with-revealed-accounts)
|
||||||
|
:fx [(when (vector? on-success)
|
||||||
|
[:dispatch (conj on-success revealed-accounts)])]}))))
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/get-revealed-accounts-failed
|
(rf/reg-event-fx :communities/get-revealed-accounts-failed
|
||||||
(fn [{:keys [db]} [community-id]]
|
(fn [{:keys [db]} [community-id]]
|
||||||
|
|
|
@ -7,99 +7,6 @@
|
||||||
|
|
||||||
(def community-id "community-id")
|
(def community-id "community-id")
|
||||||
|
|
||||||
(deftest initialize-permission-addresses-test
|
|
||||||
(let [initial-db {:db {:wallet {:accounts {"0x1" {:address "0x1"
|
|
||||||
:position 0}
|
|
||||||
"0x2" {:address "0x2"
|
|
||||||
:position 1}}}}}
|
|
||||||
expected-db {:db (update-in (:db initial-db)
|
|
||||||
[:communities community-id]
|
|
||||||
assoc
|
|
||||||
:share-all-addresses? true
|
|
||||||
:previous-share-all-addresses? true
|
|
||||||
:previous-permission-addresses #{"0x1" "0x2"}
|
|
||||||
:selected-permission-addresses #{"0x1" "0x2"}
|
|
||||||
:airdrop-address "0x1")}]
|
|
||||||
(is (match? expected-db (events/initialize-permission-addresses initial-db [community-id])))))
|
|
||||||
|
|
||||||
(deftest toggle-selected-permission-address-test
|
|
||||||
(let [initial-db {:db {:communities {community-id {:selected-permission-addresses #{"0x1" "0x2"}}}}}]
|
|
||||||
(is (match? {:db {:communities {community-id {:selected-permission-addresses #{"0x1"}}}}}
|
|
||||||
(events/toggle-selected-permission-address initial-db ["0x2" community-id])))
|
|
||||||
(is (match? {:db {:communities {community-id {:selected-permission-addresses #{"0x1" "0x2" "0x3"}}}}}
|
|
||||||
(events/toggle-selected-permission-address initial-db ["0x3" community-id])))))
|
|
||||||
|
|
||||||
(deftest update-previous-permission-addresses-test
|
|
||||||
(let [wallet {:accounts {"0x1" {:address "0x1"
|
|
||||||
:position 0}
|
|
||||||
"0x2" {:address "0x2"
|
|
||||||
:position 1}
|
|
||||||
"0x3" {:address "0x3"
|
|
||||||
:position 2}}}]
|
|
||||||
(let [initial-db {:db {:wallet wallet
|
|
||||||
:communities {community-id {:previous-permission-addresses #{"0x1" "0x2"}
|
|
||||||
:selected-permission-addresses #{"0x1" "0x2"
|
|
||||||
"0x3"}
|
|
||||||
:share-all-addresses? true
|
|
||||||
:previous-share-all-addresses? false
|
|
||||||
:airdrop-address "0x1"}}}}
|
|
||||||
expected-db {:db {:wallet wallet
|
|
||||||
:communities {community-id {:previous-permission-addresses #{"0x1" "0x2"
|
|
||||||
"0x3"}
|
|
||||||
:selected-permission-addresses #{"0x1" "0x2"
|
|
||||||
"0x3"}
|
|
||||||
:share-all-addresses? true
|
|
||||||
:previous-share-all-addresses? true
|
|
||||||
:airdrop-address "0x1"}}}}]
|
|
||||||
(is
|
|
||||||
(match? expected-db
|
|
||||||
(events/update-previous-permission-addresses initial-db [community-id]))))
|
|
||||||
(let [initial-db {:db {:wallet wallet
|
|
||||||
:communities {community-id {:previous-permission-addresses #{"0x1" "0x2"}
|
|
||||||
:selected-permission-addresses #{"0x2" "0x3"}
|
|
||||||
:airdrop-address "0x1"}}}}
|
|
||||||
expected-db {:db {:wallet wallet
|
|
||||||
:communities {community-id {:previous-permission-addresses #{"0x2" "0x3"}
|
|
||||||
:selected-permission-addresses #{"0x2" "0x3"}
|
|
||||||
:airdrop-address "0x2"}}}}]
|
|
||||||
(is
|
|
||||||
(match? expected-db
|
|
||||||
(events/update-previous-permission-addresses initial-db [community-id]))))))
|
|
||||||
|
|
||||||
(deftest toggle-share-all-addresses-test
|
|
||||||
(let [initial-db {:db {:wallet {:accounts {"0x1" {:address "0x1"
|
|
||||||
:position 0}
|
|
||||||
"0x2" {:address "0x2"
|
|
||||||
:position 1}}}
|
|
||||||
:communities {community-id {:share-all-addresses? true
|
|
||||||
:previous-share-all-addresses? true
|
|
||||||
:previous-permission-addresses #{"0x1" "0x2"}
|
|
||||||
:selected-permission-addresses #{"0x1" "0x2"}
|
|
||||||
:airdrop-address "0x1"}}}}
|
|
||||||
expected-db (update-in initial-db
|
|
||||||
[:db :communities community-id]
|
|
||||||
assoc
|
|
||||||
:previous-share-all-addresses? true
|
|
||||||
:share-all-addresses?
|
|
||||||
false)]
|
|
||||||
(is (match? expected-db (events/toggle-share-all-addresses initial-db [community-id]))))
|
|
||||||
(let [initial-db {:db {:wallet {:accounts {"0x1" {:address "0x1"
|
|
||||||
:position 0}
|
|
||||||
"0x2" {:address "0x2"
|
|
||||||
:position 1}}}
|
|
||||||
:communities {community-id {:share-all-addresses? false
|
|
||||||
:previous-share-all-addresses? false
|
|
||||||
:previous-permission-addresses #{"0x1"}
|
|
||||||
:selected-permission-addresses #{"0x1"}
|
|
||||||
:airdrop-address "0x1"}}}}
|
|
||||||
expected-db (update-in initial-db
|
|
||||||
[:db :communities community-id]
|
|
||||||
assoc
|
|
||||||
:selected-permission-addresses #{"0x1" "0x2"}
|
|
||||||
:previous-share-all-addresses? false
|
|
||||||
:share-all-addresses? true)]
|
|
||||||
(is (match? expected-db (events/toggle-share-all-addresses initial-db [community-id])))))
|
|
||||||
|
|
||||||
(deftest fetch-community
|
(deftest fetch-community
|
||||||
(testing "with community id"
|
(testing "with community id"
|
||||||
(testing "update fetching indicator in db"
|
(testing "update fetching indicator in db"
|
||||||
|
@ -243,12 +150,14 @@
|
||||||
(is (match?
|
(is (match?
|
||||||
nil
|
nil
|
||||||
(events/get-revealed-accounts {:db {:communities {community-id community}}} [community-id]))))
|
(events/get-revealed-accounts {:db {:communities {community-id community}}} [community-id]))))
|
||||||
|
|
||||||
(testing "given a already :fetching-revealed-accounts community"
|
(testing "given a already :fetching-revealed-accounts community"
|
||||||
(is (match?
|
(is (match?
|
||||||
nil
|
nil
|
||||||
(events/get-revealed-accounts
|
(events/get-revealed-accounts
|
||||||
{:db {:communities {community-id (assoc community :fetching-revealed-accounts true)}}}
|
{:db {:communities {community-id (assoc community :fetching-revealed-accounts true)}}}
|
||||||
[community-id]))))
|
[community-id]))))
|
||||||
|
|
||||||
(testing "given joined community"
|
(testing "given joined community"
|
||||||
(let [community (assoc community :joined true)
|
(let [community (assoc community :joined true)
|
||||||
db {:communities {community-id community}
|
db {:communities {community-id community}
|
||||||
|
@ -258,7 +167,26 @@
|
||||||
(:db effects)))
|
(:db effects)))
|
||||||
(is (match? {:method "wakuext_getRevealedAccounts"
|
(is (match? {:method "wakuext_getRevealedAccounts"
|
||||||
:params [community-id "profile-public-key"]}
|
:params [community-id "profile-public-key"]}
|
||||||
(-> effects :json-rpc/call first (select-keys [:method :params]))))))))
|
(-> effects :json-rpc/call first (select-keys [:method :params]))))))
|
||||||
|
|
||||||
|
(testing "given there is a pending request"
|
||||||
|
(let [pub-key "profile-public-key"
|
||||||
|
community (assoc community :joined false)
|
||||||
|
db {:communities {community-id community}
|
||||||
|
:profile/profile {:public-key pub-key}
|
||||||
|
:communities/my-pending-requests-to-join {community-id [:anything]}}
|
||||||
|
on-success [:some-event-id]
|
||||||
|
actual (events/get-revealed-accounts {:db db} [community-id on-success])
|
||||||
|
expected {:db (assoc-in db
|
||||||
|
[:communities community-id :fetching-revealed-accounts]
|
||||||
|
true)
|
||||||
|
:json-rpc/call [{:method "wakuext_getRevealedAccounts"
|
||||||
|
:params [community-id pub-key]
|
||||||
|
:js-response true
|
||||||
|
:on-success [:communities/get-revealed-accounts-success
|
||||||
|
community-id on-success]
|
||||||
|
:on-error fn?}]}]
|
||||||
|
(is (match? expected actual))))))
|
||||||
|
|
||||||
(deftest handle-community
|
(deftest handle-community
|
||||||
(let [community {:id community-id :clock 2}]
|
(let [community {:id community-id :clock 2}]
|
||||||
|
@ -267,24 +195,22 @@
|
||||||
(is (match? community-id
|
(is (match? community-id
|
||||||
(-> effects :db :communities (get community-id) :id)))
|
(-> effects :db :communities (get community-id) :id)))
|
||||||
(is (match?
|
(is (match?
|
||||||
[[:dispatch [:communities/initialize-permission-addresses community-id]]
|
[[:dispatch [:chat.ui/spectate-community community-id]]
|
||||||
[:dispatch [:chat.ui/spectate-community community-id]]
|
|
||||||
[:dispatch [:communities/check-permissions-to-join-community community-id]]]
|
[:dispatch [:communities/check-permissions-to-join-community community-id]]]
|
||||||
(filter some? (:fx effects))))))
|
(filter some? (:fx effects))))))
|
||||||
|
|
||||||
(testing "given a joined community"
|
(testing "given a joined community"
|
||||||
(let [community (assoc community :joined true)
|
(let [community (assoc community :joined true)
|
||||||
effects (events/handle-community {} [community])]
|
effects (events/handle-community {} [community])]
|
||||||
(is (match?
|
(is (match?
|
||||||
[[:dispatch [:communities/initialize-permission-addresses community-id]]
|
[[:dispatch [:communities/check-permissions-to-join-community community-id]]]
|
||||||
[:dispatch [:communities/check-permissions-to-join-community community-id]]
|
|
||||||
[:dispatch [:communities/get-revealed-accounts community-id]]]
|
|
||||||
(filter some? (:fx effects))))))
|
(filter some? (:fx effects))))))
|
||||||
|
|
||||||
(testing "given a community with token-permissions-check"
|
(testing "given a community with token-permissions-check"
|
||||||
(let [community (assoc community :token-permissions-check :fake-token-permissions-check)
|
(let [community (assoc community :token-permissions-check :fake-token-permissions-check)
|
||||||
effects (events/handle-community {} [community])]
|
effects (events/handle-community {} [community])]
|
||||||
(is (match?
|
(is (match?
|
||||||
[[:dispatch [:communities/initialize-permission-addresses community-id]]
|
[[:dispatch [:chat.ui/spectate-community community-id]]]
|
||||||
[:dispatch [:chat.ui/spectate-community community-id]]]
|
|
||||||
(filter some? (:fx effects))))))
|
(filter some? (:fx effects))))))
|
||||||
(testing "given a community with lower clock"
|
(testing "given a community with lower clock"
|
||||||
(let [effects (events/handle-community {:db {:communities {community-id {:clock 3}}}} [community])]
|
(let [effects (events/handle-community {:db {:communities {community-id {:clock 3}}}} [community])]
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/check-permissions-to-join-community-success
|
(rf/reg-event-fx :communities/check-permissions-to-join-community-success
|
||||||
(fn [{:keys [db]} [community-id based-on-client-selection? result]]
|
(fn [{:keys [db]} [community-id based-on-client-selection? result]]
|
||||||
(let [token-permissions-check (cond-> result
|
(let [token-permissions-check (cond-> result
|
||||||
|
@ -118,41 +116,19 @@
|
||||||
:category-id category-id
|
:category-id category-id
|
||||||
:collapse? collapse?})}]}))
|
:collapse? collapse?})}]}))
|
||||||
|
|
||||||
(defn request-to-join-with-signatures-and-addresses
|
|
||||||
[{:keys [db]} [community-id signatures]]
|
|
||||||
(let [{:keys [airdrop-address selected-permission-addresses]} (get-in db [:communities community-id])]
|
|
||||||
{:fx [[:json-rpc/call
|
|
||||||
[{:method "wakuext_requestToJoinCommunity"
|
|
||||||
:params [{:communityId community-id
|
|
||||||
:signatures signatures
|
|
||||||
:addressesToReveal selected-permission-addresses
|
|
||||||
:airdropAddress airdrop-address}]
|
|
||||||
:js-response true
|
|
||||||
:on-success [:communities/requested-to-join]
|
|
||||||
:on-error [:communities/requested-to-join-error community-id]}]]]}))
|
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/request-to-join-with-signatures-and-addresses
|
|
||||||
request-to-join-with-signatures-and-addresses)
|
|
||||||
|
|
||||||
(defn sign-data-with-addresses
|
|
||||||
[_ [community-id password sign-params]]
|
|
||||||
{:fx [[:json-rpc/call
|
|
||||||
[{:method "wakuext_signData"
|
|
||||||
:params [(map #(assoc % :password password) sign-params)]
|
|
||||||
:on-success [:communities/request-to-join-with-signatures-and-addresses community-id]
|
|
||||||
:on-error [:communities/requested-to-join-error community-id]}]]]})
|
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/sign-data-with-addresses sign-data-with-addresses)
|
|
||||||
|
|
||||||
(defn request-to-join-with-addresses
|
(defn request-to-join-with-addresses
|
||||||
[{:keys [db]}
|
[{:keys [db]}
|
||||||
[{:keys [community-id password]}]]
|
[{:keys [community-id password]}]]
|
||||||
(let [pub-key (get-in db [:profile/profile :public-key])
|
(let [pub-key (get-in db [:profile/profile :public-key])
|
||||||
addresses-to-reveal (get-in db [:communities community-id :selected-permission-addresses])]
|
addresses-to-reveal (get-in db [:communities/all-addresses-to-reveal community-id])
|
||||||
{:fx [[:json-rpc/call
|
airdrop-address (get-in db [:communities/all-airdrop-addresses community-id])]
|
||||||
[{:method "wakuext_generateJoiningCommunityRequestsForSigning"
|
{:fx [[:effects.community/request-to-join
|
||||||
:params [pub-key community-id addresses-to-reveal]
|
{:community-id community-id
|
||||||
:on-success [:communities/sign-data-with-addresses community-id password]
|
:password password
|
||||||
:on-error [:communities/requested-to-join-error community-id]}]]]}))
|
:pub-key pub-key
|
||||||
|
:addresses-to-reveal addresses-to-reveal
|
||||||
|
:airdrop-address airdrop-address
|
||||||
|
:on-success [:communities/requested-to-join]
|
||||||
|
:on-error [:communities/requested-to-join-error community-id]}]]}))
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/request-to-join-with-addresses request-to-join-with-addresses)
|
(rf/reg-event-fx :communities/request-to-join-with-addresses request-to-join-with-addresses)
|
||||||
|
|
|
@ -120,7 +120,7 @@
|
||||||
[id color]
|
[id color]
|
||||||
[quo/button
|
[quo/button
|
||||||
{:on-press (if config/community-accounts-selection-enabled?
|
{:on-press (if config/community-accounts-selection-enabled?
|
||||||
#(rf/dispatch [:open-modal :community-account-selection
|
#(rf/dispatch [:open-modal :community-account-selection-sheet
|
||||||
{:community-id id}])
|
{:community-id id}])
|
||||||
#(rf/dispatch [:open-modal :community-requests-to-join {:id id}]))
|
#(rf/dispatch [:open-modal :community-requests-to-join {:id id}]))
|
||||||
:accessibility-label :show-request-to-join-screen-button
|
:accessibility-label :show-request-to-join-screen-button
|
||||||
|
@ -168,7 +168,7 @@
|
||||||
:padding? true}]
|
:padding? true}]
|
||||||
[quo/button
|
[quo/button
|
||||||
{:on-press (if config/community-accounts-selection-enabled?
|
{:on-press (if config/community-accounts-selection-enabled?
|
||||||
#(rf/dispatch [:open-modal :community-account-selection
|
#(rf/dispatch [:open-modal :community-account-selection-sheet
|
||||||
{:community-id id}])
|
{:community-id id}])
|
||||||
#(rf/dispatch [:open-modal :community-requests-to-join {:id id}]))
|
#(rf/dispatch [:open-modal :community-requests-to-join {:id id}]))
|
||||||
:accessibility-label :join-community-button
|
:accessibility-label :join-community-button
|
||||||
|
|
|
@ -63,6 +63,10 @@
|
||||||
{:key :admin}
|
{:key :admin}
|
||||||
{:key :member}]})
|
{:key :member}]})
|
||||||
|
|
||||||
|
(def description-top-descriptor
|
||||||
|
{:key :description-top-text
|
||||||
|
:type :text})
|
||||||
|
|
||||||
(def description-descriptor
|
(def description-descriptor
|
||||||
{:key :description-text
|
{:key :description-text
|
||||||
:type :text})
|
:type :text})
|
||||||
|
@ -76,6 +80,7 @@
|
||||||
(let [state (reagent/atom {:actions :two-actions
|
(let [state (reagent/atom {:actions :two-actions
|
||||||
:description :bottom
|
:description :bottom
|
||||||
:description-text description
|
:description-text description
|
||||||
|
:description-top-text "Eligible to join as"
|
||||||
:error-message "Error message"
|
:error-message "Error message"
|
||||||
:button-one-label button-one
|
:button-one-label button-one
|
||||||
:button-two-label button-two
|
:button-two-label button-two
|
||||||
|
@ -89,12 +94,15 @@
|
||||||
(fn []
|
(fn []
|
||||||
[preview/preview-container
|
[preview/preview-container
|
||||||
{:state state
|
{:state state
|
||||||
:descriptor (merge descriptor
|
:descriptor (cond-> descriptor
|
||||||
(case (:description @state)
|
(= (:description @state) :top)
|
||||||
:top role-descriptor
|
(conj role-descriptor description-top-descriptor)
|
||||||
:bottom description-descriptor
|
|
||||||
:top-error error-descriptor
|
(= (:description @state) :bottom)
|
||||||
nil))
|
(conj description-descriptor)
|
||||||
|
|
||||||
|
(= (:description @state) :top-error)
|
||||||
|
(conj error-descriptor))
|
||||||
:blur? (:blur? @state)
|
:blur? (:blur? @state)
|
||||||
:show-blur-background? true
|
:show-blur-background? true
|
||||||
:blur-dark-only? true
|
:blur-dark-only? true
|
||||||
|
|
|
@ -12,8 +12,10 @@
|
||||||
(reagent/atom
|
(reagent/atom
|
||||||
{::wallet.edit-default-keypair true
|
{::wallet.edit-default-keypair true
|
||||||
::wallet.bridge-token (enabled-in-env? :FLAG_BRIDGE_TOKEN_ENABLED)
|
::wallet.bridge-token (enabled-in-env? :FLAG_BRIDGE_TOKEN_ENABLED)
|
||||||
|
::wallet.remove-account (enabled-in-env? :FLAG_REMOVE_ACCOUNT_ENABLED)
|
||||||
::wallet.network-filter (enabled-in-env? :FLAG_NETWORK_FILTER_ENABLED)
|
::wallet.network-filter (enabled-in-env? :FLAG_NETWORK_FILTER_ENABLED)
|
||||||
::profile.new-contact-ui (enabled-in-env? :FLAG_NEW_CONTACT_UI_ENABLED)}))
|
::profile.new-contact-ui (enabled-in-env? :FLAG_NEW_CONTACT_UI_ENABLED)
|
||||||
|
::community.edit-account-selection (enabled-in-env? :FLAG_EDIT_ACCOUNT_SELECTION_ENABLED)}))
|
||||||
|
|
||||||
(defn feature-flags [] @feature-flags-config)
|
(defn feature-flags [] @feature-flags-config)
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
[status-im.contexts.chat.messenger.messages.view :as chat]
|
[status-im.contexts.chat.messenger.messages.view :as chat]
|
||||||
[status-im.contexts.chat.messenger.photo-selector.view :as photo-selector]
|
[status-im.contexts.chat.messenger.photo-selector.view :as photo-selector]
|
||||||
[status-im.contexts.communities.actions.accounts-selection.view :as communities.accounts-selection]
|
[status-im.contexts.communities.actions.accounts-selection.view :as communities.accounts-selection]
|
||||||
|
[status-im.contexts.communities.actions.addresses-for-permissions.view :as addresses-for-permissions]
|
||||||
|
[status-im.contexts.communities.actions.airdrop-addresses.view :as airdrop-addresses]
|
||||||
[status-im.contexts.communities.actions.request-to-join.view :as join-menu]
|
[status-im.contexts.communities.actions.request-to-join.view :as join-menu]
|
||||||
[status-im.contexts.communities.actions.share-community-channel.view :as share-community-channel]
|
[status-im.contexts.communities.actions.share-community-channel.view :as share-community-channel]
|
||||||
[status-im.contexts.communities.discover.view :as communities.discover]
|
[status-im.contexts.communities.discover.view :as communities.discover]
|
||||||
|
@ -122,9 +124,23 @@
|
||||||
:options options/transparent-screen-options
|
:options options/transparent-screen-options
|
||||||
:component share-community-channel/view}
|
:component share-community-channel/view}
|
||||||
|
|
||||||
{:name :community-account-selection
|
;; Note: the sheet screen is used when selecting addresses to share when
|
||||||
|
;; joining a community. The non-sheet screen is used when editing shared
|
||||||
|
;; addresses after the join request was sent.
|
||||||
|
{:name :community-account-selection-sheet
|
||||||
:options {:sheet? true}
|
:options {:sheet? true}
|
||||||
:component communities.accounts-selection/view}
|
:component communities.accounts-selection/view}
|
||||||
|
{:name :community-account-selection
|
||||||
|
:options {:insets {:top? true}}
|
||||||
|
:component communities.accounts-selection/view}
|
||||||
|
|
||||||
|
{:name :addresses-for-permissions
|
||||||
|
:options {:insets {:top? true}}
|
||||||
|
:component addresses-for-permissions/view}
|
||||||
|
|
||||||
|
{:name :address-for-airdrop
|
||||||
|
:options {:insets {:top? true}}
|
||||||
|
:component airdrop-addresses/view}
|
||||||
|
|
||||||
{:name :lightbox
|
{:name :lightbox
|
||||||
:options options/lightbox
|
:options options/lightbox
|
||||||
|
|
|
@ -350,57 +350,6 @@
|
||||||
(fn [communities [_ community-id]]
|
(fn [communities [_ community-id]]
|
||||||
(get-in communities [community-id :intro-message])))
|
(get-in communities [community-id :intro-message])))
|
||||||
|
|
||||||
(re-frame/reg-sub :communities/permissioned-balances-by-address
|
|
||||||
:<- [:communities/permissioned-balances]
|
|
||||||
(fn [balances [_ community-id account-address]]
|
|
||||||
(get-in balances [community-id (keyword account-address)])))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:communities/selected-permission-addresses
|
|
||||||
(fn [[_ community-id]]
|
|
||||||
[(re-frame/subscribe [:communities/community community-id])])
|
|
||||||
(fn [[{:keys [selected-permission-addresses]}] _]
|
|
||||||
selected-permission-addresses))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:communities/share-all-addresses?
|
|
||||||
(fn [[_ community-id]]
|
|
||||||
[(re-frame/subscribe [:communities/community community-id])])
|
|
||||||
(fn [[{:keys [share-all-addresses?]}] _]
|
|
||||||
share-all-addresses?))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:communities/unsaved-address-changes?
|
|
||||||
(fn [[_ community-id]]
|
|
||||||
[(re-frame/subscribe [:communities/community community-id])])
|
|
||||||
(fn [[{:keys [share-all-addresses? previous-share-all-addresses?
|
|
||||||
selected-permission-addresses previous-permission-addresses]}] _]
|
|
||||||
(or (not= share-all-addresses? previous-share-all-addresses?)
|
|
||||||
(not= selected-permission-addresses previous-permission-addresses))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:communities/selected-permission-accounts
|
|
||||||
(fn [[_ community-id]]
|
|
||||||
[(re-frame/subscribe [:wallet/accounts-without-watched-accounts])
|
|
||||||
(re-frame/subscribe [:communities/selected-permission-addresses community-id])])
|
|
||||||
(fn [[accounts selected-permission-addresses]]
|
|
||||||
(filter #(contains? selected-permission-addresses (:address %)) accounts)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:communities/airdrop-address
|
|
||||||
(fn [[_ community-id]]
|
|
||||||
[(re-frame/subscribe [:communities/community community-id])])
|
|
||||||
(fn [[{:keys [airdrop-address]}] _]
|
|
||||||
airdrop-address))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:communities/airdrop-account
|
|
||||||
(fn [[_ community-id]]
|
|
||||||
[(re-frame/subscribe [:wallet/accounts-with-customization-color])
|
|
||||||
(re-frame/subscribe [:communities/airdrop-address community-id])])
|
|
||||||
(fn [[accounts airdrop-address]]
|
|
||||||
(first (filter #(= (:address %) airdrop-address) accounts))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:communities/token-images-by-symbol
|
:communities/token-images-by-symbol
|
||||||
(fn [[_ community-id]]
|
(fn [[_ community-id]]
|
||||||
|
|
|
@ -358,48 +358,6 @@
|
||||||
:img-src token-image-eth}]]}
|
:img-src token-image-eth}]]}
|
||||||
(rf/sub [sub-name community-id])))))
|
(rf/sub [sub-name community-id])))))
|
||||||
|
|
||||||
(h/deftest-sub :communities/airdrop-account
|
|
||||||
[sub-name]
|
|
||||||
(testing "returns airdrop account"
|
|
||||||
(swap! rf-db/app-db assoc-in [:communities community-id :airdrop-address] "0x1")
|
|
||||||
(swap! rf-db/app-db assoc
|
|
||||||
:wallet
|
|
||||||
{:accounts {"0x1" {:address "0x1"
|
|
||||||
:color :blue
|
|
||||||
:name "account1"}
|
|
||||||
"0x2" {:address "0x2"
|
|
||||||
:color :orange
|
|
||||||
:name "account2"}}})
|
|
||||||
(is (match? {:address "0x1"
|
|
||||||
:network-preferences-names #{}
|
|
||||||
:name "account1"
|
|
||||||
:color :blue
|
|
||||||
:customization-color :blue}
|
|
||||||
(rf/sub [sub-name community-id])))))
|
|
||||||
|
|
||||||
(h/deftest-sub :communities/selected-permission-accounts
|
|
||||||
[sub-name]
|
|
||||||
(testing "returns selected permission accounts"
|
|
||||||
(swap! rf-db/app-db assoc-in
|
|
||||||
[:communities community-id :selected-permission-addresses]
|
|
||||||
#{"0x1" "0x3"})
|
|
||||||
(swap! rf-db/app-db assoc
|
|
||||||
:wallet
|
|
||||||
{:accounts {"0x1" {:address "0x1" :color :blue :name "account1"}
|
|
||||||
"0x2" {:address "0x2" :color :orange :name "account2"}
|
|
||||||
"0x3" {:address "0x3" :color :purple :name "account3"}}})
|
|
||||||
(is (match? [{:address "0x1"
|
|
||||||
:color :blue
|
|
||||||
:customization-color :blue
|
|
||||||
:network-preferences-names #{}
|
|
||||||
:name "account1"}
|
|
||||||
{:address "0x3"
|
|
||||||
:color :purple
|
|
||||||
:customization-color :purple
|
|
||||||
:network-preferences-names #{}
|
|
||||||
:name "account3"}]
|
|
||||||
(rf/sub [sub-name community-id])))))
|
|
||||||
|
|
||||||
(h/deftest-sub :communities/community-color
|
(h/deftest-sub :communities/community-color
|
||||||
[sub-name]
|
[sub-name]
|
||||||
(testing "returns the community color"
|
(testing "returns the community color"
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
(ns status-im.subs.community.account-selection
|
||||||
|
(:require
|
||||||
|
[re-frame.core :as re-frame]))
|
||||||
|
|
||||||
|
;; This sub is particularly useful in context tags in page-nav or drawer-top
|
||||||
|
;; components. It should be preferred instead of subscribing to the whole
|
||||||
|
;; community.
|
||||||
|
(re-frame/reg-sub :communities/for-context-tag
|
||||||
|
(fn [[_ community-id]]
|
||||||
|
[(re-frame/subscribe [:communities/community community-id])])
|
||||||
|
(fn [[{:keys [name images color]}]]
|
||||||
|
{:name name
|
||||||
|
:logo (get-in images [:thumbnail :uri])
|
||||||
|
:color color}))
|
||||||
|
|
||||||
|
(re-frame/reg-sub :communities/addresses-to-reveal
|
||||||
|
:<- [:communities/all-addresses-to-reveal]
|
||||||
|
(fn [addresses-by-id [_ community-id]]
|
||||||
|
(get addresses-by-id community-id)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub :communities/airdrop-address
|
||||||
|
:<- [:communities/all-airdrop-addresses]
|
||||||
|
(fn [addresses-by-id [_ community-id]]
|
||||||
|
(get addresses-by-id community-id)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub :communities/share-all-addresses?
|
||||||
|
:<- [:communities/selected-share-all-addresses]
|
||||||
|
(fn [flags-by-id [_ community-id]]
|
||||||
|
(get flags-by-id community-id)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub :communities/can-edit-shared-addresses?
|
||||||
|
(fn [[_ community-id]]
|
||||||
|
[(re-frame/subscribe [:communities/community community-id])
|
||||||
|
(re-frame/subscribe [:communities/my-pending-request-to-join community-id])])
|
||||||
|
(fn [[{:keys [joined]} pending-requests]]
|
||||||
|
(boolean (or joined (seq pending-requests)))))
|
||||||
|
|
||||||
|
(re-frame/reg-sub :communities/permissions-check-for-selection
|
||||||
|
:<- [:communities/permissions-checks-for-selection]
|
||||||
|
(fn [permissions [_ id]]
|
||||||
|
(get permissions id)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub :communities/highest-role-for-selection
|
||||||
|
(fn [[_ community-id]]
|
||||||
|
[(re-frame/subscribe [:communities/permissions-check-for-selection community-id])])
|
||||||
|
(fn [[permissions-check] _]
|
||||||
|
(get-in permissions-check [:check :highestRole :type])))
|
||||||
|
|
||||||
|
(re-frame/reg-sub :communities/accounts-to-reveal
|
||||||
|
(fn [[_ community-id]]
|
||||||
|
[(re-frame/subscribe [:wallet/accounts-without-watched-accounts])
|
||||||
|
(re-frame/subscribe [:communities/addresses-to-reveal community-id])])
|
||||||
|
(fn [[accounts addresses] _]
|
||||||
|
(filter #(contains? addresses (:address %))
|
||||||
|
accounts)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub :communities/airdrop-account
|
||||||
|
(fn [[_ community-id]]
|
||||||
|
[(re-frame/subscribe [:wallet/accounts-without-watched-accounts])
|
||||||
|
(re-frame/subscribe [:communities/airdrop-address community-id])])
|
||||||
|
(fn [[accounts airdrop-address] _]
|
||||||
|
(->> accounts
|
||||||
|
(filter #(= (:address %) airdrop-address))
|
||||||
|
first)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub :communities/permissioned-balances-by-address
|
||||||
|
:<- [:communities/permissioned-balances]
|
||||||
|
(fn [balances [_ community-id account-address]]
|
||||||
|
(get-in balances [community-id (keyword account-address)])))
|
|
@ -0,0 +1,75 @@
|
||||||
|
(ns status-im.subs.community.account-selection-test
|
||||||
|
(:require
|
||||||
|
[cljs.test :refer [is testing]]
|
||||||
|
matcher-combinators.test
|
||||||
|
[re-frame.db :as rf-db]
|
||||||
|
status-im.subs.communities
|
||||||
|
[test-helpers.unit :as h]
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(def community-id "0x1")
|
||||||
|
|
||||||
|
(h/deftest-sub :communities/for-context-tag
|
||||||
|
[sub-name]
|
||||||
|
(reset! rf-db/app-db
|
||||||
|
{:communities
|
||||||
|
{community-id {:name "foo"
|
||||||
|
:images {:thumbnail {:uri "data:image/png;"}}
|
||||||
|
:color :orange}}})
|
||||||
|
|
||||||
|
(is (match? {:name "foo"
|
||||||
|
:logo "data:image/png;"
|
||||||
|
:color :orange}
|
||||||
|
(rf/sub [sub-name community-id]))))
|
||||||
|
|
||||||
|
(h/deftest-sub :communities/can-edit-shared-addresses?
|
||||||
|
[sub-name]
|
||||||
|
(testing "joined community and there are pending requests"
|
||||||
|
(reset! rf-db/app-db
|
||||||
|
{:communities {community-id {:id community-id :joined true}}
|
||||||
|
:communities/my-pending-request-to-join {community-id {:id :request-id-1}}})
|
||||||
|
|
||||||
|
(is (true? (rf/sub [sub-name community-id]))))
|
||||||
|
|
||||||
|
(testing "joined community and there are no pending requests"
|
||||||
|
(reset! rf-db/app-db
|
||||||
|
{:communities {community-id {:id community-id :joined true}}
|
||||||
|
:communities/my-pending-request-to-join {community-id {}}})
|
||||||
|
|
||||||
|
(is (true? (rf/sub [sub-name community-id]))))
|
||||||
|
|
||||||
|
(testing "not joined community and there are pending requests"
|
||||||
|
(reset! rf-db/app-db
|
||||||
|
{:communities {community-id {:id community-id :joined false}}
|
||||||
|
:communities/my-pending-request-to-join {community-id {:id :request-id-1}}})
|
||||||
|
|
||||||
|
(is (false? (rf/sub [sub-name community-id]))))
|
||||||
|
|
||||||
|
(testing "not joined community and there are no pending requests"
|
||||||
|
(reset! rf-db/app-db
|
||||||
|
{:communities {community-id {:id community-id :joined false}}
|
||||||
|
:communities/my-pending-request-to-join {community-id {}}})
|
||||||
|
|
||||||
|
(is (false? (rf/sub [sub-name community-id])))))
|
||||||
|
|
||||||
|
(h/deftest-sub :communities/airdrop-account
|
||||||
|
[sub-name]
|
||||||
|
(let [airdrop-account {:address "0xA" :position 1}]
|
||||||
|
(reset! rf-db/app-db
|
||||||
|
{:communities/all-airdrop-addresses {community-id "0xA"}
|
||||||
|
:wallet {:accounts {"0xB" {:address "0xB" :position 0}
|
||||||
|
"0xA" airdrop-account}}})
|
||||||
|
|
||||||
|
(is (match? airdrop-account (rf/sub [sub-name community-id])))))
|
||||||
|
|
||||||
|
(h/deftest-sub :communities/accounts-to-reveal
|
||||||
|
[sub-name]
|
||||||
|
(reset! rf-db/app-db
|
||||||
|
{:communities/all-addresses-to-reveal {community-id #{"0xC" "0xB"}}
|
||||||
|
:wallet {:accounts {"0xB" {:address "0xB" :position 0}
|
||||||
|
"0xA" {:address "0xA" :position 1}
|
||||||
|
"0xC" {:address "0xC" :position 2}}}})
|
||||||
|
|
||||||
|
(is (match? [{:address "0xB" :position 0}
|
||||||
|
{:address "0xC" :position 2}]
|
||||||
|
(rf/sub [sub-name community-id]))))
|
|
@ -6,6 +6,7 @@
|
||||||
status-im.subs.biometrics
|
status-im.subs.biometrics
|
||||||
status-im.subs.chats
|
status-im.subs.chats
|
||||||
status-im.subs.communities
|
status-im.subs.communities
|
||||||
|
status-im.subs.community.account-selection
|
||||||
status-im.subs.contact
|
status-im.subs.contact
|
||||||
status-im.subs.general
|
status-im.subs.general
|
||||||
status-im.subs.messages
|
status-im.subs.messages
|
||||||
|
@ -150,6 +151,11 @@
|
||||||
(reg-root-key-sub :contract-communities :contract-communities)
|
(reg-root-key-sub :contract-communities :contract-communities)
|
||||||
(reg-root-key-sub :communities/permissioned-balances :communities/permissioned-balances)
|
(reg-root-key-sub :communities/permissioned-balances :communities/permissioned-balances)
|
||||||
(reg-root-key-sub :communities/permissions-check :communities/permissions-check)
|
(reg-root-key-sub :communities/permissions-check :communities/permissions-check)
|
||||||
|
(reg-root-key-sub :communities/all-addresses-to-reveal :communities/all-addresses-to-reveal)
|
||||||
|
(reg-root-key-sub :communities/all-airdrop-addresses :communities/all-airdrop-addresses)
|
||||||
|
(reg-root-key-sub :communities/selected-share-all-addresses :communities/selected-share-all-addresses)
|
||||||
|
(reg-root-key-sub :communities/permissions-checks-for-selection
|
||||||
|
:communities/permissions-checks-for-selection)
|
||||||
(reg-root-key-sub :communities/channel-permissions-check :communities/channel-permissions-check)
|
(reg-root-key-sub :communities/channel-permissions-check :communities/channel-permissions-check)
|
||||||
|
|
||||||
;;activity center
|
;;activity center
|
||||||
|
|
|
@ -2279,6 +2279,19 @@
|
||||||
"sync-devices-complete-title": "Device sync complete!",
|
"sync-devices-complete-title": "Device sync complete!",
|
||||||
"sync-devices-complete-sub-title": "Your devices are now in sync",
|
"sync-devices-complete-sub-title": "Your devices are now in sync",
|
||||||
"synced-with": "Synced with",
|
"synced-with": "Synced with",
|
||||||
|
"confirm-and-leave": "Confirm and leave",
|
||||||
|
"membership-requirements-not-met": "Membership requirements not met",
|
||||||
|
"edit-shared-addresses": "Edit shared addresses",
|
||||||
|
"leave-community-farewell": "We’ll be sad to see you go but remember, you can come back at any time! All shared addresses will be unshared.",
|
||||||
|
"pending-join-request-farewell": "We’ll be sad to see you go but remember, you can request to join this community at any point. All shared addresses will be unshared.",
|
||||||
|
"all-changes-will-be-discarded": "All changes in shared addresses for permissions will be discarded.",
|
||||||
|
"cancel-request": "Cancel request",
|
||||||
|
"discard": "Discard",
|
||||||
|
"discard-changes?": "Discard changes?",
|
||||||
|
"confirm-and-cancel": "Confirm and cancel",
|
||||||
|
"you-will-be-a": "You’ll be a",
|
||||||
|
"you-are-a": "You’re a",
|
||||||
|
"you-are-a-role": "You’re a {{role}}",
|
||||||
"you-eligible-to-join": "You’re eligible to join",
|
"you-eligible-to-join": "You’re eligible to join",
|
||||||
"you-eligible-to-join-as": "You’re eligible to join as {{role}}",
|
"you-eligible-to-join-as": "You’re eligible to join as {{role}}",
|
||||||
"eligible-to-join-as": "Eligible to join as",
|
"eligible-to-join-as": "Eligible to join as",
|
||||||
|
|
Loading…
Reference in New Issue