From aaf0b8e4236a90d944744203e5519975ae0b36a1 Mon Sep 17 00:00:00 2001 From: mmilad75 <55688834+mmilad75@users.noreply.github.com> Date: Wed, 6 Dec 2023 14:09:52 +0330 Subject: [PATCH] Implement transaction progress component (#17933) * copy codes * refactor preview * refactor deprecated codes in view * change condition structure in view-internal * comment unused codes * refactor title * fix title style * fix icon style * fix context tag * fix icon and row * refactor icon-internal * rename network-state and network-type * fix progress-container style * fix progress-box-container style * fix progress container naming and style * change progress-bar component * fix progress box component * convert to functional component and bring back the animation * fix progress box for arbitrum-optimism network * fix text-steps * fix status-row * refactor code style * refactor get-network-text * resolve comment * add translations * remove btn-title prop * fix dark mode border color * fix dark mode icon color * move interval to preview * add tests ns * add tests * fix lint issues * fix rendering issue * fix lint issue * add arbitrum and optimism as separate networks * create const for progress percentage * fix progress bar component and preview * refactor text-steps * refactor names * fix lint issues * rename arbitrum-progress-percentage and optimism-progress-percentage * update tests * convert hard-coded color to customization-color * fix progress_bar tests * separate state for each network * add progress percentage for each network and refactor params of functions * separate epoch number for each network * update tests * fix lint issues * refactor codes * fix lint issues * resolve comments * add confirmation progress * use confirmation-progress component in transaction-progress * fix preview * add tests * fix lint issue * resolve comment * refactor networks * change sending state style * update tests * fix lint issues * remove unused code * add helper for calculate counter step * add assoc-props to view-networks * change text-internal props order * fix colors/resolve-color usage * refactor view codes * add get-networks to preview * add max-value to progress bar style * remove threading macros in the previews * remove inline functional components in the previews * remove optimism-arbitrum checks in the view * fix lint issues * add max-progress and min-progress to confirmation-progress * refactor text-steps * fix counter structure in transaction-progress * fix counter structure in confirmation-progress * fix resolve-color usage * fix lint issue * fix tests * resolve comments * fix color issue * fix margins * fix lint issue --- resources/images/icons2/16x16/diamond@2x.png | Bin 0 -> 851 bytes resources/images/icons2/16x16/diamond@3x.png | Bin 0 -> 1173 bytes .../confirmation_progress/component_spec.cljs | 99 +++++++++ .../wallet/confirmation_progress/style.cljs | 9 + .../wallet/confirmation_progress/view.cljs | 69 ++++++ .../wallet/progress_bar/component_spec.cljs | 12 +- .../components/wallet/progress_bar/style.cljs | 43 ++-- .../components/wallet/progress_bar/view.cljs | 6 +- .../transaction_progress/component_spec.cljs | 200 ++++++++++++++++++ .../wallet/transaction_progress/style.cljs | 38 ++++ .../wallet/transaction_progress/view.cljs | 187 ++++++++++++++++ src/quo/core.cljs | 4 + src/quo/core_spec.cljs | 2 + src/status_im2/contexts/quo_preview/main.cljs | 5 + .../wallet/confirmation_progress.cljs | 85 ++++++++ .../quo_preview/wallet/progress_bar.cljs | 10 +- .../wallet/transaction_progress.cljs | 155 ++++++++++++++ translations/en.json | 7 + 18 files changed, 909 insertions(+), 22 deletions(-) create mode 100644 resources/images/icons2/16x16/diamond@2x.png create mode 100644 resources/images/icons2/16x16/diamond@3x.png create mode 100644 src/quo/components/wallet/confirmation_progress/component_spec.cljs create mode 100644 src/quo/components/wallet/confirmation_progress/style.cljs create mode 100644 src/quo/components/wallet/confirmation_progress/view.cljs create mode 100644 src/quo/components/wallet/transaction_progress/component_spec.cljs create mode 100644 src/quo/components/wallet/transaction_progress/style.cljs create mode 100644 src/quo/components/wallet/transaction_progress/view.cljs create mode 100644 src/status_im2/contexts/quo_preview/wallet/confirmation_progress.cljs create mode 100644 src/status_im2/contexts/quo_preview/wallet/transaction_progress.cljs diff --git a/resources/images/icons2/16x16/diamond@2x.png b/resources/images/icons2/16x16/diamond@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d1968f43ead92c6231dbf14c6e5cfe2792733217 GIT binary patch literal 851 zcmV-Z1FZasP)c+G4KzBwMC+=O{G$h03}R} z2~rE4zzaxh5hVng_>OytZ7#9TzO-S2Pl|lLU*GrMz4vkk_}4*(nLNAHN^{P$;+H0b zo1BwmcN4-J0JJWebwbGI&Q`ptyQh|bnT78K4rEz0P0)iyfUoRsPpw5w3>7e!YncZJ zYy+EcI9TK3G*d6fE!7078b~d+ZnfKX?Fi%uG@y3&YBQ&r5a^_S> z_Vo{Tpxe=MH^4@ShB%H3gU8`J0^zdCUm!;$op=JJ0E~9fkMzS}&f)M7lV6-vQ{v9` zF}QtgENlvt*4yytX;FbMjf3KbktPp4NN`R z`h8(h`Bev0z%keAh*(Ja1%x2sY=lqD1Ql>hCQVF1B>o5>&Mm3Ps?7!rDze2(i#` zR2CLoA`m;4LK1Df1j5HHx8r+vtnTdX$IR{?Q1DCOZue$p|Nl2{XJ%&sjyNI_3{t=- z^4{IuZG&?@z&YdqxWO3j<(&04FT!{YznhFP{N(eRrd1Yax+{=q#qLYX#ZfkTPK0-7qW$bE)2S(kG?&ympUtOh``yq;5U2w_JCzIrs0r56Q|$#wjQ`x+%R~ZEr0@}k94?oBcoCU zzI<)K2r=Y;OGYlRKbb%^V=lw?ue*WUpb!@v)#E**mTw4lZb45_# z@x3g>MZGS2XcYel^N|p`Oa1G4+Xm?gi=tn=Ek-{oqEyF$>c0M<)C;(5KW>1l7lf@AySuCKad*l?`hvf~)QW!2p+>dE-VusH|cy2tgKmfXm&$-iUqs-cTA2sVvnA zYcqrp1Cm_7B38S0IRj7b%clXAr8+{Jm(?ah2T=(FsYkh?(H&U(Z42ipf-)wkj5peA z*ds&Fw?Ps?qc?@53{VQhF%c$SHU;rcG2O?a0gXv-Z>X9`Lwpn5TXG+Y25fs36p%HM zns{igO6T3j!dR$jylmTQi#f-{+sR{a_VoXFxCN&rzNJyCxQ~UwmljHOOJ9*4PTkNr z?ls{@67fiFdG^F9_X*)@&F4AKm#-);ha#AT_1G@W|9W8%mOup z4%$CHb(@Uy12MrEZSLBGq#>+a4F=( literal 0 HcmV?d00001 diff --git a/src/quo/components/wallet/confirmation_progress/component_spec.cljs b/src/quo/components/wallet/confirmation_progress/component_spec.cljs new file mode 100644 index 0000000000..60010c4874 --- /dev/null +++ b/src/quo/components/wallet/confirmation_progress/component_spec.cljs @@ -0,0 +1,99 @@ +(ns quo.components.wallet.confirmation-progress.component-spec + (:require [quo.core :as quo] + [reagent.core :as reagent] + [test-helpers.component :as h])) + +(defn- get-test-data + [{:keys [state network] + :or {state :pending network :mainnet}}] + {:counter (reagent/atom 0) + :total-box 85 + :progress-value "10" + :network network + :state state + :customization-color :blue}) + +(h/describe "Confirmation Progress" + (h/test "component renders when state is sending and network is optimism" + (h/render [quo/confirmation-propgress + (get-test-data {:state :sending + :network :optimism})]) + (h/is-truthy (h/get-by-label-text :progress-box))) + + (h/test "component renders when state is confirmed and network is optimism" + (h/render [quo/confirmation-propgress + (get-test-data {:state :confirmed + :network :optimism})]) + (h/is-truthy (h/get-by-label-text :progress-box))) + + (h/test "component renders when state is finalising and network is optimism" + (h/render [quo/confirmation-propgress + (get-test-data {:state :finalising + :network :optimism})]) + (h/is-truthy (h/get-by-label-text :progress-box))) + + (h/test "component renders when state is finalized and network is optimism" + (h/render [quo/confirmation-propgress + (get-test-data {:state :finalized + :network :optimism})]) + (h/is-truthy (h/get-by-label-text :progress-box))) + + (h/test "component renders when state is error and network is optimism" + (h/render [quo/confirmation-propgress + (get-test-data {:state :error + :network :optimism})]) + (h/is-truthy (h/get-by-label-text :progress-box))) + + (h/test "component renders when state is sending and network is arbitrum" + (h/render [quo/confirmation-propgress + (get-test-data {:state :sending + :network :arbitrum})]) + (h/is-truthy (h/get-by-label-text :progress-box))) + + (h/test "component renders when state is confirmed and network is arbitrum" + (h/render [quo/confirmation-propgress + (get-test-data {:state :confirmed + :network :arbitrum})]) + (h/is-truthy (h/get-by-label-text :progress-box))) + + (h/test "component renders when state is finalising and network is arbitrum" + (h/render [quo/confirmation-propgress + (get-test-data {:state :finalising + :network :arbitrum})]) + (h/is-truthy (h/get-by-label-text :progress-box))) + + (h/test "component renders when state is finalized and network is arbitrum" + (h/render [quo/confirmation-propgress + (get-test-data {:state :finalized + :network :arbitrum})]) + (h/is-truthy (h/get-by-label-text :progress-box))) + + (h/test "component renders when state is error and network is arbitrum" + (h/render [quo/confirmation-propgress + (get-test-data {:state :error + :network :arbitrum})]) + (h/is-truthy (h/get-by-label-text :progress-box))) + + (h/test "component renders when state is pending and network is mainnet" + (h/render [quo/confirmation-propgress (get-test-data {})]) + (h/is-truthy (h/get-by-label-text :mainnet-progress-box))) + + (h/test "component renders when state is sending and network is mainnet" + (h/render [quo/confirmation-propgress (get-test-data {:state :sending})]) + (h/is-truthy (h/get-by-label-text :mainnet-progress-box))) + + (h/test "component renders when state is confirmed and network is mainnet" + (h/render [quo/confirmation-propgress (get-test-data {:state :confirmed})]) + (h/is-truthy (h/get-by-label-text :mainnet-progress-box))) + + (h/test "component renders when state is finalising and network is mainnet" + (h/render [quo/confirmation-propgress (get-test-data {:state :finalising})]) + (h/is-truthy (h/get-by-label-text :mainnet-progress-box))) + + (h/test "component renders when state is finalized and network is mainnet" + (h/render [quo/confirmation-propgress (get-test-data {:state :finalized})]) + (h/is-truthy (h/get-by-label-text :mainnet-progress-box))) + + (h/test "component renders when state is error and network is mainnet" + (h/render [quo/confirmation-propgress (get-test-data {:state :error})]) + (h/is-truthy (h/get-by-label-text :mainnet-progress-box)))) diff --git a/src/quo/components/wallet/confirmation_progress/style.cljs b/src/quo/components/wallet/confirmation_progress/style.cljs new file mode 100644 index 0000000000..511ba496f8 --- /dev/null +++ b/src/quo/components/wallet/confirmation_progress/style.cljs @@ -0,0 +1,9 @@ +(ns quo.components.wallet.confirmation-progress.style) + +(def progress-box-container + {:flex-direction :row + :align-items :center + :padding-horizontal 12 + :padding-bottom 10 + :padding-top 4 + :flex-wrap :wrap}) diff --git a/src/quo/components/wallet/confirmation_progress/view.cljs b/src/quo/components/wallet/confirmation_progress/view.cljs new file mode 100644 index 0000000000..0a43841587 --- /dev/null +++ b/src/quo/components/wallet/confirmation_progress/view.cljs @@ -0,0 +1,69 @@ +(ns quo.components.wallet.confirmation-progress.view + (:require [quo.components.wallet.confirmation-progress.style :as style] + [quo.components.wallet.progress-bar.view :as progress-box] + [quo.theme :as quo.theme] + [react-native.core :as rn])) + +(def ^:private max-progress 100) +(def ^:private min-progress 0) + +(defn- calculate-box-state + [state counter index] + (cond + (and (= state :sending) (>= counter index) (< index 3)) :confirmed + (and (= state :confirmed) (>= counter index) (< index 5)) :confirmed + (and (= state :finalising) (>= counter index) (< index 5)) :confirmed + (and (= state :finalising) (>= counter index) (> index 4) (< index 20)) :finalized + (and (= state :finalized) (>= counter index) (< index 5)) :confirmed + (and (= state :finalized) (>= counter index) (> index 4)) :finalized + (and (= state :error) (>= counter index) (< index 2)) :error + :else :pending)) + +(defn- calculate-box-state-sidenet + [state] + (case state + :error :error + (:confirmed :finalising :finalized) :finalized + :pending)) + +(defn- calculate-progressed-value + [state progress-value] + (case state + :finalising progress-value + :finalized max-progress + min-progress)) + +(defn- progress-boxes-mainnet + [{:keys [state counter total-box]}] + [rn/view + {:accessibility-label :mainnet-progress-box + :style style/progress-box-container} + (let [numbers (range 1 total-box)] + (doall (for [n numbers] + [progress-box/view + {:state (calculate-box-state state counter n) + :customization-color :blue + :key n}])))]) + +(defn- progress-boxes-sidenet + [{:keys [state progress-value]}] + [rn/view + {:accessibility-label :progress-box + :style style/progress-box-container} + [progress-box/view + {:state (calculate-box-state-sidenet state) + :customization-color :success}] + [progress-box/view + {:state (calculate-box-state-sidenet state) + :full-width? true + :progressed-value (calculate-progressed-value state progress-value) + :customization-color :blue}]]) + +(defn- view-internal + [{:keys [network] :as props}] + (case network + :mainnet [progress-boxes-mainnet props] + (:arbitrum :optimism) [progress-boxes-sidenet props] + nil)) + +(def view (quo.theme/with-theme view-internal)) diff --git a/src/quo/components/wallet/progress_bar/component_spec.cljs b/src/quo/components/wallet/progress_bar/component_spec.cljs index 39d48caf6a..b5612b3661 100644 --- a/src/quo/components/wallet/progress_bar/component_spec.cljs +++ b/src/quo/components/wallet/progress_bar/component_spec.cljs @@ -39,7 +39,7 @@ :width 8 :borderRadius 3 :borderColor colors/neutral-80-opa-5 - :backgroundColor (colors/custom-color (:customization-color props) 50)}))) + :backgroundColor (colors/resolve-color (:customization-color props) theme)}))) (h/test "finalized state with customtization-color blue in dark mode" (let [theme :dark @@ -51,7 +51,7 @@ :width 8 :borderRadius 3 :borderColor colors/neutral-80-opa-5 - :backgroundColor (colors/custom-color (:customization-color props) 60)}))) + :backgroundColor (colors/resolve-color (:customization-color props) theme)}))) (h/test "finalized state with customtization-color army in light mode" (let [theme :light @@ -63,7 +63,7 @@ :width 8 :borderRadius 3 :borderColor colors/neutral-80-opa-5 - :backgroundColor (colors/custom-color (:customization-color props) 50)}))) + :backgroundColor (colors/resolve-color (:customization-color props) theme)}))) (h/test "confirmed state in light mode" (let [theme :light @@ -75,7 +75,7 @@ :width 8 :borderRadius 3 :borderColor colors/neutral-80-opa-5 - :backgroundColor colors/success-50}))) + :backgroundColor (colors/resolve-color :success theme)}))) (h/test "confirmed state in dark mode" (let [theme :dark @@ -99,7 +99,7 @@ :width 8 :borderRadius 3 :borderColor colors/neutral-80-opa-5 - :backgroundColor colors/danger-50}))) + :backgroundColor (colors/resolve-color :danger theme)}))) (h/test "error state in dark mode" (let [theme :dark @@ -111,4 +111,4 @@ :width 8 :borderRadius 3 :borderColor colors/white-opa-5 - :backgroundColor colors/danger-60})))) + :backgroundColor (colors/resolve-color :danger theme)})))) diff --git a/src/quo/components/wallet/progress_bar/style.cljs b/src/quo/components/wallet/progress_bar/style.cljs index 71b1aa2796..8a1ebe76c1 100644 --- a/src/quo/components/wallet/progress_bar/style.cljs +++ b/src/quo/components/wallet/progress_bar/style.cljs @@ -3,31 +3,48 @@ [quo.foundations.colors :as colors])) (defn- border-and-background-color - [customization-color] + [customization-color theme] {:light {:pending {:border-color colors/neutral-80-opa-5 :background-color colors/neutral-5} :confirmed {:border-color colors/neutral-80-opa-5 - :background-color (colors/custom-color :success 50)} + :background-color (colors/resolve-color :success theme)} :finalized {:border-color colors/neutral-80-opa-5 - :background-color (colors/custom-color customization-color 50)} + :background-color (colors/resolve-color customization-color theme)} :error {:border-color colors/neutral-80-opa-5 - :background-color (colors/custom-color :danger 50)}} + :background-color (colors/resolve-color :danger theme)}} :dark {:pending {:border-color colors/neutral-70 :background-color colors/neutral-80} :confirmed {:border-color colors/white-opa-5 - :background-color (colors/custom-color :success 60)} + :background-color (colors/resolve-color :success theme)} :finalized {:border-color colors/neutral-80-opa-5 - :background-color (colors/custom-color customization-color 60)} + :background-color (colors/resolve-color customization-color theme)} :error {:border-color colors/white-opa-5 - :background-color (colors/custom-color :danger 60)}}}) + :background-color (colors/resolve-color :danger theme)}}}) + +(def max-value 100) (defn root-container - [{:keys [customization-color state theme]}] - (let [{:keys [background-color border-color]} (get-in (border-and-background-color customization-color) - [theme state])] + [{:keys [customization-color state theme full-width?]}] + (let [{:keys [background-color border-color]} (get-in (border-and-background-color customization-color + theme) + [theme (if full-width? :pending state)])] + {:height 12 + :flex (when full-width? 1) + :width (when (not full-width?) 8) + :border-radius 3 + :border-width 1 + :border-color border-color + :background-color background-color + :margin-horizontal 1 + :margin-vertical 2})) + +(defn progressed-bar + [{:keys [customization-color state theme progressed-value]}] + (let [{:keys [background-color]} (get-in (border-and-background-color customization-color theme) + [theme state]) + progress (if (> progressed-value max-value) max-value progressed-value)] {:height 12 - :width 8 + :margin-top -1 + :width (str progress "%") :border-radius 3 - :border-width 1 - :border-color border-color :background-color background-color})) diff --git a/src/quo/components/wallet/progress_bar/view.cljs b/src/quo/components/wallet/progress_bar/view.cljs index 98cf8e599d..f923091016 100644 --- a/src/quo/components/wallet/progress_bar/view.cljs +++ b/src/quo/components/wallet/progress_bar/view.cljs @@ -5,9 +5,11 @@ [react-native.core :as rn])) (defn- view-internal - [props] + [{:keys [full-width?] :as props}] [rn/view {:accessibility-label :progress-bar - :style (style/root-container props)}]) + :style (style/root-container props)} + (when full-width? + [rn/view {:style (style/progressed-bar props)}])]) (def view (quo.theme/with-theme view-internal)) diff --git a/src/quo/components/wallet/transaction_progress/component_spec.cljs b/src/quo/components/wallet/transaction_progress/component_spec.cljs new file mode 100644 index 0000000000..eb82518e10 --- /dev/null +++ b/src/quo/components/wallet/transaction_progress/component_spec.cljs @@ -0,0 +1,200 @@ +(ns quo.components.wallet.transaction-progress.component-spec + (:require [quo.core :as quo] + [reagent.core :as reagent] + [test-helpers.component :as h])) + +(defn- get-test-data + [{:keys [state network] + :or {state :pending network :mainnet}}] + {:title "Title" + :tag-name "Doodle" + :tag-number "120" + :network network + :customization-color :blue + :networks [{:network :mainnet + :state state + :counter (reagent/atom 0) + :total-box 85 + :progress 30 + :epoch-number "123"} + {:network :optimism + :state state + :progress "50" + :epoch-number "123"} + {:network :arbitrum + :state state + :progress "30" + :epoch-number "123"}] + :on-press (fn [] + (js/alert "Transaction progress item pressed"))}) + +(h/describe "Transaction Progress" + (h/test "component renders without props" + (h/render [quo/transaction-progress]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is pending and network is mainnet" + (h/render [quo/transaction-progress (get-test-data {:network :optimism-arbitrum})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is sending and network is optimism-arbitrum" + (h/render [quo/transaction-progress + (get-test-data {:state :sending + :network :optimism-arbitrum})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is confirmed and network is optimism-arbitrum" + (h/render [quo/transaction-progress + (get-test-data {:state :confirmed + :network :optimism-arbitrum})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is finalising and network is optimism-arbitrum" + (h/render [quo/transaction-progress + (get-test-data {:state :finalising + :network :optimism-arbitrum})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is finalized and network is optimism-arbitrum" + (h/render [quo/transaction-progress + (get-test-data {:state :finalized + :network :optimism-arbitrum})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is error and network is optimism-arbitrum" + (h/render [quo/transaction-progress + (get-test-data {:state :error + :network :optimism-arbitrum})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is sending and network is optimism" + (h/render [quo/transaction-progress + (get-test-data {:state :sending + :network :optimism})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is confirmed and network is optimism" + (h/render [quo/transaction-progress + (get-test-data {:state :confirmed + :network :optimism})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is finalising and network is optimism" + (h/render [quo/transaction-progress + (get-test-data {:state :finalising + :network :optimism})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is finalized and network is optimism" + (h/render [quo/transaction-progress + (get-test-data {:state :finalized + :network :optimism})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is error and network is optimism" + (h/render [quo/transaction-progress + (get-test-data {:state :error + :network :optimism})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is sending and network is arbitrum" + (h/render [quo/transaction-progress + (get-test-data {:state :sending + :network :arbitrum})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is confirmed and network is arbitrum" + (h/render [quo/transaction-progress + (get-test-data {:state :confirmed + :network :arbitrum})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is finalising and network is arbitrum" + (h/render [quo/transaction-progress + (get-test-data {:state :finalising + :network :arbitrum})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is finalized and network is arbitrum" + (h/render [quo/transaction-progress + (get-test-data {:state :finalized + :network :arbitrum})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is error and network is arbitrum" + (h/render [quo/transaction-progress + (get-test-data {:state :error + :network :arbitrum})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is pending and network is mainnet" + (h/render [quo/transaction-progress (get-test-data {})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is sending and network is mainnet" + (h/render [quo/transaction-progress (get-test-data {:state :sending})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is confirmed and network is mainnet" + (h/render [quo/transaction-progress (get-test-data {:state :confirmed})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is finalising and network is mainnet" + (h/render [quo/transaction-progress (get-test-data {:state :finalising})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is finalized and network is mainnet" + (h/render [quo/transaction-progress (get-test-data {:state :finalized})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "component renders when state is error and network is mainnet" + (h/render [quo/transaction-progress (get-test-data {:state :error})]) + (h/is-truthy (h/get-by-label-text :transaction-progress))) + + (h/test "mainnet progress box is visible network is mainnet" + (h/render [quo/transaction-progress (get-test-data {})]) + (h/is-truthy (h/get-by-label-text :mainnet-progress-box))) + + (h/test "arbitrum-optimism progress box is visible network is optimism-arbitrum" + (h/render [quo/transaction-progress (get-test-data {:network :optimism-arbitrum})]) + (h/is-truthy (h/get-all-by-label-text :progress-box))) + + (h/test "arbitrum progress box is visible network is arbitrum" + (h/render [quo/transaction-progress (get-test-data {:network :arbitrum})]) + (h/is-truthy (h/get-all-by-label-text :progress-box))) + + (h/test "optimism progress box is visible network is optimism" + (h/render [quo/transaction-progress (get-test-data {:network :optimism})]) + (h/is-truthy (h/get-all-by-label-text :progress-box))) + + (h/test "title is visible network is optimism-arbitrum" + (h/render [quo/transaction-progress (get-test-data {:network :optimism-arbitrum})]) + (h/is-truthy (h/get-by-text "Title"))) + + (h/test "title is visible network is mainnet" + (h/render [quo/transaction-progress (get-test-data {})]) + (h/is-truthy (h/get-by-text "Title"))) + + (h/test "title is visible network is optimism" + (h/render [quo/transaction-progress (get-test-data {:network :optimism})]) + (h/is-truthy (h/get-by-text "Title"))) + + (h/test "title is visible network is arbitrum" + (h/render [quo/transaction-progress (get-test-data {:network :arbitrum})]) + (h/is-truthy (h/get-by-text "Title"))) + + (h/test "context tag is visible network is optimism-arbitrum" + (h/render [quo/transaction-progress (get-test-data {:network :optimism-arbitrum})]) + (h/is-truthy (h/get-by-label-text :context-tag))) + + (h/test "context tag is visible network is mainnet" + (h/render [quo/transaction-progress (get-test-data {})]) + (h/is-truthy (h/get-by-label-text :context-tag))) + + (h/test "context tag is visible network is optimism" + (h/render [quo/transaction-progress (get-test-data {:network :optimism})]) + (h/is-truthy (h/get-by-label-text :context-tag))) + + (h/test "context tag is visible network is optimism" + (h/render [quo/transaction-progress (get-test-data {:network :arbitrum})]) + (h/is-truthy (h/get-by-label-text :context-tag)))) diff --git a/src/quo/components/wallet/transaction_progress/style.cljs b/src/quo/components/wallet/transaction_progress/style.cljs new file mode 100644 index 0000000000..dd6c07c55b --- /dev/null +++ b/src/quo/components/wallet/transaction_progress/style.cljs @@ -0,0 +1,38 @@ +(ns quo.components.wallet.transaction-progress.style + (:require [quo.foundations.colors :as colors])) + +(def title-text-container + {:flex 1}) + +(def icon + {:margin-right 4}) + +(defn box-style + [theme] + {:border-radius 16 + :border-width 1 + :border-color (colors/theme-colors colors/neutral-10 colors/neutral-80 theme)}) + +(def title-container + {:align-items :center + :flex-direction :row + :padding-left 12 + :padding-top 8 + :padding-right 8 + :padding-bottom 4}) + +(def status-row-container + {:flex-direction :row + :align-items :center + :flex 1 + :padding-horizontal 12 + :padding-top 8 + :padding-bottom 4}) + +(defn context-tag-container + [theme] + {:padding-horizontal 12 + :padding-bottom 8 + :flex-direction :row + :border-bottom-width 1 + :border-color (colors/theme-colors colors/neutral-10 colors/neutral-80 theme)}) diff --git a/src/quo/components/wallet/transaction_progress/view.cljs b/src/quo/components/wallet/transaction_progress/view.cljs new file mode 100644 index 0000000000..2f6048b378 --- /dev/null +++ b/src/quo/components/wallet/transaction_progress/view.cljs @@ -0,0 +1,187 @@ +(ns quo.components.wallet.transaction-progress.view + (:require [quo.components.buttons.button.view :as button] + [quo.components.icon :as icons] + [quo.components.markdown.text :as text] + [quo.components.tags.context-tag.view :as context-tag] + [quo.components.wallet.confirmation-progress.view :as confirmation-progress] + [quo.components.wallet.transaction-progress.style :as style] + [quo.foundations.colors :as colors] + [quo.theme :as quo.theme] + [react-native.core :as rn] + [utils.i18n :as i18n])) + +(def ^:private max-mainnet-verifications 4) +(def ^:private max-sidenet-verifications 1) + +(defn- icon-internal + ([icon] + (icon-internal icon nil 20)) + ([icon color] + (icon-internal icon color 20)) + ([icon color size] + [rn/view {:style style/icon} + [icons/icon + icon + {:color color + :size size + :no-color (when (not color) true)}]])) + +(defn- text-internal + [{:keys [weight size accessibility-label color] + :or {weight :semi-bold + size :paragraph-1}} + title] + [text/text + {:accessibility-label accessibility-label + :ellipsize-mode :tail + :number-of-lines 1 + :weight weight + :size size + :style {:color color}} + title]) + +(defn- network-type-text + [state] + (case state + (:sending :pending) (i18n/label :t/pending-on) + (:confirmed :finalising) (i18n/label :t/confirmed-on) + :finalized (i18n/label :t/finalized-on) + :error (i18n/label :t/failed-on) + nil)) + +(defn- calculate-counter + [counter] + (if (< counter 4) counter max-mainnet-verifications)) + +(defn mainnet-label + [counter] + (str counter "/" max-mainnet-verifications)) + +(defn subnet-label + [counter] + (str counter "/" max-sidenet-verifications)) + +(defn- text-steps + [network state epoch-number counter] + (let [steps (case network + :mainnet + {:pending (mainnet-label 0) + :sending (mainnet-label (calculate-counter counter)) + :confirmed (mainnet-label (calculate-counter counter)) + :finalising (mainnet-label (calculate-counter counter)) + :finalized (i18n/label :t/epoch-number {:number epoch-number}) + :error (mainnet-label 0)} + (or :optimism :arbitrum) + {:pending (subnet-label 0) + :sending (subnet-label 0) + :confirmed (subnet-label 0) + :finalising (subnet-label 1) + :finalized (i18n/label :t/epoch-number {:number epoch-number}) + :error (subnet-label 0)} + nil)] + (get steps state))) + +(defn- get-status-icon + [theme state] + (case state + (:pending :sending) {:icon :i/pending-state + :color (colors/theme-colors colors/neutral-50 + colors/neutral-40 + theme)} + (:confirmed :finalising) {:icon :i/positive-state + :color (colors/resolve-color :success theme)} + :finalized {:icon :i/diamond} + :error {:icon :i/negative-state + :color (colors/resolve-color :danger theme)} + nil)) + +(defn- get-network + [networks network] + (some #(when (= (:network %) network) %) + networks)) + +(defn- calculate-error-state + [networks] + (some #(= (:state %) :error) networks)) + +(defn- title-internal + [{:keys [title theme networks]}] + [rn/view {:style style/title-container} + [icon-internal :i/placeholder (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)] + [rn/view {:style style/title-text-container} + [text-internal nil title]] + (when (calculate-error-state networks) + [button/button + {:size 24 + :icon-left :i/refresh} + (i18n/label :t/retry)])]) + +(defn- tag-internal + [tag-photo tag-name tag-number theme] + [rn/view {:style (style/context-tag-container theme)} + [context-tag/view + {:size 24 + :collectible tag-photo + :collectible-name tag-name + :collectible-number tag-number + :type :collectible}]]) + +(defn- get-network-text + [network] + (case network + :arbitrum (i18n/label :t/arbitrum) + :mainnet (i18n/label :t/mainnet) + :optimism (i18n/label :t/optimism) + nil)) + +(defn- status-row + [{:keys [theme state network epoch-number counter]}] + (let [{:keys [icon color]} (get-status-icon theme state)] + [rn/view {:style style/status-row-container} + [icon-internal icon color 16] + [rn/view {:style style/title-text-container} + [text-internal + {:weight :regular + :size :paragraph-2} + (str (network-type-text state) " " (get-network-text network))]] + [rn/view + [text-internal + {:weight :regular + :size :paragraph-2 + :color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)} + (text-steps network state epoch-number counter)]]])) + +(defn- view-network + [{:keys [theme state epoch-number counter total-box progress network]}] + [:<> + [status-row + {:theme theme + :state state + :network network + :epoch-number epoch-number + :counter counter}] + [confirmation-progress/view + {:state state + :network network + :counter counter + :total-box total-box + :progress-value progress}]]) + +(defn- view-internal + [{:keys [title on-press accessibility-label theme tag-photo tag-name tag-number networks] + :or {accessibility-label :transaction-progress}}] + [rn/touchable-without-feedback + {:on-press on-press + :accessibility-label accessibility-label} + [rn/view {:style (style/box-style theme)} + [title-internal + {:title title + :theme theme + :networks networks}] + [tag-internal tag-photo tag-name tag-number theme] + (for [network networks] + ^{:key (:network network)} + (let [assoc-props #(get-network networks %)] + [view-network (assoc-props (:network network))]))]]) + +(def view (quo.theme/with-theme view-internal)) diff --git a/src/quo/core.cljs b/src/quo/core.cljs index a72ea57ac7..85e3930987 100644 --- a/src/quo/core.cljs +++ b/src/quo/core.cljs @@ -146,6 +146,7 @@ quo.components.wallet.account-origin.view quo.components.wallet.account-overview.view quo.components.wallet.address-text.view + quo.components.wallet.confirmation-progress.view quo.components.wallet.keypair.view quo.components.wallet.network-amount.view quo.components.wallet.network-bridge.view @@ -154,6 +155,7 @@ quo.components.wallet.progress-bar.view quo.components.wallet.summary-info.view quo.components.wallet.token-input.view + quo.components.wallet.transaction-progress.view quo.components.wallet.transaction-summary.view quo.components.wallet.wallet-activity.view quo.components.wallet.wallet-overview.view)) @@ -389,6 +391,7 @@ (def account-origin quo.components.wallet.account-origin.view/view) (def account-overview quo.components.wallet.account-overview.view/view) (def address-text quo.components.wallet.address-text.view/view) +(def confirmation-propgress quo.components.wallet.confirmation-progress.view/view) (def keypair quo.components.wallet.keypair.view/view) (def network-amount quo.components.wallet.network-amount.view/view) (def network-bridge quo.components.wallet.network-bridge.view/view) @@ -399,4 +402,5 @@ (def token-input quo.components.wallet.token-input.view/view) (def wallet-overview quo.components.wallet.wallet-overview.view/view) (def wallet-activity quo.components.wallet.wallet-activity.view/view) +(def transaction-progress quo.components.wallet.transaction-progress.view/view) (def transaction-summary quo.components.wallet.transaction-summary.view/view) diff --git a/src/quo/core_spec.cljs b/src/quo/core_spec.cljs index d642ebfc3c..a7ab024cf4 100644 --- a/src/quo/core_spec.cljs +++ b/src/quo/core_spec.cljs @@ -80,6 +80,7 @@ [quo.components.wallet.account-card.component-spec] [quo.components.wallet.account-origin.component-spec] [quo.components.wallet.account-overview.component-spec] + [quo.components.wallet.confirmation-progress.component-spec] [quo.components.wallet.keypair.component-spec] [quo.components.wallet.network-amount.component-spec] [quo.components.wallet.network-bridge.component-spec] @@ -87,6 +88,7 @@ [quo.components.wallet.progress-bar.component-spec] [quo.components.wallet.summary-info.component-spec] [quo.components.wallet.token-input.component-spec] + [quo.components.wallet.transaction-progress.component-spec] [quo.components.wallet.transaction-summary.component-spec] [quo.components.wallet.wallet-activity.component-spec] [quo.components.wallet.wallet-overview.component-spec])) diff --git a/src/status_im2/contexts/quo_preview/main.cljs b/src/status_im2/contexts/quo_preview/main.cljs index 3a9406f7e7..c9754bc8d0 100644 --- a/src/status_im2/contexts/quo_preview/main.cljs +++ b/src/status_im2/contexts/quo_preview/main.cljs @@ -170,6 +170,7 @@ [status-im2.contexts.quo-preview.wallet.account-origin :as account-origin] [status-im2.contexts.quo-preview.wallet.account-overview :as account-overview] + [status-im2.contexts.quo-preview.wallet.confirmation-progress :as confirmation-progress] [status-im2.contexts.quo-preview.wallet.keypair :as keypair] [status-im2.contexts.quo-preview.wallet.network-amount :as network-amount] [status-im2.contexts.quo-preview.wallet.network-bridge :as network-bridge] @@ -178,6 +179,7 @@ [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.token-input :as token-input] + [status-im2.contexts.quo-preview.wallet.transaction-progress :as transaction-progress] [status-im2.contexts.quo-preview.wallet.transaction-summary :as transaction-summary] [status-im2.contexts.quo-preview.wallet.wallet-activity :as wallet-activity] @@ -464,6 +466,8 @@ {:name :account-origin :component account-origin/view} {:name :account-overview :component account-overview/view} + {:name :confirmation-progress + :component confirmation-progress/view} {:name :keypair :component keypair/view} {:name :network-amount :component network-amount/view} {:name :network-bridge :component network-bridge/view} @@ -473,6 +477,7 @@ {:name :summary-info :component summary-info/view} {:name :token-input :component token-input/view} {:name :wallet-activity :component wallet-activity/view} + {:name :transaction-progress :component transaction-progress/view} {:name :transaction-summary :component transaction-summary/view} {:name :wallet-overview :component wallet-overview/view}] diff --git a/src/status_im2/contexts/quo_preview/wallet/confirmation_progress.cljs b/src/status_im2/contexts/quo_preview/wallet/confirmation_progress.cljs new file mode 100644 index 0000000000..5a5a99f7a3 --- /dev/null +++ b/src/status_im2/contexts/quo_preview/wallet/confirmation_progress.cljs @@ -0,0 +1,85 @@ +(ns status-im2.contexts.quo-preview.wallet.confirmation-progress + (:require + [quo.core :as quo] + [react-native.core :as rn] + [reagent.core :as reagent] + [status-im2.contexts.quo-preview.preview :as preview])) + +(def descriptor + [{:type :text + :key :progress-value} + {:type :select + :key :network + :options [{:key :mainnet} + {:key :optimism} + {:key :arbitrum}]} + {:type :select + :key :state + :options [{:key :pending} + {:key :sending} + {:key :confirmed} + {:key :finalising} + {:key :finalized} + {:key :error}]} + (preview/customization-color-option)]) + +(def total-box 85) +(def counter (reagent/atom 0)) +(def interval-id (reagent/atom nil)) +(def interval-ms 50) + +(defn- stop-interval + [] + (when @interval-id + (js/clearInterval @interval-id) + (reset! interval-id nil))) + +(defn- clear-counter + [] + (reset! counter 0)) + +(defn- update-counter + [state] + (let [new-counter-value (inc @counter)] + (if (or (and (= state :pending) (> new-counter-value 0)) + (and (= state :sending) (> new-counter-value 2)) + (and (= state :confirmed) (> new-counter-value 4)) + (and (= state :finalising) (> new-counter-value 18)) + (and (= state :finalized) (> new-counter-value total-box)) + (and (= state :error) (> new-counter-value 2))) + (stop-interval) + (reset! counter new-counter-value)))) + +(defn- start-interval + [state] + (reset! interval-id + (js/setInterval + (fn [] + (update-counter state)) + interval-ms))) + +(defn- f-view + [state] + (fn [] + (rn/use-effect + (fn [] + (start-interval (:state @state)) + (clear-counter) + (fn [] + (stop-interval))) + [(:state @state)]) + [preview/preview-container {:state state :descriptor descriptor} + [quo/confirmation-propgress + (assoc @state + :counter + @counter)]])) + +(defn view + [] + (let [state (reagent/atom + {:total-box total-box + :progress-value "10" + :network :mainnet + :state :pending + :customization-color :blue})] + [:f> f-view state])) diff --git a/src/status_im2/contexts/quo_preview/wallet/progress_bar.cljs b/src/status_im2/contexts/quo_preview/wallet/progress_bar.cljs index d9b4f2cad8..eec0741ed4 100644 --- a/src/status_im2/contexts/quo_preview/wallet/progress_bar.cljs +++ b/src/status_im2/contexts/quo_preview/wallet/progress_bar.cljs @@ -1,6 +1,7 @@ (ns status-im2.contexts.quo-preview.wallet.progress-bar (:require [quo.core :as quo] + [react-native.core :as rn] [reagent.core :as reagent] [status-im2.contexts.quo-preview.preview :as preview])) @@ -11,11 +12,17 @@ {:key :confirmed} {:key :finalized} {:key :error}]} + {:key :full-width? + :type :boolean} + {:key :progressed-value + :type :text} (preview/customization-color-option)]) (defn view [] (let [state (reagent/atom {:state :pending + :full-width? false + :progressed-value "10" :customization-color :blue})] (fn [] [preview/preview-container @@ -23,4 +30,5 @@ :descriptor descriptor :component-container-style {:padding-top 40 :align-items :center}} - [quo/progress-bar @state]]))) + [rn/view {:style {:flex-direction :row}} + [quo/progress-bar @state]]]))) diff --git a/src/status_im2/contexts/quo_preview/wallet/transaction_progress.cljs b/src/status_im2/contexts/quo_preview/wallet/transaction_progress.cljs new file mode 100644 index 0000000000..ad66ad4197 --- /dev/null +++ b/src/status_im2/contexts/quo_preview/wallet/transaction_progress.cljs @@ -0,0 +1,155 @@ +(ns status-im2.contexts.quo-preview.wallet.transaction-progress + (:require + [quo.core :as quo] + [react-native.core :as rn] + [reagent.core :as reagent] + [status-im2.common.resources :as resources] + [status-im2.contexts.quo-preview.preview :as preview])) + +(def descriptor + [{:type :text + :key :title} + {:type :text + :key :tag-name} + {:type :text + :key :epoch-number-mainnet} + {:type :text + :key :epoch-number-optimism} + {:type :text + :key :epoch-number-arbitrum} + {:type :text + :key :tag-number} + {:type :text + :key :optimism-progress-percentage} + {:type :text + :key :arbitrum-progress-percentage} + {:type :select + :key :network + :options [{:key :mainnet} + {:key :optimism} + {:key :arbitrum} + {:key :optimism-arbitrum}]} + {:type :select + :key :state-mainnet + :options [{:key :pending} + {:key :sending} + {:key :confirmed} + {:key :finalising} + {:key :finalized} + {:key :error}]} + {:type :select + :key :state-optimism + :options [{:key :pending} + {:key :sending} + {:key :confirmed} + {:key :finalising} + {:key :finalized} + {:key :error}]} + {:type :select + :key :state-arbitrum + :options [{:key :pending} + {:key :sending} + {:key :confirmed} + {:key :finalising} + {:key :finalized} + {:key :error}]} + (preview/customization-color-option)]) + +(def total-box 85) +(def counter (reagent/atom 0)) +(def interval-id (reagent/atom nil)) +(def interval-ms 50) + +(defn- stop-interval + [] + (when @interval-id + (js/clearInterval @interval-id) + (reset! interval-id nil))) + +(defn- clear-counter + [] + (reset! counter 0)) + +(defn- update-counter + [state] + (let [new-counter-value (inc @counter)] + (if (or (and (= state :pending) (> new-counter-value 0)) + (and (= state :sending) (> new-counter-value 2)) + (and (= state :confirmed) (> new-counter-value 4)) + (and (= state :finalising) (> new-counter-value 18)) + (and (= state :finalized) (> new-counter-value total-box)) + (and (= state :error) (> new-counter-value 2))) + (stop-interval) + (reset! counter new-counter-value)))) + +(defn- start-interval + [state] + (reset! interval-id + (js/setInterval + (fn [] + (update-counter state)) + interval-ms))) + +(defn- get-networks + [state] + (case (:network state) + :mainnet [{:network :mainnet + :state (:state-mainnet state) + :counter @counter + :total-box total-box + :epoch-number (:epoch-number-mainnet state)}] + :optimism [{:network :optimism + :state (:state-optimism state) + :progress (:optimism-progress-percentage state) + :epoch-number (:epoch-number-optimism state)}] + :arbitrum [{:network :arbitrum + :state (:state-arbitrum state) + :progress (:arbitrum-progress-percentage state) + :epoch-number (:epoch-number-arbitrum state)}] + :optimism-arbitrum [{:network :optimism + :state (:state-optimism state) + :progress (:optimism-progress-percentage state) + :epoch-number (:epoch-number-optimism state)} + {:network :arbitrum + :state (:state-arbitrum state) + :progress (:arbitrum-progress-percentage state) + :epoch-number (:epoch-number-arbitrum state)}])) + +(defn- f-view + [state] + (fn [] + (rn/use-effect + (fn [] + (start-interval (:state-mainnet @state)) + (clear-counter) + (fn [] + (stop-interval))) + [(:state-mainnet @state)]) + [preview/preview-container {:state state :descriptor descriptor} + [quo/transaction-progress + (assoc @state + :networks + (get-networks @state))]])) + +(defn view + [] + (let [state (reagent/atom + {:title "Title" + :counter 40 + :total-box total-box + :tag-name "Doodle" + :tag-number "120" + :epoch-number-mainnet "181,329" + :epoch-number-optimism "181,329" + :epoch-number-arbitrum "181,329" + :optimism-progress-percentage "10" + :arbitrum-progress-percentage "10" + :network :mainnet + :state-mainnet :pending + :state-arbitrum :pending + :state-optimism :pending + :customization-color :blue + :tag-photo (resources/get-mock-image :collectible) + :on-press (fn [] + (js/alert "Transaction progress item pressed"))})] + [:f> f-view state])) diff --git a/translations/en.json b/translations/en.json index 2f86b33ba3..8dd205bff4 100644 --- a/translations/en.json +++ b/translations/en.json @@ -2389,6 +2389,13 @@ "keypairs": "Keypairs", "keypairs-description": "Select keypair to derive your new account from", "confirm-account-origin": "Confirm account origin", + "confirmed-on": "Confirmed on", + "pending-on": "Pending on", + "finalized-on": "Finalized on", + "failed-on": "Failed on", + "epoch-number": "Epoch {{number}}", + "arbitrum": "Arbitrum", + "optimism": "Optimism", "address-placeholder": "0x123abc... or bob.eth", "invalid-address": "It’s not Ethereum address or ENS name", "address-already-in-use": "Address already being used",