* Add network routing component & animations * Add basic tests and accessibility labels
This commit is contained in:
parent
c9b3196203
commit
1f71883fa4
|
@ -0,0 +1,115 @@
|
||||||
|
(ns quo.components.wallet.network-routing.animation
|
||||||
|
(:require [react-native.reanimated :as reanimated]))
|
||||||
|
|
||||||
|
(def ^:private slider-timing 300)
|
||||||
|
|
||||||
|
(defn show-slider
|
||||||
|
[opacity-shared-value]
|
||||||
|
(reanimated/animate opacity-shared-value 1 slider-timing))
|
||||||
|
|
||||||
|
(defn hide-slider
|
||||||
|
[opacity-shared-value]
|
||||||
|
(reanimated/animate opacity-shared-value 0 slider-timing))
|
||||||
|
|
||||||
|
(defn increase-slider
|
||||||
|
[width-shared-value height-shared-value]
|
||||||
|
(reanimated/animate width-shared-value 8 slider-timing)
|
||||||
|
(reanimated/animate height-shared-value 40 slider-timing))
|
||||||
|
|
||||||
|
(defn decrease-slider
|
||||||
|
[width-shared-value height-shared-value]
|
||||||
|
(reanimated/animate width-shared-value 4 slider-timing)
|
||||||
|
(reanimated/animate height-shared-value 32 slider-timing))
|
||||||
|
|
||||||
|
(def ^:private pressed-bar-timing 600)
|
||||||
|
|
||||||
|
(defn move-previous-bars
|
||||||
|
[{:keys [bars bars-widths-negative]}]
|
||||||
|
(doseq [[bar-idx bar] (map-indexed vector bars)
|
||||||
|
:let [new-translation-x (->> (take (inc bar-idx) bars-widths-negative)
|
||||||
|
(reduce +)
|
||||||
|
(dec))]]
|
||||||
|
(reanimated/animate (:translate-x-shared-value bar)
|
||||||
|
new-translation-x
|
||||||
|
pressed-bar-timing)))
|
||||||
|
|
||||||
|
(defn move-pressed-bar
|
||||||
|
[{:keys [bars-widths-negative number-previous-bars]
|
||||||
|
{:keys [translate-x-shared-value]} :bar}]
|
||||||
|
(let [new-translation-x (reduce + (take number-previous-bars bars-widths-negative))]
|
||||||
|
(reanimated/animate translate-x-shared-value
|
||||||
|
new-translation-x
|
||||||
|
(- pressed-bar-timing 20))))
|
||||||
|
|
||||||
|
(defn move-next-bars
|
||||||
|
[{:keys [bars bars-widths-negative number-previous-bars extra-offset add-new-timeout]}]
|
||||||
|
(doseq [[bar-idx bar] (map-indexed vector bars)
|
||||||
|
:let [number-bars-before (+ number-previous-bars
|
||||||
|
(inc bar-idx))
|
||||||
|
new-translation-x (->> (take number-bars-before bars-widths-negative)
|
||||||
|
(reduce +)
|
||||||
|
(* 1.05))]]
|
||||||
|
(reanimated/animate (:translate-x-shared-value bar) new-translation-x pressed-bar-timing)
|
||||||
|
(add-new-timeout
|
||||||
|
(keyword (str "fix-next-bars-position-" bar-idx))
|
||||||
|
(fn []
|
||||||
|
(let [translate-x-value (reanimated/get-shared-value (:translate-x-shared-value bar))
|
||||||
|
hidden-position (- translate-x-value extra-offset)]
|
||||||
|
(reanimated/set-shared-value (:translate-x-shared-value bar) hidden-position)))
|
||||||
|
pressed-bar-timing)))
|
||||||
|
|
||||||
|
(def ^:private max-limit-bar-timing 300)
|
||||||
|
|
||||||
|
(defn show-max-limit-bar
|
||||||
|
[max-limit-bar-opacity]
|
||||||
|
(reanimated/animate max-limit-bar-opacity 1 max-limit-bar-timing))
|
||||||
|
|
||||||
|
(defn hide-max-limit-bar
|
||||||
|
[max-limit-bar-opacity]
|
||||||
|
(reanimated/animate max-limit-bar-opacity 0 max-limit-bar-timing))
|
||||||
|
|
||||||
|
(defn reset-bars-positions
|
||||||
|
[bars unlock-press-fn add-new-timeout]
|
||||||
|
(let [bars-reset-timing 500]
|
||||||
|
(doseq [{:keys [translate-x-shared-value]} bars]
|
||||||
|
(reanimated/animate translate-x-shared-value 0 bars-reset-timing))
|
||||||
|
(add-new-timeout :unlock-press unlock-press-fn bars-reset-timing)))
|
||||||
|
|
||||||
|
(defn align-bars-off-screen
|
||||||
|
[{:keys [new-network-values network-bars amount->width add-new-timeout]}]
|
||||||
|
(let [width-to-off-screen (->> new-network-values
|
||||||
|
(reduce #(- %1 (:amount %2)) 0)
|
||||||
|
(amount->width))]
|
||||||
|
(doseq [[bar-idx {new-amount :amount} bar] (map vector (range) new-network-values network-bars)]
|
||||||
|
(reanimated/set-shared-value (:amount-shared-value bar) new-amount)
|
||||||
|
(reanimated/set-shared-value (:translate-x-shared-value bar) (* 2 width-to-off-screen))
|
||||||
|
(add-new-timeout
|
||||||
|
(keyword (str "align-bar-" bar-idx))
|
||||||
|
#(reanimated/set-shared-value (:translate-x-shared-value bar) width-to-off-screen)
|
||||||
|
1))))
|
||||||
|
|
||||||
|
(def ^:private hide-bar-timing 400)
|
||||||
|
|
||||||
|
(defn hide-pressed-bar
|
||||||
|
[{:keys [translate-x-shared-value amount-shared-value]} amount->width]
|
||||||
|
(let [bar-width (amount->width (reanimated/get-shared-value amount-shared-value))
|
||||||
|
new-translation-x (- (reanimated/get-shared-value translate-x-shared-value)
|
||||||
|
bar-width)]
|
||||||
|
(reanimated/animate translate-x-shared-value new-translation-x hide-bar-timing)))
|
||||||
|
|
||||||
|
(defn update-bar-values-and-reset-animations
|
||||||
|
[{:keys [new-network-values network-bars amount->width reset-values-fn add-new-timeout
|
||||||
|
lock-press-fn unlock-press-fn]}]
|
||||||
|
(lock-press-fn)
|
||||||
|
(add-new-timeout
|
||||||
|
:update-bars-values
|
||||||
|
(fn []
|
||||||
|
(align-bars-off-screen {:new-network-values new-network-values
|
||||||
|
:network-bars network-bars
|
||||||
|
:amount->width amount->width
|
||||||
|
:add-new-timeout add-new-timeout})
|
||||||
|
(reset-values-fn)
|
||||||
|
(add-new-timeout :reset-bars
|
||||||
|
#(reset-bars-positions network-bars unlock-press-fn add-new-timeout)
|
||||||
|
100))
|
||||||
|
hide-bar-timing))
|
|
@ -0,0 +1,79 @@
|
||||||
|
(ns quo.components.wallet.network-routing.style
|
||||||
|
(:require [quo.foundations.colors :as colors]
|
||||||
|
[react-native.reanimated :as reanimated]))
|
||||||
|
|
||||||
|
(defn container
|
||||||
|
[container-style theme]
|
||||||
|
(assoc container-style
|
||||||
|
:flex-direction :row
|
||||||
|
:height 64
|
||||||
|
:background-color (colors/theme-colors colors/neutral-100-opa-5 colors/neutral-90 theme)
|
||||||
|
:border-radius 20
|
||||||
|
:overflow :hidden))
|
||||||
|
|
||||||
|
(defn max-limit-bar
|
||||||
|
[{:keys [opacity-shared-value width]}]
|
||||||
|
(reanimated/apply-animations-to-style
|
||||||
|
{:opacity opacity-shared-value}
|
||||||
|
{:position :absolute
|
||||||
|
:top 0
|
||||||
|
:bottom 0
|
||||||
|
:left 0
|
||||||
|
:width width
|
||||||
|
:z-index -1
|
||||||
|
:flex-direction :row}))
|
||||||
|
|
||||||
|
(defn max-limit-bar-background
|
||||||
|
[network-name]
|
||||||
|
{:flex 1
|
||||||
|
:background-color (colors/resolve-color network-name nil 10)})
|
||||||
|
|
||||||
|
(defn network-bar
|
||||||
|
[{:keys [max-width on-top? bar-division? theme]
|
||||||
|
{:keys [network-name translate-x-shared-value]} :bar}
|
||||||
|
width-shared-value]
|
||||||
|
(reanimated/apply-animations-to-style
|
||||||
|
{:width width-shared-value
|
||||||
|
:transform [{:translate-x translate-x-shared-value}]}
|
||||||
|
{:max-width max-width
|
||||||
|
:flex-direction :row
|
||||||
|
:justify-content :flex-end
|
||||||
|
:background-color (colors/resolve-color network-name nil)
|
||||||
|
:z-index (if on-top? 1 0)
|
||||||
|
:border-right-width (if bar-division? 0 1)
|
||||||
|
:border-color (colors/theme-colors colors/white colors/neutral-95 theme)}))
|
||||||
|
|
||||||
|
(def slider-container
|
||||||
|
{:width 40
|
||||||
|
:background-color :transparent
|
||||||
|
:justify-content :center
|
||||||
|
:align-items :center
|
||||||
|
:right -20})
|
||||||
|
|
||||||
|
(def ^:private slider-fixed-styles
|
||||||
|
{:background-color colors/white
|
||||||
|
:height 32
|
||||||
|
:width 4
|
||||||
|
:border-radius 4})
|
||||||
|
|
||||||
|
(defn slider
|
||||||
|
[{:keys [width-shared-value height-shared-value opacity-shared-value]}]
|
||||||
|
(reanimated/apply-animations-to-style
|
||||||
|
{:width width-shared-value
|
||||||
|
:height height-shared-value
|
||||||
|
:opacity opacity-shared-value}
|
||||||
|
slider-fixed-styles))
|
||||||
|
|
||||||
|
(def dashed-line
|
||||||
|
{:width 1
|
||||||
|
:height "100%"
|
||||||
|
:margin-left -1
|
||||||
|
:margin-top -1.5})
|
||||||
|
|
||||||
|
(defn dashed-line-line
|
||||||
|
[network-name]
|
||||||
|
{:background-color (colors/resolve-color network-name nil)
|
||||||
|
:height 3
|
||||||
|
:width 1})
|
||||||
|
|
||||||
|
(def dashed-line-space {:height 4 :width 1})
|
|
@ -0,0 +1,189 @@
|
||||||
|
(ns quo.components.wallet.network-routing.view
|
||||||
|
(:require
|
||||||
|
[oops.core :as oops]
|
||||||
|
[quo.components.wallet.network-routing.animation :as animation]
|
||||||
|
[quo.components.wallet.network-routing.style :as style]
|
||||||
|
[quo.theme :as quo.theme]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[react-native.gesture :as gesture]
|
||||||
|
[react-native.reanimated :as reanimated]
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[utils.number]))
|
||||||
|
|
||||||
|
(def ^:private timeouts (atom {}))
|
||||||
|
|
||||||
|
(defn- add-new-timeout
|
||||||
|
[k f ms]
|
||||||
|
(letfn [(exec-fn-and-remove-timeout []
|
||||||
|
(f)
|
||||||
|
(swap! timeouts dissoc k))]
|
||||||
|
(js/clearTimeout (k @timeouts))
|
||||||
|
(swap! timeouts assoc k (js/setTimeout exec-fn-and-remove-timeout ms))))
|
||||||
|
|
||||||
|
(defn- f-slider
|
||||||
|
[slider-shared-values]
|
||||||
|
[rn/view {:style style/slider-container}
|
||||||
|
[reanimated/view {:style (style/slider slider-shared-values)}]])
|
||||||
|
|
||||||
|
(defn f-network-bar
|
||||||
|
[_]
|
||||||
|
(let [detecting-gesture? (reagent/atom false)
|
||||||
|
amount-on-gesture-start (atom 0)]
|
||||||
|
(fn [{:keys [total-width total-amount on-press on-new-amount allow-press?]
|
||||||
|
{:keys [amount-shared-value
|
||||||
|
max-amount]} :bar
|
||||||
|
:as props}]
|
||||||
|
(let [slider-width-shared-value (reanimated/use-shared-value 4)
|
||||||
|
slider-height-shared-value (reanimated/use-shared-value 32)
|
||||||
|
slider-opacity-shared-value (reanimated/use-shared-value 0)
|
||||||
|
network-bar-shared-value (reanimated/interpolate amount-shared-value
|
||||||
|
[0 total-amount]
|
||||||
|
[0 total-width])
|
||||||
|
width->amount #(/ (* % total-amount) total-width)]
|
||||||
|
[rn/touchable-without-feedback
|
||||||
|
{:on-press (fn []
|
||||||
|
(when (and (not @detecting-gesture?) allow-press?)
|
||||||
|
(on-press)
|
||||||
|
(reset! detecting-gesture? true)
|
||||||
|
(animation/show-slider slider-opacity-shared-value)))}
|
||||||
|
[reanimated/view
|
||||||
|
{:style (style/network-bar props network-bar-shared-value)
|
||||||
|
:accessibility-label :network-routing-bar}
|
||||||
|
[gesture/gesture-detector
|
||||||
|
{:gesture
|
||||||
|
(-> (gesture/gesture-pan)
|
||||||
|
(gesture/enabled @detecting-gesture?)
|
||||||
|
(gesture/on-begin
|
||||||
|
(fn [_]
|
||||||
|
(animation/increase-slider slider-width-shared-value slider-height-shared-value)
|
||||||
|
(reset! amount-on-gesture-start (reanimated/get-shared-value amount-shared-value))))
|
||||||
|
(gesture/on-update
|
||||||
|
(fn [event]
|
||||||
|
(let [new-amount (-> (oops/oget event "translationX")
|
||||||
|
(width->amount)
|
||||||
|
(+ @amount-on-gesture-start)
|
||||||
|
(utils.number/value-in-range 1 max-amount))]
|
||||||
|
(reanimated/set-shared-value amount-shared-value new-amount))))
|
||||||
|
(gesture/on-finalize
|
||||||
|
(fn [_]
|
||||||
|
(animation/decrease-slider slider-width-shared-value slider-height-shared-value)
|
||||||
|
(animation/hide-slider slider-opacity-shared-value)
|
||||||
|
(on-new-amount (reanimated/get-shared-value amount-shared-value))
|
||||||
|
(add-new-timeout :turn-off-gesture #(reset! detecting-gesture? false) 20))))}
|
||||||
|
[:f> f-slider
|
||||||
|
{:width-shared-value slider-width-shared-value
|
||||||
|
:height-shared-value slider-height-shared-value
|
||||||
|
:opacity-shared-value slider-opacity-shared-value}]]]]))))
|
||||||
|
|
||||||
|
(defn- add-bar-shared-values
|
||||||
|
[{:keys [amount] :as network}]
|
||||||
|
(assoc network
|
||||||
|
:amount-shared-value (reanimated/use-shared-value amount)
|
||||||
|
:translate-x-shared-value (reanimated/use-shared-value 0)))
|
||||||
|
|
||||||
|
(def ^:private get-negative-amount
|
||||||
|
(comp - reanimated/get-shared-value :amount-shared-value))
|
||||||
|
|
||||||
|
(defn- dashed-line
|
||||||
|
[network-name]
|
||||||
|
[rn/view {:style style/dashed-line}
|
||||||
|
(take 19
|
||||||
|
(interleave (repeat [rn/view {:style (style/dashed-line-line network-name)}])
|
||||||
|
(repeat [rn/view {:style style/dashed-line-space}])))])
|
||||||
|
|
||||||
|
(defn f-network-routing-bars
|
||||||
|
[_]
|
||||||
|
(let [selected-network-idx (reagent/atom nil)
|
||||||
|
press-locked? (reagent/atom false)
|
||||||
|
lock-press #(reset! press-locked? true)
|
||||||
|
unlock-press #(reset! press-locked? false)
|
||||||
|
reset-state-values #(reset! selected-network-idx nil)]
|
||||||
|
(fn [{:keys [networks total-width total-amount requesting-data? on-amount-selected]}]
|
||||||
|
(let [bar-opacity-shared-value (reanimated/use-shared-value 0)
|
||||||
|
network-bars (map add-bar-shared-values networks)
|
||||||
|
amount->width #(* % (/ total-width total-amount))
|
||||||
|
bars-widths-negative (map #(-> % get-negative-amount amount->width)
|
||||||
|
network-bars)
|
||||||
|
last-bar-idx (dec (count network-bars))]
|
||||||
|
(rn/use-effect
|
||||||
|
#(when (and (not requesting-data?) @selected-network-idx)
|
||||||
|
(let [bar (nth network-bars @selected-network-idx)]
|
||||||
|
(animation/hide-pressed-bar bar amount->width))
|
||||||
|
(animation/update-bar-values-and-reset-animations
|
||||||
|
{:new-network-values networks
|
||||||
|
:network-bars network-bars
|
||||||
|
:amount->width amount->width
|
||||||
|
:reset-values-fn reset-state-values
|
||||||
|
:lock-press-fn lock-press
|
||||||
|
:unlock-press-fn unlock-press
|
||||||
|
:add-new-timeout add-new-timeout}))
|
||||||
|
[requesting-data?])
|
||||||
|
[:<>
|
||||||
|
(doall
|
||||||
|
(for [[bar-idx bar] (map-indexed vector network-bars)
|
||||||
|
:let [bar-max-width (amount->width (:max-amount bar))
|
||||||
|
bar-width (-> (:amount-shared-value bar)
|
||||||
|
(reanimated/get-shared-value)
|
||||||
|
(amount->width))
|
||||||
|
hide-division? (or (= last-bar-idx bar-idx) @selected-network-idx)
|
||||||
|
this-bar-selected? (= @selected-network-idx bar-idx)]]
|
||||||
|
^{:key (str "network-bar-" bar-idx)}
|
||||||
|
[:f> f-network-bar
|
||||||
|
{:bar bar
|
||||||
|
:max-width bar-max-width
|
||||||
|
:total-width total-width
|
||||||
|
:total-amount total-amount
|
||||||
|
:bar-division? hide-division?
|
||||||
|
:on-top? this-bar-selected?
|
||||||
|
:allow-press? (and (or (not @selected-network-idx) this-bar-selected?)
|
||||||
|
(not requesting-data?)
|
||||||
|
(not @press-locked?))
|
||||||
|
:on-press (fn []
|
||||||
|
(when-not @selected-network-idx
|
||||||
|
(let [[previous-bars [_ & next-bars]] (split-at bar-idx network-bars)
|
||||||
|
number-previous-bars bar-idx]
|
||||||
|
(animation/move-previous-bars
|
||||||
|
{:bars previous-bars
|
||||||
|
:bars-widths-negative bars-widths-negative})
|
||||||
|
(animation/move-pressed-bar
|
||||||
|
{:bar bar
|
||||||
|
:bars-widths-negative bars-widths-negative
|
||||||
|
:number-previous-bars number-previous-bars})
|
||||||
|
(animation/move-next-bars
|
||||||
|
{:bars next-bars
|
||||||
|
:bars-widths-negative bars-widths-negative
|
||||||
|
:number-previous-bars (inc number-previous-bars)
|
||||||
|
:extra-offset (max 0 (- bar-max-width bar-width))
|
||||||
|
:add-new-timeout add-new-timeout}))
|
||||||
|
(animation/show-max-limit-bar bar-opacity-shared-value)
|
||||||
|
(reset! selected-network-idx bar-idx)))
|
||||||
|
:on-new-amount (fn [new-amount]
|
||||||
|
(animation/hide-max-limit-bar bar-opacity-shared-value)
|
||||||
|
(when on-amount-selected
|
||||||
|
(on-amount-selected new-amount @selected-network-idx)))}]))
|
||||||
|
|
||||||
|
(let [{:keys [max-amount network-name]} (some->> @selected-network-idx
|
||||||
|
(nth network-bars))
|
||||||
|
limit-bar-width (amount->width max-amount)]
|
||||||
|
[reanimated/view
|
||||||
|
{:style (style/max-limit-bar
|
||||||
|
{:opacity-shared-value bar-opacity-shared-value
|
||||||
|
:width limit-bar-width})}
|
||||||
|
[rn/view {:style (style/max-limit-bar-background network-name)}]
|
||||||
|
[dashed-line network-name]])]))))
|
||||||
|
|
||||||
|
(defn view-internal
|
||||||
|
[{:keys [networks container-style theme] :as params}]
|
||||||
|
(reagent/with-let [total-width (reagent/atom nil)]
|
||||||
|
[rn/view
|
||||||
|
{:accessibility-label :network-routing
|
||||||
|
:style (style/container container-style theme)
|
||||||
|
:on-layout #(reset! total-width (oops/oget % "nativeEvent.layout.width"))}
|
||||||
|
(when @total-width
|
||||||
|
^{:key (str "network-routing-" (count networks))}
|
||||||
|
[:f> f-network-routing-bars (assoc params :total-width @total-width)])]
|
||||||
|
(finally
|
||||||
|
(doseq [[_ living-timeout] @timeouts]
|
||||||
|
(js/clearTimeout living-timeout)))))
|
||||||
|
|
||||||
|
(def view (quo.theme/with-theme view-internal))
|
|
@ -141,6 +141,7 @@
|
||||||
quo.components.wallet.network-amount.view
|
quo.components.wallet.network-amount.view
|
||||||
quo.components.wallet.network-bridge.view
|
quo.components.wallet.network-bridge.view
|
||||||
quo.components.wallet.network-link.view
|
quo.components.wallet.network-link.view
|
||||||
|
quo.components.wallet.network-routing.view
|
||||||
quo.components.wallet.progress-bar.view
|
quo.components.wallet.progress-bar.view
|
||||||
quo.components.wallet.summary-info.view
|
quo.components.wallet.summary-info.view
|
||||||
quo.components.wallet.token-input.view
|
quo.components.wallet.token-input.view
|
||||||
|
@ -373,6 +374,7 @@
|
||||||
(def keypair quo.components.wallet.keypair.view/view)
|
(def keypair quo.components.wallet.keypair.view/view)
|
||||||
(def network-amount quo.components.wallet.network-amount.view/view)
|
(def network-amount quo.components.wallet.network-amount.view/view)
|
||||||
(def network-bridge quo.components.wallet.network-bridge.view/view)
|
(def network-bridge quo.components.wallet.network-bridge.view/view)
|
||||||
|
(def network-routing quo.components.wallet.network-routing.view/view)
|
||||||
(def progress-bar quo.components.wallet.progress-bar.view/view)
|
(def progress-bar quo.components.wallet.progress-bar.view/view)
|
||||||
(def summary-info quo.components.wallet.summary-info.view/view)
|
(def summary-info quo.components.wallet.summary-info.view/view)
|
||||||
(def network-link quo.components.wallet.network-link.view/view)
|
(def network-link quo.components.wallet.network-link.view/view)
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
(ns quo2.components.wallet.network-routing.component-spec
|
||||||
|
(:require [oops.core :as oops]
|
||||||
|
[quo2.components.wallet.network-routing.view :as network-routing]
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[test-helpers.component :as h]))
|
||||||
|
|
||||||
|
(h/describe "Network-routing tests"
|
||||||
|
(let [network {:amount 250 :max-amount 300 :network-name :unknown}
|
||||||
|
default-props {:networks [network network network]
|
||||||
|
:total-amount 500
|
||||||
|
:requesting-data? false
|
||||||
|
:on-amount-selected (fn [_new-amount _network-idx] nil)}]
|
||||||
|
(h/test "Renders Default"
|
||||||
|
(h/render [network-routing/view default-props])
|
||||||
|
(h/is-truthy (h/get-by-label-text :network-routing)))
|
||||||
|
|
||||||
|
(h/test "Renders bars inside"
|
||||||
|
(let [component (h/render [network-routing/view default-props])
|
||||||
|
rerender-fn #((oops/oget component "rerender") (reagent/as-element %))
|
||||||
|
component (h/get-by-label-text :network-routing)]
|
||||||
|
;; Fires on-layout callback since the total width is required
|
||||||
|
(h/fire-event :layout component #js {:nativeEvent #js {:layout #js {:width 1000}}})
|
||||||
|
;; Update props to trigger rerender, otherwise it won't be updated
|
||||||
|
(rerender-fn [network-routing/view (assoc default-props :requesting-data? true)])
|
||||||
|
;; Check number of networks rendered
|
||||||
|
(->> (js->clj (h/query-all-by-label-text :network-routing-bar))
|
||||||
|
(count)
|
||||||
|
(h/is-equal 3))))))
|
|
@ -166,6 +166,7 @@
|
||||||
[status-im2.contexts.quo-preview.wallet.network-amount :as network-amount]
|
[status-im2.contexts.quo-preview.wallet.network-amount :as network-amount]
|
||||||
[status-im2.contexts.quo-preview.wallet.network-bridge :as network-bridge]
|
[status-im2.contexts.quo-preview.wallet.network-bridge :as network-bridge]
|
||||||
[status-im2.contexts.quo-preview.wallet.network-link :as network-link]
|
[status-im2.contexts.quo-preview.wallet.network-link :as network-link]
|
||||||
|
[status-im2.contexts.quo-preview.wallet.network-routing :as network-routing]
|
||||||
[status-im2.contexts.quo-preview.wallet.progress-bar :as progress-bar]
|
[status-im2.contexts.quo-preview.wallet.progress-bar :as progress-bar]
|
||||||
[status-im2.contexts.quo-preview.wallet.summary-info :as summary-info]
|
[status-im2.contexts.quo-preview.wallet.summary-info :as summary-info]
|
||||||
[status-im2.contexts.quo-preview.wallet.token-input :as token-input]
|
[status-im2.contexts.quo-preview.wallet.token-input :as token-input]
|
||||||
|
@ -447,6 +448,7 @@
|
||||||
{:name :network-amount :component network-amount/preview}
|
{:name :network-amount :component network-amount/preview}
|
||||||
{:name :network-bridge :component network-bridge/preview}
|
{:name :network-bridge :component network-bridge/preview}
|
||||||
{:name :network-link :component network-link/preview}
|
{:name :network-link :component network-link/preview}
|
||||||
|
{:name :network-routing :component network-routing/preview}
|
||||||
{:name :progress-bar :component progress-bar/preview}
|
{:name :progress-bar :component progress-bar/preview}
|
||||||
{:name :summary-info :component summary-info/preview}
|
{:name :summary-info :component summary-info/preview}
|
||||||
{:name :token-input :component token-input/preview}
|
{:name :token-input :component token-input/preview}
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
(ns status-im2.contexts.quo-preview.wallet.network-routing
|
||||||
|
(:require [quo.core :as quo]
|
||||||
|
[quo.foundations.colors :as colors]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||||
|
|
||||||
|
(def descriptor
|
||||||
|
[{:label "Number of networks"
|
||||||
|
:key :number-networks
|
||||||
|
:type :select
|
||||||
|
:options [{:key 2} {:key 3} {:key 4} {:key 5}]}])
|
||||||
|
|
||||||
|
(defn- fake-call-to-get-amounts
|
||||||
|
[{:keys [new-amount fixed-index current-values on-success]}]
|
||||||
|
(let [number-networks (count current-values)
|
||||||
|
amount-difference (- (get current-values fixed-index) new-amount)
|
||||||
|
difference-distributed (/ amount-difference (dec number-networks))
|
||||||
|
new-values (assoc (mapv #(+ % difference-distributed) current-values)
|
||||||
|
fixed-index
|
||||||
|
new-amount)]
|
||||||
|
(js/setTimeout #(on-success new-values) (rand-nth (range 700 5000 250)))))
|
||||||
|
|
||||||
|
(defn preview-internal
|
||||||
|
[{:keys [total-amount number-networks] :as descriptor-state}]
|
||||||
|
(let [initial-amount (/ total-amount number-networks)
|
||||||
|
networks (reagent/atom
|
||||||
|
[{:amount initial-amount
|
||||||
|
:max-amount (descriptor-state :max-amount-0)
|
||||||
|
:network-name :ethereum}
|
||||||
|
{:amount initial-amount
|
||||||
|
:max-amount (descriptor-state :max-amount-1)
|
||||||
|
:network-name :arbitrum}
|
||||||
|
{:amount initial-amount
|
||||||
|
:max-amount (descriptor-state :max-amount-2)
|
||||||
|
:network-name :xDai}
|
||||||
|
{:amount initial-amount
|
||||||
|
:max-amount (descriptor-state :max-amount-3)
|
||||||
|
:network-name :optimism}
|
||||||
|
{:amount initial-amount
|
||||||
|
:max-amount (descriptor-state :max-amount-4)
|
||||||
|
:network-name :polygon}])
|
||||||
|
requesting-data? (reagent/atom false)]
|
||||||
|
(fn [_]
|
||||||
|
(let [asked-networks (vec (take number-networks @networks))
|
||||||
|
on-success-fn (fn [new-network-amounts]
|
||||||
|
(reset! requesting-data? false)
|
||||||
|
(swap! networks
|
||||||
|
#(map (fn [network new-amount]
|
||||||
|
(assoc network :amount new-amount))
|
||||||
|
%
|
||||||
|
new-network-amounts)))]
|
||||||
|
[rn/view
|
||||||
|
[quo/network-routing
|
||||||
|
{:total-amount total-amount
|
||||||
|
:networks asked-networks
|
||||||
|
:requesting-data? @requesting-data?
|
||||||
|
:on-amount-selected (fn [new-amount selected-idx]
|
||||||
|
(reset! requesting-data? true)
|
||||||
|
(fake-call-to-get-amounts
|
||||||
|
{:new-amount new-amount
|
||||||
|
:fixed-index selected-idx
|
||||||
|
:current-values (mapv :amount asked-networks)
|
||||||
|
:on-success on-success-fn}))}]
|
||||||
|
(reduce (fn [acc {:keys [amount max-amount network-name]}]
|
||||||
|
(conj acc
|
||||||
|
[rn/view
|
||||||
|
{:style {:flex-direction :row
|
||||||
|
:margin-vertical 12}}
|
||||||
|
[rn/view
|
||||||
|
{:style {:background-color (colors/custom-color network-name)
|
||||||
|
:width 24
|
||||||
|
:height 24
|
||||||
|
:margin-right 12}}]
|
||||||
|
[quo/text
|
||||||
|
"Max limit: " max-amount " Amount: " (subs (str amount) 0 6)]]))
|
||||||
|
[rn/view {:style {:margin-vertical 12}}
|
||||||
|
[quo/text "Total amount: " (reduce + (map :amount asked-networks))]]
|
||||||
|
asked-networks)]))))
|
||||||
|
|
||||||
|
(defn preview
|
||||||
|
[]
|
||||||
|
(let [descriptor-state (reagent/atom {:total-amount 400
|
||||||
|
:number-networks 4
|
||||||
|
:max-amount-0 350
|
||||||
|
:max-amount-1 350
|
||||||
|
:max-amount-2 300
|
||||||
|
:max-amount-3 250
|
||||||
|
:max-amount-4 200})]
|
||||||
|
(fn []
|
||||||
|
[preview/preview-container {:state descriptor-state :descriptor descriptor}
|
||||||
|
[rn/view {:style {:flex 1 :margin-vertical 28}}
|
||||||
|
^{:key (str "preview-network-routing-" (:number-networks @descriptor-state))}
|
||||||
|
[preview-internal @descriptor-state]]])))
|
Loading…
Reference in New Issue