Wallet activity component (#17141)

* Wallet activity component

* Component description added

* removed unnecessary piece

* lint fix

* Review notes

* fix issue with blur preview

* lint fix
This commit is contained in:
Volodymyr Kozieiev 2023-09-01 16:20:15 +01:00 committed by GitHub
parent 5e3255ea57
commit f3f85f9911
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 519 additions and 23 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 676 B

After

Width:  |  Height:  |  Size: 731 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 964 B

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,15 @@
(ns quo2.components.wallet.wallet-activity.component-spec
(:require [quo2.components.wallet.wallet-activity.view :as wallet-activity]
[test-helpers.component :as h]))
(h/describe "Wallet activity"
(h/test "default render"
(h/render [wallet-activity/view {}])
(h/is-truthy (h/query-by-label-text :wallet-activity)))
(h/test "Should call :on-press"
(let [on-press (h/mock-fn)]
(h/render [wallet-activity/view {:on-press on-press}])
(h/is-truthy (h/query-by-label-text :wallet-activity))
(h/fire-event :press (h/query-by-label-text :wallet-activity))
(h/was-called on-press))))

View File

@ -0,0 +1,86 @@
(ns quo2.components.wallet.wallet-activity.style
(:require [quo2.foundations.colors :as colors]))
(defn wallet-activity-container
[{:keys [pressed?
theme
blur?]}]
(merge
{:border-radius 16
:padding-top 8
:padding-left 12
:padding-right 12
:padding-bottom 12}
(when pressed?
{:background-color (if blur?
colors/white-opa-5
(colors/theme-colors colors/neutral-5 colors/neutral-90 theme))})))
(def transaction-header-container
{:flex-direction :row
:align-items :center})
(defn transaction-header
[theme]
{:color (colors/theme-colors colors/neutral-100 colors/white theme)
:margin-right 4})
(defn transaction-counter
[theme]
{:color (colors/theme-colors colors/neutral-100 colors/white theme)})
(defn transaction-counter-container
[theme blur?]
{:border-width 1
:border-radius 6
:margin-right 8
:padding-horizontal 2
:border-color (if-not blur?
(colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
colors/white-opa-10)})
(defn timestamp
[theme blur?]
{:color (if-not blur?
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme)
colors/white-opa-40)})
(defn prop-text
[theme]
{:margin-right 4
:color (colors/theme-colors colors/neutral-100 colors/white theme)})
(def icon-container
{:width 32
:height 32
:margin-top 8})
(def content-container
{:margin-left 8})
(def content-line
{:flex-direction :row
:margin-top 2
:align-items :center})
(defn icon-hole-view
[theme blur?]
{:width 32
:height 32
:border-width 1
:border-color (if-not blur?
(colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
colors/white-opa-5)
:border-radius 16
:align-items :center
:justify-content :center})
(defn icon-color
[theme]
(colors/theme-colors colors/neutral-100 colors/white theme))
(def icon-status-container
{:position :absolute
:bottom 0
:right 0})

View File

@ -0,0 +1,165 @@
(ns quo2.components.wallet.wallet-activity.view
(:require [quo2.theme :as quo.theme]
[quo2.components.wallet.wallet-activity.style :as style]
[react-native.core :as rn]
[quo2.components.markdown.text :as text]
[quo2.components.icon :as icon]
[quo2.components.tags.context-tag.view :as context-tag]
[react-native.hole-view :as hole-view]
[utils.i18n :as i18n]
[reagent.core :as reagent]))
(def transaction-translation
{:receive [i18n/label :t/receive]
:send [i18n/label :t/send]
:swap [i18n/label :t/swap]
:bridge [i18n/label :t/bridge]
:buy [i18n/label :t/buy]
:destroy [i18n/label :t/destroy]
:mint [i18n/label :t/mint]})
(def transaction-icon
{:receive :i/receive
:send :i/send
:swap :i/swap
:bridge :i/bridge
:buy :i/buy
:destroy :i/destroy
:mint :i/mint})
(def status-icon
{:pending :i/pending-state
:confirmed :i/positive-state
:finalised :i/diamond-blue
:failed :i/negative-state})
(defn transaction-header
[{:keys [transaction
timestamp
counter
theme
blur?]
:or {transaction :receive
counter 1}}]
[rn/view
{:style style/transaction-header-container}
[text/text
{:weight :semi-bold
:size :paragraph-1
:style (style/transaction-header theme)}
(transaction transaction-translation)]
(when (> counter 1)
[rn/view (style/transaction-counter-container theme blur?)
[text/text
{:weight :medium
:size :label
:style (style/transaction-counter theme)}
(i18n/label :t/x-counter {:counter counter})]])
[rn/view
[text/text
{:weight :regular
:size :label
:style (style/timestamp theme blur?)}
timestamp]]])
(defn transaction-icon-view
[{:keys [theme blur? transaction status]
:or {transaction :receive
status :pending}}]
[rn/view {:style style/icon-container}
[hole-view/hole-view
{:style (style/icon-hole-view theme blur?)
:holes [{:x 20
:y 20
:right 0
:width 12
:height 12
:borderRadius 6}]}
[icon/icon (transaction-icon transaction)
{:color (style/icon-color theme)}]]
[rn/view {:style style/icon-status-container}
[icon/icon (status-icon status)
{:size 12
:no-color :true}]]])
(defn prop-text
[label theme]
[text/text
{:weight :regular
:size :paragraph-2
:style (style/prop-text theme)}
[i18n/label label]])
(defn prop-tag
[props blur?]
[rn/view {:style {:margin-right 4}}
[context-tag/view (merge props {:size 24 :blur? blur?})]])
(defn- view-internal
[_]
(let [pressed? (reagent/atom false)]
(fn
[{:keys [state theme blur?
on-press
first-tag second-tag third-tag fourth-tag
second-tag-prefix third-tag-prefix fourth-tag-prefix]
:as props}]
[rn/pressable
{:style (style/wallet-activity-container {:pressed? @pressed?
:theme theme
:blur? blur?})
:accessibility-label :wallet-activity
:disabled (= state :disabled)
:on-press on-press
:on-press-in (fn [] (reset! pressed? true))
:on-press-out (fn [] (reset! pressed? false))}
[rn/view
{:style {:flex-direction :row}}
[transaction-icon-view props]
[rn/view
{:style style/content-container}
[transaction-header props]
[rn/view {:style style/content-line}
(when first-tag [prop-tag first-tag blur?])
(when second-tag-prefix [prop-text second-tag-prefix theme])
(when second-tag [prop-tag second-tag blur?])]
[rn/view {:style style/content-line}
(when third-tag-prefix [prop-text third-tag-prefix theme])
(when third-tag [prop-tag third-tag blur?])
(when fourth-tag-prefix [prop-text fourth-tag-prefix theme])
(when fourth-tag [prop-tag fourth-tag blur?])]]]])))
(def view
"Properties:
- :transaction - type of transaction`. Possible values:
- :receive
- :send
- :swap
- :bridge
- :buy
- :destroy
- :mint
- :status - transaction status. Possible values:
- :pending
- :confirmed
- :finalised
- :failed
- :counter - amount of transactions shown by instance of the component
- :timestamp - when transaction occured (string)
- :blur?
- :first-tag - props for context tag component that will be first on the first line
- :second-tag - props for context tag component that will be second on the first line
- :third-tag - props for context tag component that will be first on the second line
- :fourth-tag - props for context tag component that will be second on the second line
- :second-tag-prefix - translation keyword to be used with label before second context tag
- :third-tag-prefix - translation keyword to be used with label before third context tag
- :fourth-tag-prefix - translation keyword to be used with label before fourth context tag
"
(quo.theme/with-theme view-internal))

View File

@ -125,6 +125,7 @@
quo2.components.wallet.progress-bar.view
quo2.components.wallet.summary-info.view
quo2.components.wallet.token-input.view
quo2.components.wallet.wallet-activity.view
quo2.components.wallet.wallet-overview.view
[quo2.components.graph.interactive-graph.view :as interactive-graph]))
@ -339,3 +340,4 @@
(def network-link quo2.components.wallet.network-link.view/view)
(def token-input quo2.components.wallet.token-input.view/view)
(def wallet-overview quo2.components.wallet.wallet-overview.view/view)
(def wallet-activity quo2.components.wallet.wallet-activity.view/view)

View File

@ -69,4 +69,5 @@
[quo2.components.wallet.progress-bar.component-spec]
[quo2.components.wallet.summary-info.component-spec]
[quo2.components.wallet.token-input.component-spec]
[quo2.components.wallet.wallet-overview.component-spec]))
[quo2.components.wallet.wallet-overview.component-spec]
[quo2.components.wallet.wallet-activity.component-spec]))

View File

@ -101,7 +101,7 @@
[react/nested-text
{:style {:color colors/gray}
:ellipsize-mode :middle
:number-of-lines 1} (i18n/label :t/to) " "
:number-of-lines 1} (i18n/label :t/to-capitalized) " "
[{:style {:color colors/black}} (displayed-name contact)]]
[react/text {:style {:margin-top 6 :color colors/gray}}
(str fee " " fee-display-symbol " " (string/lower-case (i18n/label :t/network-fee)))])]
@ -497,9 +497,9 @@
[react/view
[network-item]
[separator]])
[contact-item (i18n/label :t/from) from]
[contact-item (i18n/label :t/from-capitalized) from]
[separator]
[contact-item (i18n/label :t/to) contact]
[contact-item (i18n/label :t/to-capitalized) contact]
(when-not cancel?
[separator])
(when-not cancel?

View File

@ -138,7 +138,7 @@
:align-items :center
:margin-vertical 16}]
[quo/list-header
(i18n/label :t/from)]
(i18n/label :t/from-capitalized)]
[react/view {:flex-direction :row :flex 1 :align-items :center}
[react/view {:flex 1}
[render-account from nil ::commands/set-selected-account]]]
@ -204,7 +204,7 @@
[fiat-value amount-text token prices wallet-currency]
[components/separator]
[quo/list-header
(i18n/label :t/to)]
(i18n/label :t/to-capitalized)]
[react/view {:flex-direction :row :flex 1 :align-items :center}
[react/view {:flex 1}
[render-account from token :wallet.request/set-field]]]]]
@ -278,12 +278,12 @@
(when-not (or request? from-chat?)
[set-max token])
[components/separator]
[quo/list-header (i18n/label :t/from)]
[quo/list-header (i18n/label :t/from-capitalized)]
[react/view {:flex-direction :row :flex 1 :align-items :center}
[react/view {:flex 1}
[render-account from token :wallet.send/set-field]]]
[quo/list-header
(i18n/label :t/to)]
(i18n/label :t/to-capitalized)]
[react/view {:flex-direction :row :flex 1 :align-items :center}
[react/view {:flex 1}
[render-contact to from-chat?]]]]]

View File

@ -241,18 +241,17 @@
to to-wallet to-contact
gas-limit gas-price-gwei gas-price-eth gas-used
fee-cap-gwei tip-cap-gwei
cost nonce data]
:as tx}]
cost nonce data]}]
[react/view {:style styles/details-block}
[details-list-row :t/block block]
[details-list-row :t/hash (:hash tx)]
[details-list-row :t/from
[details-list-row :t/hash hash]
[details-list-row :t/from-capitalized
[{:accessibility-label (if from-wallet :sender-name-text :sender-address-text)}
(or from-wallet from-contact from)]
(when (or from-wallet from-contact)
[{:accessibility-label :sender-address-text}
from])]
[details-list-row :t/to
[details-list-row :t/to-capitalized
[{:accessibility-label (if to-wallet :recipient-name-text :recipient-address-text)}
(or to-wallet to-contact to)]
(when (or to-wallet to-contact)

View File

@ -125,6 +125,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.wallet-activity :as wallet-activity]
[status-im2.contexts.quo-preview.wallet.wallet-overview :as wallet-overview]
[utils.re-frame :as rf]))
@ -377,6 +378,8 @@
:component summary-info/preview}
{:name :token-input
:component token-input/preview}
{:name :wallet-activity
:component wallet-activity/view}
{:name :wallet-overview
:component wallet-overview/preview-wallet-overview}]
:keycard [{:name :keycard-component

View File

@ -0,0 +1,218 @@
(ns status-im2.contexts.quo-preview.wallet.wallet-activity
(:require [quo2.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]
[quo2.foundations.resources :as quo.resources]))
(def asset-snt
{:size 24
:type :token
:token-name "SNT"
:amount 1500
:token-logo (quo.resources/get-token :snt)})
(def asset-dai
{:size 24
:type :token
:token-name "DAI"
:amount 2400
:token-logo (quo.resources/get-token :dai)})
(def asset-collectible
{:size 24
:type :collectible
:collectible (resources/mock-images :collectible)
:collectible-name "Collectible"
:collectible-number "123"})
(def trip-to-vegas
{:size 24
:type :account
:account-name "Trip to Vegas"
:emoji "🤑"})
(def piggy-bank
{:size 24
:type :account
:account-name "Piggy bank"
:emoji "🐷"})
(def aretha-gosling
{:size 24
:type :default
:full-name "Aretha Gosling"
:profile-picture (resources/mock-images :user-picture-female2)})
(def james-bond
{:size 24
:type :default
:full-name "James Bond"
:profile-picture (resources/mock-images :user-picture-male4)})
(def mainnet
{:size 24
:type :network
:network-logo (quo.resources/get-network :ethereum)
:network-name "Mainnet"})
(def optimism
{:size 24
:type :network
:network-logo (quo.resources/get-network :optimism)
:network-name "Optimism"})
(def arbitrum
{:size 24
:type :network
:network-logo (quo.resources/get-network :arbitrum)
:network-name "Arbitrum"})
(def multinetwork
{:size 24
:type :multinetwork
:networks [(quo.resources/get-network :ethereum)
(quo.resources/get-network :arbitrum)
(quo.resources/get-network :optimism)]})
(def moonpay
{:size 24
:type :network
:network-logo (quo.resources/get-network :ethereum)
:network-name "Moonpay"})
(def binance
{:size 24
:type :network
:network-logo (quo.resources/get-network :ethereum)
:network-name "Binance"})
(def context-tags
[{:key asset-snt
:value "SNT"}
{:key asset-dai
:value "UNK"}
{:key asset-collectible
:value "Collectible"}
{:key trip-to-vegas
:value "Account: Trip to Vegas"}
{:key piggy-bank
:value "Account: Piggy bank"}
{:key aretha-gosling
:value "Person: Aretha Gosling"}
{:key james-bond
:value "Person: James Bond"}
{:key mainnet
:value "Network: Mainnet"}
{:key optimism
:value "Network: Optimism"}
{:key arbitrum
:value "Network: Arbitrum"}
{:key multinetwork
:value "Network: Multinetwork"}
{:key moonpay
:value "Market: Moonpay"}
{:key binance
:value "Market: Binance"}])
(def prefixes
[{:key :t/to
:value "To"}
{:key :t/in
:value "In"}
{:key :t/via
:value "Via"}
{:key :t/from
:value "From"}
{:key :t/on
:value "On"}
{:key :t/at
:value "At"}])
(def descriptor
(concat
[{:key :blur?
:type :select
:options [{:key true}
{:key false}]}
{:key :transaction
:type :select
:options [{:key :receive}
{:key :send}
{:key :swap}
{:key :bridge}
{:key :buy}
{:key :destroy}
{:key :mint}]}
{:key :status
:type :select
:options [{:key :pending}
{:key :confirmed}
{:key :finalised}
{:key :failed}]}
{:key :timestamp
:type :text}
{:key :counter
:type :select
:options [{:key 1
:value 1}
{:key 2
:value 2}
{:key 3
:value 3}]}
{:label "Slot 1"
:key :first-tag
:type :select
:options context-tags}
{:label "Slot 2 prefix"
:key :second-tag-prefix
:type :select
:options prefixes}
{:label "Slot 2"
:key :second-tag
:type :select
:options context-tags}
{:label "Slot 3 prefix"
:key :third-tag-prefix
:type :select
:options prefixes}
{:label "Slot 3"
:key :third-tag
:type :select
:options context-tags}
{:label "Slot 4 prefix"
:key :fourth-tag-prefix
:type :select
:options prefixes}
{:label "Slot 4"
:key :fourth-tag
:type :select
:options context-tags}]))
(defn view
[]
(let [component-state (reagent/atom {:transaction :send
:timestamp "Today 22:20"
:status :pending
:counter 1
:first-tag asset-snt
:second-tag-prefix :t/from
:second-tag piggy-bank
:third-tag-prefix :t/to
:third-tag aretha-gosling
:fourth-tag-prefix :t/via
:fourth-tag mainnet
:blur? false})]
(fn []
[preview/preview-container
{:state component-state
:descriptor descriptor
:blur? (:blur? @component-state)
:show-blur-background? true}
[rn/view {:style {:align-self :center}}
[quo/wallet-activity
(merge {:on-press #(js/alert "Dropdown pressed")}
@component-state)]]])))

View File

@ -70,11 +70,11 @@
(assoc acc
tx-hash
(enrich-transaction transaction contacts native-currency))) ;;TODO this doesn't
;;look good for
;;performance, we
;;need to calculate
;;this only once for
;;each transaction
;;look good for
;;performance, we
;;need to calculate
;;this only once for
;;each transaction
{}
transactions)))
@ -125,13 +125,13 @@
(case type
:inbound
(assoc transaction
:label (i18n/label :t/from)
:label (i18n/label :t/from-capitalized)
:contact-accessibility-label :sender-text
:address-accessibility-label :sender-address-text
:contact from-contact
:address from)
(assoc transaction
:label (i18n/label :t/to)
:label (i18n/label :t/to-capitalized)
:contact-accessibility-label :recipient-name-text
:address-accessibility-label :recipient-address-text
:contact to-contact

View File

@ -625,7 +625,8 @@
"follow-your-interests": "Jump into a public chat and meet new people",
"follow": "Follow",
"free": "↓ Free",
"from": "From",
"from-capitalized": "From",
"from": "from",
"gas-limit": "Gas limit",
"gas-price": "Gas price",
"gas-used": "Gas used",
@ -687,6 +688,7 @@
"profile-pic-take": "Take photo",
"profile-pic-pick": "Select from gallery",
"profile-pic-remove": "Remove photo",
"in": "in",
"in-contacts": "In contacts",
"incoming": "Incoming",
"incoming-transaction": "Incoming transaction",
@ -1330,7 +1332,8 @@
"this-will-take-few-seconds": "This will take a few seconds",
"three-words-description": "You should see these 3 words before signing each transaction",
"three-words-description-2": "If you see a different combination, cancel the transaction and sign out",
"to": "To",
"to": "to",
"to-capitalized": "To",
"to-block": "Block",
"to-encrypt-enter-password": "To encrypt the account please enter your password",
"to-see-this-message": "To see this message,",
@ -2294,5 +2297,9 @@
"add-address-description": "Watch a public address or ENS name",
"colour": "Colour",
"origin": "Origin",
"slide-create": "Slide to create account"
"slide-create": "Slide to create account",
"destroy": "Destroy",
"mint": "Mint",
"via": "via",
"x-counter": "x{{counter}}"
}