From 8f75761ae9480c6e7673c1a95f2acf77cc92f856 Mon Sep 17 00:00:00 2001 From: Parvesh Monu Date: Wed, 12 Jun 2024 18:29:28 +0530 Subject: [PATCH 01/11] fix continue button partially hidden on the Change password screen (#20409) --- .../ui/components/keyboard_avoid_presentation.cljs | 2 +- src/legacy/status_im/ui/components/react.cljs | 4 ++-- src/status_im/contexts/profile/profiles/view.cljs | 4 ++-- .../screens/password/change_password/style.cljs | 3 ++- .../screens/password/change_password/view.cljs | 10 +++++++--- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/legacy/status_im/ui/components/keyboard_avoid_presentation.cljs b/src/legacy/status_im/ui/components/keyboard_avoid_presentation.cljs index 2f68be6d04..e3e4a8bb8e 100644 --- a/src/legacy/status_im/ui/components/keyboard_avoid_presentation.cljs +++ b/src/legacy/status_im/ui/components/keyboard_avoid_presentation.cljs @@ -10,7 +10,7 @@ (reagent/as-element (into [react/keyboard-avoiding-view (update props - :keyboardVerticalOffset + :keyboard-vertical-offset + 20 (if (:ignore-offset props) 44 0))] diff --git a/src/legacy/status_im/ui/components/react.cljs b/src/legacy/status_im/ui/components/react.cljs index 43f9dc7bbe..ce9abf362c 100644 --- a/src/legacy/status_im/ui/components/react.cljs +++ b/src/legacy/status_im/ui/components/react.cljs @@ -275,7 +275,7 @@ (merge (when platform/ios? {:behavior :padding}) (if (:ignore-offset props) props - (update props :keyboardVerticalOffset + 44 (:status-bar-height @navigation-const))))] + (update props :keyboard-vertical-offset + 44 (:status-bar-height @navigation-const))))] children)) (defn keyboard-avoiding-view-new @@ -284,7 +284,7 @@ (merge (when platform/ios? {:behavior :padding}) (if (:ignore-offset props) props - (update props :keyboardVerticalOffset + 44)))] + (update props :keyboard-vertical-offset + 44)))] children)) (defn scroll-view diff --git a/src/status_im/contexts/profile/profiles/view.cljs b/src/status_im/contexts/profile/profiles/view.cljs index eeb3a43da3..73371204d1 100644 --- a/src/status_im/contexts/profile/profiles/view.cljs +++ b/src/status_im/contexts/profile/profiles/view.cljs @@ -195,8 +195,8 @@ profile-picture (rf/sub [:profile/login-profiles-picture key-uid]) login-multiaccount (rn/use-callback #(rf/dispatch [:profile.login/login]))] [rn/keyboard-avoiding-view - {:style style/login-container - :keyboardVerticalOffset (- (safe-area/get-bottom))} + {:style style/login-container + :keyboard-vertical-offset (- (safe-area/get-bottom))} [rn/view {:style style/multi-profile-button-container} (when config/quo-preview-enabled? [quo/button diff --git a/src/status_im/contexts/profile/settings/screens/password/change_password/style.cljs b/src/status_im/contexts/profile/settings/screens/password/change_password/style.cljs index 86d62f95ba..ceee6c82b5 100644 --- a/src/status_im/contexts/profile/settings/screens/password/change_password/style.cljs +++ b/src/status_im/contexts/profile/settings/screens/password/change_password/style.cljs @@ -1,6 +1,7 @@ (ns status-im.contexts.profile.settings.screens.password.change-password.style (:require [quo.foundations.colors :as colors] + [react-native.platform :as platform] [react-native.safe-area :as safe-area])) (def form-container @@ -48,7 +49,7 @@ :justify-content :space-between}) (def bottom-part - {:margin-bottom (- (safe-area/get-bottom) 12) + {:margin-bottom (if platform/ios? (safe-area/get-bottom) 12) :justify-content :flex-end}) (def disclaimer-container diff --git a/src/status_im/contexts/profile/settings/screens/password/change_password/view.cljs b/src/status_im/contexts/profile/settings/screens/password/change_password/view.cljs index 910efb64b7..0c050a8a6d 100644 --- a/src/status_im/contexts/profile/settings/screens/password/change_password/view.cljs +++ b/src/status_im/contexts/profile/settings/screens/password/change_password/view.cljs @@ -17,7 +17,7 @@ (defn view [] - (let [{:keys [top]} (safe-area/get-insets) + (let [{:keys [top bottom]} (safe-area/get-insets) alert-banners-top-margin (rf/sub [:alert-banners/top-margin]) current-step (rf/sub [:settings/change-password-current-step])] (rn/use-unmount #(rf/dispatch [:change-password/reset])) @@ -33,8 +33,12 @@ :icon-name :i/arrow-left :on-press navigate-back}] [rn/keyboard-avoiding-view - {:style {:flex 1} - :keyboardVerticalOffset (if platform/ios? alert-banners-top-margin 0)} + {:style {:flex 1} + :keyboard-vertical-offset (if platform/ios? + (-> 12 + (+ alert-banners-top-margin) + (- bottom)) + 0)} (condp = current-step :old-password [old-password-form/view] :new-password [new-password-form/view])]]])) From 3208ec1b28df43d5fec2fa6f30cbb426601f0918 Mon Sep 17 00:00:00 2001 From: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com> Date: Wed, 12 Jun 2024 19:38:17 +0530 Subject: [PATCH 02/11] feat(wallet): display saved addresses in send flow (#20418) This commit adds a feature to display saved addresses in the send flow Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com> --- .../wallet/send/select_address/tabs/view.cljs | 50 +++++++++++++++++-- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/src/status_im/contexts/wallet/send/select_address/tabs/view.cljs b/src/status_im/contexts/wallet/send/select_address/tabs/view.cljs index 809e81c4ae..6e3100ddce 100644 --- a/src/status_im/contexts/wallet/send/select_address/tabs/view.cljs +++ b/src/status_im/contexts/wallet/send/select_address/tabs/view.cljs @@ -46,16 +46,56 @@ :stack-id :screen/wallet.select-address}])}])) recent-recipients)))) +(defn- saved-address + [{:keys [name address chain-short-names customization-color ens? ens]}] + (let [full-address (str chain-short-names address) + on-press-saved-address (rn/use-callback + #(rf/dispatch + [:wallet/select-send-address + {:address full-address + :recipient full-address + :stack-id :screen/wallet.select-address}]) + [full-address])] + [quo/saved-address + {:user-props {:name name + :address full-address + :ens (when ens? ens) + :customization-color customization-color} + :container-style {:margin-horizontal 8} + :on-press on-press-saved-address}])) + +(defn- saved-addresses + [theme] + (let [group-saved-addresses (rf/sub [:wallet/grouped-saved-addresses]) + section-header (rn/use-callback + (fn [{:keys [title index]}] + [quo/divider-label + {:tight? true + :container-style (when (pos? index) {:margin-top 8})} + title])) + empty-state-component (rn/use-memo + (fn [] + [quo/empty-state + {:title (i18n/label :t/no-saved-addresses) + :description (i18n/label + :t/you-like-to-type-43-characters) + :image (resources/get-themed-image :sweating-man + theme)}]) + [theme])] + [rn/section-list + {:key-fn :title + :shows-vertical-scroll-indicator false + :render-section-header-fn section-header + :sections group-saved-addresses + :render-fn saved-address + :empty-component empty-state-component}])) + (defn view [{:keys [selected-tab]}] (let [theme (quo.theme/use-theme)] (case selected-tab :tab/recent [recent-transactions theme] - :tab/saved [quo/empty-state - {:title (i18n/label :t/no-saved-addresses) - :description (i18n/label :t/you-like-to-type-43-characters) - :image (resources/get-themed-image :sweating-man theme) - :container-style style/empty-container-style}] + :tab/saved [saved-addresses theme] :tab/contacts [quo/empty-state {:title (i18n/label :t/no-contacts) :description (i18n/label :t/no-contacts-description) From 60e1783b367738310dd19e4ec9f563d6294b17b3 Mon Sep 17 00:00:00 2001 From: Jamie Caprani Date: Wed, 12 Jun 2024 17:36:30 +0200 Subject: [PATCH 03/11] chore(wallet): show activity tab after sending a transaction --- src/quo/components/tabs/tabs/schema.cljs | 32 ++++++ src/quo/components/tabs/tabs/view.cljs | 47 +++----- .../contexts/wallet/account/view.cljs | 106 +++++++++--------- .../contexts/wallet/bridge/flow_config.cljs | 3 +- .../contexts/wallet/collectible/view.cljs | 1 + .../wallet/common/token_value/view.cljs | 2 + src/status_im/contexts/wallet/events.cljs | 15 +++ .../contexts/wallet/send/events.cljs | 25 +++-- .../contexts/wallet/send/flow_config.cljs | 3 +- .../send/transaction_progress/view.cljs | 2 +- src/status_im/navigation/events.cljs | 4 +- src/status_im/subs/wallet/wallet.cljs | 6 + 12 files changed, 149 insertions(+), 97 deletions(-) create mode 100644 src/quo/components/tabs/tabs/schema.cljs diff --git a/src/quo/components/tabs/tabs/schema.cljs b/src/quo/components/tabs/tabs/schema.cljs new file mode 100644 index 0000000000..e7d35323e6 --- /dev/null +++ b/src/quo/components/tabs/tabs/schema.cljs @@ -0,0 +1,32 @@ +(ns quo.components.tabs.tabs.schema) + +(def ^:private ?data + [:sequential + [:maybe + [:map + [:id [:or :int :keyword [:set :int]]] + [:label [:maybe :string]] + [:accessibility-label {:optional true} [:maybe [:or :keyword :string]]] + [:notification-dot? {:optional true} [:maybe :boolean]]]]]) + +(def ?schema + [:=> + [:catn + [:props + [:map + [:default-active {:optional true} [:maybe [:or :int :keyword]]] + [:active-tab-id {:optional true} [:maybe [:or :int :keyword]]] + [:data ?data] + [:fade-end-percentage {:optional true} [:or :double :string]] + [:fade-end? {:optional true} [:maybe :boolean]] + [:blur? {:optional true} [:maybe :boolean]] + [:on-change {:optional true} [:maybe fn?]] + [:on-scroll {:optional true} [:maybe fn?]] + [:scroll-on-press? {:optional true} [:maybe :boolean]] + [:scrollable? {:optional true} [:maybe :boolean]] + [:style {:optional true} [:maybe :map]] + [:container-style {:optional true} [:maybe :map]] + [:size {:optional true} [:maybe [:or :keyword :int]]] + [:in-scroll-view? {:optional true} [:maybe :boolean]] + [:customization-color {:optional true} [:maybe :schema.common/customization-color]]]]] + :any]) diff --git a/src/quo/components/tabs/tabs/view.cljs b/src/quo/components/tabs/tabs/view.cljs index 74b8cb0451..696af6c07a 100644 --- a/src/quo/components/tabs/tabs/view.cljs +++ b/src/quo/components/tabs/tabs/view.cljs @@ -2,12 +2,14 @@ (:require [oops.core :refer [oget]] [quo.components.tabs.tab.view :as tab] + [quo.components.tabs.tabs.schema :as component-schema] [quo.components.tabs.tabs.style :as style] [react-native.core :as rn] [react-native.gesture :as gesture] [react-native.linear-gradient :as linear-gradient] [react-native.masked-view :as masked-view] [reagent.core :as reagent] + [schema.core :as schema] [utils.collection :as utils.collection] [utils.number])) @@ -84,36 +86,20 @@ :on-press #(on-press % index)} label]]) -(defn view - " Common options (for scrollable and non-scrollable tabs): - - - `blur?` Boolean passed down to `quo.components.tabs.tab/tab`. - - `data` Vector of tab items. - - `on-change` Callback called after a tab is selected. - - `size` 32/24 - - `style` Style map passed to View wrapping tabs or to the FlatList when tabs - are scrollable. - - Options for scrollable tabs: - - `fade-end-percentage` Percentage where fading starts relative to the total - layout width of the `flat-list` data. - - `fade-end?` When non-nil, causes the end of the scrollable view to fade out. - - `on-scroll` Callback called on the on-scroll event of the FlatList. Only - used when `scrollable?` is non-nil. - - `scrollable?` When non-nil, use a scrollable flat-list to render tabs. - - `scroll-on-press?` When non-nil, clicking on a tag centers it the middle - (with animation enabled). - " +(defn- view-internal [{:keys [default-active data fade-end-percentage fade-end? on-change on-scroll scroll-on-press? - scrollable? style container-style size blur? in-scroll-view? customization-color] + scrollable? style container-style size blur? in-scroll-view? customization-color + active-tab-id] :or {fade-end-percentage 0.8 fade-end? false scrollable? false scroll-on-press? false size default-tab-size} :as props}] - (let [[active-tab-id - set-active-tab-id] (rn/use-state default-active) + (let [[active-tab-internal-id + set-active-tab-internal-id] (rn/use-state default-active) + tab-id (or active-tab-id active-tab-internal-id) + [fading set-fading] (rn/use-state fade-end-percentage) flat-list-ref (rn/use-ref-atom nil) tabs-data (rn/use-memo (fn [] (filterv some? data)) @@ -143,11 +129,11 @@ {:animated false :index (utils.collection/first-index - #(= active-tab-id (:id %)) + #(= tab-id (:id %)) tabs-data)})))) - [active-tab-id tabs-data]) + [tab-id tabs-data]) on-tab-press (rn/use-callback (fn [id index] - (set-active-tab-id id) + (set-active-tab-internal-id id) (when (and scroll-on-press? @flat-list-ref) (.scrollToIndex ^js @flat-list-ref #js @@ -156,7 +142,8 @@ :viewPosition 0.5})) (when on-change (on-change id))) - [set-active-tab-id scroll-on-press? on-change])] + [set-active-tab-internal-id scroll-on-press? + on-change])] (if scrollable? [rn/view {:style {:margin-top (- (dec unread-count-offset))}} [masked-view-wrapper @@ -183,7 +170,7 @@ :on-scroll on-scroll :on-layout set-initial-scroll-poisition :render-fn tab-view - :render-data {:active-tab-id active-tab-id + :render-data {:active-tab-id tab-id :blur? blur? :customization-color customization-color :number-of-items (count tabs-data) @@ -194,7 +181,7 @@ (map-indexed (fn [index item] ^{:key (:id item)} [tab-view item index nil - {:active-tab-id active-tab-id + {:active-tab-id tab-id :blur? blur? :customization-color customization-color :number-of-items (count tabs-data) @@ -202,3 +189,5 @@ :on-press on-tab-press :style style}]) tabs-data)]))) + +(def view (schema/instrument #'view-internal component-schema/?schema)) diff --git a/src/status_im/contexts/wallet/account/view.cljs b/src/status_im/contexts/wallet/account/view.cljs index 6c08f0f547..f76fb0ad31 100644 --- a/src/status_im/contexts/wallet/account/view.cljs +++ b/src/status_im/contexts/wallet/account/view.cljs @@ -2,7 +2,6 @@ (:require [quo.core :as quo] [react-native.core :as rn] - [reagent.core :as reagent] [status-im.contexts.wallet.account.style :as style] [status-im.contexts.wallet.account.tabs.view :as tabs] [status-im.contexts.wallet.common.account-switcher.view :as account-switcher] @@ -21,57 +20,58 @@ (not watch-only?) (conj {:id :dapps :label (i18n/label :t/dapps) :accessibility-label :dapps}) true (conj {:id :about :label (i18n/label :t/about) :accessibility-label :about}))) +(defn- change-tab [id] (rf/dispatch [:wallet/select-account-tab id])) + (defn view [] - (let [selected-tab (reagent/atom first-tab-id)] - (fn [] - (let [{:keys [name color formatted-balance - watch-only?]} (rf/sub [:wallet/current-viewing-account]) - customization-color (rf/sub [:profile/customization-color])] - (rn/use-unmount #(rf/dispatch [:wallet/close-account-page])) - [rn/view {:style {:flex 1}} - [account-switcher/view - {:type :wallet-networks - :on-press #(rf/dispatch [:wallet/close-account-page])}] - [quo/account-overview - {:container-style style/account-overview - :current-value formatted-balance - :account-name name - :account (if watch-only? :watched-address :default) - :customization-color color}] - (when (ff/enabled? ::ff/wallet.graph) [quo/wallet-graph {:time-frame :empty}]) - (when (not watch-only?) - [quo/wallet-ctas - {:container-style style/cta-buttons - :send-action (fn [] - (rf/dispatch [:wallet/clean-send-data]) - (rf/dispatch [:wallet/wizard-navigate-forward - {:start-flow? true - :flow-id :wallet-send-flow}])) - :receive-action #(rf/dispatch [:open-modal :screen/wallet.share-address - {:status :receive}]) - :buy-action #(rf/dispatch [:show-bottom-sheet - {:content buy-token/view}]) - :bridge-action (fn [] - (rf/dispatch [:wallet/clean-send-data]) - (rf/dispatch [:wallet/wizard-navigate-forward - {:start-flow? true - :flow-id :wallet-bridge-flow}])) - :swap-action (when (ff/enabled? ::ff/wallet.swap) - #(rf/dispatch [:wallet.swap/start]))}]) - [quo/tabs - {:style style/tabs - :size 32 - :default-active @selected-tab - :data (tabs-data watch-only?) - :on-change (rn/use-callback (fn [tab] (reset! selected-tab tab))) - :scrollable? true - :scroll-on-press? true}] - [tabs/view {:selected-tab @selected-tab}] - (when (ff/enabled? ::ff/shell.jump-to) - [quo/floating-shell-button - {:jump-to - {:on-press #(rf/dispatch [:shell/navigate-to-jump-to]) - :customization-color customization-color - :label (i18n/label :t/jump-to)}} - style/shell-button])])))) + (let [selected-tab (or (rf/sub [:wallet/account-tab]) first-tab-id) + {:keys [name color formatted-balance + watch-only?]} (rf/sub [:wallet/current-viewing-account]) + customization-color (rf/sub [:profile/customization-color])] + (rn/use-unmount #(rf/dispatch [:wallet/close-account-page])) + [rn/view {:style {:flex 1}} + [account-switcher/view + {:type :wallet-networks + :on-press #(rf/dispatch [:wallet/close-account-page])}] + [quo/account-overview + {:container-style style/account-overview + :current-value formatted-balance + :account-name name + :account (if watch-only? :watched-address :default) + :customization-color color}] + (when (ff/enabled? ::ff/wallet.graph) [quo/wallet-graph {:time-frame :empty}]) + (when (not watch-only?) + [quo/wallet-ctas + {:container-style style/cta-buttons + :send-action (fn [] + (rf/dispatch [:wallet/clean-send-data]) + (rf/dispatch [:wallet/wizard-navigate-forward + {:start-flow? true + :flow-id :wallet-send-flow}])) + :receive-action #(rf/dispatch [:open-modal :screen/wallet.share-address + {:status :receive}]) + :buy-action #(rf/dispatch [:show-bottom-sheet + {:content buy-token/view}]) + :bridge-action (fn [] + (rf/dispatch [:wallet/clean-send-data]) + (rf/dispatch [:wallet/wizard-navigate-forward + {:start-flow? true + :flow-id :wallet-bridge-flow}])) + :swap-action (when (ff/enabled? ::ff/wallet.swap) + #(rf/dispatch [:wallet.swap/start]))}]) + [quo/tabs + {:style style/tabs + :size 32 + :active-tab-id selected-tab + :data (tabs-data watch-only?) + :on-change change-tab + :scrollable? true + :scroll-on-press? true}] + [tabs/view {:selected-tab selected-tab}] + (when (ff/enabled? ::ff/shell.jump-to) + [quo/floating-shell-button + {:jump-to + {:on-press #(rf/dispatch [:shell/navigate-to-jump-to]) + :customization-color customization-color + :label (i18n/label :t/jump-to)}} + style/shell-button])])) diff --git a/src/status_im/contexts/wallet/bridge/flow_config.cljs b/src/status_im/contexts/wallet/bridge/flow_config.cljs index d662674dfd..9dbbfd7d0c 100644 --- a/src/status_im/contexts/wallet/bridge/flow_config.cljs +++ b/src/status_im/contexts/wallet/bridge/flow_config.cljs @@ -7,5 +7,4 @@ :skip-step? (fn [db] (some? (get-in db [:wallet :ui :send :bridge-to-chain-id])))} {:screen-id :screen/wallet.bridge-input-amount :skip-step? (fn [db] (some? (get-in db [:wallet :ui :send :amount])))} - {:screen-id :screen/wallet.transaction-confirmation} - {:screen-id :screen/wallet.transaction-progress}]) + {:screen-id :screen/wallet.transaction-confirmation}]) diff --git a/src/status_im/contexts/wallet/collectible/view.cljs b/src/status_im/contexts/wallet/collectible/view.cljs index 22c80810a0..795220bf42 100644 --- a/src/status_im/contexts/wallet/collectible/view.cljs +++ b/src/status_im/contexts/wallet/collectible/view.cljs @@ -49,6 +49,7 @@ :on-press #(rf/dispatch [:wallet/set-collectible-to-send {:collectible collectible + :start-flow? true :current-screen :screen/wallet.collectible}])} (i18n/label :t/send)]) [quo/button diff --git a/src/status_im/contexts/wallet/common/token_value/view.cljs b/src/status_im/contexts/wallet/common/token_value/view.cljs index 88be7d1a07..e23cd6b76d 100644 --- a/src/status_im/contexts/wallet/common/token_value/view.cljs +++ b/src/status_im/contexts/wallet/common/token_value/view.cljs @@ -72,8 +72,10 @@ selected-account? (rf/sub [:wallet/current-viewing-account-address]) send-params (if selected-account? {:token token-data + :stack-id :screen/wallet.accounts :start-flow? true} {:token-symbol token-symbol + :stack-id :wallet-stack :start-flow? true})] [quo/action-drawer [(cond->> [(when (ff/enabled? ::ff/wallet.assets-modal-manage-tokens) diff --git a/src/status_im/contexts/wallet/events.cljs b/src/status_im/contexts/wallet/events.cljs index 37c510bd54..9cb344b5d6 100644 --- a/src/status_im/contexts/wallet/events.cljs +++ b/src/status_im/contexts/wallet/events.cljs @@ -37,6 +37,12 @@ :fx [[:dispatch [:navigate-to :screen/wallet.accounts address]] [:dispatch [:wallet/fetch-activities]]]})) +(rf/reg-event-fx :wallet/navigate-to-account-within-stack + (fn [{:keys [db]} [address]] + {:db (assoc-in db [:wallet :current-viewing-account-address] address) + :fx [[:dispatch [:navigate-to-within-stack [:screen/wallet.accounts :shell-stack] address]] + [:dispatch [:wallet/fetch-activities]]]})) + (rf/reg-event-fx :wallet/navigate-to-new-account (fn [{:keys [db]} [address]] {:db (assoc-in db [:wallet :current-viewing-account-address] address) @@ -44,6 +50,14 @@ [:dispatch [:navigate-to :screen/wallet.accounts address]] [:dispatch [:wallet/show-account-created-toast address]]]})) +(rf/reg-event-fx :wallet/select-account-tab + (fn [{:keys [db]} [tab]] + {:db (assoc-in db [:wallet :ui :account-page :active-tab] tab)})) + +(rf/reg-event-fx :wallet/clear-account-tab + (fn [{:keys [db]}] + {:db (assoc-in db [:wallet :ui :account-page :active-tab] nil)})) + (rf/reg-event-fx :wallet/switch-current-viewing-account (fn [{:keys [db]} [address]] {:db (assoc-in db [:wallet :current-viewing-account-address] address)})) @@ -55,6 +69,7 @@ (rf/reg-event-fx :wallet/close-account-page (fn [_] {:fx [[:dispatch [:wallet/clean-current-viewing-account]] + [:dispatch [:wallet/clear-account-tab]] [:dispatch [:pop-to-root :shell-stack]]]})) (defn log-rpc-error diff --git a/src/status_im/contexts/wallet/send/events.cljs b/src/status_im/contexts/wallet/send/events.cljs index 446d9a0ec9..a95d64feec 100644 --- a/src/status_im/contexts/wallet/send/events.cljs +++ b/src/status_im/contexts/wallet/send/events.cljs @@ -253,7 +253,7 @@ (rf/reg-event-fx :wallet/set-collectible-to-send - (fn [{db :db} [{:keys [collectible current-screen]}]] + (fn [{db :db} [{:keys [collectible current-screen start-flow?]}]] (let [collection-data (:collection-data collectible) collectible-data (:collectible-data collectible) contract-type (:contract-type collectible) @@ -282,6 +282,7 @@ [:dispatch [:wallet/wizard-navigate-forward {:current-screen current-screen + :start-flow? start-flow? :flow-id :wallet-send-flow}]]]}))) (rf/reg-event-fx @@ -447,18 +448,26 @@ (assoc-in [:wallet :transactions] transaction-details) (assoc-in [:wallet :ui :send :transaction-ids] transaction-ids)) :fx [[:dispatch - [:wallet/wizard-navigate-forward - {:current-screen :screen/wallet.transaction-confirmation - :flow-id :wallet-send-flow}]]]}))) + [:wallet/end-transaction-flow]]]}))) -(rf/reg-event-fx :wallet/close-transaction-progress-page +(rf/reg-event-fx :wallet/clean-up-transaction-flow (fn [_] - {:fx [[:dispatch [:wallet/clean-scanned-address]] + {:fx [[:dispatch [:dismiss-modal :screen/wallet.transaction-confirmation]] + [:dispatch [:wallet/clean-scanned-address]] [:dispatch [:wallet/clean-local-suggestions]] [:dispatch [:wallet/clean-send-address]] [:dispatch [:wallet/clean-disabled-from-networks]] - [:dispatch [:wallet/select-address-tab nil]] - [:dispatch [:dismiss-modal :screen/wallet.transaction-progress]]]})) + [:dispatch [:wallet/select-address-tab nil]]]})) + +(rf/reg-event-fx :wallet/end-transaction-flow + (fn [{:keys [db]}] + (let [address (get-in db [:wallet :current-viewing-account-address])] + {:fx [[:dispatch [:wallet/navigate-to-account-within-stack address]] + [:dispatch [:wallet/fetch-activities]] + [:dispatch [:wallet/select-account-tab :activity]] + [:dispatch-later + [{:ms 20 + :dispatch [:wallet/clean-up-transaction-flow]}]]]}))) (defn- transaction-data [{:keys [from-address to-address token-address route data eth-transfer?]}] diff --git a/src/status_im/contexts/wallet/send/flow_config.cljs b/src/status_im/contexts/wallet/send/flow_config.cljs index 9c6456c71c..60092e1d23 100644 --- a/src/status_im/contexts/wallet/send/flow_config.cljs +++ b/src/status_im/contexts/wallet/send/flow_config.cljs @@ -27,5 +27,4 @@ :skip-step? (fn [db] (or (not (collectible-selected? db)) (some? (get-in db [:wallet :ui :send :amount]))))} - {:screen-id :screen/wallet.transaction-confirmation} - {:screen-id :screen/wallet.transaction-progress}]) + {:screen-id :screen/wallet.transaction-confirmation}]) diff --git a/src/status_im/contexts/wallet/send/transaction_progress/view.cljs b/src/status_im/contexts/wallet/send/transaction_progress/view.cljs index d6d73f99c2..d1fd73b846 100644 --- a/src/status_im/contexts/wallet/send/transaction_progress/view.cljs +++ b/src/status_im/contexts/wallet/send/transaction_progress/view.cljs @@ -47,7 +47,7 @@ (defn view [] - (let [leave-page #(rf/dispatch [:wallet/close-transaction-progress-page]) + (let [leave-page #(rf/dispatch [:wallet/end-transaction-flow]) {:keys [color]} (rf/sub [:wallet/current-viewing-account])] (fn [] (rn/use-effect diff --git a/src/status_im/navigation/events.cljs b/src/status_im/navigation/events.cljs index b50886df73..bfce492b47 100644 --- a/src/status_im/navigation/events.cljs +++ b/src/status_im/navigation/events.cljs @@ -27,8 +27,8 @@ (rf/defn navigate-to-within-stack {:events [:navigate-to-within-stack]} - [{:keys [db]} comp-id] - {:db (assoc db :view-id (first comp-id)) + [{:keys [db]} comp-id screen-params] + {:db (all-screens-params db (first comp-id) screen-params) :fx [[:navigate-to-within-stack comp-id]]}) (re-frame/reg-event-fx :open-modal diff --git a/src/status_im/subs/wallet/wallet.cljs b/src/status_im/subs/wallet/wallet.cljs index dc16566c77..a7d9df1a2b 100644 --- a/src/status_im/subs/wallet/wallet.cljs +++ b/src/status_im/subs/wallet/wallet.cljs @@ -435,6 +435,12 @@ accounts) accounts)))) +(rf/reg-sub + :wallet/account-tab + :<- [:wallet/ui] + (fn [ui] + (get-in ui [:account-page :active-tab]))) + (rf/reg-sub :wallet/current-viewing-account-token-values :<- [:wallet/current-viewing-account] From 256c9f7b10724d00ad470d65d36e1e42f4c8fccb Mon Sep 17 00:00:00 2001 From: Parvesh Monu Date: Wed, 12 Jun 2024 22:50:07 +0530 Subject: [PATCH 04/11] fix wrong community logo position when scrolling down the channel list (#20408) --- src/quo/components/navigation/page_nav/view.cljs | 4 ++-- .../contexts/wallet/common/account_switcher/view.cljs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/quo/components/navigation/page_nav/view.cljs b/src/quo/components/navigation/page_nav/view.cljs index 3a6136eb66..8bf9ebf12a 100644 --- a/src/quo/components/navigation/page_nav/view.cljs +++ b/src/quo/components/navigation/page_nav/view.cljs @@ -25,12 +25,12 @@ :blur :grey}) (defn- page-nav-base - [{:keys [margin-top background on-press accessibility-label icon-name behind-overlay?] + [{:keys [margin-top background on-press accessibility-label icon-name behind-overlay? align-center?] :or {background :white}} & children] (into [rn/view {:style (style/container margin-top)} (when icon-name - [rn/view {:style style/icon-container} + [rn/view (when align-center? {:style style/icon-container}) [button/button {:type (button-type background) :icon-only? true diff --git a/src/status_im/contexts/wallet/common/account_switcher/view.cljs b/src/status_im/contexts/wallet/common/account_switcher/view.cljs index a9097a005a..17ab23c194 100644 --- a/src/status_im/contexts/wallet/common/account_switcher/view.cljs +++ b/src/status_im/contexts/wallet/common/account_switcher/view.cljs @@ -35,6 +35,7 @@ :on-press on-press :accessibility-label accessibility-label :networks networks + :align-center? true :networks-on-press #(rf/dispatch [:show-bottom-sheet {:content network-filter/view}]) :right-side [(when (and (ff/enabled? ::ff/wallet.wallet-connect) (not watch-only?)) From 799bd1d4dcca10979ef25c7648ebf936d0d667a6 Mon Sep 17 00:00:00 2001 From: Ulises Manuel <90291778+ulisesmac@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:37:06 -0600 Subject: [PATCH 05/11] fix(wallet): Multiple activity tab fixes (#20367) * Add missing circle in wallet-activity component * Move activity calculations to subscription and fix wrong data * Fetch activities when visiting an account --- .../wallet/wallet_activity/style.cljs | 28 +++++-- .../wallet/wallet_activity/view.cljs | 19 ++--- .../contexts/wallet/account/view.cljs | 11 +-- .../wallet/common/activity_tab/events.cljs | 44 ++++++++++ .../wallet/common/activity_tab/view.cljs | 74 +++++++--------- src/status_im/contexts/wallet/events.cljs | 46 +--------- src/status_im/contexts/wallet/signals.cljs | 7 +- src/status_im/subs/wallet/activities.cljs | 84 +++++++++++++++---- .../subs/wallet/activities_test.cljs | 72 +++++++++++++--- src/status_im/subs/wallet/send.cljs | 16 ++-- src/status_im/subs/wallet/send_test.cljs | 30 +++++-- 11 files changed, 277 insertions(+), 154 deletions(-) create mode 100644 src/status_im/contexts/wallet/common/activity_tab/events.cljs diff --git a/src/quo/components/wallet/wallet_activity/style.cljs b/src/quo/components/wallet/wallet_activity/style.cljs index 688f16f87f..76d3c89e20 100644 --- a/src/quo/components/wallet/wallet_activity/style.cljs +++ b/src/quo/components/wallet/wallet_activity/style.cljs @@ -59,26 +59,36 @@ :height 32 :margin-top 8}) -(def content-container - {:margin-left 8}) +(def container + {:flex-direction :row + :column-gap 8}) (def content-line {:flex-direction :row :margin-top 2 :align-items :center}) -(defn icon-hole-view - [theme blur?] +(def icon-hole-view {: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-circle-border + [theme blur?] + {:position :absolute + :top 0 + :left 0 + :right 0 + :bottom 0 + :width 32 + :height 32 + :border-width 1 + :border-radius 16 + :border-color (if-not blur? + (colors/theme-colors colors/neutral-20 colors/neutral-80 theme) + colors/white-opa-5)}) + (defn icon-color [theme] (colors/theme-colors colors/neutral-100 colors/white theme)) diff --git a/src/quo/components/wallet/wallet_activity/view.cljs b/src/quo/components/wallet/wallet_activity/view.cljs index aa675dd9fa..6c1aa26477 100644 --- a/src/quo/components/wallet/wallet_activity/view.cljs +++ b/src/quo/components/wallet/wallet_activity/view.cljs @@ -70,20 +70,21 @@ status :pending}} theme] [rn/view {:style style/icon-container} + [rn/view {:style style/icon-status-container} + [icon/icon (status-icon status) + {:size 12 + :no-color :true}]] [hole-view/hole-view - {:style (style/icon-hole-view theme blur?) + {:style style/icon-hole-view :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}]]]) + [icon/icon (transaction-icon transaction :i/placeholder) + {:color (style/icon-color theme)}] + [rn/view {:style (style/icon-circle-border theme blur?)}]]]) (defn prop-text [label theme] @@ -116,11 +117,9 @@ :on-press on-press :on-press-in on-press-in :on-press-out on-press-out} - [rn/view - {:style {:flex-direction :row}} + [rn/view {:style style/container} [transaction-icon-view props theme] [rn/view - {:style style/content-container} [transaction-header props theme] [rn/view {:style style/content-line} (when first-tag [prop-tag first-tag blur?]) diff --git a/src/status_im/contexts/wallet/account/view.cljs b/src/status_im/contexts/wallet/account/view.cljs index f76fb0ad31..09a4ab9cfe 100644 --- a/src/status_im/contexts/wallet/account/view.cljs +++ b/src/status_im/contexts/wallet/account/view.cljs @@ -24,11 +24,12 @@ (defn view [] - (let [selected-tab (or (rf/sub [:wallet/account-tab]) first-tab-id) - {:keys [name color formatted-balance - watch-only?]} (rf/sub [:wallet/current-viewing-account]) - customization-color (rf/sub [:profile/customization-color])] - (rn/use-unmount #(rf/dispatch [:wallet/close-account-page])) + (let [selected-tab (or (rf/sub [:wallet/account-tab]) first-tab-id) + {:keys [name color formatted-balance watch-only? + address]} (rf/sub [:wallet/current-viewing-account]) + customization-color (rf/sub [:profile/customization-color])] + (rn/use-mount + #(rf/dispatch [:wallet/fetch-activities-for-current-account address])) [rn/view {:style {:flex 1}} [account-switcher/view {:type :wallet-networks diff --git a/src/status_im/contexts/wallet/common/activity_tab/events.cljs b/src/status_im/contexts/wallet/common/activity_tab/events.cljs new file mode 100644 index 0000000000..0ee358e4b6 --- /dev/null +++ b/src/status_im/contexts/wallet/common/activity_tab/events.cljs @@ -0,0 +1,44 @@ +(ns status-im.contexts.wallet.common.activity-tab.events + (:require [camel-snake-kebab.extras :as cske] + [utils.ethereum.chain :as chain] + [utils.re-frame :as rf] + [utils.transforms :as transforms])) + +(rf/reg-event-fx + :wallet/fetch-activities-for-current-account + (fn [{:keys [db]}] + (let [address (-> db :wallet :current-viewing-account-address) + chain-ids (chain/chain-ids db) + request-id 0 + filters {:period {:startTimestamp 0 + :endTimestamp 0} + :types [] + :statuses [] + :counterpartyAddresses [] + :assets [] + :collectibles [] + :filterOutAssets false + :filterOutCollectibles false} + offset 0 + limit 35 + request-params [request-id [address] chain-ids filters offset limit]] + {:fx [[:json-rpc/call + [{;; This method is deprecated and will be replaced by + ;; "wallet_startActivityFilterSession" + ;; https://github.com/status-im/status-mobile/issues/19864 + :method "wallet_filterActivityAsync" + :params request-params + :on-error [:wallet/log-rpc-error + {:event :wallet/fetch-activities-for-current-account + :params request-params}]}]]]}))) + +(rf/reg-event-fx + :wallet/activity-filtering-for-current-account-done + (fn [{:keys [db]} [{:keys [message]}]] + (let [address (-> db :wallet :current-viewing-account-address) + activities (->> message + (transforms/json->clj) + (:activities) + (cske/transform-keys transforms/->kebab-case-keyword)) + sorted-activities (sort :timestamp activities)] + {:db (assoc-in db [:wallet :activities address] sorted-activities)}))) diff --git a/src/status_im/contexts/wallet/common/activity_tab/view.cljs b/src/status_im/contexts/wallet/common/activity_tab/view.cljs index 8a29a37e64..b10f9d0b52 100644 --- a/src/status_im/contexts/wallet/common/activity_tab/view.cljs +++ b/src/status_im/contexts/wallet/common/activity_tab/view.cljs @@ -1,61 +1,42 @@ (ns status-im.contexts.wallet.common.activity-tab.view (:require - [legacy.status-im.utils.hex :as utils.hex] - [native-module.core :as native-module] [quo.core :as quo] - [quo.foundations.resources :as quo.resources] [quo.theme] [react-native.core :as rn] [status-im.common.resources :as resources] [status-im.contexts.shell.jump-to.constants :as jump-to.constants] - [status-im.contexts.wallet.common.activity-tab.constants :as constants] [status-im.contexts.wallet.common.empty-tab.view :as empty-tab] - [utils.datetime :as datetime] - [utils.ethereum.chain :as chain] [utils.i18n :as i18n] - [utils.money :as money] [utils.re-frame :as rf])) -(def precision 6) +(defn send-and-receive-activity + [{:keys [transaction relative-date status sender recipient token amount network-name + network-logo]}] + [quo/wallet-activity + {:transaction transaction + :timestamp relative-date + :status status + :counter 1 + :first-tag {:size 24 + :type :token + :token token + :amount amount} + :second-tag-prefix :t/from + :second-tag {:type :address :address sender} + :third-tag-prefix :t/to + :third-tag {:type :address :address recipient} + :fourth-tag-prefix :t/via + :fourth-tag {:size 24 + :type :network + :network-name network-name + :network-logo network-logo} + :blur? false}]) (defn activity-item - [{:keys [activity-type activity-status timestamp symbol-out symbol-in token-in token-out amount-in - amount-out sender recipient]}] - (let [chain-id (or (:chain-id token-in) (:chain-id token-out)) - amount-in-units (native-module/hex-to-number - (utils.hex/normalize-hex amount-in)) - amount-in-value (str (money/with-precision - (money/wei->ether amount-in-units) - precision)) - amount-out-units (native-module/hex-to-number - (utils.hex/normalize-hex amount-out)) - amount-out-value (str (money/with-precision - (money/wei->ether amount-out-units) - precision)) - relative-date (datetime/timestamp->relative (* timestamp 1000)) - receiving-activity? (= activity-type constants/wallet-activity-type-receive)] - [quo/wallet-activity - {:transaction (constants/wallet-activity-id->name activity-type) - :timestamp relative-date - :status (constants/wallet-activity-status->name activity-status) - :counter 1 - :first-tag {:size 24 - :type :token - :token (or symbol-out symbol-in) - :amount (if receiving-activity? amount-in-value amount-out-value)} - :second-tag-prefix (constants/second-tag-prefix activity-type) - :second-tag {:type :address - :address (if receiving-activity? recipient sender)} - :third-tag-prefix (constants/third-tag-prefix activity-type) - :third-tag {:type :address - :address (if receiving-activity? sender recipient)} - :fourth-tag-prefix (constants/fourth-tag-prefix activity-type) - :fourth-tag {:size 24 - :type :network - :network-logo (quo.resources/get-network (chain/chain-id->chain-keyword - chain-id)) - :network-name (chain/chain-id->chain-name chain-id)} - :blur? false}])) + [{:keys [transaction] :as activity}] + (case transaction + (:send :receive) [send-and-receive-activity activity] + nil)) (defn view [] @@ -69,7 +50,8 @@ [rn/section-list {:sections activity-list :sticky-section-headers-enabled false - :style {:flex 1} + :style {:flex 1 + :padding-horizontal 8} :content-container-style {:padding-bottom jump-to.constants/floating-shell-button-height} :render-fn activity-item :render-section-header-fn (fn [{:keys [title]}] [quo/divider-date title])}]))) diff --git a/src/status_im/contexts/wallet/events.cljs b/src/status_im/contexts/wallet/events.cljs index 9cb344b5d6..6c692e0764 100644 --- a/src/status_im/contexts/wallet/events.cljs +++ b/src/status_im/contexts/wallet/events.cljs @@ -6,6 +6,7 @@ [status-im.constants :as constants] [status-im.contexts.settings.wallet.effects] [status-im.contexts.settings.wallet.events] + [status-im.contexts.wallet.common.activity-tab.events] [status-im.contexts.wallet.common.utils.external-links :as external-links] [status-im.contexts.wallet.common.utils.networks :as network-utils] [status-im.contexts.wallet.data-store :as data-store] @@ -35,7 +36,7 @@ (fn [{:keys [db]} [address]] {:db (assoc-in db [:wallet :current-viewing-account-address] address) :fx [[:dispatch [:navigate-to :screen/wallet.accounts address]] - [:dispatch [:wallet/fetch-activities]]]})) + [:dispatch [:wallet/fetch-activities-for-current-account]]]})) (rf/reg-event-fx :wallet/navigate-to-account-within-stack (fn [{:keys [db]} [address]] @@ -506,49 +507,6 @@ (rf/reg-event-fx :wallet/update-selected-networks update-selected-networks) -(rf/reg-event-fx - :wallet/fetch-activities - (fn [{:keys [db]}] - (let [addresses (->> (get-in db [:wallet :accounts]) - vals - (map :address)) - chain-ids (chain/chain-ids db) - request-id 0 - filters {:period {:startTimestamp 0 - :endTimestamp 0} - :types [] - :statuses [] - :counterpartyAddresses [] - :assets [] - :collectibles [] - :filterOutAssets false - :filterOutCollectibles false} - offset 0 - limit 20 - request-params [request-id - addresses - chain-ids - filters - offset - limit]] - {:fx [[:json-rpc/call - [{;; This method is deprecated and will be replaced by - ;; "wallet_startActivityFilterSession" - ;; https://github.com/status-im/status-mobile/issues/19864 - :method "wallet_filterActivityAsync" - :params request-params - :on-error [:wallet/log-rpc-error - {:event :wallet/fetch-activities - :params request-params}]}]]]}))) - -(rf/reg-event-fx - :wallet/activity-filtering-done - (fn [{:keys [db]} [{:keys [message]}]] - (let [{:keys [activities]} (transforms/json->clj message) - activities (cske/transform-keys transforms/->kebab-case-keyword activities) - sorted-activities (sort :timestamp activities)] - {:db (assoc-in db [:wallet :activities] sorted-activities)}))) - (rf/reg-event-fx :wallet/get-crypto-on-ramps-success (fn [{:keys [db]} [data]] diff --git a/src/status_im/contexts/wallet/signals.cljs b/src/status_im/contexts/wallet/signals.cljs index 04208e1f90..3b503d80b9 100644 --- a/src/status_im/contexts/wallet/signals.cljs +++ b/src/status_im/contexts/wallet/signals.cljs @@ -37,7 +37,8 @@ "wallet-blockchain-status-changed" {:fx [[:dispatch [:wallet/blockchain-status-changed (transforms/js->clj event-js)]]]} - "wallet-activity-filtering-done" {:fx [[:dispatch - [:wallet/activity-filtering-done - (transforms/js->clj event-js)]]]} + "wallet-activity-filtering-done" {:fx + [[:dispatch + [:wallet/activity-filtering-for-current-account-done + (transforms/js->clj event-js)]]]} (log/debug ::unknown-wallet-event :type event-type))))) diff --git a/src/status_im/subs/wallet/activities.cljs b/src/status_im/subs/wallet/activities.cljs index 7973ee0049..d636ceb88a 100644 --- a/src/status_im/subs/wallet/activities.cljs +++ b/src/status_im/subs/wallet/activities.cljs @@ -1,26 +1,82 @@ (ns status-im.subs.wallet.activities (:require + [legacy.status-im.utils.hex :as utils.hex] + [native-module.core :as native-module] + [quo.foundations.resources :as quo.resources] + [quo.foundations.resources] [re-frame.core :as rf] [status-im.contexts.wallet.common.activity-tab.constants :as constants] - [utils.datetime :as datetime])) + [utils.datetime :as datetime] + [utils.money :as money])) + +(def precision 6) (rf/reg-sub :wallet/all-activities :<- [:wallet] :-> :activities) -(rf/reg-sub :wallet/activities-for-current-viewing-account +(defn- activity-amount + [amount] + (-> amount + (utils.hex/normalize-hex) + (native-module/hex-to-number) + (money/wei->ether) + (money/with-precision precision) + (str))) + +(defn- process-send-activity + [{:keys [symbol-out chain-id-out amount-out]} activity chain-id->network-name] + (let [network-name (chain-id->network-name chain-id-out)] + (assoc activity + :transaction :send + :token symbol-out + :amount (activity-amount amount-out) + :network-name network-name + :network-logo (quo.resources/get-network network-name)))) + +(defn- process-receive-activity + [{:keys [symbol-in amount-in chain-id-in]} activity chain-id->network-name] + (let [network-name (chain-id->network-name chain-id-in)] + (assoc activity + :transaction :receive + :token symbol-in + :amount (activity-amount amount-in) + :network-name network-name + :network-logo (quo.resources/get-network network-name)))) + +(defn- process-activity-by-type + [chain-id->network-name + {:keys [activity-type activity-status timestamp sender recipient] :as data}] + (let [activity {:relative-date (datetime/timestamp->relative (* timestamp 1000)) + :timestamp timestamp + :status (constants/wallet-activity-status->name activity-status) + :sender sender + :recipient recipient}] + (condp = activity-type + constants/wallet-activity-type-send + (process-send-activity data activity chain-id->network-name) + + constants/wallet-activity-type-receive + (process-receive-activity data activity chain-id->network-name) + + nil))) + +(rf/reg-sub + :wallet/activities-for-current-viewing-account :<- [:wallet/all-activities] :<- [:wallet/current-viewing-account-address] - (fn [[activities current-viewing-account-address]] - (->> activities - (filter (fn [{:keys [sender recipient activity-type]}] - (let [receiving-activity? (= activity-type constants/wallet-activity-type-receive) - relevant-address (if receiving-activity? recipient sender)] - (= relevant-address current-viewing-account-address)))) - (distinct) - (group-by (fn [{:keys [timestamp]}] - (datetime/timestamp->relative-short-date (* timestamp 1000)))) - (map (fn [[date activities]] - {:title date :data activities :timestamp (:timestamp (first activities))})) - (sort-by (fn [{:keys [timestamp]}] (- timestamp)))))) + :<- [:wallet/network-details] + (fn [[activities current-viewing-account-address network-details]] + (let [chain-id->network-name (update-vals (group-by :chain-id network-details) + (comp :network-name first))] + (->> current-viewing-account-address + (get activities) + (keep #(process-activity-by-type chain-id->network-name %)) + (group-by (fn [{:keys [timestamp]}] + (datetime/timestamp->relative-short-date (* timestamp 1000)))) + (map (fn [[date activities]] + {:title date + :data activities + :timestamp (:timestamp (first activities))})) + (sort-by (fn [{:keys [timestamp]}] (- timestamp))))))) diff --git a/src/status_im/subs/wallet/activities_test.cljs b/src/status_im/subs/wallet/activities_test.cljs index 8cef0e7355..b949598910 100644 --- a/src/status_im/subs/wallet/activities_test.cljs +++ b/src/status_im/subs/wallet/activities_test.cljs @@ -2,8 +2,9 @@ (:require [cljs.test :refer [is testing]] [re-frame.db :as rf-db] - status-im.subs.root - status-im.subs.wallet.collectibles + [status-im.contexts.wallet.common.activity-tab.constants :as constants] + [status-im.subs.root] + [status-im.subs.wallet.collectibles] [test-helpers.unit :as h] [utils.re-frame :as rf])) @@ -14,7 +15,7 @@ [:wallet :activities] [{:id 1 :name "Transaction1"} {:id 2 :name "Transaction2"}]) - (is (= [{:id 1 :name "Transaction1"} {:id 2 :name "Transaction2"}] (rf/sub [sub-name]))))) + (is (match? [{:id 1 :name "Transaction1"} {:id 2 :name "Transaction2"}] (rf/sub [sub-name]))))) (h/deftest-sub :wallet/activities-for-current-viewing-account [sub-name] @@ -23,11 +24,62 @@ (fn [db] (-> db (assoc-in [:wallet :activities] - [{:sender "acc1" :recipient "acc2" :timestamp 1588291200} - {:sender "acc2" :recipient "acc1" :timestamp 1588377600} - {:sender "acc3" :recipient "acc4" :timestamp 1588464000}]) + {"acc1" [{:activity-type constants/wallet-activity-type-send + :amount-out "0x1" + :sender "acc1" + :recipient "acc2" + :timestamp 1588291200} + {:activity-type constants/wallet-activity-type-receive + :amount-in "0x1" + :sender "acc2" + :recipient "acc1" + :timestamp 1588377600} + {:activity-type constants/wallet-activity-type-send + :amount-out "0x1" + :sender "acc1" + :recipient "acc4" + :timestamp 1588464000}] + "acc3" [{:activity-type constants/wallet-activity-type-receive + :amount-in "0x1" + :sender "acc4" + :recipient "acc3" + :timestamp 1588464000}]}) (assoc-in [:wallet :current-viewing-account-address] "acc1")))) - (is (= [{:title "May 1, 2020" - :data [{:sender "acc1" :recipient "acc2" :timestamp 1588291200}] - :timestamp 1588291200}] - (rf/sub [sub-name]))))) + (is + (match? [{:title "May 3, 2020" + :timestamp 1588464000 + :data [{:relative-date "May 3, 2020" + :amount "0" + :network-logo nil + :recipient "acc4" + :transaction :send + :token nil + :network-name nil + :status nil + :sender "acc1" + :timestamp 1588464000}]} + {:title "May 2, 2020" + :timestamp 1588377600 + :data [{:relative-date "May 2, 2020" + :amount "0" + :network-logo nil + :recipient "acc1" + :transaction :receive + :token nil + :network-name nil + :status nil + :sender "acc2" + :timestamp 1588377600}]} + {:title "May 1, 2020" + :timestamp 1588291200 + :data [{:relative-date "May 1, 2020" + :amount "0" + :network-logo nil + :recipient "acc2" + :transaction :send + :token nil + :network-name nil + :status nil + :sender "acc1" + :timestamp 1588291200}]}] + (rf/sub [sub-name]))))) diff --git a/src/status_im/subs/wallet/send.cljs b/src/status_im/subs/wallet/send.cljs index 38a818076a..31c8eae142 100644 --- a/src/status_im/subs/wallet/send.cljs +++ b/src/status_im/subs/wallet/send.cljs @@ -1,6 +1,7 @@ (ns status-im.subs.wallet.send (:require [re-frame.core :as rf] + [status-im.contexts.wallet.common.activity-tab.constants :as constants] [utils.number])) (rf/reg-sub @@ -40,14 +41,15 @@ (rf/reg-sub :wallet/recent-recipients - :<- [:wallet/activities-for-current-viewing-account] + :<- [:wallet/all-activities] :<- [:wallet/current-viewing-account-address] - (fn [[sections current-viewing-account-address]] - (let [all-transactions (mapcat :data sections) - users-sent-transactions (filter (fn [{:keys [sender]}] - (= sender current-viewing-account-address)) - all-transactions)] - (set (map :recipient users-sent-transactions))))) + (fn [[all-activities current-viewing-account-address]] + (let [address-activity (get all-activities current-viewing-account-address)] + (->> address-activity + (keep (fn [{:keys [activity-type recipient]}] + (when (= constants/wallet-activity-type-send activity-type) + recipient))) + (distinct))))) (rf/reg-sub :wallet/send-token-not-supported-in-receiver-networks? diff --git a/src/status_im/subs/wallet/send_test.cljs b/src/status_im/subs/wallet/send_test.cljs index 328b62159a..0cb307b41b 100644 --- a/src/status_im/subs/wallet/send_test.cljs +++ b/src/status_im/subs/wallet/send_test.cljs @@ -2,8 +2,9 @@ (:require [cljs.test :refer [is testing]] [re-frame.db :as rf-db] - status-im.subs.root - status-im.subs.wallet.send + [status-im.contexts.wallet.common.activity-tab.constants :as constants] + [status-im.subs.root] + [status-im.subs.wallet.send] [test-helpers.unit :as h] [utils.re-frame :as rf])) @@ -61,8 +62,25 @@ (fn [db] (-> db (assoc-in [:wallet :activities] - [{:sender "acc1" :recipient "acc2" :timestamp 1588291200} - {:sender "acc2" :recipient "acc1" :timestamp 1588377600} - {:sender "acc3" :recipient "acc4" :timestamp 1588464000}]) + {"acc1" [{:activity-type constants/wallet-activity-type-send + :amount-out "0x1" + :sender "acc1" + :recipient "acc2" + :timestamp 1588291200} + {:activity-type constants/wallet-activity-type-receive + :amount-in "0x1" + :sender "acc2" + :recipient "acc1" + :timestamp 1588377600} + {:activity-type constants/wallet-activity-type-send + :amount-out "0x1" + :sender "acc1" + :recipient "acc4" + :timestamp 1588464000}] + "acc3" [{:activity-type constants/wallet-activity-type-receive + :amount-in "0x1" + :sender "acc4" + :recipient "acc3" + :timestamp 1588464000}]}) (assoc-in [:wallet :current-viewing-account-address] "acc1")))) - (is (= #{"acc2"} (rf/sub [sub-name]))))) + (is (match? ["acc2" "acc4"] (rf/sub [sub-name]))))) From 874906b11f50ac90a337bcd0a9ebd880304492b6 Mon Sep 17 00:00:00 2001 From: yqrashawn Date: Thu, 13 Jun 2024 09:28:07 +0800 Subject: [PATCH 06/11] fix: face id toggle respect system face id permission (#20227) Signed-off-by: yqrashawn --- src/react_native/biometrics.cljs | 4 ++-- src/status_im/common/biometric/events.cljs | 5 ++++- src/status_im/common/biometric/events_test.cljs | 2 +- .../profile/settings/screens/password/view.cljs | 12 ++++++------ translations/en.json | 1 + 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/react_native/biometrics.cljs b/src/react_native/biometrics.cljs index c6682baf42..189dc89ca8 100644 --- a/src/react_native/biometrics.cljs +++ b/src/react_native/biometrics.cljs @@ -41,13 +41,13 @@ [message] (let [cause (if platform/android? (condp = message - android-not-enrolled-error-message :biometrics/not-enrolled-error + android-not-enrolled-error-message :biometrics/fingerprints-not-enrolled-error android-not-available-error-message :biometrics/not-available-error android-too-many-attempts-error-message :biometric/too-many-attempts :biometrics/unknown-error) (condp #(string/includes? %2 %1) message - ios-not-enrolled-error-message :biometrics/not-enrolled-error + ios-not-enrolled-error-message :biometrics/ios-not-enrolled-error :biometrics/unknown-error))] (ex-info "Failed to authenticate with biometrics" {:orig-error-message message} diff --git a/src/status_im/common/biometric/events.cljs b/src/status_im/common/biometric/events.cljs index a8b8ea67e9..176a2a31d8 100644 --- a/src/status_im/common/biometric/events.cljs +++ b/src/status_im/common/biometric/events.cljs @@ -14,8 +14,11 @@ (defn show-message [_ [code]] (let [content (case code - (:biometrics/not-enrolled-error + (:biometrics/fingerprints-not-enrolled-error :biometrics/not-available-error) + (i18n/label :t/grant-fingerprints-permissions) + + :biometrics/ios-not-enrolled-error (i18n/label :t/grant-face-id-permissions) :biometric/too-many-attempts diff --git a/src/status_im/common/biometric/events_test.cljs b/src/status_im/common/biometric/events_test.cljs index 9857456120..1837673cb0 100644 --- a/src/status_im/common/biometric/events_test.cljs +++ b/src/status_im/common/biometric/events_test.cljs @@ -18,7 +18,7 @@ (let [cofx {:db {}} expected {:fx [[:effects.utils/show-popup {:title (i18n/label :t/biometric-auth-login-error-title) - :content (i18n/label :t/grant-face-id-permissions)}]]}] + :content (i18n/label :t/grant-fingerprints-permissions)}]]}] (is (match? expected (sut/show-message cofx [:biometrics/not-available-error]))))) diff --git a/src/status_im/contexts/profile/settings/screens/password/view.cljs b/src/status_im/contexts/profile/settings/screens/password/view.cljs index 0f6d27ea49..499e788e45 100644 --- a/src/status_im/contexts/profile/settings/screens/password/view.cljs +++ b/src/status_im/contexts/profile/settings/screens/password/view.cljs @@ -30,18 +30,18 @@ supported? (boolean biometric-type) enabled? (= auth-method constants/auth-method-biometric) biometric-on? (and supported? enabled?) - press-handler (if biometric-on? - (fn [] (rf/dispatch [:biometric/disable])) - (on-press-biometric-enable label theme))] + press-handler (when supported? + (if biometric-on? + (fn [] (rf/dispatch [:biometric/disable])) + (on-press-biometric-enable label theme)))] {:title label :image-props icon :image :icon :blur? true :action :selector - :action-props {:disabled? (not supported?) - :on-change press-handler + :action-props {:on-change press-handler :checked? biometric-on?} - :on-press (when supported? press-handler)})) + :on-press press-handler})) (defn- get-change-password-item [] diff --git a/translations/en.json b/translations/en.json index caa355c369..481ed05ad2 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1629,6 +1629,7 @@ "ok-save-pass": "OK, save password", "lock-app-with": "Lock app with", "grant-face-id-permissions": "To grant the required Face ID permission, please go to your system settings and make sure that Status > Face ID is selected", + "grant-fingerprints-permissions": "To grant the required fingerprints permission, please go to your system settings and make sure that Status > Fingerprints is selected", "request-feature": "Request a feature", "select-account-dapp": "Select the account you wish to use with Dapps", "apply": "Apply", From df939bf85fd03f1a6a1da0e2ba8d9252949d92e1 Mon Sep 17 00:00:00 2001 From: Parvesh Monu Date: Thu, 13 Jun 2024 13:56:33 +0530 Subject: [PATCH 07/11] fix inability to move cursor to next line in bio field (#20403) --- .../contexts/profile/edit/bio/view.cljs | 121 +++++++++--------- 1 file changed, 60 insertions(+), 61 deletions(-) diff --git a/src/status_im/contexts/profile/edit/bio/view.cljs b/src/status_im/contexts/profile/edit/bio/view.cljs index 94d0ae45a1..e8c0cd257d 100644 --- a/src/status_im/contexts/profile/edit/bio/view.cljs +++ b/src/status_im/contexts/profile/edit/bio/view.cljs @@ -4,7 +4,6 @@ [react-native.core :as rn] [react-native.platform :as platform] [react-native.safe-area :as safe-area] - [reagent.core :as reagent] [status-im.common.validation.profile :as profile-validator] [status-im.constants :as constants] [status-im.contexts.profile.edit.bio.style :as style] @@ -14,63 +13,63 @@ (defn view [] - (let [insets (safe-area/get-insets) - profile (rf/sub [:profile/profile-with-image]) - customization-color (rf/sub [:profile/customization-color]) - alert-banners-top-margin (rf/sub [:alert-banners/top-margin]) - profile-bio (:bio profile) - unsaved-bio (reagent/atom profile-bio) - error-msg (reagent/atom nil) - typing? (reagent/atom false) - validate-bio (debounce/debounce (fn [bio] - (reset! error-msg - (profile-validator/validation-bio bio)) - (reset! typing? false)) - 300) - on-change-text (fn [s] - (reset! typing? true) - (reset! unsaved-bio s) - (validate-bio s))] - (fn [] - [quo/overlay - {:type :shell - :container-style (style/page-wrapper insets)} - [quo/page-nav - {:key :header - :background :blur - :icon-name :i/arrow-left - :on-press #(rf/dispatch [:navigate-back])}] - [rn/keyboard-avoiding-view - {:key :content - :keyboard-vertical-offset (if platform/ios? alert-banners-top-margin 0) - :style style/screen-container} - [rn/view {:style {:gap 22}} - [quo/text-combinations {:title (i18n/label :t/bio)}] - [quo/input - {:blur? true - :multiline? true - :error? (not (string/blank? @error-msg)) - :container-style {:margin-bottom -11} - :default-value @unsaved-bio - :auto-focus true - :char-limit constants/profile-bio-max-length - :label (i18n/label :t/profile-bio) - :placeholder (i18n/label :t/something-about-you) - :on-change-text on-change-text}] - (when-not (string/blank? @error-msg) - [quo/info-message - {:type :error - :size :default - :icon :i/info} - @error-msg])] - [rn/view {:style style/button-wrapper} - [quo/button - {:type :primary - :customization-color customization-color - :on-press (fn [] - (rf/dispatch [:profile/edit-bio @unsaved-bio])) - :disabled? (boolean (or @typing? - (and (string/blank? profile-bio) - (string/blank? @unsaved-bio)) - (not (string/blank? @error-msg))))} - (i18n/label :t/save-bio)]]]]))) + (let [insets (safe-area/get-insets) + profile (rf/sub [:profile/profile-with-image]) + customization-color (rf/sub [:profile/customization-color]) + alert-banners-top-margin (rf/sub [:alert-banners/top-margin]) + current-bio (:bio profile) + [bio set-bio] (rn/use-state current-bio) + [error-msg set-error-msg] (rn/use-state nil) + [typing? set-typing] (rn/use-state false) + validate-bio (debounce/debounce (fn [bio] + (set-error-msg (profile-validator/validation-bio + bio)) + (set-typing false)) + 300) + on-change-text (fn [s] + (set-typing true) + (set-bio s) + (validate-bio s))] + [quo/overlay + {:type :shell + :container-style (style/page-wrapper insets)} + [quo/page-nav + {:key :header + :background :blur + :icon-name :i/arrow-left + :on-press #(rf/dispatch [:navigate-back])}] + [rn/keyboard-avoiding-view + {:key :content + :keyboard-vertical-offset (if platform/ios? alert-banners-top-margin 0) + :style style/screen-container} + [rn/view {:style {:gap 22}} + [quo/text-combinations {:title (i18n/label :t/bio)}] + [quo/input + {:blur? true + :multiline? true + :error? (not (string/blank? error-msg)) + :container-style {:margin-bottom -11} + :default-value bio + :auto-focus true + :max-height 200 + :char-limit constants/profile-bio-max-length + :label (i18n/label :t/profile-bio) + :placeholder (i18n/label :t/something-about-you) + :on-change-text on-change-text}] + (when-not (string/blank? error-msg) + [quo/info-message + {:type :error + :size :default + :icon :i/info} + error-msg])] + [rn/view {:style style/button-wrapper} + [quo/button + {:type :primary + :customization-color customization-color + :on-press (fn [] + (rf/dispatch [:profile/edit-bio bio])) + :disabled? (boolean (or typing? + (and (string/blank? current-bio) + (string/blank? bio)) + (not (string/blank? error-msg))))} + (i18n/label :t/save-bio)]]]])) From 5f7d7254e722a26ab7769fc98c60d83afd258026 Mon Sep 17 00:00:00 2001 From: Parvesh Monu Date: Thu, 13 Jun 2024 16:48:21 +0530 Subject: [PATCH 08/11] fix bottom message hidden behind composer with minimised keyboard when replying to message (#20371) --- .../chat/messenger/composer/edit/view.cljs | 4 +- .../chat/messenger/composer/utils.cljs | 8 +++- .../chat/messenger/composer/view.cljs | 5 ++- .../chat/messenger/messages/list/view.cljs | 45 ++++++++++++++----- 4 files changed, 46 insertions(+), 16 deletions(-) diff --git a/src/status_im/contexts/chat/messenger/composer/edit/view.cljs b/src/status_im/contexts/chat/messenger/composer/edit/view.cljs index 5daba1c0bf..40cb0b6839 100644 --- a/src/status_im/contexts/chat/messenger/composer/edit/view.cljs +++ b/src/status_im/contexts/chat/messenger/composer/edit/view.cljs @@ -12,7 +12,7 @@ [utils.re-frame :as rf])) (defn edit-message - [{:keys [text-value input-ref]}] + [{:keys [text-value input-ref input-height]}] (let [theme (quo.theme/use-theme)] [rn/view {:style style/container @@ -32,7 +32,7 @@ {:size 24 :icon-only? true :accessibility-label :edit-cancel-button - :on-press #(utils/cancel-edit-message text-value input-ref) + :on-press #(utils/cancel-edit-message text-value input-ref input-height) :type :outline} :i/close]])) diff --git a/src/status_im/contexts/chat/messenger/composer/utils.cljs b/src/status_im/contexts/chat/messenger/composer/utils.cljs index 843bea8b4a..734ed72e93 100644 --- a/src/status_im/contexts/chat/messenger/composer/utils.cljs +++ b/src/status_im/contexts/chat/messenger/composer/utils.cljs @@ -101,12 +101,16 @@ (rf/dispatch [:chat.ui/cancel-message-reply])) (defn cancel-edit-message - [text-value input-ref] + [text-value input-ref input-height] (reset! text-value "") ;; NOTE: adding a timeout to assure the input is blurred on the next tick ;; after the `text-value` was cleared. Otherwise the height will be calculated ;; with the old `text-value`, leading to wrong composer height after blur. - (js/setTimeout #(blur-input input-ref) 100) + (js/setTimeout + (fn [] + (blur-input input-ref) + (reanimated/set-shared-value input-height constants/input-height)) + 100) (.setNativeProps ^js @input-ref (clj->js {:text ""})) (rf/dispatch [:chat.ui/set-input-content-height constants/input-height]) (rf/dispatch [:chat.ui/cancel-message-edit])) diff --git a/src/status_im/contexts/chat/messenger/composer/view.cljs b/src/status_im/contexts/chat/messenger/composer/view.cljs index 080d7a3d46..9103e14f1d 100644 --- a/src/status_im/contexts/chat/messenger/composer/view.cljs +++ b/src/status_im/contexts/chat/messenger/composer/view.cljs @@ -105,8 +105,9 @@ [:<> [reply/view state (:input-ref props)] [edit/view - {:text-value (:text-value state) - :input-ref (:input-ref props)}]] + {:text-value (:text-value state) + :input-height (:height animations) + :input-ref (:input-ref props)}]] [reanimated/touchable-opacity {:active-opacity 1 :on-press (fn [] diff --git a/src/status_im/contexts/chat/messenger/messages/list/view.cljs b/src/status_im/contexts/chat/messenger/messages/list/view.cljs index cc2908f1b2..47d5b81e03 100644 --- a/src/status_im/contexts/chat/messenger/messages/list/view.cljs +++ b/src/status_im/contexts/chat/messenger/messages/list/view.cljs @@ -102,18 +102,43 @@ ;; https://github.com/status-im/status-mobile/issues/17426 [quo/skeleton-list (skeleton-list-props :messages parent-height platform/ios?)]])) +(defn header-height + [{:keys [insets able-to-send-message? images reply edit link-previews? input-content-height]}] + (if able-to-send-message? + (cond-> composer.constants/composer-default-height + (ff/enabled? ::ff/shell.jump-to) + (+ jump-to.constants/floating-shell-button-height) + + (seq images) + (+ composer.constants/images-container-height) + + reply + (+ composer.constants/reply-container-height) + + edit + (+ composer.constants/edit-container-height) + + link-previews? + (+ composer.constants/links-container-height) + + (and input-content-height (not= input-content-height composer.constants/input-height)) + (+ composer.constants/input-height) + + true + (+ (:bottom insets))) + (- 70 (:bottom insets)))) + (defn list-header [insets able-to-send-message?] - (let [images (rf/sub [:chats/sending-image]) - height (if able-to-send-message? - (+ composer.constants/composer-default-height - (if (ff/enabled? ::ff/shell.jump-to) - jump-to.constants/floating-shell-button-height - 0) - (if (seq images) composer.constants/images-container-height 0) - (:bottom insets)) - (- 70 (:bottom insets)))] - [rn/view {:style {:height height}}])) + (let [header-data {:insets insets + :able-to-send-message? able-to-send-message? + :input-content-height (:input-content-height (rf/sub [:chats/current-chat-input])) + :images (rf/sub [:chats/sending-image]) + :reply (rf/sub [:chats/reply-message]) + :edit (rf/sub [:chats/edit-message]) + :link-previews? (or (rf/sub [:chats/link-previews?]) + (rf/sub [:chats/status-link-previews?]))}] + [rn/view {:style {:height (header-height header-data)}}])) (defn list-footer-avatar [{:keys [distance-from-list-top display-name online? profile-picture theme group-chat color From d33648917aeb8842236f55a421412c06d9eb358e Mon Sep 17 00:00:00 2001 From: mmilad75 <55688834+mmilad75@users.noreply.github.com> Date: Thu, 13 Jun 2024 14:19:19 +0200 Subject: [PATCH 09/11] The network marks are not shown on the 'send to' page for accounts #19545 (#20365) --- .../components/list_items/account/view.cljs | 5 +--- .../contexts/wallet/send/from/view.cljs | 17 ++++++++----- .../wallet/send/select_address/tabs/view.cljs | 24 ++++++++++++------- src/status_im/subs/wallet/networks.cljs | 15 +++++++++++- src/status_im/subs/wallet/networks_test.cljs | 11 +++++++++ 5 files changed, 52 insertions(+), 20 deletions(-) diff --git a/src/quo/components/list_items/account/view.cljs b/src/quo/components/list_items/account/view.cljs index 62066ef4e3..4d732f8c20 100644 --- a/src/quo/components/list_items/account/view.cljs +++ b/src/quo/components/list_items/account/view.cljs @@ -30,10 +30,7 @@ (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)) :container-style style/title-icon-container :accessibility-label :title-icon}])] - [address-text/view - {:networks (:networks account-props) - :address (:address account-props) - :format :short}]]]) + [address-text/view (assoc account-props :format :short)]]]) (defn- balance-view [{:keys [balance-props type theme]}] diff --git a/src/status_im/contexts/wallet/send/from/view.cljs b/src/status_im/contexts/wallet/send/from/view.cljs index 45f50a1f86..929f0f3b0f 100644 --- a/src/status_im/contexts/wallet/send/from/view.cljs +++ b/src/status_im/contexts/wallet/send/from/view.cljs @@ -9,7 +9,7 @@ [utils.i18n :as i18n] [utils.re-frame :as rf])) -(defn- on-press +(defn- on-account-press [address network-details] (rf/dispatch [:wallet/select-from-account {:address address @@ -22,15 +22,19 @@ (rf/dispatch [:navigate-back])) (defn- render-fn - [item] - (let [network-details (rf/sub [:wallet/network-details])] + [item _ _ {:keys [network-details]}] + (let [transformed-address (rf/sub [:wallet/account-address (:address item) + (:network-preferences-names item)])] [quo/account-item - {:on-press #(on-press (:address item) network-details) - :account-props item}])) + {:on-press #(on-account-press (:address item) network-details) + :account-props (assoc item + :address transformed-address + :full-address? true)}])) (defn view [] - (let [accounts (rf/sub [:wallet/accounts-with-current-asset])] + (let [accounts (rf/sub [:wallet/accounts-with-current-asset]) + network-details (rf/sub [:wallet/network-details])] [floating-button-page/view {:footer-container-padding 0 :header [account-switcher/view @@ -45,5 +49,6 @@ {:style style/accounts-list :content-container-style style/accounts-list-container :data accounts + :render-data {:network-details network-details} :render-fn render-fn :shows-horizontal-scroll-indicator false}]])) diff --git a/src/status_im/contexts/wallet/send/select_address/tabs/view.cljs b/src/status_im/contexts/wallet/send/select_address/tabs/view.cljs index 6e3100ddce..5137e7ac77 100644 --- a/src/status_im/contexts/wallet/send/select_address/tabs/view.cljs +++ b/src/status_im/contexts/wallet/send/select_address/tabs/view.cljs @@ -17,15 +17,21 @@ :description (i18n/label :t/here-is-a-cat-in-a-box-instead) :image (resources/get-themed-image :cat-in-box theme) :container-style style/empty-container-style}] - (into [rn/view {:style style/my-accounts-container}] - (map (fn [{:keys [color address] :as account}] - [quo/account-item - {:account-props (assoc account :customization-color color) - :on-press #(rf/dispatch [:wallet/select-send-address - {:address address - :recipient account - :stack-id :screen/wallet.select-address}])}])) - other-accounts)))) + [rn/view {:style style/my-accounts-container} + (doall + (for [{:keys [color address] :as account} other-accounts] + ^{:key (str address)} + (let [transformed-address (rf/sub [:wallet/account-address address + (:network-preferences-names account)])] + [quo/account-item + {:account-props (assoc account + :customization-color color + :address transformed-address + :full-address? true) + :on-press #(rf/dispatch [:wallet/select-send-address + {:address address + :recipient account + :stack-id :screen/wallet.select-address}])}])))]))) (defn- recent-transactions [theme] diff --git a/src/status_im/subs/wallet/networks.cljs b/src/status_im/subs/wallet/networks.cljs index 80c2422309..d8bdea7c43 100644 --- a/src/status_im/subs/wallet/networks.cljs +++ b/src/status_im/subs/wallet/networks.cljs @@ -1,7 +1,10 @@ (ns status-im.subs.wallet.networks (:require [quo.foundations.resources :as resources] [re-frame.core :as re-frame] - [status-im.constants :as constants])) + [status-im.constants :as constants] + [status-im.contexts.wallet.common.utils.networks :as network-utils])) + +(def max-network-prefixes 2) (re-frame/reg-sub :wallet/networks @@ -88,3 +91,13 @@ (filter #(contains? selected-networks (:network-name %)) network-details))) + +(re-frame/reg-sub + :wallet/account-address + (fn [_ [_ address network-preferences]] + (let [short-names (map network-utils/network->short-name network-preferences) + prefix (when (<= (count short-names) max-network-prefixes) + (network-utils/short-names->network-preference-prefix + short-names)) + transformed-address (str prefix address)] + transformed-address))) diff --git a/src/status_im/subs/wallet/networks_test.cljs b/src/status_im/subs/wallet/networks_test.cljs index d54f0a3817..15d49dc5f8 100644 --- a/src/status_im/subs/wallet/networks_test.cljs +++ b/src/status_im/subs/wallet/networks_test.cljs @@ -82,3 +82,14 @@ :chain-id 10 :layer 2}} (rf/sub [sub-name]))))) + +(h/deftest-sub :wallet/account-address + [sub-name] + (testing + "returns the address with prefixes when an address and less than 3 network preferences are passed" + (is + (match? "eth:0x01" (rf/sub [sub-name "0x01" [:ethereum]])))) + (testing + "returns the address without the prefixes when an address and equal or more than 3 network preferences are passed" + (is + (match? "0x01" (rf/sub [sub-name "0x01" [:ethereum :optimism :arbitrum]]))))) From e0c7ecc6dfb2bab186113cb4fe877af39b40d1e0 Mon Sep 17 00:00:00 2001 From: mmilad75 <55688834+mmilad75@users.noreply.github.com> Date: Thu, 13 Jun 2024 14:41:06 +0200 Subject: [PATCH 10/11] No routes found error is displayed in case asset value is within max amount but not enough balance for fee #20148 (#20272) --- .../wallet/send/input_amount/view.cljs | 36 +++++++++++++++++-- translations/en.json | 4 ++- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/status_im/contexts/wallet/send/input_amount/view.cljs b/src/status_im/contexts/wallet/send/input_amount/view.cljs index 7d142c5fe1..5f21f0df82 100644 --- a/src/status_im/contexts/wallet/send/input_amount/view.cljs +++ b/src/status_im/contexts/wallet/send/input_amount/view.cljs @@ -7,11 +7,13 @@ [react-native.core :as rn] [react-native.safe-area :as safe-area] [status-im.common.controlled-input.utils :as controlled-input] + [status-im.constants :as constants] [status-im.contexts.wallet.common.account-switcher.view :as account-switcher] [status-im.contexts.wallet.common.asset-list.view :as asset-list] [status-im.contexts.wallet.common.utils :as utils] [status-im.contexts.wallet.send.input-amount.style :as style] [status-im.contexts.wallet.send.routes.view :as routes] + [status-im.contexts.wallet.sheets.buy-token.view :as buy-token] [status-im.contexts.wallet.sheets.unpreferred-networks-alert.view :as unpreferred-networks-alert] [utils.debounce :as debounce] [utils.i18n :as i18n] @@ -125,6 +127,15 @@ :style {:margin-top 15}} (i18n/label :t/no-routes-found)]]) +(defn- not-enough-asset + [] + [quo/alert-banner + {:action? true + :text (i18n/label :t/not-enough-assets) + :button-text (i18n/label :t/buy-eth) + :on-button-press #(rf/dispatch [:show-bottom-sheet + {:content buy-token/view}])}]) + (defn view ;; crypto-decimals, limit-crypto and initial-crypto-currency? args are needed ;; for component tests only @@ -264,7 +275,25 @@ limit-insufficient? (> (controlled-input/numeric-value input-state) current-limit) should-try-again? (and (not limit-insufficient?) no-routes-found?) - current-address (rf/sub [:wallet/current-viewing-account-address])] + current-address (rf/sub [:wallet/current-viewing-account-address]) + owned-eth-token (rf/sub [:wallet/token-by-symbol + (string/upper-case + constants/mainnet-short-name) + enabled-from-chain-ids]) + not-enough-asset? (and + (or no-routes-found? limit-insufficient?) + (not-empty sender-network-values) + (if (= token-symbol + (string/upper-case + constants/mainnet-short-name)) + (= current-limit input-amount) + (money/equal-to (:total-balance + owned-eth-token) + 0))) + show-no-routes? (and + (or no-routes-found? limit-insufficient?) + (not-empty sender-network-values) + (not not-enough-asset?))] (rn/use-mount (fn [] (let [dismiss-keyboard-fn #(when (= % "active") (rn/dismiss-keyboard!)) @@ -339,8 +368,9 @@ {:loading-routes? loading-routes? :fees fee-formatted :amount amount-text}]) - (when (and (or no-routes-found? limit-insufficient?) (not-empty sender-network-values)) - [no-routes-found]) + (cond + show-no-routes? [no-routes-found] + not-enough-asset? [not-enough-asset]) [quo/bottom-actions {:actions :one-action :button-one-label (if should-try-again? diff --git a/translations/en.json b/translations/en.json index 481ed05ad2..50c2ea7239 100644 --- a/translations/en.json +++ b/translations/en.json @@ -2700,5 +2700,7 @@ "wallet-connect-version-not-supported": "WalletConnect version {{version}} is not supported", "add-network-preferences": "Add network preferences", "saved-address-network-preference-selection-description": "Only change if you know which networks the address owner is happy to to receive funds on", - "add-preferences": "Add preferences" + "add-preferences": "Add preferences", + "buy-eth": "Buy ETH", + "not-enough-assets": "Not enough assets to pay gas fees" } From dc335cc3334984fbd9000b593676bd49134fc0e4 Mon Sep 17 00:00:00 2001 From: Sean Hagstrom Date: Thu, 13 Jun 2024 14:13:26 +0100 Subject: [PATCH 11/11] chore: Revise code for wallet settings (#20439) * fix: use correct error message when displaying seed phrase as incorrect * tidy: cleanup naming of events and effects * tweak: show incorrect-seed-phrase error for any import error * fix: show correct error message for incorrect private key * chore: move import-private-key and import-seed-phrase namespaces * chore: move encrypted-qr namespace * chore: move scan-qr namespace * tidy: rename key-pair to keypair inside for wallet settings * tweak: use :open-modal navigation instead of :navigate-to-within-stack * tweak: rename screen for importing missing key-pair by seed-phrase * tidy: refactor code --- .../common/enter_seed_phrase/view.cljs | 88 ++++++++++--------- .../contexts/profile/settings/list_items.cljs | 2 +- .../contexts/settings/wallet/events.cljs | 18 ++-- .../keypairs_and_accounts/actions/view.cljs | 10 ++- .../encrypted_qr/countdown/view.cljs | 2 +- .../encrypted_qr/style.cljs | 2 +- .../encrypted_qr/view.cljs | 8 +- .../import_private_key/style.cljs | 2 +- .../import_private_key/view.cljs | 10 +-- .../import_seed_phrase/view.cljs | 17 ++-- .../{ => missing_keypairs}/scan_qr/view.cljs | 2 +- .../add_address_to_save/view.cljs | 4 +- .../settings/wallet/saved_addresses/view.cljs | 3 +- .../settings/wallet/wallet_options/view.cljs | 6 +- src/status_im/contexts/wallet/effects.cljs | 10 +-- src/status_im/navigation/screens.cljs | 25 +++--- src/status_im/subs/wallet/wallet.cljs | 18 ++-- translations/en.json | 3 +- 18 files changed, 120 insertions(+), 110 deletions(-) rename src/status_im/contexts/settings/wallet/keypairs_and_accounts/{ => missing_keypairs}/encrypted_qr/countdown/view.cljs (94%) rename src/status_im/contexts/settings/wallet/keypairs_and_accounts/{ => missing_keypairs}/encrypted_qr/style.cljs (90%) rename src/status_im/contexts/settings/wallet/keypairs_and_accounts/{ => missing_keypairs}/encrypted_qr/view.cljs (93%) rename src/status_im/contexts/settings/wallet/keypairs_and_accounts/{ => missing_keypairs}/import_private_key/style.cljs (58%) rename src/status_im/contexts/settings/wallet/keypairs_and_accounts/{ => missing_keypairs}/import_private_key/view.cljs (96%) rename src/status_im/contexts/settings/wallet/keypairs_and_accounts/{ => missing_keypairs}/import_seed_phrase/view.cljs (82%) rename src/status_im/contexts/settings/wallet/keypairs_and_accounts/{ => missing_keypairs}/scan_qr/view.cljs (91%) diff --git a/src/status_im/common/enter_seed_phrase/view.cljs b/src/status_im/common/enter_seed_phrase/view.cljs index ffe6dabcef..361ec2e619 100644 --- a/src/status_im/common/enter_seed_phrase/view.cljs +++ b/src/status_im/common/enter_seed_phrase/view.cljs @@ -2,6 +2,7 @@ (:require [clojure.string :as string] [legacy.status-im.ethereum.mnemonic :as mnemonic] + [oops.core :as oops] [quo.core :as quo] [quo.foundations.colors :as colors] [react-native.core :as rn] @@ -96,35 +97,36 @@ (defn recovery-phrase-screen [{:keys [keypair title recovering-keypair? render-controls]}] - (reagent/with-let [keyboard-shown? (reagent/atom false) - keyboard-show-listener (.addListener rn/keyboard - "keyboardDidShow" - #(reset! keyboard-shown? true)) - keyboard-hide-listener (.addListener rn/keyboard - "keyboardDidHide" - #(reset! keyboard-shown? false)) - invalid-seed-phrase? (reagent/atom false) - input-ref (reagent/atom nil) - focus-input (fn [] - (let [ref @input-ref] - (when ref - (.focus ref)))) - set-invalid-seed-phrase #(reset! invalid-seed-phrase? true) - seed-phrase (reagent/atom "") - on-change-seed-phrase (fn [new-phrase] - (when @invalid-seed-phrase? - (reset! invalid-seed-phrase? false)) - (reset! seed-phrase new-phrase)) - on-submit (fn [] - (swap! seed-phrase clean-seed-phrase) - (if recovering-keypair? - (rf/dispatch [:wallet/seed-phrase-entered - (security/mask-data - @seed-phrase) - set-invalid-seed-phrase]) - (rf/dispatch [:onboarding/seed-phrase-entered - (security/mask-data @seed-phrase) - set-invalid-seed-phrase])))] + (reagent/with-let [keyboard-shown? (reagent/atom false) + keyboard-show-listener (.addListener rn/keyboard + "keyboardDidShow" + #(reset! keyboard-shown? true)) + keyboard-hide-listener (.addListener rn/keyboard + "keyboardDidHide" + #(reset! keyboard-shown? false)) + invalid-seed-phrase? (reagent/atom false) + incorrect-seed-phrase? (reagent/atom false) + input-ref (reagent/atom nil) + focus-input #(some-> @input-ref + (oops/ocall "focus")) + set-incorrect-seed-phrase #(reset! incorrect-seed-phrase? true) + set-invalid-seed-phrase #(reset! invalid-seed-phrase? true) + seed-phrase (reagent/atom "") + on-change-seed-phrase (fn [new-phrase] + (when @invalid-seed-phrase? + (reset! invalid-seed-phrase? false) + (reset! incorrect-seed-phrase? false)) + (reset! seed-phrase new-phrase)) + on-submit (fn [] + (swap! seed-phrase clean-seed-phrase) + (if recovering-keypair? + (rf/dispatch [:wallet/seed-phrase-entered + (security/mask-data + @seed-phrase) + set-invalid-seed-phrase]) + (rf/dispatch [:onboarding/seed-phrase-entered + (security/mask-data @seed-phrase) + set-invalid-seed-phrase])))] (let [words-coll (mnemonic/passphrase->words @seed-phrase) last-word (peek words-coll) pick-suggested-word (fn [pressed-word] @@ -143,16 +145,18 @@ suggestions-state (cond (or error-in-words? words-exceeded? - @invalid-seed-phrase?) :error + @invalid-seed-phrase? + @incorrect-seed-phrase?) :error (string/blank? @seed-phrase) :info (string/ends-with? @seed-phrase " ") :empty :else :words) suggestions-text (cond - upper-case? (i18n/label :t/seed-phrase-words-uppercase) - words-exceeded? (i18n/label :t/seed-phrase-words-exceeded) - error-in-words? (i18n/label :t/seed-phrase-error) - @invalid-seed-phrase? (i18n/label :t/seed-phrase-invalid) - :else (i18n/label :t/seed-phrase-info)) + upper-case? (i18n/label :t/seed-phrase-words-uppercase) + words-exceeded? (i18n/label :t/seed-phrase-words-exceeded) + error-in-words? (i18n/label :t/seed-phrase-error) + @invalid-seed-phrase? (i18n/label :t/seed-phrase-invalid) + @incorrect-seed-phrase? (i18n/label :t/seed-phrase-incorrect) + :else (i18n/label :t/seed-phrase-info)) error-state? (= suggestions-state :error) button-disabled? (or error-state? (not (constants/seed-phrase-valid-length word-count)) @@ -166,13 +170,13 @@ :word-count word-count :ref #(reset! input-ref %)} (if (fn? render-controls) - (render-controls {:submit-disabled? button-disabled? - :keyboard-shown? @keyboard-shown? - :container-style (style/continue-button @keyboard-shown?) - :prepare-seed-phrase secure-clean-seed-phrase - :focus-input focus-input - :seed-phrase (security/mask-data @seed-phrase) - :set-invalid-seed-phrase set-invalid-seed-phrase}) + (render-controls {:submit-disabled? button-disabled? + :keyboard-shown? @keyboard-shown? + :container-style (style/continue-button @keyboard-shown?) + :prepare-seed-phrase secure-clean-seed-phrase + :focus-input focus-input + :seed-phrase (security/mask-data @seed-phrase) + :set-incorrect-seed-phrase set-incorrect-seed-phrase}) [quo/button {:container-style (style/continue-button @keyboard-shown?) :type :primary diff --git a/src/status_im/contexts/profile/settings/list_items.cljs b/src/status_im/contexts/profile/settings/list_items.cljs index e8c9c2dfb8..26f84d709d 100644 --- a/src/status_im/contexts/profile/settings/list_items.cljs +++ b/src/status_im/contexts/profile/settings/list_items.cljs @@ -35,7 +35,7 @@ :blur? true :action :arrow} {:title (i18n/label :t/wallet) - :on-press #(rf/dispatch [:navigate-to-within-stack [:screen/settings.wallet :settings]]) + :on-press #(rf/dispatch [:open-modal :screen/settings.wallet]) :image-props :i/wallet :image :icon :blur? true diff --git a/src/status_im/contexts/settings/wallet/events.cljs b/src/status_im/contexts/settings/wallet/events.cljs index 13ffb0dec8..9796dc5d69 100644 --- a/src/status_im/contexts/settings/wallet/events.cljs +++ b/src/status_im/contexts/settings/wallet/events.cljs @@ -167,9 +167,9 @@ (rf/reg-event-fx :wallet/verify-private-key-for-keypair verify-private-key-for-keypair) -(defn import-keypair-by-seed-phrase +(defn import-missing-keypair-by-seed-phrase [_ [{:keys [keypair-key-uid seed-phrase password on-success on-error]}]] - {:fx [[:import-keypair-by-seed-phrase + {:fx [[:effects.wallet/import-missing-keypair-by-seed-phrase {:keypair-key-uid keypair-key-uid :seed-phrase seed-phrase :password password @@ -178,24 +178,26 @@ #{keypair-key-uid}]) (rf/call-continuation on-success)) :on-error (fn [error] - (rf/dispatch [:wallet/import-keypair-by-seed-phrase-failed error]) + (rf/dispatch [:wallet/import-missing-keypair-by-seed-phrase-failed error]) + (log/error "failed to import missing keypair with seed phrase" + {:error error}) (rf/call-continuation on-error error))}]]}) -(rf/reg-event-fx :wallet/import-keypair-by-seed-phrase import-keypair-by-seed-phrase) +(rf/reg-event-fx :wallet/import-missing-keypair-by-seed-phrase import-missing-keypair-by-seed-phrase) -(defn import-keypair-by-seed-phrase-failed +(defn import-missing-keypair-by-seed-phrase-failed [_ [error]] (let [error-type (-> error ex-message keyword) error-data (ex-data error)] - (when-not (and (= error-type :import-keypair-by-seed-phrase/import-error) - (= (:hint error-data) :incorrect-seed-phrase-for-keypair)) + (when-not (= error-type :import-missing-keypair-by-seed-phrase/import-error) {:fx [[:dispatch [:toasts/upsert {:type :negative :theme :dark :text (:error error-data)}]]]}))) -(rf/reg-event-fx :wallet/import-keypair-by-seed-phrase-failed import-keypair-by-seed-phrase-failed) +(rf/reg-event-fx :wallet/import-missing-keypair-by-seed-phrase-failed + import-missing-keypair-by-seed-phrase-failed) (defn import-missing-keypair-by-private-key [_ [{:keys [keypair-key-uid private-key password on-success on-error]}]] diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/actions/view.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/actions/view.cljs index d0e822a4bd..622b64c272 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/actions/view.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/actions/view.cljs @@ -1,7 +1,7 @@ (ns status-im.contexts.settings.wallet.keypairs-and-accounts.actions.view (:require [quo.core :as quo] [react-native.core :as rn] - [status-im.contexts.settings.wallet.keypairs-and-accounts.remove.view :as remove-key-pair] + [status-im.contexts.settings.wallet.keypairs-and-accounts.remove.view :as remove-keypair] [utils.i18n :as i18n] [utils.re-frame :as rf])) @@ -14,20 +14,22 @@ [(:key-uid keypair)]]) [keypair]) on-show-qr (rn/use-callback #(rf/dispatch [:open-modal - :screen/settings.encrypted-key-pair-qr + :screen/settings.encrypted-keypair-qr keypair]) [keypair]) on-remove-keypair (rn/use-callback #(rf/dispatch [:show-bottom-sheet {:theme :dark :content (fn [] - [remove-key-pair/view keypair])}]) + [remove-keypair/view keypair])}]) [keypair]) on-rename-keypair (rn/use-callback #(rf/dispatch [:open-modal :screen/settings.rename-keypair keypair]) [keypair]) on-import-seed-phrase (rn/use-callback - #(rf/dispatch [:open-modal :screen/settings.import-seed-phrase keypair]) + #(rf/dispatch [:open-modal + :screen/settings.missing-keypair.import-seed-phrase + keypair]) [keypair]) on-import-private-key (rn/use-callback #(rf/dispatch [:open-modal diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/encrypted_qr/countdown/view.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/encrypted_qr/countdown/view.cljs similarity index 94% rename from src/status_im/contexts/settings/wallet/keypairs_and_accounts/encrypted_qr/countdown/view.cljs rename to src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/encrypted_qr/countdown/view.cljs index cce451e9c1..c88ddb3a1c 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/encrypted_qr/countdown/view.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/encrypted_qr/countdown/view.cljs @@ -1,4 +1,4 @@ -(ns status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.countdown.view +(ns status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.encrypted-qr.countdown.view (:require [quo.core :as quo] [quo.foundations.colors :as colors] diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/encrypted_qr/style.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/encrypted_qr/style.cljs similarity index 90% rename from src/status_im/contexts/settings/wallet/keypairs_and_accounts/encrypted_qr/style.cljs rename to src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/encrypted_qr/style.cljs index 5598fbce21..9958f19443 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/encrypted_qr/style.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/encrypted_qr/style.cljs @@ -1,4 +1,4 @@ -(ns status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.style +(ns status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.encrypted-qr.style (:require [quo.foundations.colors :as colors] [react-native.safe-area :as safe-area])) diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/encrypted_qr/view.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/encrypted_qr/view.cljs similarity index 93% rename from src/status_im/contexts/settings/wallet/keypairs_and_accounts/encrypted_qr/view.cljs rename to src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/encrypted_qr/view.cljs index 7e28c4b390..772eefbaa3 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/encrypted_qr/view.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/encrypted_qr/view.cljs @@ -1,4 +1,4 @@ -(ns status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.view +(ns status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.encrypted-qr.view (:require [quo.core :as quo] [quo.foundations.colors :as colors] @@ -7,8 +7,10 @@ [status-im.common.qr-codes.view :as qr-codes] [status-im.common.resources :as resources] [status-im.common.standard-authentication.core :as standard-auth] - [status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.countdown.view :as countdown] - [status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.style :as style] + [status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.encrypted-qr.countdown.view + :as countdown] + [status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.encrypted-qr.style + :as style] [status-im.contexts.syncing.utils :as sync-utils] [utils.i18n :as i18n] [utils.re-frame :as rf])) diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/import_private_key/style.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/import_private_key/style.cljs similarity index 58% rename from src/status_im/contexts/settings/wallet/keypairs_and_accounts/import_private_key/style.cljs rename to src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/import_private_key/style.cljs index 01dbf913c8..a2b52a68d4 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/import_private_key/style.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/import_private_key/style.cljs @@ -1,4 +1,4 @@ -(ns status-im.contexts.settings.wallet.keypairs-and-accounts.import-private-key.style) +(ns status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.import-private-key.style) (def form-container {:row-gap 8 diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/import_private_key/view.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/import_private_key/view.cljs similarity index 96% rename from src/status_im/contexts/settings/wallet/keypairs_and_accounts/import_private_key/view.cljs rename to src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/import_private_key/view.cljs index beeb35b8ff..42931a1cb0 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/import_private_key/view.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/import_private_key/view.cljs @@ -1,4 +1,4 @@ -(ns status-im.contexts.settings.wallet.keypairs-and-accounts.import-private-key.view +(ns status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.import-private-key.view (:require [clojure.string :as string] [quo.core :as quo] @@ -7,7 +7,8 @@ [react-native.safe-area :as safe-area] [status-im.common.floating-button-page.view :as floating-button-page] [status-im.common.standard-authentication.core :as standard-auth] - [status-im.contexts.settings.wallet.keypairs-and-accounts.import-private-key.style :as style] + [status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.import-private-key.style + :as style] [status-im.contexts.wallet.common.validation :as validation] [utils.debounce :as debounce] [utils.i18n :as i18n] @@ -68,8 +69,7 @@ [on-change]) on-import-error (rn/use-callback (fn [_error] - (rf/dispatch [:hide-bottom-sheet]) - (show-invalid))) + (rf/dispatch [:hide-bottom-sheet]))) on-import-success (rn/use-callback (fn [] (rf/dispatch [:hide-bottom-sheet]) @@ -134,5 +134,5 @@ (case flow-state :correct-private-key (i18n/label :t/correct-private-key) :invalid-private-key (i18n/label :t/invalid-private-key) - :incorrect-private-key (i18n/label :t/incorrect-private-key {:name (:name keypair)}) + :incorrect-private-key (i18n/label :t/incorrect-private-key) nil)])]]])) diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/import_seed_phrase/view.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/import_seed_phrase/view.cljs similarity index 82% rename from src/status_im/contexts/settings/wallet/keypairs_and_accounts/import_seed_phrase/view.cljs rename to src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/import_seed_phrase/view.cljs index 4b04768bcd..3407679889 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/import_seed_phrase/view.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/import_seed_phrase/view.cljs @@ -1,4 +1,4 @@ -(ns status-im.contexts.settings.wallet.keypairs-and-accounts.import-seed-phrase.view +(ns status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.import-seed-phrase.view (:require [quo.core :as quo] [react-native.core :as rn] @@ -14,16 +14,17 @@ container-style prepare-seed-phrase seed-phrase - set-invalid-seed-phrase + set-incorrect-seed-phrase focus-input]}] (let [keypair (rf/sub [:get-screen-params]) customization-color (rf/sub [:profile/customization-color]) show-errors (rn/use-callback - #(js/setTimeout - (fn [] - (focus-input) - (reagent/next-tick set-invalid-seed-phrase)) - 600)) + (fn [_error] + (js/setTimeout + (fn [] + (focus-input) + (reagent/next-tick set-incorrect-seed-phrase)) + 600))) on-import-error (rn/use-callback (fn [_error] (rf/dispatch [:hide-bottom-sheet]) @@ -34,7 +35,7 @@ (rf/dispatch [:navigate-back]))) on-auth-success (rn/use-callback (fn [password] - (rf/dispatch [:wallet/import-keypair-by-seed-phrase + (rf/dispatch [:wallet/import-missing-keypair-by-seed-phrase {:keypair-key-uid (:key-uid keypair) :seed-phrase (prepare-seed-phrase seed-phrase) :password password diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/scan_qr/view.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/scan_qr/view.cljs similarity index 91% rename from src/status_im/contexts/settings/wallet/keypairs_and_accounts/scan_qr/view.cljs rename to src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/scan_qr/view.cljs index d93b4541be..3978f90277 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/scan_qr/view.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/scan_qr/view.cljs @@ -1,4 +1,4 @@ -(ns status-im.contexts.settings.wallet.keypairs-and-accounts.scan-qr.view +(ns status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.scan-qr.view (:require [react-native.core :as rn] [status-im.common.scan-qr-code.view :as scan-qr-code] diff --git a/src/status_im/contexts/settings/wallet/saved_addresses/add_address_to_save/view.cljs b/src/status_im/contexts/settings/wallet/saved_addresses/add_address_to_save/view.cljs index 936de8a238..e580c5bf61 100644 --- a/src/status_im/contexts/settings/wallet/saved_addresses/add_address_to_save/view.cljs +++ b/src/status_im/contexts/settings/wallet/saved_addresses/add_address_to_save/view.cljs @@ -159,9 +159,7 @@ :ens address-or-ens :ens? ens-name?}]) (rf/dispatch - [:navigate-to-within-stack - [:screen/settings.save-address - :screen/settings.add-address-to-save]])) + [:open-modal :screen/settings.save-address])) [address ens-name? address-or-ens])] (rn/use-unmount #(rf/dispatch [:wallet/clear-address-to-save])) [quo/overlay {:type :shell} diff --git a/src/status_im/contexts/settings/wallet/saved_addresses/view.cljs b/src/status_im/contexts/settings/wallet/saved_addresses/view.cljs index a5f3c1991f..2c6d66237a 100644 --- a/src/status_im/contexts/settings/wallet/saved_addresses/view.cljs +++ b/src/status_im/contexts/settings/wallet/saved_addresses/view.cljs @@ -66,8 +66,7 @@ (defn- add-address-to-save [] - (rf/dispatch [:navigate-to-within-stack - [:screen/settings.add-address-to-save :screen/settings.saved-addresses]])) + (rf/dispatch [:open-modal :screen/settings.add-address-to-save])) (defn view [] diff --git a/src/status_im/contexts/settings/wallet/wallet_options/view.cljs b/src/status_im/contexts/settings/wallet/wallet_options/view.cljs index 71f6a40275..67cbc20d8f 100644 --- a/src/status_im/contexts/settings/wallet/wallet_options/view.cljs +++ b/src/status_im/contexts/settings/wallet/wallet_options/view.cljs @@ -8,11 +8,11 @@ (defn open-saved-addresses-settings-modal [] - (rf/dispatch [:navigate-to-within-stack [:screen/settings.saved-addresses :settings]])) + (rf/dispatch [:open-modal :screen/settings.saved-addresses])) (defn open-keypairs-and-accounts-settings-modal [] - (rf/dispatch [:navigate-to-within-stack [:screen/settings.keypairs-and-accounts :settings]])) + (rf/dispatch [:open-modal :screen/settings.keypairs-and-accounts])) (defn basic-settings-options [] @@ -38,7 +38,7 @@ (defn open-network-settings-modal [] - (rf/dispatch [:navigate-to-within-stack [:screen/settings.network-settings :settings]])) + (rf/dispatch [:open-modal :screen/settings.network-settings])) (defn advanced-settings-options [] diff --git a/src/status_im/contexts/wallet/effects.cljs b/src/status_im/contexts/wallet/effects.cljs index 7987e93527..8c0fedae29 100644 --- a/src/status_im/contexts/wallet/effects.cljs +++ b/src/status_im/contexts/wallet/effects.cljs @@ -79,7 +79,7 @@ :on-success (fn [value] (resolver {:value value}))})))) -(defn import-keypair-by-seed-phrase +(defn import-missing-keypair-by-seed-phrase [keypair-key-uid seed-phrase password] (-> (validate-mnemonic seed-phrase) (promesa/then @@ -87,20 +87,20 @@ (if (not= keypair-key-uid key-uid) (promesa/rejected (ex-info - (error-message :import-keypair-by-seed-phrase/import-error) + (error-message :import-missing-keypair-by-seed-phrase/import-error) {:hint :incorrect-seed-phrase-for-keypair})) (make-seed-phrase-fully-operable seed-phrase password)))) (promesa/catch (fn [error] (promesa/rejected (ex-info - (error-message :import-keypair-by-seed-phrase/import-error) + (error-message :import-missing-keypair-by-seed-phrase/import-error) (ex-data error))))))) (rf/reg-fx - :import-keypair-by-seed-phrase + :effects.wallet/import-missing-keypair-by-seed-phrase (fn [{:keys [keypair-key-uid seed-phrase password on-success on-error]}] - (-> (import-keypair-by-seed-phrase keypair-key-uid seed-phrase password) + (-> (import-missing-keypair-by-seed-phrase keypair-key-uid seed-phrase password) (promesa/then (partial rf/call-continuation on-success)) (promesa/catch (partial rf/call-continuation on-error))))) diff --git a/src/status_im/navigation/screens.cljs b/src/status_im/navigation/screens.cljs index 1335df59ad..4be18c3014 100644 --- a/src/status_im/navigation/screens.cljs +++ b/src/status_im/navigation/screens.cljs @@ -57,14 +57,15 @@ [status-im.contexts.profile.settings.screens.password.change-password.view :as change-password] [status-im.contexts.profile.settings.screens.password.view :as settings-password] [status-im.contexts.profile.settings.view :as settings] - [status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.view :as - encrypted-key-pair-qr] - [status-im.contexts.settings.wallet.keypairs-and-accounts.import-private-key.view :as - import-private-key] - [status-im.contexts.settings.wallet.keypairs-and-accounts.import-seed-phrase.view :as - import-seed-phrase] + [status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.encrypted-qr.view + :as encrypted-keypair-qr] + [status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.import-private-key.view + :as missing-keypairs.import-private-key] + [status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.import-seed-phrase.view + :as missing-keypairs.import-seed-phrase] + [status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.scan-qr.view + :as scan-keypair-qr] [status-im.contexts.settings.wallet.keypairs-and-accounts.rename.view :as keypair-rename] - [status-im.contexts.settings.wallet.keypairs-and-accounts.scan-qr.view :as scan-keypair-qr] [status-im.contexts.settings.wallet.keypairs-and-accounts.view :as keypairs-and-accounts] [status-im.contexts.settings.wallet.network-settings.view :as network-settings] [status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.view :as @@ -535,9 +536,9 @@ :options (assoc options/dark-screen :sheet? true) :component keypair-rename/view} - {:name :screen/settings.encrypted-key-pair-qr + {:name :screen/settings.encrypted-keypair-qr :options options/transparent-screen-options - :component encrypted-key-pair-qr/view} + :component encrypted-keypair-qr/view} {:name :screen/settings.saved-addresses :options options/transparent-modal-screen-options @@ -551,13 +552,13 @@ :options options/transparent-modal-screen-options :component scan-keypair-qr/view} - {:name :screen/settings.import-seed-phrase + {:name :screen/settings.missing-keypair.import-seed-phrase :options options/transparent-screen-options - :component import-seed-phrase/view} + :component missing-keypairs.import-seed-phrase/view} {:name :screen/settings.missing-keypair-import-private-key :options options/transparent-screen-options - :component import-private-key/view} + :component missing-keypairs.import-private-key/view} {:name :screen/settings.network-settings :options options/transparent-modal-screen-options diff --git a/src/status_im/subs/wallet/wallet.cljs b/src/status_im/subs/wallet/wallet.cljs index a7d9df1a2b..69561b9992 100644 --- a/src/status_im/subs/wallet/wallet.cljs +++ b/src/status_im/subs/wallet/wallet.cljs @@ -259,22 +259,22 @@ :wallet/settings-keypairs-accounts :<- [:wallet/keypairs] (fn [keypairs [_ format-options]] - (let [grouped-keypairs (group-by :lowest-operability keypairs) - operable-key-pair-ids (->> (concat (:fully grouped-keypairs) - (:partially grouped-keypairs)) - (map :key-uid) - (into #{})) - missing-key-pair-ids (->> (map :key-uid (:no grouped-keypairs)) - (into #{}))] + (let [grouped-keypairs (group-by :lowest-operability keypairs) + operable-keypair-ids (->> (concat (:fully grouped-keypairs) + (:partially grouped-keypairs)) + (map :key-uid) + (into #{})) + missing-keypair-ids (->> (map :key-uid (:no grouped-keypairs)) + (into #{}))] {:operable (->> keypairs - (filter #(contains? operable-key-pair-ids (:key-uid %))) + (filter #(contains? operable-keypair-ids (:key-uid %))) (map (fn [{:keys [accounts name type key-uid]}] {:type (keyword type) :name name :key-uid key-uid :accounts (format-settings-keypair-accounts accounts format-options)}))) :missing (->> keypairs - (filter #(contains? missing-key-pair-ids (:key-uid %))) + (filter #(contains? missing-keypair-ids (:key-uid %))) (map (fn [{:keys [accounts name type key-uid]}] {:type (keyword type) :name name diff --git a/translations/en.json b/translations/en.json index 50c2ea7239..a9b88ba050 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1587,6 +1587,7 @@ "seed-phrase-words-uppercase": "Recovery phrase cannot contain uppercase characters", "seed-phrase-error": "Recovery phrase contains invalid words", "seed-phrase-invalid": "Invalid recovery phrase", + "seed-phrase-incorrect": "Recovery phrase does not match key pair", "seed-phrase-info": "Enter 12, 18 or 24 words separated by spaces", "word-count": "Word count", "word-n": "Word #{{number}}", @@ -2659,7 +2660,7 @@ "import-private-key-info": "New addresses cannot be derived from an account imported from a private key. Import using a seed phrase if you wish to derive addresses.", "invalid-private-key": "It’s not a valid private key", "correct-private-key": "Correct private key", - "incorrect-private-key": "This is not the private key for {{name}}", + "incorrect-private-key": "This is not the private key for this key pair", "private-key-public-address": "Public address of private key", "this-account-has-no-activity": "This account has no activity", "this-address-has-activity": "This address has activity",