Communities: Show relevant tokens (#18636)
Show "relevant tokens" in account selection step. Related status-go PR https://github.com/status-im/status-go/pull/4631. - Balances are fetched on the account selection screen. Assuming most users won't care about selecting addresses, this eliminates unnecessary calls to get balances, at the expense of refetching them every time the component is mounted. I think for now this is acceptable. - Relevant tokens is a terminology used in Figma, but more specifically, it means "balances for all assets that have at least one Token Criteria associated, and for a given address". Or, as I tried to give it a more distinct name, "permissioned balances". Areas that may be impacted: None because all affected code is behind a disabled feature flag. Fixes https://github.com/status-im/status-mobile/issues/18126
This commit is contained in:
parent
ac32de89f9
commit
505f2fe624
|
@ -42,18 +42,22 @@
|
||||||
(render [account-permissions/view
|
(render [account-permissions/view
|
||||||
{:account account
|
{:account account
|
||||||
:token-details [{:token "SNT"
|
:token-details [{:token "SNT"
|
||||||
:amount "100"}]}])
|
:amount "100"
|
||||||
|
:type :token}]}])
|
||||||
(h/is-truthy (h/get-by-text "100 SNT")))
|
(h/is-truthy (h/get-by-text "100 SNT")))
|
||||||
|
|
||||||
(h/test "render with multiple token details"
|
(h/test "render with multiple token details"
|
||||||
(render [account-permissions/view
|
(render [account-permissions/view
|
||||||
{:account account
|
{:account account
|
||||||
:token-details [{:token "SNT"
|
:token-details [{:token "SNT"
|
||||||
:amount "100"}
|
:amount "100"
|
||||||
|
:type :token}
|
||||||
{:token "ETH"
|
{:token "ETH"
|
||||||
:amount "18"}
|
:amount "18"
|
||||||
|
:type :token}
|
||||||
{:token "BTM"
|
{:token "BTM"
|
||||||
:amount "1000"}]}])
|
:amount "1000"
|
||||||
|
:type :token}]}])
|
||||||
(h/is-truthy (h/get-by-text "100 SNT"))
|
(h/is-truthy (h/get-by-text "100 SNT"))
|
||||||
(h/is-truthy (h/get-by-text "18 ETH"))
|
(h/is-truthy (h/get-by-text "18 ETH"))
|
||||||
(h/is-truthy (h/get-by-text "1000 BTM")))
|
(h/is-truthy (h/get-by-text "1000 BTM")))
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
[:address [:maybe :string]]
|
[:address [:maybe :string]]
|
||||||
[:emoji [:maybe :string]]
|
[:emoji [:maybe :string]]
|
||||||
[:customization-color [:maybe [:or :string :keyword]]]]]
|
[:customization-color [:maybe [:or :string :keyword]]]]]
|
||||||
[:token-details {:optional true} [:maybe [:vector required-tokens/?schema]]]
|
[:token-details {:optional true} [:maybe [:sequential required-tokens/?schema]]]
|
||||||
[:keycard? {:optional true} [:maybe :boolean]]
|
[:keycard? {:optional true} [:maybe :boolean]]
|
||||||
[:checked? {:optional true} [:maybe :boolean]]
|
[:checked? {:optional true} [:maybe :boolean]]
|
||||||
[:disabled? {:optional true} [:maybe :boolean]]
|
[:disabled? {:optional true} [:maybe :boolean]]
|
||||||
|
@ -47,13 +47,15 @@
|
||||||
(i18n/label :t/no-relevant-tokens)]
|
(i18n/label :t/no-relevant-tokens)]
|
||||||
|
|
||||||
(let [token-length (dec (count tokens))]
|
(let [token-length (dec (count tokens))]
|
||||||
(map-indexed (fn [idx {:keys [token amount]}]
|
(map-indexed (fn [idx {:keys [type token amount collectible-name collectible-img-src]}]
|
||||||
^{:key idx}
|
^{:key idx}
|
||||||
[required-tokens/view
|
[required-tokens/view
|
||||||
{:container-style style/token-and-text
|
{:container-style style/token-and-text
|
||||||
:type :token
|
:type type
|
||||||
:amount amount
|
:amount amount
|
||||||
:token token
|
:token token
|
||||||
|
:collectible-img-src collectible-img-src
|
||||||
|
:collectible-name collectible-name
|
||||||
:divider? (not= token-length idx)}])
|
:divider? (not= token-length idx)}])
|
||||||
tokens)))]]))
|
tokens)))]]))
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
[:amount {:optional true} [:maybe [:or :string :int]]]
|
[:amount {:optional true} [:maybe [:or :string :int]]]
|
||||||
[:token {:optional true} [:maybe :string]]
|
[:token {:optional true} [:maybe :string]]
|
||||||
[:token-img-src {:optional true} [:maybe :schema.common/image-source]]
|
[:token-img-src {:optional true} [:maybe :schema.common/image-source]]
|
||||||
[:collectible-img-src {:optional true} :schema.common/image-source]
|
[:collectible-img-src {:optional true} [:maybe :schema.common/image-source]]
|
||||||
[:collectible-name {:optional true} [:maybe :string]]
|
[:collectible-name {:optional true} [:maybe :string]]
|
||||||
[:divider? {:optional true} [:maybe :boolean]]
|
[:divider? {:optional true} [:maybe :boolean]]
|
||||||
[:theme :schema.common/theme]
|
[:theme :schema.common/theme]
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
{:min 1}
|
{:min 1}
|
||||||
[:map
|
[:map
|
||||||
{:closed true}
|
{:closed true}
|
||||||
[:method :string]
|
[:method [:or :keyword :string]]
|
||||||
[:params [:sequential :any]]
|
[:params [:sequential :any]]
|
||||||
[:js-response {:optional true} :any]
|
[:js-response {:optional true} :any]
|
||||||
[:on-success [:or fn? [:cat keyword? [:* :any]]]]
|
[:on-success [:or fn? [:cat keyword? [:* :any]]]]
|
||||||
|
|
|
@ -159,6 +159,9 @@
|
||||||
community-token-permission-become-token-master
|
community-token-permission-become-token-master
|
||||||
community-token-permission-become-token-owner})
|
community-token-permission-become-token-owner})
|
||||||
|
|
||||||
|
(def ^:const community-token-type-erc20 1)
|
||||||
|
(def ^:const community-token-type-erc721 2)
|
||||||
|
|
||||||
;; Community rules for joining
|
;; Community rules for joining
|
||||||
(def ^:const community-rule-ens-only "ens-only")
|
(def ^:const community-rule-ens-only "ens-only")
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
{:community-id id :password %}])}])
|
{:community-id id :password %}])}])
|
||||||
(rf/dispatch [:navigate-back]))
|
(rf/dispatch [:navigate-back]))
|
||||||
|
|
||||||
(defn f-view-internal
|
(defn view
|
||||||
[]
|
[]
|
||||||
(let [{id :community-id} (rf/sub [:get-screen-params])
|
(let [{id :community-id} (rf/sub [:get-screen-params])
|
||||||
{:keys [name color images]} (rf/sub [:communities/community id])
|
{:keys [name color images]} (rf/sub [:communities/community id])
|
||||||
|
@ -83,7 +83,3 @@
|
||||||
:track-icon :i/face-id
|
:track-icon :i/face-id
|
||||||
:customization-color color
|
:customization-color color
|
||||||
:on-complete #(join-community-and-navigate-back id)}]]]))
|
:on-complete #(join-community-and-navigate-back id)}]]]))
|
||||||
|
|
||||||
(defn view
|
|
||||||
[]
|
|
||||||
[:f> f-view-internal])
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
(ns status-im.contexts.communities.actions.addresses-for-permissions.events
|
||||||
|
(:require
|
||||||
|
[schema.core :as schema]
|
||||||
|
[taoensso.timbre :as log]
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(defn get-permissioned-balances
|
||||||
|
[{[event-id _] :original-event} [community-id]]
|
||||||
|
{:fx [[:json-rpc/call
|
||||||
|
[{:method :wakuext_getCommunityPermissionedBalances
|
||||||
|
:params [{:communityId community-id}]
|
||||||
|
:on-success [:communities/get-permissioned-balances-success community-id]
|
||||||
|
:on-error (fn [error]
|
||||||
|
(log/error "failed to get balances"
|
||||||
|
{:community-id community-id
|
||||||
|
:event event-id
|
||||||
|
:error error}))}]]]})
|
||||||
|
|
||||||
|
(schema/=> get-permissioned-balances
|
||||||
|
[:=>
|
||||||
|
[:catn
|
||||||
|
[:cofx :schema.re-frame/cofx]
|
||||||
|
[:args [:schema [:catn [:community-id :string]]]]]
|
||||||
|
[:map {:closed true}
|
||||||
|
[:fx
|
||||||
|
[:tuple
|
||||||
|
[:tuple [:= :json-rpc/call] :schema.common/rpc-call]]]]])
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/get-permissioned-balances get-permissioned-balances)
|
||||||
|
|
||||||
|
(defn get-permissioned-balances-success
|
||||||
|
[{:keys [db]} [community-id response]]
|
||||||
|
{:db (assoc-in db [:communities/permissioned-balances community-id] response)})
|
||||||
|
|
||||||
|
(def ^:private ?account-address keyword?)
|
||||||
|
|
||||||
|
(def ^:private ?permissioned-balances-response
|
||||||
|
[:map-of
|
||||||
|
?account-address
|
||||||
|
[:sequential
|
||||||
|
[:map
|
||||||
|
[:type int?]
|
||||||
|
[:symbol string?]
|
||||||
|
[:decimals int?]
|
||||||
|
[:amount string?]]]])
|
||||||
|
|
||||||
|
(schema/=> get-permissioned-balances-success
|
||||||
|
[:=>
|
||||||
|
[:catn
|
||||||
|
[:cofx :schema.re-frame/cofx]
|
||||||
|
[:args
|
||||||
|
[:schema
|
||||||
|
[:catn
|
||||||
|
[:community-id string?]
|
||||||
|
[:response ?permissioned-balances-response]]]]]
|
||||||
|
map?])
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/get-permissioned-balances-success get-permissioned-balances-success)
|
|
@ -0,0 +1,15 @@
|
||||||
|
(ns status-im.contexts.communities.actions.addresses-for-permissions.events-test
|
||||||
|
(:require
|
||||||
|
[cljs.test :refer [is deftest]]
|
||||||
|
[status-im.contexts.communities.actions.addresses-for-permissions.events :as sut]))
|
||||||
|
|
||||||
|
(def community-id "0x1")
|
||||||
|
|
||||||
|
(deftest get-permissioned-balances-test
|
||||||
|
(let [cofx {:db {}}]
|
||||||
|
(is (match? {:fx [[:json-rpc/call
|
||||||
|
[{:method :wakuext_getCommunityPermissionedBalances
|
||||||
|
:params [{:communityId community-id}]
|
||||||
|
:on-success [:communities/get-permissioned-balances-success community-id]
|
||||||
|
:on-error fn?}]]]}
|
||||||
|
(sut/get-permissioned-balances cofx [community-id])))))
|
|
@ -3,34 +3,58 @@
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[status-im.common.not-implemented :as not-implemented]
|
[status-im.common.not-implemented :as not-implemented]
|
||||||
|
[status-im.common.resources :as resources]
|
||||||
|
[status-im.constants :as constants]
|
||||||
[status-im.contexts.communities.actions.addresses-for-permissions.style :as style]
|
[status-im.contexts.communities.actions.addresses-for-permissions.style :as style]
|
||||||
[status-im.contexts.communities.utils :as communities.utils]
|
[status-im.contexts.communities.utils :as communities.utils]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
|
[utils.money :as money]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(defn- balances->components-props
|
||||||
|
[balances]
|
||||||
|
(for [{:keys [amount decimals type name] :as balance} balances]
|
||||||
|
(cond-> balance
|
||||||
|
true
|
||||||
|
(assoc :type
|
||||||
|
(condp = type
|
||||||
|
constants/community-token-type-erc20 :token
|
||||||
|
constants/community-token-type-erc721 :collectible
|
||||||
|
:token))
|
||||||
|
|
||||||
|
(= type constants/community-token-type-erc721)
|
||||||
|
(assoc :collectible-name name
|
||||||
|
:collectible-img-src (resources/get-mock-image :collectible))
|
||||||
|
|
||||||
|
(= type constants/community-token-type-erc20)
|
||||||
|
(assoc :amount (str (money/with-precision (money/token->unit amount decimals) 3))
|
||||||
|
:token (:symbol balance)))))
|
||||||
|
|
||||||
(defn- account-item
|
(defn- account-item
|
||||||
[item _ _ [selected-addresses community-id]]
|
[{:keys [customization-color address name emoji]} _ _ [selected-addresses community-id]]
|
||||||
|
(let [balances (rf/sub [:communities/permissioned-balances-by-address community-id address])]
|
||||||
[quo/account-permissions
|
[quo/account-permissions
|
||||||
{:account {:name (:name item)
|
{:account {:name name
|
||||||
:address (:address item)
|
:address address
|
||||||
:emoji (:emoji item)
|
:emoji emoji
|
||||||
:customization-color (:customization-color item)}
|
:customization-color customization-color}
|
||||||
:token-details []
|
:token-details (balances->components-props balances)
|
||||||
:checked? (contains? selected-addresses (:address item))
|
:checked? (contains? selected-addresses address)
|
||||||
:on-change #(rf/dispatch [:communities/toggle-selected-permission-address
|
:on-change #(rf/dispatch [:communities/toggle-selected-permission-address
|
||||||
(:address item) community-id])
|
address community-id])
|
||||||
:container-style {:margin-bottom 8}}])
|
:container-style {:margin-bottom 8}}]))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
(let [{id :community-id} (rf/sub [:get-screen-params])
|
(let [{id :community-id} (rf/sub [:get-screen-params])]
|
||||||
{:keys [name color images]} (rf/sub [:communities/community id])
|
(rf/dispatch [:communities/get-permissioned-balances id])
|
||||||
|
(fn []
|
||||||
|
(let [{:keys [name color images]} (rf/sub [:communities/community id])
|
||||||
{:keys [highest-permission-role]} (rf/sub [:community/token-gated-overview id])
|
{:keys [highest-permission-role]} (rf/sub [:community/token-gated-overview id])
|
||||||
accounts (rf/sub [:wallet/accounts-with-customization-color])
|
accounts (rf/sub [:wallet/accounts-with-customization-color])
|
||||||
selected-addresses (rf/sub [:communities/selected-permission-addresses id])
|
selected-addresses (rf/sub [:communities/selected-permission-addresses id])
|
||||||
highest-role-text
|
highest-role-text (i18n/label (communities.utils/role->translation-key
|
||||||
(i18n/label
|
highest-permission-role))]
|
||||||
(communities.utils/role->translation-key highest-permission-role))]
|
|
||||||
[rn/safe-area-view {:style style/container}
|
[rn/safe-area-view {:style style/container}
|
||||||
[quo/drawer-top
|
[quo/drawer-top
|
||||||
{:type :context-tag
|
{:type :context-tag
|
||||||
|
@ -89,4 +113,4 @@
|
||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
(rf/dispatch [:communities/update-previous-permission-addresses id])
|
(rf/dispatch [:communities/update-previous-permission-addresses id])
|
||||||
(rf/dispatch [:navigate-back]))}
|
(rf/dispatch [:navigate-back]))}
|
||||||
(i18n/label :t/confirm-changes)]]]))
|
(i18n/label :t/confirm-changes)]]]))))
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
[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.addresses-for-permissions.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.navigation.events :as navigation]
|
[status-im.navigation.events :as navigation]
|
||||||
|
|
|
@ -363,6 +363,11 @@
|
||||||
(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
|
(re-frame/reg-sub
|
||||||
:communities/selected-permission-addresses
|
:communities/selected-permission-addresses
|
||||||
(fn [[_ community-id]]
|
(fn [[_ community-id]]
|
||||||
|
|
|
@ -145,6 +145,7 @@
|
||||||
(reg-root-key-sub :communities/collapsed-categories :communities/collapsed-categories)
|
(reg-root-key-sub :communities/collapsed-categories :communities/collapsed-categories)
|
||||||
(reg-root-key-sub :communities/selected-tab :communities/selected-tab)
|
(reg-root-key-sub :communities/selected-tab :communities/selected-tab)
|
||||||
(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)
|
||||||
|
|
||||||
;;activity center
|
;;activity center
|
||||||
(reg-root-key-sub :activity-center :activity-center)
|
(reg-root-key-sub :activity-center :activity-center)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
||||||
"owner": "status-im",
|
"owner": "status-im",
|
||||||
"repo": "status-go",
|
"repo": "status-go",
|
||||||
"version": "v0.174.2",
|
"version": "v0.174.3",
|
||||||
"commit-sha1": "cd228d97dde2063352654f426d7fc50df90c3d30",
|
"commit-sha1": "c15f9e73654ed2f21887af680d7730dec5bec3e3",
|
||||||
"src-sha256": "1kpyyrv0kjzlzmm6mwhh6lv3bilza18ngx1vq1drrp8m8wggwmfa"
|
"src-sha256": "09jvamavnkii2fikpz2a5d345aspfp5lzlg5lpymz7lyjif4qn1s"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue