Share all current and future addresses - UI (#18843)

Fixes
- 'Confirm changes' button unexpected enabled state
- The Confirm button remains enabled even after deselecting all addresses when the user has watch-only wallet accounts.
- Disable the Confirm button when the user deselects the accounts with the token required to join.
- Use community color for address checkbox
This commit is contained in:
Ajay Sivan 2024-02-16 17:41:22 +05:30 committed by GitHub
parent 49567596da
commit 54d9e5ebeb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 164 additions and 49 deletions

View File

@ -18,5 +18,6 @@
[:disabled? {:optional true} [:maybe :boolean]] [:disabled? {:optional true} [:maybe :boolean]]
[:on-change {:optional true} [:maybe fn?]] [:on-change {:optional true} [:maybe fn?]]
[:container-style {:optional true} [:maybe :map]] [:container-style {:optional true} [:maybe :map]]
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
[:theme :schema.common/theme]]]] [:theme :schema.common/theme]]]]
:any]) :any])

View File

@ -42,9 +42,11 @@
(defn- view-internal (defn- view-internal
[{:keys [{:keys
[checked? disabled? on-change token-details keycard? theme container-style] [checked? disabled? on-change token-details keycard? theme container-style customization-color]
{:keys {:keys
[name address emoji customization-color]} :account}] [name address emoji]
:as account} :account
:or {customization-color :blue}}]
[rn/view [rn/view
{:style (merge (style/container theme) container-style) {:style (merge (style/container theme) container-style)
:accessibility-label :wallet-account-permissions} :accessibility-label :wallet-account-permissions}
@ -52,7 +54,7 @@
[account-avatar/view [account-avatar/view
{:size 32 {:size 32
:emoji emoji :emoji emoji
:customization-color customization-color}] :customization-color (:customization-color account)}]
[rn/view {:style style/account-details} [rn/view {:style style/account-details}
[rn/view {:style style/name-and-keycard} [rn/view {:style style/name-and-keycard}
[text/text [text/text
@ -67,10 +69,11 @@
{:address address {:address address
:format :short}]] :format :short}]]
[selectors/view [selectors/view
{:type :checkbox {:type :checkbox
:checked? checked? :checked? checked?
:disabled? disabled? :customization-color customization-color
:on-change on-change}]] :disabled? disabled?
:on-change on-change}]]
[token-details-section token-details]]) [token-details-section token-details]])

View File

@ -32,18 +32,21 @@
:token (:symbol balance))))) :token (:symbol balance)))))
(defn- account-item (defn- account-item
[{:keys [color address name emoji]} _ _ [selected-addresses community-id]] [{:keys [color address name emoji]} _ _
{:keys [selected-addresses community-id share-all-addresses? community-color]}]
(let [balances (rf/sub [:communities/permissioned-balances-by-address community-id address])] (let [balances (rf/sub [:communities/permissioned-balances-by-address community-id address])]
[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 color}
:token-details (balances->components-props balances) :token-details (balances->components-props balances)
:checked? (contains? selected-addresses address) :checked? (contains? selected-addresses address)
:on-change #(rf/dispatch [:communities/toggle-selected-permission-address :disabled? share-all-addresses?
address community-id]) :on-change #(rf/dispatch [:communities/toggle-selected-permission-address
:container-style {:margin-bottom 8}}])) address community-id])
:container-style {:margin-bottom 8}
:customization-color community-color}]))
(defn view (defn view
[{:keys [scroll-enabled? on-scroll]}] [{:keys [scroll-enabled? on-scroll]}]
@ -54,6 +57,8 @@
{: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-without-watched-accounts]) accounts (rf/sub [:wallet/accounts-without-watched-accounts])
selected-addresses (rf/sub [:communities/selected-permission-addresses id]) selected-addresses (rf/sub [:communities/selected-permission-addresses id])
share-all-addresses? (rf/sub [:communities/share-all-addresses? id])
unsaved-address-changes? (rf/sub [:communities/unsaved-address-changes? id])
highest-role-text (when highest-permission-role highest-role-text (when highest-permission-role
(i18n/label (communities.utils/role->translation-key (i18n/label (communities.utils/role->translation-key
highest-permission-role)))] highest-permission-role)))]
@ -68,10 +73,24 @@
:community-logo (get-in images [:thumbnail :uri]) :community-logo (get-in images [:thumbnail :uri])
:customization-color color}] :customization-color color}]
[quo/category
{:list-type :settings
:data [{:title (i18n/label :t/share-all-current-and-future-addresses)
:action :selector
:action-props {:on-change #(rf/dispatch
[:communities/toggle-share-all-addresses
id])
:customization-color color
:checked? share-all-addresses?}}]
:container-style {:padding-bottom 16}}]
[gesture/flat-list [gesture/flat-list
{:render-fn account-item {:render-fn account-item
:render-data [selected-addresses id] :render-data {:selected-addresses selected-addresses
:content-container-style {:padding 20} :community-id id
:share-all-addresses? share-all-addresses?
:community-color color}
:content-container-style {:padding-horizontal 20}
:scroll-enabled scroll-enabled? :scroll-enabled scroll-enabled?
:on-scroll on-scroll :on-scroll on-scroll
:key-fn :address :key-fn :address
@ -109,7 +128,9 @@
[quo/button [quo/button
{:container-style {:flex 1} {:container-style {:flex 1}
:customization-color color :customization-color color
:disabled? (empty? selected-addresses) :disabled? (or (empty? selected-addresses)
(not highest-permission-role)
(not unsaved-address-changes?))
: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]))}

View File

@ -12,6 +12,7 @@
status-im.contexts.communities.actions.addresses-for-permissions.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.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]
@ -163,15 +164,16 @@
(defn initialize-permission-addresses (defn initialize-permission-addresses
[{:keys [db]} [community-id]] [{:keys [db]} [community-id]]
(when community-id (when community-id
(let [accounts (get-in db [:wallet :accounts]) (let [accounts (utils/sorted-non-watch-only-accounts db)
sorted-accounts (sort-by :position (vals accounts)) addresses (set (map :address accounts))]
addresses (set (map :address sorted-accounts))]
{:db (update-in db {:db (update-in db
[:communities community-id] [:communities community-id]
assoc assoc
:previous-share-all-addresses? true
:share-all-addresses? true
:previous-permission-addresses addresses :previous-permission-addresses addresses
:selected-permission-addresses addresses :selected-permission-addresses addresses
:airdrop-address (:address (first sorted-accounts)))}))) :airdrop-address (:address (first accounts)))})))
(rf/reg-event-fx :communities/initialize-permission-addresses (rf/reg-event-fx :communities/initialize-permission-addresses
initialize-permission-addresses) initialize-permission-addresses)
@ -179,17 +181,18 @@
(defn update-previous-permission-addresses (defn update-previous-permission-addresses
[{:keys [db]} [community-id]] [{:keys [db]} [community-id]]
(when community-id (when community-id
(let [accounts (get-in db [:wallet :accounts]) (let [accounts (utils/sorted-non-watch-only-accounts db)
sorted-accounts (sort-by :position (vals accounts))
selected-permission-addresses (get-in db selected-permission-addresses (get-in db
[:communities community-id [:communities community-id
:selected-permission-addresses]) :selected-permission-addresses])
selected-accounts (filter #(contains? selected-permission-addresses (:address %)) selected-accounts (filter #(contains? selected-permission-addresses (:address %))
sorted-accounts) accounts)
current-airdrop-address (get-in db [:communities community-id :airdrop-address])] 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 {:db (update-in db
[:communities community-id] [:communities community-id]
assoc assoc
:previous-share-all-addresses? share-all-addresses?
:previous-permission-addresses selected-permission-addresses :previous-permission-addresses selected-permission-addresses
:airdrop-address (if (contains? selected-permission-addresses :airdrop-address (if (contains? selected-permission-addresses
current-airdrop-address) current-airdrop-address)
@ -218,12 +221,32 @@
(rf/reg-event-fx :communities/toggle-selected-permission-address (rf/reg-event-fx :communities/toggle-selected-permission-address
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?])
accounts (utils/sorted-non-watch-only-accounts db)
addresses (set (map :address accounts))]
{:db (update-in db
[:communities community-id]
(fn [community]
(-> community
(assoc :share-all-addresses? (not share-all-addresses?))
(cond-> (not share-all-addresses?)
(assoc :selected-permission-addresses addresses)))))}))
(rf/reg-event-fx :communities/toggle-share-all-addresses
toggle-share-all-addresses)
(rf/reg-event-fx :communities/reset-selected-permission-addresses (rf/reg-event-fx :communities/reset-selected-permission-addresses
(fn [{:keys [db]} [community-id]] (fn [{:keys [db]} [community-id]]
(when community-id (when community-id
{:db (assoc-in db {:db (update-in db
[:communities community-id :selected-permission-addresses] [:communities community-id]
(get-in db [:communities community-id :previous-permission-addresses])) 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]]]}))) :fx [[:dispatch [:communities/check-permissions-to-join-community community-id]]]})))
(rf/reg-event-fx :communities/share-community-channel-url-with-data (rf/reg-event-fx :communities/share-community-channel-url-with-data

View File

@ -16,6 +16,8 @@
expected-db {:db (update-in (:db initial-db) expected-db {:db (update-in (:db initial-db)
[:communities community-id] [:communities community-id]
assoc assoc
:share-all-addresses? true
:previous-share-all-addresses? true
:previous-permission-addresses #{"0x1" "0x2"} :previous-permission-addresses #{"0x1" "0x2"}
:selected-permission-addresses #{"0x1" "0x2"} :selected-permission-addresses #{"0x1" "0x2"}
:airdrop-address "0x1")}] :airdrop-address "0x1")}]
@ -39,12 +41,16 @@
:communities {community-id {:previous-permission-addresses #{"0x1" "0x2"} :communities {community-id {:previous-permission-addresses #{"0x1" "0x2"}
:selected-permission-addresses #{"0x1" "0x2" :selected-permission-addresses #{"0x1" "0x2"
"0x3"} "0x3"}
:share-all-addresses? true
:previous-share-all-addresses? false
:airdrop-address "0x1"}}}} :airdrop-address "0x1"}}}}
expected-db {:db {:wallet wallet expected-db {:db {:wallet wallet
:communities {community-id {:previous-permission-addresses #{"0x1" "0x2" :communities {community-id {:previous-permission-addresses #{"0x1" "0x2"
"0x3"} "0x3"}
:selected-permission-addresses #{"0x1" "0x2" :selected-permission-addresses #{"0x1" "0x2"
"0x3"} "0x3"}
:share-all-addresses? true
:previous-share-all-addresses? true
:airdrop-address "0x1"}}}}] :airdrop-address "0x1"}}}}]
(is (is
(match? expected-db (match? expected-db
@ -61,6 +67,40 @@
(match? expected-db (match? expected-db
(events/update-previous-permission-addresses initial-db [community-id])))))) (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"}
:selected-permission-addresses #{"0x1"}
: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"

View File

@ -11,3 +11,10 @@
constants/community-token-permission-become-admin :t/admin constants/community-token-permission-become-admin :t/admin
constants/community-token-permission-become-member :t/member constants/community-token-permission-become-member :t/member
fallback-to))) fallback-to)))
(defn sorted-non-watch-only-accounts
[db]
(->> (get-in db [:wallet :accounts])
(vals)
(remove :watch-only?)
(sort-by :position)))

View File

@ -24,7 +24,8 @@
{:key :empty-token-list} {:key :empty-token-list}
{:key :1-token} {:key :1-token}
{:key :3-tokens} {:key :3-tokens}
{:key :5-tokens}]}]) {:key :5-tokens}]}
(preview/customization-color-option {:key :customization-color})])
(def ^:private token-details (def ^:private token-details
{:no-tokens nil {:no-tokens nil
@ -50,23 +51,25 @@
(defn view (defn view
[] []
(let [state (reagent/atom {:name "Trip to Vegas" (let [state (reagent/atom {:name "Trip to Vegas"
:address "0x2f0fbf0a93c5999e9b4410848403a02b38983eb2" :address "0x2f0fbf0a93c5999e9b4410848403a02b38983eb2"
:emoji "😊" :emoji "😊"
:account-color :blue :account-color :blue
:token-details :no-tokens :token-details :no-tokens
:keycard? true :customization-color :blue
:checked? true :keycard? true
:disabled? false})] :checked? true
:disabled? false})]
(fn [] (fn []
[preview/preview-container {:state state :descriptor descriptor} [preview/preview-container {:state state :descriptor descriptor}
[quo/account-permissions [quo/account-permissions
{:account {:name (:name @state) {:account {:name (:name @state)
:address (:address @state) :address (:address @state)
:emoji (:emoji @state) :emoji (:emoji @state)
:customization-color (:account-color @state)} :customization-color (:account-color @state)}
:token-details (token-details (:token-details @state)) :token-details (token-details (:token-details @state))
:keycard? (:keycard? @state) :keycard? (:keycard? @state)
:checked? (:checked? @state) :checked? (:checked? @state)
:disabled? (:disabled? @state) :disabled? (:disabled? @state)
:on-change (fn [checked?] (swap! state assoc :checked? checked?))}]]))) :customization-color (:customization-color @state)
:on-change (fn [checked?] (swap! state assoc :checked? checked?))}]])))

View File

@ -367,6 +367,22 @@
(fn [[{:keys [selected-permission-addresses]}] _] (fn [[{:keys [selected-permission-addresses]}] _]
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 (re-frame/reg-sub
:communities/selected-permission-accounts :communities/selected-permission-accounts
(fn [[_ community-id]] (fn [[_ community-id]]

View File

@ -180,6 +180,7 @@
"other": "{{count}} members" "other": "{{count}} members"
}, },
"community-rules": "Community rules", "community-rules": "Community rules",
"share-all-current-and-future-addresses": "Share all current and future addresses",
"address-to-share": "Addresses to share", "address-to-share": "Addresses to share",
"addresses-for-permissions": "Addresses for permissions", "addresses-for-permissions": "Addresses for permissions",
"no-addresses-selected": "At least 1 address must be shared with community", "no-addresses-selected": "At least 1 address must be shared with community",