Account selection: Use bottom sheet component (#18919)
Use bottom sheet component as designed in Figma https://www.figma.com/file/h9wo4GipgZURbqqr1vShFN/Communities-for-Mobile?type=design&node-id=16409-98076&mode=design&t=jrVNb3JnWNurJwP8-0 - Fixes no animation when closing Addresses For Permissions modal: https://github.com/status-im/status-mobile/issues/18617 - Fixes drawer is always expanded: https://github.com/status-im/status-mobile/issues/18619 Additionally: - Fixed incorrect code passing a function instance to a style prop, which leads to incorrect appearance for settings.category.reorder.view/view. - Optimized Reagent a little bit by extracting functions that need to close over the community ID to the mount phase. That way, we avoid regenerating function instances on every re-render and Reagent can avoid a bit of re-work. The challenge was to make the scrollable content work inside a bottom sheet, while supporting the designs for a fixed (always visible) header and footer.
This commit is contained in:
parent
f8cd14296f
commit
27e177f18b
|
@ -16,9 +16,9 @@
|
|||
(reagent/flush))
|
||||
|
||||
(defn- reorder-category-internal
|
||||
[{:keys [label data blur? theme]}]
|
||||
[{:keys [label data blur? theme container-style]}]
|
||||
(reagent/with-let [atom-data (reagent/atom data)]
|
||||
[rn/view {:style style/container}
|
||||
[rn/view {:style (merge (style/container label) container-style)}
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
|
|
|
@ -3,18 +3,18 @@
|
|||
[quo.foundations.colors :as colors]
|
||||
[react-native.platform :as platform]))
|
||||
|
||||
(def ^:private sheet-border-radius 20)
|
||||
|
||||
(defn sheet
|
||||
[{:keys [top]} window-height selected-item]
|
||||
[{:keys [max-height]}]
|
||||
{:position :absolute
|
||||
:max-height (- window-height top)
|
||||
:z-index 1
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0
|
||||
:border-top-left-radius 20
|
||||
:border-top-right-radius 20
|
||||
:overflow (when-not selected-item :hidden)
|
||||
:flex 1})
|
||||
:z-index 1
|
||||
:max-height max-height
|
||||
:border-top-left-radius sheet-border-radius
|
||||
:border-top-right-radius sheet-border-radius})
|
||||
|
||||
(def gradient-bg
|
||||
{:position :absolute
|
||||
|
@ -31,10 +31,11 @@
|
|||
:bottom 0})
|
||||
|
||||
(defn sheet-content
|
||||
[theme padding-bottom-override {:keys [bottom]} shell? bottom-margin]
|
||||
{:border-top-left-radius 20
|
||||
:border-top-right-radius 20
|
||||
:padding-bottom (or padding-bottom-override (+ bottom bottom-margin))
|
||||
[{:keys [theme padding-bottom shell?]}]
|
||||
{:overflow :scroll
|
||||
:padding-bottom padding-bottom
|
||||
:border-top-left-radius sheet-border-radius
|
||||
:border-top-right-radius sheet-border-radius
|
||||
:background-color (if shell?
|
||||
:transparent
|
||||
(colors/theme-colors colors/white colors/neutral-95 theme))})
|
||||
|
|
|
@ -56,6 +56,10 @@
|
|||
(show translate-y bg-opacity)
|
||||
(hide translate-y bg-opacity window-height on-close))))))
|
||||
|
||||
(defn- get-layout-height
|
||||
[event]
|
||||
(oops/oget event "nativeEvent.layout.height"))
|
||||
|
||||
(defn view
|
||||
[{:keys [hide? insets]}
|
||||
{:keys [content selected-item padding-bottom-override border-radius on-close shell?
|
||||
|
@ -64,6 +68,8 @@
|
|||
(let [theme (quo.theme/use-theme-value)
|
||||
sheet-height (rn/use-ref-atom 0)
|
||||
item-height (rn/use-ref-atom 0)
|
||||
set-sheet-height (rn/use-callback #(reset! sheet-height (get-layout-height %)))
|
||||
set-item-height (rn/use-callback #(reset! item-height (get-layout-height %)))
|
||||
{window-height :height} (rn/get-window)
|
||||
bg-opacity (reanimated/use-shared-value 0)
|
||||
translate-y (reanimated/use-shared-value window-height)
|
||||
|
@ -80,7 +86,10 @@
|
|||
top (- window-height (:top insets) @sheet-height)
|
||||
bottom (if selected-item-smaller-than-sheet?
|
||||
(+ @sheet-height bottom-margin)
|
||||
(:bottom insets))]
|
||||
(:bottom insets))
|
||||
sheet-max-height (- window-height (:top insets))
|
||||
content-padding-bottom (or padding-bottom-override
|
||||
(+ (:bottom insets) bottom-margin))]
|
||||
(rn/use-effect
|
||||
#(if hide?
|
||||
(hide translate-y bg-opacity window-height on-close)
|
||||
|
@ -105,7 +114,7 @@
|
|||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:transform [{:translateY translate-y}]}
|
||||
(style/sheet insets window-height selected-item))}
|
||||
(style/sheet {:max-height sheet-max-height}))}
|
||||
(when shell?
|
||||
[blur/ios-view
|
||||
{:style style/shell-bg
|
||||
|
@ -114,14 +123,14 @@
|
|||
:overlay-color :transparent}])
|
||||
(when selected-item
|
||||
[rn/view
|
||||
{:on-layout #(reset! item-height (.-nativeEvent.layout.height ^js %))
|
||||
:style
|
||||
(style/selected-item theme top bottom selected-item-smaller-than-sheet? border-radius)}
|
||||
{:on-layout set-item-height
|
||||
:style (style/selected-item theme top bottom selected-item-smaller-than-sheet? border-radius)}
|
||||
[selected-item]])
|
||||
|
||||
[rn/view
|
||||
{:style (style/sheet-content theme padding-bottom-override insets shell? bottom-margin)
|
||||
:on-layout #(reset! sheet-height (.-nativeEvent.layout.height ^js %))}
|
||||
{:on-layout set-sheet-height
|
||||
:style (style/sheet-content {:theme theme
|
||||
:shell? shell?
|
||||
:padding-bottom content-padding-bottom})}
|
||||
(when (and gradient-cover? customization-color)
|
||||
[rn/view {:style style/gradient-bg}
|
||||
[quo/gradient-cover
|
||||
|
|
|
@ -5,81 +5,92 @@
|
|||
[react-native.gesture :as gesture]
|
||||
[status-im.common.password-authentication.view :as password-authentication]
|
||||
[status-im.contexts.communities.actions.accounts-selection.style :as style]
|
||||
[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.community-rules.view :as community-rules]
|
||||
[status-im.contexts.communities.utils :as communities.utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- join-community-and-navigate-back
|
||||
[id]
|
||||
(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 %}])}])
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{id :community-id} (rf/sub [:get-screen-params])
|
||||
{:keys [name color images]} (rf/sub [:communities/community id])
|
||||
airdrop-account (rf/sub [:communities/airdrop-account id])
|
||||
selected-accounts (rf/sub [:communities/selected-permission-accounts id])
|
||||
{:keys [highest-permission-role]} (rf/sub [:community/token-gated-overview id])
|
||||
highest-role-text (i18n/label (communities.utils/role->translation-key
|
||||
highest-permission-role
|
||||
:t/member))]
|
||||
[rn/safe-area-view {:style style/container}
|
||||
[quo/page-nav
|
||||
{:text-align :left
|
||||
:icon-name :i/close
|
||||
:on-press #(rf/dispatch [:navigate-back])
|
||||
:accessibility-label :back-button}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/request-to-join)
|
||||
:description :context-tag
|
||||
:context-tag {:type :community
|
||||
:size 24
|
||||
:community-logo (get-in images [:thumbnail :uri])
|
||||
:community-name name}}]
|
||||
[gesture/scroll-view
|
||||
[:<>
|
||||
[quo/text
|
||||
{:style style/section-title
|
||||
:accessibility-label :community-rules-title
|
||||
:weight :semi-bold
|
||||
:size :paragraph-1}
|
||||
(i18n/label :t/address-to-share)]
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
:data [{:title (i18n/label :t/join-as-a {:role highest-role-text})
|
||||
:on-press #(rf/dispatch [:open-modal :addresses-for-permissions
|
||||
{:community-id id}])
|
||||
:description :text
|
||||
:action :arrow
|
||||
:label :preview
|
||||
:label-props {:type :accounts
|
||||
:data selected-accounts}
|
||||
:description-props {:text (i18n/label :t/all-addresses)}}
|
||||
{:title (i18n/label :t/for-airdrops)
|
||||
:on-press #(rf/dispatch [:open-modal :airdrop-addresses
|
||||
{:community-id id}])
|
||||
:description :text
|
||||
:action :arrow
|
||||
:label :preview
|
||||
:label-props {:type :accounts
|
||||
:data [airdrop-account]}
|
||||
:description-props {:text (:name airdrop-account)}}]}]
|
||||
[quo/text
|
||||
{:style style/section-title
|
||||
:accessibility-label :community-rules-title
|
||||
:weight :semi-bold
|
||||
:size :paragraph-1}
|
||||
(i18n/label :t/community-rules)]
|
||||
[community-rules/view id]]]
|
||||
[rn/view {:style (style/bottom-actions)}
|
||||
[quo/slide-button
|
||||
{:size :size-48
|
||||
:track-text (i18n/label :t/slide-to-request-to-join)
|
||||
:track-icon :i/face-id
|
||||
:customization-color color
|
||||
:on-complete #(join-community-and-navigate-back id)}]]]))
|
||||
(let [{id :community-id} (rf/sub [:get-screen-params])
|
||||
show-addresses-for-permissions (fn []
|
||||
(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])
|
||||
selected-accounts (rf/sub [:communities/selected-permission-accounts id])
|
||||
{:keys [highest-permission-role]} (rf/sub [:community/token-gated-overview id])
|
||||
highest-role-text (i18n/label (communities.utils/role->translation-key
|
||||
highest-permission-role
|
||||
:t/member))]
|
||||
[rn/safe-area-view {:style style/container}
|
||||
[quo/page-nav
|
||||
{:text-align :left
|
||||
:icon-name :i/close
|
||||
:on-press navigate-back
|
||||
:accessibility-label :back-button}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/request-to-join)
|
||||
:description :context-tag
|
||||
:context-tag {:type :community
|
||||
:size 24
|
||||
:community-logo (get-in images [:thumbnail :uri])
|
||||
:community-name name}}]
|
||||
[gesture/scroll-view
|
||||
[:<>
|
||||
[quo/text
|
||||
{:style style/section-title
|
||||
:accessibility-label :community-rules-title
|
||||
:weight :semi-bold
|
||||
:size :paragraph-1}
|
||||
(i18n/label :t/address-to-share)]
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
:data [{:title (i18n/label :t/join-as-a {:role highest-role-text})
|
||||
:on-press show-addresses-for-permissions
|
||||
:description :text
|
||||
:action :arrow
|
||||
:label :preview
|
||||
:label-props {:type :accounts
|
||||
:data selected-accounts}
|
||||
:description-props {:text (i18n/label :t/all-addresses)}}
|
||||
{:title (i18n/label :t/for-airdrops)
|
||||
:on-press show-airdrop-addresses
|
||||
:description :text
|
||||
:action :arrow
|
||||
:label :preview
|
||||
:label-props {:type :accounts
|
||||
:data [airdrop-account]}
|
||||
:description-props {:text (:name airdrop-account)}}]}]
|
||||
[quo/text
|
||||
{:style style/section-title
|
||||
:accessibility-label :community-rules-title
|
||||
:weight :semi-bold
|
||||
:size :paragraph-1}
|
||||
(i18n/label :t/community-rules)]
|
||||
[community-rules/view id]]]
|
||||
[rn/view {:style (style/bottom-actions)}
|
||||
[quo/slide-button
|
||||
{:size :size-48
|
||||
:track-text (i18n/label :t/slide-to-request-to-join)
|
||||
:track-icon :i/face-id
|
||||
:customization-color color
|
||||
:on-complete join-and-go-back}]]]))))
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
(ns status-im.contexts.communities.actions.addresses-for-permissions.style)
|
||||
|
||||
(def container {:flex 1})
|
|
@ -1,11 +1,9 @@
|
|||
(ns status-im.contexts.communities.actions.addresses-for-permissions.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
[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]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.money :as money]
|
||||
[utils.re-frame :as rf]))
|
||||
|
@ -56,8 +54,15 @@
|
|||
:customization-color community-color}]))
|
||||
|
||||
(defn view
|
||||
[{:keys [scroll-enabled? on-scroll]}]
|
||||
(let [{id :community-id} (rf/sub [:get-screen-params])]
|
||||
[]
|
||||
(let [{id :community-id} (rf/sub [:get-screen-params])
|
||||
toggle-share-all-addresses #(rf/dispatch [:communities/toggle-share-all-addresses id])
|
||||
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 []
|
||||
(let [{:keys [name color images]} (rf/sub [:communities/community id])
|
||||
|
@ -67,7 +72,7 @@
|
|||
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])]
|
||||
[rn/safe-area-view {:style style/container}
|
||||
[:<>
|
||||
[quo/drawer-top
|
||||
{:type :context-tag
|
||||
:title (i18n/label :t/addresses-for-permissions)
|
||||
|
@ -79,26 +84,24 @@
|
|||
:community-logo (get-in images [:thumbnail :uri])
|
||||
: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
|
||||
{:render-fn account-item
|
||||
:render-data {:selected-addresses selected-addresses
|
||||
:community-id id
|
||||
:share-all-addresses? share-all-addresses?
|
||||
:community-color color}
|
||||
:header [quo/category
|
||||
{:list-type :settings
|
||||
:data [{:title
|
||||
(i18n/label
|
||||
:t/share-all-current-and-future-addresses)
|
||||
:action :selector
|
||||
:action-props
|
||||
{:on-change toggle-share-all-addresses
|
||||
:customization-color color
|
||||
:checked? share-all-addresses?}}]
|
||||
:container-style {:padding-bottom 16 :padding-horizontal 0}}]
|
||||
:content-container-style {:padding-horizontal 20}
|
||||
:scroll-enabled @scroll-enabled?
|
||||
:on-scroll on-scroll
|
||||
:key-fn :address
|
||||
:data accounts}]
|
||||
|
||||
|
@ -110,25 +113,18 @@
|
|||
(empty? selected-addresses)
|
||||
(not highest-permission-role)
|
||||
(not unsaved-address-changes?))
|
||||
:on-press (fn []
|
||||
(rf/dispatch
|
||||
[:communities/update-previous-permission-addresses
|
||||
id])
|
||||
(rf/dispatch [:navigate-back]))}
|
||||
:on-press update-previous-addresses}
|
||||
:button-two-label (i18n/label :t/cancel)
|
||||
:button-two-props {:type :grey
|
||||
:on-press (fn []
|
||||
(rf/dispatch
|
||||
[:communities/reset-selected-permission-addresses id])
|
||||
(rf/dispatch [:navigate-back]))}
|
||||
:on-press reset-selected-addresses}
|
||||
: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
|
||||
(empty? selected-addresses) (i18n/label :t/no-addresses-selected)
|
||||
(not highest-permission-role) (i18n/label
|
||||
:t/addresses-dont-contain-tokens-needed)
|
||||
:else nil)}]]))))
|
||||
(empty? selected-addresses)
|
||||
(i18n/label :t/no-addresses-selected)
|
||||
|
||||
(not highest-permission-role)
|
||||
(i18n/label :t/addresses-dont-contain-tokens-needed))}]]))))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
(ns status-im.contexts.communities.actions.airdrop-addresses.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
[status-im.common.not-implemented :as not-implemented]
|
||||
[status-im.contexts.communities.actions.airdrop-addresses.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
|
@ -14,7 +14,7 @@
|
|||
:state (when (= airdrop-address (:address item)) :selected)
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:communities/set-airdrop-address (:address item) community-id])
|
||||
(rf/dispatch [:navigate-back]))
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
:emoji (:emoji item)}])
|
||||
|
||||
(defn view
|
||||
|
@ -33,7 +33,7 @@
|
|||
:on-button-press not-implemented/alert
|
||||
:community-logo (get-in images [:thumbnail :uri])
|
||||
:customization-color color}]
|
||||
[rn/flat-list
|
||||
[gesture/flat-list
|
||||
{:data selected-accounts
|
||||
:render-fn render-item
|
||||
:render-data [airdrop-address id]
|
||||
|
|
|
@ -13,9 +13,6 @@
|
|||
[status-im.contexts.chat.messenger.messages.view :as chat]
|
||||
[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.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.share-community-channel.view :as share-community-channel]
|
||||
[status-im.contexts.communities.discover.view :as communities.discover]
|
||||
|
@ -126,14 +123,6 @@
|
|||
:options {:sheet? true}
|
||||
:component communities.accounts-selection/view}
|
||||
|
||||
{:name :addresses-for-permissions
|
||||
:options {:sheet? true}
|
||||
:component addresses-for-permissions/view}
|
||||
|
||||
{:name :airdrop-addresses
|
||||
:options {:sheet? true}
|
||||
:component airdrop-addresses/view}
|
||||
|
||||
{:name :lightbox
|
||||
:options options/lightbox
|
||||
:component lightbox/lightbox}
|
||||
|
|
Loading…
Reference in New Issue