diff --git a/resources/images/icons2/12x12/diamond@2x.png b/resources/images/icons2/12x12/diamond@2x.png index 27617f8a99..a78fbe23fc 100644 Binary files a/resources/images/icons2/12x12/diamond@2x.png and b/resources/images/icons2/12x12/diamond@2x.png differ diff --git a/resources/images/icons2/12x12/diamond@3x.png b/resources/images/icons2/12x12/diamond@3x.png index fce0f3aa94..84761f6526 100644 Binary files a/resources/images/icons2/12x12/diamond@3x.png and b/resources/images/icons2/12x12/diamond@3x.png differ diff --git a/src/quo2/components/wallet/wallet_activity/component_spec.cljs b/src/quo2/components/wallet/wallet_activity/component_spec.cljs new file mode 100644 index 0000000000..11915c5f60 --- /dev/null +++ b/src/quo2/components/wallet/wallet_activity/component_spec.cljs @@ -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)))) diff --git a/src/quo2/components/wallet/wallet_activity/style.cljs b/src/quo2/components/wallet/wallet_activity/style.cljs new file mode 100644 index 0000000000..97a2548701 --- /dev/null +++ b/src/quo2/components/wallet/wallet_activity/style.cljs @@ -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}) + diff --git a/src/quo2/components/wallet/wallet_activity/view.cljs b/src/quo2/components/wallet/wallet_activity/view.cljs new file mode 100644 index 0000000000..1f5026eb26 --- /dev/null +++ b/src/quo2/components/wallet/wallet_activity/view.cljs @@ -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)) diff --git a/src/quo2/core.cljs b/src/quo2/core.cljs index 5615d33f96..f6996215e9 100644 --- a/src/quo2/core.cljs +++ b/src/quo2/core.cljs @@ -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) diff --git a/src/quo2/core_spec.cljs b/src/quo2/core_spec.cljs index cc3f0b4ec6..899dfcfaeb 100644 --- a/src/quo2/core_spec.cljs +++ b/src/quo2/core_spec.cljs @@ -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])) diff --git a/src/status_im/ui/screens/signing/views.cljs b/src/status_im/ui/screens/signing/views.cljs index 47ead29c21..c61be68678 100644 --- a/src/status_im/ui/screens/signing/views.cljs +++ b/src/status_im/ui/screens/signing/views.cljs @@ -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? diff --git a/src/status_im/ui/screens/wallet/send/views.cljs b/src/status_im/ui/screens/wallet/send/views.cljs index 23587d67db..2f65f67bd1 100644 --- a/src/status_im/ui/screens/wallet/send/views.cljs +++ b/src/status_im/ui/screens/wallet/send/views.cljs @@ -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?]]]]] diff --git a/src/status_im/ui/screens/wallet/transactions/views.cljs b/src/status_im/ui/screens/wallet/transactions/views.cljs index cedfdd110c..430a50dfab 100644 --- a/src/status_im/ui/screens/wallet/transactions/views.cljs +++ b/src/status_im/ui/screens/wallet/transactions/views.cljs @@ -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) diff --git a/src/status_im2/contexts/quo_preview/main.cljs b/src/status_im2/contexts/quo_preview/main.cljs index acf3704450..fc8950bc14 100644 --- a/src/status_im2/contexts/quo_preview/main.cljs +++ b/src/status_im2/contexts/quo_preview/main.cljs @@ -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 diff --git a/src/status_im2/contexts/quo_preview/wallet/wallet_activity.cljs b/src/status_im2/contexts/quo_preview/wallet/wallet_activity.cljs new file mode 100644 index 0000000000..8cd4fda82d --- /dev/null +++ b/src/status_im2/contexts/quo_preview/wallet/wallet_activity.cljs @@ -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)]]]))) diff --git a/src/status_im2/subs/wallet/transactions.cljs b/src/status_im2/subs/wallet/transactions.cljs index 9fba0449c6..e672772b7b 100644 --- a/src/status_im2/subs/wallet/transactions.cljs +++ b/src/status_im2/subs/wallet/transactions.cljs @@ -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 diff --git a/translations/en.json b/translations/en.json index fe59cdae76..c6460bf173 100644 --- a/translations/en.json +++ b/translations/en.json @@ -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}}" }