From 4f9544d20cf4a54675d4fd561ae9d9029e46fd50 Mon Sep 17 00:00:00 2001 From: Omar Basem Date: Thu, 21 Dec 2023 22:07:27 +0400 Subject: [PATCH] Wallet: receive screen (#18167) * wallet: receive screen --- .../components/drawers/drawer_top/style.cljs | 7 +- .../components/drawers/drawer_top/view.cljs | 3 +- .../settings/category/settings/view.cljs | 13 +- .../components/settings/category/style.cljs | 10 +- .../components/settings/data_item/style.cljs | 13 +- .../components/settings/data_item/view.cljs | 7 +- .../settings/settings_item/view.cljs | 7 +- .../share/share_qr_code/component_spec.cljs | 8 -- .../components/share/share_qr_code/style.cljs | 36 ++--- .../components/share/share_qr_code/view.cljs | 136 +++++++----------- .../components/wallet/address_text/style.cljs | 10 +- src/status_im/common/qr_codes/view.cljs | 2 +- .../contexts/wallet/account/view.cljs | 9 +- .../sheets/network_preferences/style.cljs | 11 +- .../sheets/network_preferences/view.cljs | 28 +++- .../contexts/wallet/common/utils.cljs | 15 ++ .../contexts/wallet/common/utils_test.cljs | 18 +++ .../contexts/wallet/receive/style.cljs | 5 + .../contexts/wallet/receive/view.cljs | 95 ++++++++++++ src/status_im/core_spec.cljs | 3 +- src/status_im/navigation/screens.cljs | 5 + 21 files changed, 282 insertions(+), 159 deletions(-) create mode 100644 src/status_im/contexts/wallet/common/utils_test.cljs create mode 100644 src/status_im/contexts/wallet/receive/style.cljs create mode 100644 src/status_im/contexts/wallet/receive/view.cljs diff --git a/src/quo/components/drawers/drawer_top/style.cljs b/src/quo/components/drawers/drawer_top/style.cljs index 8a674daf41..3a7a03a923 100644 --- a/src/quo/components/drawers/drawer_top/style.cljs +++ b/src/quo/components/drawers/drawer_top/style.cljs @@ -12,9 +12,10 @@ (defn description [theme blur?] - {:color (if blur? - colors/white-opa-40 - (colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}) + {:color (if blur? + colors/white-opa-40 + (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)) + :margin-top 2}) (def left-container {:margin-right 8 diff --git a/src/quo/components/drawers/drawer_top/view.cljs b/src/quo/components/drawers/drawer_top/view.cljs index d775d2d47e..b76fc09fce 100644 --- a/src/quo/components/drawers/drawer_top/view.cljs +++ b/src/quo/components/drawers/drawer_top/view.cljs @@ -160,7 +160,8 @@ [rn/view {:style style/title-container} [text/text {:size :heading-2 - :weight :semi-bold} + :weight :semi-bold + :style {:color (when blur? colors/white)}} title] (when title-icon [icons/icon title-icon diff --git a/src/quo/components/settings/category/settings/view.cljs b/src/quo/components/settings/category/settings/view.cljs index 18073c404c..df2b68c7ec 100644 --- a/src/quo/components/settings/category/settings/view.cljs +++ b/src/quo/components/settings/category/settings/view.cljs @@ -3,23 +3,22 @@ [quo.components.markdown.text :as text] [quo.components.settings.category.style :as style] [quo.components.settings.settings-item.view :as settings-item] - [quo.foundations.colors :as colors] [quo.theme :as quo.theme] [react-native.core :as rn])) (defn- category-internal - [{:keys [label data blur? container-style theme]}] - [rn/view {:style (merge (style/container label) container-style)} + [{:keys [label data] :as props}] + [rn/view {:style (style/container label)} (when label [text/text {:weight :medium :size :paragraph-2 - :style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}} + :style (style/label props)} label]) [rn/flat-list {:data data - :style (style/settings-items theme blur?) - :render-fn (fn [item] [settings-item/view item]) - :separator [rn/view {:style (style/settings-separator theme blur?)}]}]]) + :style (style/settings-items props) + :render-fn settings-item/view + :separator [rn/view {:style (style/settings-separator props)}]}]]) (def settings-category (quo.theme/with-theme category-internal)) diff --git a/src/quo/components/settings/category/style.cljs b/src/quo/components/settings/category/style.cljs index dd39ddd1fe..e10db83a51 100644 --- a/src/quo/components/settings/category/style.cljs +++ b/src/quo/components/settings/category/style.cljs @@ -11,7 +11,7 @@ :padding-bottom 8}) (defn settings-items - [theme blur?] + [{:keys [blur? theme]}] {:margin-top 12 :border-radius 16 :background-color (if blur? @@ -22,11 +22,17 @@ colors/white-opa-5 (colors/theme-colors colors/neutral-10 colors/neutral-80 theme))}) +(defn label + [{:keys [blur? theme]}] + {:color (if blur? + colors/white-opa-40 + (colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}) + (def reorder-items {:margin-top 12}) (defn settings-separator - [theme blur?] + [{:keys [blur? theme]}] {:height 1 :background-color (if blur? colors/white-opa-5 diff --git a/src/quo/components/settings/data_item/style.cljs b/src/quo/components/settings/data_item/style.cljs index f05877e690..a9436f7895 100644 --- a/src/quo/components/settings/data_item/style.cljs +++ b/src/quo/components/settings/data_item/style.cljs @@ -10,6 +10,9 @@ :padding-horizontal (when (= size :default) 12) :border-radius 16 :border-width (when (and card? (not= size :small)) 1) + :background-color (if blur? + colors/white-opa-5 + (colors/theme-colors colors/white colors/neutral-95 theme)) :border-color (if blur? colors/white-opa-10 (colors/theme-colors colors/neutral-10 @@ -42,10 +45,12 @@ :justify-content :center}) (defn title - [theme] - {:color (colors/theme-colors colors/neutral-50 - colors/neutral-40 - theme) + [blur? theme] + {:color (if blur? + colors/white-opa-40 + (colors/theme-colors colors/neutral-50 + colors/neutral-40 + theme)) :margin-right 4}) (def title-container diff --git a/src/quo/components/settings/data_item/view.cljs b/src/quo/components/settings/data_item/view.cljs index 98da9fc25d..a0ecaa7b5d 100644 --- a/src/quo/components/settings/data_item/view.cljs +++ b/src/quo/components/settings/data_item/view.cljs @@ -44,18 +44,18 @@ subtitle]]) (defn- left-title - [{:keys [title label size theme]}] + [{:keys [title label size blur? theme]}] [rn/view {:style style/title-container} [text/text {:weight :regular :size :paragraph-2 - :style (style/title theme)} + :style (style/title blur? theme)} title] (when (and (= :graph label) (not= :small size)) [text/text {:weight :regular :size :label - :style (style/title theme)} + :style (style/title blur? theme)} (i18n/label :t/days)])]) (defn- left-side @@ -68,6 +68,7 @@ {:title title :label label :size size + :blur? blur? :theme theme}] (if (= status :loading) [left-loading diff --git a/src/quo/components/settings/settings_item/view.cljs b/src/quo/components/settings/settings_item/view.cljs index f7cdd2464f..5029909fbd 100644 --- a/src/quo/components/settings/settings_item/view.cljs +++ b/src/quo/components/settings/settings_item/view.cljs @@ -10,6 +10,7 @@ [quo.components.settings.settings-item.style :as style] [quo.components.tags.context-tag.view :as context-tag] [quo.components.tags.status-tags :as status-tags] + [quo.foundations.colors :as colors] [quo.theme :as quo.theme] [react-native.core :as rn] [utils.i18n :as i18n])) @@ -101,7 +102,7 @@ nil)]) (defn- internal-view - [{:keys [title on-press action-props accessibility-label container-style] :as props}] + [{:keys [title on-press action-props accessibility-label blur? container-style] :as props}] [rn/pressable {:style (merge style/container container-style) :on-press on-press @@ -109,7 +110,9 @@ [rn/view {:style (style/left-sub-container props)} [image-component props] [rn/view {:style style/left-container} - [text/text {:weight :medium} title] + [text/text + {:weight :medium + :style {:color (when blur? colors/white)}} title] [description-component props] [tag-component props]]] [rn/view {:style (style/sub-container (:alignment action-props))} diff --git a/src/quo/components/share/share_qr_code/component_spec.cljs b/src/quo/components/share/share_qr_code/component_spec.cljs index 00864029df..26991c26d5 100644 --- a/src/quo/components/share/share_qr_code/component_spec.cljs +++ b/src/quo/components/share/share_qr_code/component_spec.cljs @@ -73,10 +73,6 @@ :accessibility-label :link-to-profile :event-name :press :callback-prop-key :on-share-press} - {:test-name "Info icon pressed" - :accessibility-label :share-qr-code-info-icon - :event-name :press - :callback-prop-key :on-info-press} {:test-name "Legacy tab pressed" :accessibility-label :share-qr-code-legacy-tab :event-name :press @@ -101,10 +97,6 @@ :accessibility-label :link-to-profile :event-name :press :callback-prop-key :on-share-press} - {:test-name "Info icon pressed" - :accessibility-label :share-qr-code-info-icon - :event-name :press - :callback-prop-key :on-info-press} {:test-name "Legacy tab pressed" :accessibility-label :share-qr-code-legacy-tab :event-name :press diff --git a/src/quo/components/share/share_qr_code/style.cljs b/src/quo/components/share/share_qr_code/style.cljs index 3dfb5f3029..96f8ef5bbc 100644 --- a/src/quo/components/share/share_qr_code/style.cljs +++ b/src/quo/components/share/share_qr_code/style.cljs @@ -25,17 +25,20 @@ (def header-tab-inactive {:background-color colors/white-opa-5}) (def space-between-tabs {:width 8}) -(def info-icon - {:margin-left :auto - :align-self :center}) - -(def info-icon-color colors/white-opa-40) - ;;; QR code (defn qr-code-size [total-width] (- total-width (* 2 padding-horizontal))) +(def share-qr-container + {:flex-direction :row + :justify-content :space-between + :margin-bottom 20}) + +(def share-qr-inner-container + {:flex-direction :row + :align-items :center}) + ;;; Bottom part (def bottom-container {:margin-top 8 @@ -57,29 +60,12 @@ {:width (- total-width (* 2 padding-horizontal) share-button-size share-button-gap)}) ;;; Wallet variants -(def wallet-data-and-share-container - {:margin-top 2 - :flex-direction :row - :justify-content :space-between}) - -(def wallet-legacy-container {:flex 1}) - -(def wallet-multichain-container {:flex 1 :margin-top 4}) - -(def wallet-multichain-networks +(def wallet-multichain-container {:flex-direction :row :justify-content :space-between - :margin-bottom 8}) - -(def wallet-multichain-data-container {:margin-top 4}) + :flex 1}) ;;; Dashed line -(def divider-container - {:height 8 - :margin-horizontal 4 - :justify-content :center - :overflow :hidden}) - (def ^:private padding-for-divider (+ padding-horizontal 4)) (def ^:private dashed-line-width 2) (def ^:private dashed-line-space 4) diff --git a/src/quo/components/share/share_qr_code/view.cljs b/src/quo/components/share/share_qr_code/view.cljs index 52c5aa0fc7..fa02c018b6 100644 --- a/src/quo/components/share/share_qr_code/view.cljs +++ b/src/quo/components/share/share_qr_code/view.cljs @@ -2,14 +2,12 @@ (:require [clojure.set] [clojure.string :as string] [oops.core :as oops] + [quo.components.avatars.account-avatar.view :as account-avatar] [quo.components.buttons.button.view :as button] - [quo.components.icon :as icon] - [quo.components.list-items.preview-list.view :as preview-list] [quo.components.markdown.text :as text] [quo.components.share.qr-code.view :as qr-code] [quo.components.share.share-qr-code.style :as style] [quo.components.tabs.tab.view :as tab] - [quo.foundations.resources :as quo.resources] [quo.theme] [react-native.blur :as blur] [react-native.core :as rn] @@ -17,17 +15,8 @@ [reagent.core :as reagent] [utils.i18n :as i18n])) -(defn- line [] [rn/view {:style style/line}]) -(defn- space [] [rn/view {:style style/line-space}]) - -(defn- dashed-line - [width] - (into [rn/view {:style style/dashed-line}] - (take (style/number-lines-and-spaces-to-fill width)) - (cycle [[line] [space]]))) - (defn- header - [{:keys [share-qr-type on-info-press on-legacy-press on-multichain-press]}] + [{:keys [share-qr-type on-legacy-press on-multichain-press]}] [rn/view {:style style/header-container} [tab/view {:accessibility-label :share-qr-code-legacy-tab @@ -47,22 +36,13 @@ :size 24 :active (= :wallet-multichain share-qr-type) :on-press on-multichain-press} - (i18n/label :t/multichain)] - [rn/pressable - {:accessibility-label :share-qr-code-info-icon - :style style/info-icon - :on-press on-info-press - :hit-slop 6} - [icon/icon :i/info - {:size 20 - :color style/info-icon-color}]]]) + (i18n/label :t/multichain)]]) (defn- info-label [share-qr-code-type] [text/text {:size :paragraph-2 :weight :medium :style style/title} - (if (= share-qr-code-type :profile) - (i18n/label :t/link-to-profile) - (i18n/label :t/wallet-address))]) + (when (= share-qr-code-type :profile) + (i18n/label :t/link-to-profile))]) (defn- info-text [{:keys [width on-press on-long-press ellipsize?]} qr-data-text] @@ -106,74 +86,60 @@ (conj $ address)))) (defn- profile-bottom - [{:keys [component-width qr-data on-text-press on-text-long-press on-share-press share-qr-type]}] - [:<> - [rn/view - [info-label share-qr-type] - [info-text - {:width component-width - :ellipsize? true - :on-press on-text-press - :on-long-press on-text-long-press} - qr-data]] - [share-button - {:alignment :center - :on-press on-share-press}]]) + [{:keys [component-width qr-data on-text-press on-text-long-press share-qr-type]}] + [rn/view + [info-label share-qr-type] + [info-text + {:width component-width + :ellipsize? true + :on-press on-text-press + :on-long-press on-text-long-press} + qr-data]]) (defn- wallet-legacy-bottom - [{:keys [share-qr-type component-width qr-data on-text-press on-text-long-press on-share-press]}] - [rn/view {:style style/wallet-legacy-container} - [info-label share-qr-type] - [rn/view {:style style/wallet-data-and-share-container} - [info-text - {:width component-width - :on-press on-text-press - :on-long-press on-text-long-press} - qr-data] - [share-button - {:alignment :top - :on-press on-share-press}]]]) - -(def ^:private known-networks #{:ethereum :optimism :arbitrum}) - -(defn- get-network-image-source - [network] - {:source (quo.resources/get-network (get known-networks network :unknown))}) + [{:keys [component-width qr-data on-text-press on-text-long-press]}] + [info-text + {:width component-width + :on-press on-text-press + :on-long-press on-text-long-press} + qr-data]) (defn wallet-multichain-bottom - [{:keys [share-qr-type component-width qr-data on-text-press on-text-long-press - on-share-press networks on-settings-press]}] - [rn/view {:style style/wallet-multichain-container} - [rn/view {:style style/wallet-multichain-networks} - [preview-list/view {:type :network :size :size-32} - (map get-network-image-source networks)] - [button/button - {:icon-only? true - :type :grey - :background :blur - :size 32 - :accessibility-label :share-qr-code-settings - :on-press on-settings-press} - :i/advanced]] - [rn/view {:style style/divider-container} - [dashed-line component-width]] - [rn/view {:style style/wallet-multichain-data-container} - [info-label share-qr-type] - [rn/view {:style style/wallet-data-and-share-container} - [info-text - {:width component-width - :on-press on-text-press - :on-long-press on-text-long-press} - [wallet-multichain-colored-address qr-data]] - [share-button - {:alignment :top - :on-press on-share-press}]]]]) + [{:keys [component-width qr-data on-text-press on-text-long-press on-settings-press]}] + [rn/view + {:style style/wallet-multichain-container} + [info-text + {:width component-width + :on-press on-text-press + :on-long-press on-text-long-press} + [wallet-multichain-colored-address qr-data]] + [button/button + {:icon-only? true + :type :grey + :background :blur + :size 32 + :accessibility-label :share-qr-code-settings + :on-press on-settings-press} + :i/advanced]]) (defn- share-qr-code [{:keys [share-qr-type qr-image-uri component-width customization-color full-name - profile-picture emoji] + profile-picture emoji on-share-press] :as props}] [rn/view {:style style/content-container} + [rn/view + {:style style/share-qr-container} + [rn/view + {:style style/share-qr-inner-container} + [account-avatar/view + {:customization-color customization-color + :emoji emoji + :size 32}] + [text/text + {:size :heading-2 + :weight :semi-bold + :style {:margin-left 8}} full-name]] + [share-button {:on-press on-share-press}]] (when (#{:wallet-legacy :wallet-multichain} share-qr-type) [header props]) [quo.theme/provider {:theme :light} @@ -211,14 +177,12 @@ - profile-picture: map ({:source image-source}) or any image source. `:wallet-legacy` - emoji: Emoji in a string to show in the QR code. - - on-info-press: Callback for the info icon. - on-legacy-press: Callback for the legacy tab. - on-multichain-press: Callback for the multichain tab. `:wallet-multichain` - networks: A vector of network names as keywords (`[:ethereum, :my-net, ...]`). - on-settings-press: Callback for the settings button. - emoji: Emoji in a string to show in the QR code. - - on-info-press: Callback for the info icon. - on-legacy-press: Callback for the legacy tab. - on-multichain-press: Callback for the multichain tab. diff --git a/src/quo/components/wallet/address_text/style.cljs b/src/quo/components/wallet/address_text/style.cljs index fadfc4ecbd..396c0ad15b 100644 --- a/src/quo/components/wallet/address_text/style.cljs +++ b/src/quo/components/wallet/address_text/style.cljs @@ -3,7 +3,9 @@ (defn address-text [format blur? theme] - (when (= format :short) - {:color (if blur? - colors/white-opa-40 - (colors/theme-colors colors/neutral-50 colors/neutral-40 theme))})) + (if (and (= format :long) blur?) + {:color colors/white} + (when (= format :short) + {:color (if blur? + colors/white-opa-40 + (colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}))) diff --git a/src/status_im/common/qr_codes/view.cljs b/src/status_im/common/qr_codes/view.cljs index fa7adce7ad..1594a15560 100644 --- a/src/status_im/common/qr_codes/view.cljs +++ b/src/status_im/common/qr_codes/view.cljs @@ -37,7 +37,7 @@ :error-level :highest})] [quo/qr-code (assoc props :qr-image-uri qr-media-server-uri)])) -(defn- get-network-short-name-url +(defn get-network-short-name-url [network] (case network :ethereum "eth:" diff --git a/src/status_im/contexts/wallet/account/view.cljs b/src/status_im/contexts/wallet/account/view.cljs index 47b0e3d806..5f4dc180a8 100644 --- a/src/status_im/contexts/wallet/account/view.cljs +++ b/src/status_im/contexts/wallet/account/view.cljs @@ -47,10 +47,11 @@ [quo/wallet-graph {:time-frame :empty}] (when (not watch-only?) [quo/wallet-ctas - {:send-action #(rf/dispatch [:open-modal :wallet-select-address]) - :buy-action #(rf/dispatch [:show-bottom-sheet - {:content buy-drawer}]) - :bridge-action #(rf/dispatch [:open-modal :wallet-bridge])}]) + {:send-action #(rf/dispatch [:open-modal :wallet-select-address]) + :receive-action #(rf/dispatch [:open-modal :wallet-receive]) + :buy-action #(rf/dispatch [:show-bottom-sheet + {:content buy-drawer}]) + :bridge-action #(rf/dispatch [:open-modal :wallet-bridge])}]) [quo/tabs {:style style/tabs :size 32 diff --git a/src/status_im/contexts/wallet/common/sheets/network_preferences/style.cljs b/src/status_im/contexts/wallet/common/sheets/network_preferences/style.cljs index db3312130b..8668afe5ba 100644 --- a/src/status_im/contexts/wallet/common/sheets/network_preferences/style.cljs +++ b/src/status_im/contexts/wallet/common/sheets/network_preferences/style.cljs @@ -1,4 +1,13 @@ -(ns status-im.contexts.wallet.common.sheets.network-preferences.style) +(ns status-im.contexts.wallet.common.sheets.network-preferences.style + (:require [quo.foundations.colors :as colors])) + +(def blur + {:position :absolute + :top 0 + :left 0 + :right 0 + :bottom 0 + :overlay-color colors/neutral-100-opa-70-blur}) (def data-item {:margin-horizontal 20 diff --git a/src/status_im/contexts/wallet/common/sheets/network_preferences/view.cljs b/src/status_im/contexts/wallet/common/sheets/network_preferences/view.cljs index 5b8cf52630..4cc47f72e2 100644 --- a/src/status_im/contexts/wallet/common/sheets/network_preferences/view.cljs +++ b/src/status_im/contexts/wallet/common/sheets/network_preferences/view.cljs @@ -4,6 +4,7 @@ [quo.foundations.colors :as colors] [quo.foundations.resources :as resources] [quo.theme :as quo.theme] + [react-native.blur :as blur] [reagent.core :as reagent] [status-im.contexts.wallet.common.sheets.network-preferences.style :as style] [utils.i18n :as i18n] @@ -12,8 +13,9 @@ (defn- make-network-item [{:keys [network-name] :as _network} - {:keys [title color on-change network-preferences state] :as _options}] + {:keys [title color on-change network-preferences state blur?] :as _options}] {:title (or title (string/capitalize (name network-name))) + :blur? blur? :image :icon-avatar :image-props {:icon (resources/get-network network-name) :size :size-20} @@ -26,11 +28,11 @@ :on-change on-change}}) (defn- view-internal - [] + [{:keys [selected-networks]}] (let [state (reagent/atom :default) {:keys [color address network-preferences-names]} (rf/sub [:wallet/current-viewing-account]) - initial-network-preferences-names network-preferences-names + initial-network-preferences-names (or selected-networks network-preferences-names) network-preferences-names-state (reagent/atom #{}) toggle-network (fn [network-name] (reset! state :changed) @@ -44,7 +46,7 @@ (if (= @state :default) initial-network-preferences-names @network-preferences-names-state))] - (fn [{:keys [on-save theme]}] + (fn [{:keys [on-save blur? theme]}] (let [network-details (rf/sub [:wallet/network-details]) mainnet (first network-details) layer-2-networks (rest network-details) @@ -53,21 +55,29 @@ (:network-name network))) network-details)] [:<> + ;; quo/overlay isn't compatible with sheets + (when blur? + [blur/view + {:style style/blur + :blur-amount 20 + :blur-radius 25}]) [quo/drawer-top {:title (i18n/label :t/network-preferences) - :description (i18n/label :t/network-preferences-desc)}] + :description (i18n/label :t/network-preferences-desc) + :blur? blur?}] [quo/data-item {:status :default :size :default :description :default :label :none - :blur? false + :blur? blur? :card? true :title (i18n/label :t/address) :custom-subtitle (fn [] [quo/address-text {:networks current-networks :address address + :blur? blur? :format :long}]) :container-style (merge style/data-item {:background-color (colors/theme-colors colors/neutral-2_5 @@ -75,26 +85,30 @@ theme)})}] [quo/category {:list-type :settings + :blur? blur? :data [(make-network-item mainnet {:state @state :title (i18n/label :t/mainnet) :color color + :blur? blur? :network-preferences (get-current-preferences-names) :on-change #(toggle-network (:network-name mainnet))})]}] [quo/category {:list-type :settings + :blur? blur? :label (i18n/label :t/layer-2) :data (mapv (fn [network] (make-network-item network {:state @state :color color + :blur? blur? :network-preferences (get-current-preferences-names) :on-change #(toggle-network (:network-name network))})) layer-2-networks)}] [quo/bottom-actions - {:button-one-label (i18n/label :t/confirm) + {:button-one-label (i18n/label :t/update) :button-one-props {:disabled? (= @state :default) :on-press (fn [] (let [chain-ids (map :chain-id current-networks)] diff --git a/src/status_im/contexts/wallet/common/utils.cljs b/src/status_im/contexts/wallet/common/utils.cljs index b7c4329547..15dfd1394e 100644 --- a/src/status_im/contexts/wallet/common/utils.cljs +++ b/src/status_im/contexts/wallet/common/utils.cljs @@ -1,5 +1,6 @@ (ns status-im.contexts.wallet.common.utils (:require [clojure.string :as string] + [status-im.common.qr-codes.view :as qr-codes] [status-im.constants :as constants] [utils.money :as money] [utils.number])) @@ -98,3 +99,17 @@ (defn calculate-fiat-change [fiat-value change-pct-24hour] (money/bignumber (* fiat-value (/ change-pct-24hour (+ 100 change-pct-24hour))))) + +(defn get-wallet-qr + [{:keys [wallet-type selected-networks address]}] + (if (= wallet-type :wallet-multichain) + (as-> selected-networks $ + (map qr-codes/get-network-short-name-url $) + (apply str $) + (str $ address)) + address)) + +(def id-to-network + {constants/mainnet-chain-id :ethereum + constants/optimism-chain-id :optimism + constants/arbitrum-chain-id :arbitrum}) diff --git a/src/status_im/contexts/wallet/common/utils_test.cljs b/src/status_im/contexts/wallet/common/utils_test.cljs new file mode 100644 index 0000000000..4bbb654f3c --- /dev/null +++ b/src/status_im/contexts/wallet/common/utils_test.cljs @@ -0,0 +1,18 @@ +(ns status-im.contexts.wallet.common.utils-test + (:require [cljs.test :refer [deftest is testing]] + [status-im.contexts.wallet.common.utils :as utils])) + +(deftest test-get-wallet-qr + (testing "Test get-wallet-qr function" + (let [wallet-multichain {:wallet-type :wallet-multichain + :selected-networks [:ethereum :optimism] + :address "x000"} + wallet-singlechain {:wallet-type :wallet-singlechain + :selected-networks [:ethereum :optimism] + :address "x000"}] + + (is (= (utils/get-wallet-qr wallet-multichain) + "eth:opt:x000")) + + (is (= (utils/get-wallet-qr wallet-singlechain) + "x000"))))) diff --git a/src/status_im/contexts/wallet/receive/style.cljs b/src/status_im/contexts/wallet/receive/style.cljs new file mode 100644 index 0000000000..e4dc1a9b6c --- /dev/null +++ b/src/status_im/contexts/wallet/receive/style.cljs @@ -0,0 +1,5 @@ +(ns status-im.contexts.wallet.receive.style) + +(def header-container + {:padding-horizontal 20 + :padding-vertical 12}) diff --git a/src/status_im/contexts/wallet/receive/view.cljs b/src/status_im/contexts/wallet/receive/view.cljs new file mode 100644 index 0000000000..8f1b861a10 --- /dev/null +++ b/src/status_im/contexts/wallet/receive/view.cljs @@ -0,0 +1,95 @@ +(ns status-im.contexts.wallet.receive.view + (:require + [quo.core :as quo] + [react-native.core :as rn] + [react-native.platform :as platform] + [react-native.safe-area :as safe-area] + [react-native.share :as share] + [reagent.core :as reagent] + [status-im.contexts.wallet.common.sheets.network-preferences.view :as network-preferences] + [status-im.contexts.wallet.common.utils :as utils] + [status-im.contexts.wallet.receive.style :as style] + [utils.i18n :as i18n] + [utils.image-server :as image-server] + [utils.re-frame :as rf])) + +(def qr-size 500) + +(defn- share-action + [address share-title] + (share/open + (if platform/ios? + {:activity-item-sources [{:placeholder-item {:type "text" + :content address} + :item {:default {:type "text" + :content + address}} + :link-metadata {:title share-title}}]} + {:title share-title + :subject share-title + :message address}))) + +(defn- open-preferences + [selected-networks] + (rf/dispatch [:show-bottom-sheet + {:theme :dark + :shell? true + :content + (fn [] + [network-preferences/view + {:blur? true + :selected-networks (set @selected-networks) + :on-save (fn [chain-ids] + (rf/dispatch [:hide-bottom-sheet]) + (reset! selected-networks (map #(get utils/id-to-network %) + chain-ids)))}])}])) + + +(defn view + [] + (let [padding-top (:top (safe-area/get-insets)) + wallet-type (reagent/atom :wallet-legacy) + ;; Design team is yet to confirm the default selected networks here. + ;; Should be the current selected for the account or all the networks always + selected-networks (reagent/atom [:ethereum :optimism :arbitrum])] + (fn [] + (let [{:keys [address color emoji] :as account} (rf/sub [:wallet/current-viewing-account]) + share-title (str (:name account) " " (i18n/label :t/address)) + qr-url (utils/get-wallet-qr {:wallet-type @wallet-type + :selected-networks + @selected-networks + :address address}) + qr-media-server-uri (image-server/get-qr-image-uri-for-any-url + {:url qr-url + :port (rf/sub [:mediaserver/port]) + :qr-size qr-size + :error-level :highest})] + [quo/overlay {:type :shell} + [rn/view + {:flex 1 + :padding-top padding-top} + [quo/page-nav + {:icon-name :i/close + :on-press #(rf/dispatch [:navigate-back]) + :background :blur + :right-side [{:icon-name :i/scan + :on-press #(js/alert "To be implemented")}] + :accessibility-label :top-bar}] + [quo/text-combinations + {:container-style style/header-container + :title (i18n/label :t/receive)}] + [rn/view {:style {:padding-horizontal 20}} + [quo/share-qr-code + {:type @wallet-type + :qr-image-uri qr-media-server-uri + :qr-data qr-url + :networks @selected-networks + :on-share-press #(share-action qr-url share-title) + :profile-picture nil + :unblur-on-android? true + :full-name (:name account) + :customization-color color + :emoji emoji + :on-legacy-press #(reset! wallet-type :wallet-legacy) + :on-multichain-press #(reset! wallet-type :wallet-multichain) + :on-settings-press #(open-preferences selected-networks)}]]]])))) diff --git a/src/status_im/core_spec.cljs b/src/status_im/core_spec.cljs index e9431afab6..369de1e371 100644 --- a/src/status_im/core_spec.cljs +++ b/src/status_im/core_spec.cljs @@ -5,5 +5,6 @@ [status-im.contexts.communities.actions.community-options.component-spec] [status-im.contexts.wallet.add-address-to-watch.component-spec] [status-im.contexts.wallet.add-address-to-watch.confirm-address.component-spec] - [status-im.contexts.wallet.create-account.edit-derivation-path.component-spec] [status-im.contexts.wallet.send.input-amount.component-spec])) + + ;; [status-im.contexts.wallet.create-account.edit-derivation-path.component-spec] diff --git a/src/status_im/navigation/screens.cljs b/src/status_im/navigation/screens.cljs index c3c8904f79..35c8ce9a8b 100644 --- a/src/status_im/navigation/screens.cljs +++ b/src/status_im/navigation/screens.cljs @@ -55,6 +55,7 @@ [status-im.contexts.wallet.create-account.select-keypair.view :as wallet-select-keypair] [status-im.contexts.wallet.create-account.view :as wallet-create-account] [status-im.contexts.wallet.edit-account.view :as wallet-edit-account] + [status-im.contexts.wallet.receive.view :as wallet-receive] [status-im.contexts.wallet.saved-addresses.view :as wallet-saved-addresses] [status-im.contexts.wallet.scan-account.view :as scan-address] [status-im.contexts.wallet.send.input-amount.view :as wallet-send-input-amount] @@ -315,6 +316,10 @@ :options {:insets {:top? true :bottom? true}} :component wallet-backup-recovery-phrase/view} + {:name :wallet-receive + :options options/transparent-screen-options + :component wallet-receive/view} + {:name :wallet-saved-addresses :component wallet-saved-addresses/view}