feat: persistent send/receive action at bottom of asset list

When the account card is scrolled out of view a send/receive button group
appears at the bottom of the asset list; uses native animation to raise and
lower the button group into and out of view.

Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
This commit is contained in:
Michael Bradley, Jr 2020-04-28 09:21:44 -05:00 committed by Andrey Shovkoplyas
parent 6aba34b82d
commit 00501f44b9
No known key found for this signature in database
GPG Key ID: EAAB7C8622D860A4
4 changed files with 96 additions and 15 deletions

View File

@ -42,6 +42,7 @@
:ValueXY (fn []) :ValueXY (fn [])
:View {} :View {}
:FlatList {} :FlatList {}
:ScrollView {}
:Text {}} :Text {}}
:Easing {:bezier (fn []) :Easing {:bezier (fn [])
:poly (fn []) :poly (fn [])

View File

@ -68,9 +68,15 @@
(def animated-flat-list-class (def animated-flat-list-class
(reagent/adapt-react-class (.-FlatList ^js animated))) (reagent/adapt-react-class (.-FlatList ^js animated)))
(def animated-scroll-view-class
(reagent/adapt-react-class (.-ScrollView ^js animated)))
(defn animated-view [props & content] (defn animated-view [props & content]
(vec (conj content props animated-view-class))) (vec (conj content props animated-view-class)))
(defn animated-scroll-view [props & children]
(vec (conj children props animated-scroll-view-class)))
(def dimensions (.-Dimensions react-native)) (def dimensions (.-Dimensions react-native))
(def keyboard (.-Keyboard react-native)) (def keyboard (.-Keyboard react-native))
(def dismiss-keyboard! #(.dismiss ^js Keyboard)) (def dismiss-keyboard! #(.dismiss ^js Keyboard))

View File

@ -1,5 +1,6 @@
(ns status-im.ui.screens.wallet.account.styles (ns status-im.ui.screens.wallet.account.styles
(:require [status-im.ui.components.colors :as colors])) (:require [status-im.ui.components.colors :as colors]
[status-im.ui.components.animation :as animation]))
(defn card [window-width color] (defn card [window-width color]
{:width (- window-width 30) {:width (- window-width 30)
@ -24,4 +25,20 @@
:shadow-opacity 1 :shadow-opacity 1
:shadow-color (if (colors/dark?) :shadow-color (if (colors/dark?)
"rgba(0, 0, 0, 0.75)" "rgba(0, 0, 0, 0.75)"
"rgba(0, 9, 26, 0.12)")}) "rgba(0, 9, 26, 0.12)")})
(defn bottom-send-recv-buttons-raise [anim-y]
(animation/timing
anim-y
{:toValue 0
:duration 200
:easing (.-ease ^js (animation/easing))
:useNativeDriver true}))
(defn bottom-send-recv-buttons-lower [anim-y y]
(animation/timing
anim-y
{:toValue y
:duration 200
:easing (.-ease ^js (animation/easing))
:useNativeDriver true}))

View File

@ -15,7 +15,8 @@
[status-im.ui.components.list-item.views :as list-item] [status-im.ui.components.list-item.views :as list-item]
[status-im.utils.money :as money] [status-im.utils.money :as money]
[status-im.wallet.utils :as wallet.utils] [status-im.wallet.utils :as wallet.utils]
[status-im.ui.components.topbar :as topbar])) [status-im.ui.components.topbar :as topbar]
[status-im.ui.components.animation :as animation]))
(def state (reagent/atom {:tab :assets})) (def state (reagent/atom {:tab :assets}))
@ -28,12 +29,14 @@
{:content sheets/account-settings {:content sheets/account-settings
:content-height 60}])}]}]) :content-height 60}])}]}])
(defn button [label icon handler] (defn button [label icon color handler]
[react/touchable-highlight {:on-press handler :style {:flex 1}} [react/touchable-highlight {:on-press handler :style {:flex 1}}
[react/view {:flex 1 :align-items :center :justify-content :center} [react/view {:flex 1 :align-items :center :justify-content :center}
[react/view {:flex-direction :row :align-items :center} [react/view {:flex-direction :row :align-items :center}
[icons/icon icon {:color colors/white-persist}] [icons/icon icon {:color color}]
[react/text {:style {:margin-left 8 :color colors/white-persist}} label]]]]) [react/text {:style {:margin-left 8 :color color}} label]]]])
(def button-group-height 52)
(views/defview account-card [{:keys [address color type] :as account}] (views/defview account-card [{:keys [address color type] :as account}]
(views/letsubs [currency [:wallet/currency] (views/letsubs [currency [:wallet/currency]
@ -57,7 +60,7 @@
[react/touchable-highlight {:on-press #(re-frame/dispatch [:show-popover {:view :share-account :address address}])} [react/touchable-highlight {:on-press #(re-frame/dispatch [:show-popover {:view :share-account :address address}])}
[icons/icon :main-icons/share {:color colors/white-persist [icons/icon :main-icons/share {:color colors/white-persist
:accessibility-label :share-wallet-address-icon}]]] :accessibility-label :share-wallet-address-icon}]]]
[react/view {:height 52 :background-color colors/black-transparent-20 [react/view {:height button-group-height :background-color colors/black-transparent-20
:border-bottom-right-radius 8 :border-bottom-left-radius 8 :flex-direction :row} :border-bottom-right-radius 8 :border-bottom-left-radius 8 :flex-direction :row}
(if (= type :watch) (if (= type :watch)
[react/view {:flex 1 :align-items :center :justify-content :center} [react/view {:flex 1 :align-items :center :justify-content :center}
@ -66,11 +69,13 @@
[button [button
(i18n/label :t/wallet-send) (i18n/label :t/wallet-send)
:main-icons/send :main-icons/send
colors/white-persist
#(re-frame/dispatch [:wallet/prepare-transaction-from-wallet account])]) #(re-frame/dispatch [:wallet/prepare-transaction-from-wallet account])])
[react/view {:style (styles/divider)}] [react/view {:style (styles/divider)}]
[button [button
(i18n/label :t/receive) (i18n/label :t/receive)
:main-icons/receive :main-icons/receive
colors/white-persist
#(re-frame/dispatch [:show-popover {:view :share-account :address address}])]]])) #(re-frame/dispatch [:show-popover {:view :share-account :address address}])]]]))
(defn render-collectible [address] (defn render-collectible [address]
@ -119,13 +124,65 @@
(= tab :history) (= tab :history)
[transactions address])]))) [transactions address])])))
(views/defview bottom-send-recv-buttons [{:keys [address type] :as account} anim-y]
[react/animated-view {:style {:background-color colors/white
:bottom 0
:flex-direction :row
:height button-group-height
:position :absolute
:shadow-offset {:width 0 :height 1}
:shadow-opacity 0.75
:shadow-radius 1
:transform [{:translateY anim-y}]
:width "100%"}}
(if (= type :watch)
[react/view {:flex 1 :align-items :center :justify-content :center}
[react/text {:style {:margin-left 8 :color colors/blue-persist}}
(i18n/label :t/watch-only)]]
[button
(i18n/label :t/wallet-send)
:main-icons/send
colors/blue-persist
#(re-frame/dispatch [:wallet/prepare-transaction-from-wallet account])])
[button
(i18n/label :t/receive)
:main-icons/receive
colors/blue-persist
#(re-frame/dispatch [:show-popover {:view :share-account :address address}])]])
(defn anim-listener [anim-y scroll-y]
(let [to-show (atom false)]
(animation/add-listener
scroll-y
(fn [anim]
(let [y-trigger 149]
(cond
(and (>= (.-value anim) y-trigger) (not @to-show))
(animation/start
(styles/bottom-send-recv-buttons-raise anim-y)
#(reset! to-show true))
(and (< (.-value anim) y-trigger) @to-show)
(animation/start
(styles/bottom-send-recv-buttons-lower anim-y button-group-height)
#(reset! to-show false))))))))
(views/defview account [] (views/defview account []
(views/letsubs [{:keys [name address] :as account} [:multiaccount/current-account]] (views/letsubs [{:keys [name address] :as account} [:multiaccount/current-account]]
[react/view {:flex 1 :background-color colors/white} (let [anim-y (animation/create-value button-group-height)
[toolbar-view name] scroll-y (animation/create-value 0)]
[react/scroll-view (anim-listener anim-y scroll-y)
[react/view {:padding-left 16} [react/view {:flex 1 :background-color colors/white}
[react/scroll-view {:horizontal true} [toolbar-view name]
[react/view {:flex-direction :row :padding-top 8 :padding-bottom 12} [react/animated-scroll-view
[account-card account]]]] {:contentContainerStyle {:padding-bottom button-group-height}
[assets-and-collections address]]])) :on-scroll (animation/event
[{:nativeEvent {:contentOffset {:y scroll-y}}}]
{:useNativeDriver true})
:scrollEventThrottle 1}
[react/view {:padding-left 16}
[react/scroll-view {:horizontal true}
[react/view {:flex-direction :row :padding-top 8 :padding-bottom 12}
[account-card account]]]]
[assets-and-collections address]]
[bottom-send-recv-buttons account anim-y]])))