Bottom tab animation on leaving/entering main tabs

This commit is contained in:
Roman Volosovskyi 2019-02-28 18:55:56 +02:00
parent de5c23d39f
commit a30c379a87
No known key found for this signature in database
GPG Key ID: 0238A4B5ECEE70DE
14 changed files with 344 additions and 191 deletions

View File

@ -38,7 +38,7 @@
"keyboardDidHide" "keyboardDidHide"
(fn [_] (fn [_]
(dispatch [:show-tab-bar]) (dispatch [:show-tab-bar])
(when (zero? @keyboard-height) (when-not (zero? @keyboard-height)
(dispatch [:set :keyboard-height 0])))) (dispatch [:set :keyboard-height 0]))))
(.hide react/splash-screen) (.hide react/splash-screen)
(.addEventListener react/app-state "change" app-state-change-handler) (.addEventListener react/app-state "change" app-state-change-handler)

View File

@ -7,7 +7,8 @@
[status-im.chat.db :as chat.db] [status-im.chat.db :as chat.db]
[status-im.models.transactions :as transactions] [status-im.models.transactions :as transactions]
[status-im.utils.platform :as platform] [status-im.utils.platform :as platform]
[status-im.ui.components.bottom-bar.styles :as tabs-styles])) [status-im.ui.components.bottom-bar.styles :as tabs-styles]
[status-im.ui.components.bottom-bar.styles :as tabs.styles]))
(re-frame/reg-sub ::chats :chats) (re-frame/reg-sub ::chats :chats)
(re-frame/reg-sub ::access-scope->command-id :access-scope->command-id) (re-frame/reg-sub ::access-scope->command-id :access-scope->command-id)
@ -77,10 +78,13 @@
(fn [kb-height] (fn [kb-height]
(cond (cond
(and platform/iphone-x? (> kb-height 0)) (and platform/iphone-x? (> kb-height 0))
(- kb-height 34 tabs-styles/tabs-height) (- kb-height (* 2 tabs.styles/minimized-tabs-height))
platform/ios? (- kb-height (if (> kb-height 0)
tabs-styles/tabs-height platform/ios?
0)) (+ kb-height (- (if (> kb-height 0)
tabs.styles/minimized-tabs-height
0)))
:default 0))) :default 0)))
(re-frame/reg-sub (re-frame/reg-sub

View File

@ -56,4 +56,6 @@
(defn get-layout [value-xy] (defn get-layout [value-xy]
(js->clj (.getLayout value-xy))) (js->clj (.getLayout value-xy)))
(defn easing [] js/ReactNative.Easing) (defn easing [] js/ReactNative.Easing)
(defn cubic [] (.-cubic (easing)))

View File

@ -10,16 +10,22 @@
[status-im.i18n :as i18n] [status-im.i18n :as i18n]
[re-frame.core :as re-frame])) [re-frame.core :as re-frame]))
(defonce visible? (animation/create-value 1))
(defonce last-to-value (atom 1))
(defn animate (defn animate
([visible duration to] ([visible duration to]
(animate visible duration to nil)) (animate visible duration to nil))
([visible duration to callback] ([visible duration to callback]
(animation/start (when (not= to @last-to-value)
(animation/timing visible (reset! last-to-value to)
{:toValue to (animation/start
:duration duration (animation/timing visible
:useNativeDriver true}) {:toValue to
callback))) :duration duration
:easing (animation/cubic)
:useNativeDriver true})
callback))))
(def tabs-list-data (def tabs-list-data
[{:nav-stack :chat-stack [{:nav-stack :chat-stack
@ -80,17 +86,64 @@
:active? (= current-view-id nav-stack) :active? (= current-view-id nav-stack)
:nav-stack nav-stack}])]]) :nav-stack nav-stack}])]])
(defn tabs-animation-wrapper [visible? keyboard-shown? tab] (defn main-tab? [view-id]
[react/animated-view (contains?
{:style (tabs.styles/animated-container visible? keyboard-shown?)} #{:home :wallet :dapps :my-profile :wallet-onboarding-setup}
[react/safe-area-view [tabs tab]]]) view-id))
(defn minimize-bar [view-id]
(if (main-tab? view-id)
(animate visible? 150 1)
(animate visible? 150 tabs.styles/minimized-tab-ratio)))
(defn tabs-animation-wrapper-ios
[content]
[react/view
[react/view
{:style tabs.styles/title-cover-wrapper}
content
(when platform/iphone-x?
[react/view
{:style tabs.styles/ios-titles-cover}])]
[react/safe-area-view {:flex 1}]])
(defn tabs-animation-wrapper-android
[keyboard-shown? view-id content]
[react/view
{:style (tabs.styles/animation-wrapper
keyboard-shown?
(main-tab? view-id))}
[react/view
{:style tabs.styles/title-cover-wrapper}
content]])
(defn tabs-animation-wrapper [keyboard-shown? view-id tab]
(reagent.core/create-class
{:component-will-update
(fn [this new-params]
(let [old-view-id (get (.-argv (.-props this)) 2)
new-view-id (get new-params 2)]
(when (not= new-view-id old-view-id)
(minimize-bar new-view-id))))
:reagent-render
(fn [keyboard-shown? view-id tab]
(if platform/ios?
[tabs-animation-wrapper-ios
[react/animated-view
{:style (tabs.styles/animated-container visible? keyboard-shown?)}
[tabs tab]]]
[tabs-animation-wrapper-android
keyboard-shown?
view-id
[react/animated-view
{:style (tabs.styles/animated-container visible? keyboard-shown?)}
[tabs tab]]]))}))
(def disappearance-duration 150) (def disappearance-duration 150)
(def appearance-duration 100) (def appearance-duration 100)
(defn bottom-bar [_] (defn bottom-bar [_ view-id]
(let [keyboard-shown? (reagent/atom false) (let [keyboard-shown? (reagent/atom false)
visible? (animation/create-value 1)
listeners (atom [])] listeners (atom [])]
(reagent/create-class (reagent/create-class
{:component-will-mount {:component-will-mount
@ -106,7 +159,10 @@
(.addListener react/keyboard "keyboardDidHide" (.addListener react/keyboard "keyboardDidHide"
(fn [] (fn []
(reset! keyboard-shown? false) (reset! keyboard-shown? false)
(animate visible? appearance-duration 1)))]))) (animate visible? appearance-duration
(if (main-tab? @view-id)
1
tabs.styles/minimized-tab-ratio))))])))
:component-will-unmount :component-will-unmount
(fn [] (fn []
(when (not-empty @listeners) (when (not-empty @listeners)
@ -114,7 +170,7 @@
(when listener (when listener
(.remove listener))))) (.remove listener)))))
:reagent-render :reagent-render
(fn [args] (fn [args view-id]
(let [idx (.. (:navigation args) (let [idx (.. (:navigation args)
-state -state
-index) -index)
@ -123,6 +179,4 @@
1 :wallet-stack 1 :wallet-stack
2 :profile-stack 2 :profile-stack
:chat-stack)] :chat-stack)]
(if platform/ios? [tabs-animation-wrapper @keyboard-shown? @view-id tab]))})))
[react/safe-area-view [tabs tab]]
[tabs-animation-wrapper visible? @keyboard-shown? tab])))})))

View File

@ -10,6 +10,13 @@
platform/ios? 52 platform/ios? 52
platform/desktop? 68)) platform/desktop? 68))
(def minimized-tabs-height 36)
(def tabs-diff (- tabs-height minimized-tabs-height))
(def minimized-tab-ratio
(/ minimized-tabs-height tabs-height))
(def tab-height (dec tabs-height)) (def tab-height (dec tabs-height))
(def tabs-container (def tabs-container
@ -94,10 +101,34 @@
:right 0 :right 0
:background-color :white :background-color :white
:elevation 8 :elevation 8
:position (when keyboard-shown? :absolute) :position (when (or platform/ios?
keyboard-shown?)
:absolute)
:transform [{:translateY :transform [{:translateY
(animation/interpolate (animation/interpolate
visible? visible?
{:inputRange [0 1] {:inputRange [0 1]
:outputRange [tabs-height 0]})}]}) :outputRange [tabs-height 0]})}]})
(def ios-titles-cover
{:background-color :white
:position :absolute
:height (- tabs-height minimized-tabs-height)
:align-self :stretch
:top tabs-height
:right 0
:left 0})
(def title-cover-wrapper
{:position :absolute
:height tabs-height
:bottom (if platform/iphone-x? 34 0)
:right 0
:left 0})
(defn animation-wrapper [keyboard-shown? main-tab?]
{:height (cond
keyboard-shown? 0
main-tab? tabs-height
:else minimized-tabs-height)
:align-self :stretch})

View File

@ -25,7 +25,8 @@
[status-im.ui.screens.chat.stickers.views :as stickers] [status-im.ui.screens.chat.stickers.views :as stickers]
[status-im.ui.screens.chat.styles.main :as style] [status-im.ui.screens.chat.styles.main :as style]
[status-im.ui.screens.chat.toolbar-content :as toolbar-content] [status-im.ui.screens.chat.toolbar-content :as toolbar-content]
[status-im.utils.platform :as platform]) [status-im.utils.platform :as platform]
[status-im.utils.utils :as utils])
(:require-macros [status-im.utils.views :refer [defview letsubs]])) (:require-macros [status-im.utils.views :refer [defview letsubs]]))
(defn add-contact-bar [public-key] (defn add-contact-bar [public-key]
@ -84,18 +85,18 @@
:modal? modal? :modal? modal?
:current-public-key current-public-key)]) :current-public-key current-public-key)])
(def animation-duration 200)
(defview messages-view-animation [message-view] (defview messages-view-animation [message-view]
;; smooths out appearance of message-view ;; smooths out appearance of message-view
(letsubs [opacity (animation/create-value 0) (letsubs [opacity (animation/create-value 0)]
duration (if platform/android? 100 200)
timeout (if platform/android? 50 0)]
{:component-did-mount (fn [_] {:component-did-mount (fn [_]
(animation/start (animation/start
(animation/anim-sequence (animation/timing
[(animation/anim-delay timeout) opacity
(animation/spring opacity {:toValue 1 {:toValue 1
:duration duration :duration animation-duration
:useNativeDriver true})])))} :useNativeDriver true})))}
[react/with-activity-indicator [react/with-activity-indicator
{:style style/message-view-preview {:style style/message-view-preview
:preview [react/view style/message-view-preview]} :preview [react/view style/message-view-preview]}

View File

@ -16,7 +16,8 @@
[status-im.ui.screens.home.styles :as styles] [status-im.ui.screens.home.styles :as styles]
[status-im.ui.screens.home.views.inner-item :as inner-item] [status-im.ui.screens.home.views.inner-item :as inner-item]
[status-im.utils.platform :as platform] [status-im.utils.platform :as platform]
[status-im.utils.utils :as utils]) [status-im.utils.utils :as utils]
[status-im.ui.components.bottom-bar.styles :as tabs.styles])
(:require-macros [status-im.utils.views :as views])) (:require-macros [status-im.utils.views :as views]))
(defn- toolbar [show-welcome? show-sync-state sync-state latest-block-number logged-in?] (defn- toolbar [show-welcome? show-sync-state sync-state latest-block-number logged-in?]
@ -59,21 +60,25 @@
[icons/icon :main-icons/add {:color :white}])]]]) [icons/icon :main-icons/add {:color :white}])]]])
(defn home-list-item [[home-item-id home-item]] (defn home-list-item [[home-item-id home-item]]
(let [delete-action (if (:chat-id home-item) (if (= home-item-id :empty)
(if (and (:group-chat home-item) [react/view
(not (:public? home-item))) {:style {:height tabs.styles/tabs-diff
:group-chats.ui/remove-chat-pressed :align-self :stretch}}]
:chat.ui/remove-chat) (let [delete-action (if (:chat-id home-item)
:browser.ui/remove-browser-pressed) (if (and (:group-chat home-item)
inner-item-view (if (:chat-id home-item) (not (:public? home-item)))
inner-item/home-list-chat-item-inner-view :group-chats.ui/remove-chat-pressed
inner-item/home-list-browser-item-inner-view)] :chat.ui/remove-chat)
[list/deletable-list-item {:type :chats :browser.ui/remove-browser-pressed)
:id home-item-id inner-item-view (if (:chat-id home-item)
:on-delete #(do inner-item/home-list-chat-item-inner-view
(re-frame/dispatch [:set-swipe-position :chats home-item-id false]) inner-item/home-list-browser-item-inner-view)]
(re-frame/dispatch [delete-action home-item-id]))} [list/deletable-list-item {:type :chats
[inner-item-view home-item]])) :id home-item-id
:on-delete #(do
(re-frame/dispatch [:set-swipe-position :chats home-item-id false])
(re-frame/dispatch [delete-action home-item-id]))}
[inner-item-view home-item]])))
;;do not remove view-id and will-update or will-unmount handlers, this is how it works ;;do not remove view-id and will-update or will-unmount handlers, this is how it works
(views/defview welcome [view-id] (views/defview welcome [view-id]
@ -259,7 +264,8 @@
previous-position))) previous-position)))
(show-search!))) (show-search!)))
false)})) false)}))
[list/flat-list {:data all-home-items [list/flat-list {:data (conj (vec all-home-items)
[:empty {}])
:key-fn first :key-fn first
:end-fill-color colors/white :end-fill-color colors/white
:on-scroll-begin-drag :on-scroll-begin-drag

View File

@ -319,4 +319,7 @@
[react/view styles/my-profile-info-container [react/view styles/my-profile-info-container
[my-profile-settings current-account shown-account currency (nil? login-data)]] [my-profile-settings current-account shown-account currency (nil? login-data)]]
(when (nil? login-data) (when (nil? login-data)
[advanced shown-account on-show-advanced])]]]))) [advanced shown-account on-show-advanced])
[react/view
{:align-self :stretch
:height 16}]]]])))

View File

@ -2,43 +2,24 @@
(:require [status-im.utils.config :as config])) (:require [status-im.utils.config :as config]))
(def chat-stack (def chat-stack
{:name :chat-stack {:name :chat-stack
:screens [{:name :chat-main-stack :screens (cond-> [:home
:screens (cond-> :chat
[:home :profile
:chat :new
:profile :new-chat
:new :qr-scanner
:new-chat :take-picture
:qr-scanner :new-group
:take-picture :add-participants-toggle-list
:new-group :contact-toggle-list
:add-participants-toggle-list :group-chat-profile
:contact-toggle-list :new-public-chat
:group-chat-profile :open-dapp
:new-public-chat :dapp-description
:open-dapp :browser
:dapp-description :stickers
:browser :stickers-pack]
:stickers config/hardwallet-enabled?
:stickers-pack] (concat [:hardwallet-connect :enter-pin]))
config/hardwallet-enabled? :config {:initialRouteName :home}})
(concat [:hardwallet-connect :enter-pin]))
:config {:initialRouteName :home}}
:chat-modal
:show-extension-modal
:stickers-pack-modal
{:name :wallet-send-modal-stack
:screens [:wallet-send-transaction-modal
:wallet-transaction-sent-modal
:wallet-transaction-fee]
:config {:initialRouteName :wallet-send-transaction-modal}}
{:name :wallet-send-modal-stack-with-onboarding
:screens [:wallet-onboarding-setup-modal
:wallet-send-transaction-modal
:wallet-transaction-sent-modal
:wallet-transaction-fee]
:config {:initialRouteName :wallet-onboarding-setup-modal}}
:wallet-sign-message-modal]
:config {:mode :modal
:initialRouteName :chat-main-stack}})

View File

@ -13,30 +13,62 @@
[status-im.ui.screens.routing.chat-stack :as chat-stack] [status-im.ui.screens.routing.chat-stack :as chat-stack]
[status-im.ui.screens.routing.wallet-stack :as wallet-stack] [status-im.ui.screens.routing.wallet-stack :as wallet-stack]
[status-im.ui.screens.routing.profile-stack :as profile-stack] [status-im.ui.screens.routing.profile-stack :as profile-stack]
[status-im.ui.screens.routing.modals :as modals]
[status-im.ui.components.bottom-bar.core :as bottom-bar] [status-im.ui.components.bottom-bar.core :as bottom-bar]
[status-im.ui.components.status-bar.view :as status-bar])) [status-im.ui.components.status-bar.view :as status-bar]
[status-im.ui.components.bottom-bar.styles :as tabs.styles]))
(defn navigation-events [view-id modal?] (defonce view-id (reagent.core/atom nil))
(defn navigation-events [current-view-id modal?]
[:> navigation/navigation-events [:> navigation/navigation-events
{:on-will-focus {:on-will-focus
(fn [] (fn []
(log/debug :on-will-focus view-id) (when (not= @view-id current-view-id)
(reset! view-id current-view-id))
(log/debug :on-will-focus current-view-id)
(when modal? (when modal?
(status-bar/set-status-bar view-id)) (status-bar/set-status-bar current-view-id))
(re-frame/dispatch [:screens/on-will-focus view-id])) (re-frame/dispatch [:screens/on-will-focus current-view-id]))
:on-did-focus :on-did-focus
(fn [] (fn []
(log/debug :on-did-focus view-id)
(when-not modal? (when-not modal?
(status-bar/set-status-bar view-id)))}]) (status-bar/set-status-bar current-view-id)))}])
(defn wrap [view-id component] (defn wrap
"Wraps screen with main view and adds navigation-events component" "Wraps screen with main view and adds navigation-events component"
[view-id component]
(fn [] (fn []
(let [main-view (react/create-main-screen-view view-id)] (let [main-view (react/create-main-screen-view view-id)]
[main-view common-styles/flex (if platform/ios?
[component] [main-view (assoc common-styles/flex
[navigation-events view-id false]]))) :margin-bottom
(cond
;; there is no need to show bottom nav bar on
;; `intro-login-stack` screens
(contains?
intro-login-stack/all-screens
view-id)
0
;; :wallet-onboarding-setup is the only screen
;; except main tabs which requires maximised
;; bottom nav bar, that's why it requires an extra
;; bottom margin, otherwise bottom nav bar will
;; partially cover the screen
(contains?
#{:wallet-onboarding-setup}
view-id)
tabs.styles/tabs-height
:else
tabs.styles/minimized-tabs-height))
[component]
[navigation-events view-id false]]
[main-view common-styles/flex
[component]
[navigation-events view-id false]]))))
(defn wrap-modal [modal-view component] (defn wrap-modal [modal-view component]
"Wraps modal screen with necessary styling and adds :on-request-close handler "Wraps modal screen with necessary styling and adds :on-request-close handler
@ -73,8 +105,21 @@
(nav-reagent/stack-navigator (nav-reagent/stack-navigator
routes routes
(cond-> (cond->
(merge {:headerMode "none" (merge {:headerMode "none"
:cardStyle {:backgroundColor (when platform/ios? :white)}} :cardStyle {:backgroundColor (when platform/ios? :white)}
:onTransitionStart (fn [n]
(let [idx (.. n
-navigation
-state
-index)
routes (.. n
-navigation
-state
-routes)]
(when (and (array? routes) (int? idx))
(let [route (aget routes idx)
route-name (keyword (.-routeName route))]
(bottom-bar/minimize-bar route-name)))))}
(prepare-config config))))) (prepare-config config)))))
(defn switch-navigator [routes config] (defn switch-navigator [routes config]
@ -125,18 +170,30 @@
(map build-screen) (map build-screen)
(into {}))) (into {})))
(defn wrap-bottom-bar
[nav]
[bottom-bar/bottom-bar nav view-id])
(defn get-main-component [view-id] (defn get-main-component [view-id]
(log/debug :component view-id) (log/debug :component view-id)
(switch-navigator (switch-navigator
(into {} (into {}
[(build-screen (intro-login-stack/intro-login-stack view-id)) [(build-screen (intro-login-stack/intro-login-stack view-id))
[:tabs [:tabs-and-modals
{:screen (tab-navigator {:screen
(->> [(build-screen chat-stack/chat-stack) (stack-navigator
(build-screen wallet-stack/wallet-stack) (merge
(build-screen profile-stack/profile-stack)] {:tabs
(into {})) {:screen (tab-navigator
{:initialRouteName :chat-stack (->> [(build-screen chat-stack/chat-stack)
:tabBarComponent (reagent.core/reactify-component (build-screen wallet-stack/wallet-stack)
bottom-bar/bottom-bar)})}]]) (build-screen profile-stack/profile-stack)]
(into {}))
{:initialRouteName :chat-stack
:tabBarComponent (reagent.core/reactify-component
wrap-bottom-bar)})}}
(stack-screens modals/modal-screens))
{:mode :modal
:initialRouteName :tabs
:onTransitionStart (fn [])})}]])
{:initialRouteName :intro-login-stack})) {:initialRouteName :intro-login-stack}))

View File

@ -1,6 +1,19 @@
(ns status-im.ui.screens.routing.intro-login-stack (ns status-im.ui.screens.routing.intro-login-stack
(:require [status-im.utils.config :as config])) (:require [status-im.utils.config :as config]))
(def all-screens
#{:login
:progress
:create-account
:recover
:accounts
:intro
:hardwallet-authentication-method
:hardwallet-connect
:enter-pin
:hardwallet-setup
:hardwallet-success})
(defn intro-login-stack [view-id] (defn intro-login-stack [view-id]
{:name :intro-login-stack {:name :intro-login-stack
:screens (cond-> [:login :screens (cond-> [:login

View File

@ -0,0 +1,23 @@
(ns status-im.ui.screens.routing.modals)
(def modal-screens
[{:name :wallet-send-modal-stack
:screens [:wallet-send-transaction-modal
:wallet-transaction-sent-modal
:wallet-transaction-fee]
:config {:initialRouteName :wallet-send-transaction-modal}}
{:name :wallet-send-modal-stack-with-onboarding
:screens [:wallet-onboarding-setup-modal
:wallet-send-transaction-modal
:wallet-transaction-sent-modal
:wallet-transaction-fee]
:config {:initialRouteName :wallet-onboarding-setup-modal}}
:chat-modal
:show-extension-modal
:stickers-pack-modal
:wallet-sign-message-modal
:selection-modal-screen
:wallet-settings-assets
:wallet-transaction-fee
:wallet-transactions-filter
:profile-qr-viewer])

View File

@ -3,43 +3,39 @@
(def profile-stack (def profile-stack
{:name :profile-stack {:name :profile-stack
:screens [{:name :main-profile-stack :screens (cond-> [:my-profile
:screens (cond-> [:my-profile :contacts-list
:contacts-list :blocked-users-list
:blocked-users-list :profile-photo-capture
:profile-photo-capture :about-app
:about-app :bootnodes-settings
:bootnodes-settings :installations
:installations :edit-bootnode
:edit-bootnode :offline-messaging-settings
:offline-messaging-settings :edit-mailserver
:edit-mailserver :help-center
:help-center :dapps-permissions
:dapps-permissions :manage-dapps-permissions
:manage-dapps-permissions :extensions-settings
:extensions-settings :edit-extension
:edit-extension :show-extension
:show-extension :network-settings
:network-settings :network-details
:network-details :edit-network
:edit-network :log-level-settings
:log-level-settings :fleet-settings
:fleet-settings :currency-settings
:currency-settings :mobile-network-settings
:mobile-network-settings :backup-seed
:backup-seed :tribute-to-talk
:tribute-to-talk :qr-scanner]
:qr-scanner]
config/hardwallet-enabled? config/hardwallet-enabled?
(concat [:hardwallet-authentication-method (concat [:hardwallet-authentication-method
:hardwallet-connect :hardwallet-connect
:hardwallet-setup :hardwallet-setup
:hardwallet-success :hardwallet-success
:keycard-settings :keycard-settings
:reset-card :reset-card
:enter-pin])) :enter-pin]))
:config {:initialRouteName :my-profile}} :config {:initialRouteName :my-profile}})
:profile-qr-viewer]
:config {:mode :modal
:initialRouteName :main-profile-stack}})

View File

@ -2,42 +2,24 @@
(def wallet-stack (def wallet-stack
{:name :wallet-stack {:name :wallet-stack
:screens [{:name :main-wallet-stack :screens [:wallet
:screens [:wallet :collectibles-list
:collectibles-list :wallet-onboarding-setup
:wallet-onboarding-setup :wallet-send-transaction-chat
:wallet-send-transaction-chat :contact-code
:contact-code {:name :send-transaction-stack
{:name :send-transaction-stack :screens [:wallet-send-transaction
:screens [:wallet-send-transaction :recent-recipients
:recent-recipients
:wallet-transaction-sent
:recipient-qr-code
:wallet-send-assets]}
{:name :request-transaction-stack
:screens [:wallet-request-transaction
:wallet-send-transaction-request
:wallet-request-assets
:recent-recipients]}
:unsigned-transactions
:transactions-history
:wallet-transaction-details
:wallet-settings-hook]
:config {:initialRouteName :wallet}}
:selection-modal-screen
{:name :wallet-send-modal-stack
:screens [:wallet-send-transaction-modal
:wallet-transaction-sent-modal
:wallet-transaction-fee]
:config {:initialRouteName :wallet-send-transaction-modal}}
{:name :wallet-send-modal-stack-with-onboarding
:screens [:wallet-onboarding-setup-modal
:wallet-send-transaction-modal
:wallet-transaction-sent :wallet-transaction-sent
:wallet-transaction-fee] :recipient-qr-code
:config {:initialRouteName :wallet-send-modal-stack-with-onboarding}} :wallet-send-assets]}
:wallet-settings-assets {:name :request-transaction-stack
:wallet-transaction-fee :screens [:wallet-request-transaction
:wallet-transactions-filter] :wallet-send-transaction-request
:config {:mode :modal :wallet-request-assets
:initialRouteName :main-wallet-stack}}) :recent-recipients]}
:unsigned-transactions
:transactions-history
:wallet-transaction-details
:wallet-settings-hook]
:config {:initialRouteName :wallet}})