diff --git a/src/status_im/contexts/wallet/collectible/view.cljs b/src/status_im/contexts/wallet/collectible/view.cljs index 3dde3f6c52..06327f7afa 100644 --- a/src/status_im/contexts/wallet/collectible/view.cljs +++ b/src/status_im/contexts/wallet/collectible/view.cljs @@ -18,7 +18,8 @@ [rn/view {:style style/header} [quo/text {:weight :semi-bold - :size :heading-1} collectible-name] + :size :heading-1} + collectible-name] [rn/view {:style style/collection-container} [rn/view {:style style/collection-avatar-container} [quo/collection-avatar {:image collection-image-url}]] @@ -28,7 +29,7 @@ collection-name]]]) (defn cta-buttons - [{:keys [chain-id token-id contract-address watch-only?]}] + [{:keys [chain-id token-id contract-address collectible watch-only?]}] (let [theme (quo.theme/use-theme)] [rn/view {:style style/buttons-container} (when-not watch-only? @@ -36,7 +37,11 @@ {:container-style style/send-button :type :outline :size 40 - :icon-left :i/send} + :icon-left :i/send + :on-press #(rf/dispatch + [:wallet/set-collectible-to-send + {:collectible collectible + :current-screen :screen/wallet.collectible}])} (i18n/label :t/send)]) [quo/button {:container-style style/opensea-button @@ -134,7 +139,8 @@ {:chain-id chain-id :token-id token-id :contract-address contract-address - :watch-only? (:watch-only? collectible-owner)}] + :watch-only? false ;(:watch-only? collectible-owner) + :collectible collectible}] [quo/tabs {:size 32 :style style/tabs 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 e93ac0cedd..d23ecdbbc2 100644 --- a/src/status_im/contexts/wallet/common/token_value/view.cljs +++ b/src/status_im/contexts/wallet/common/token_value/view.cljs @@ -15,16 +15,14 @@ :right-icon :i/external}) (defn- action-send - [token-data] + [send-params] {:icon :i/send :accessibility-label :send :label (i18n/label :t/send) :on-press (fn [] (rf/dispatch [:hide-bottom-sheet]) (rf/dispatch [:wallet/clean-send-data]) - (rf/dispatch [:wallet/send-select-token - {:token token-data - :start-flow? true}]))}) + (rf/dispatch [:wallet/set-token-to-send send-params]))}) (defn- action-receive [] @@ -59,14 +57,21 @@ (defn token-value-drawer [token watch-only?] - (let [token-data (first (rf/sub [:wallet/current-viewing-account-tokens-filtered (:token token)]))] + (let [token-symbol (:token token) + token-data (first (rf/sub [:wallet/current-viewing-account-tokens-filtered token-symbol])) + selected-account? (rf/sub [:wallet/current-viewing-account-address]) + send-params (if selected-account? + {:token token-data + :start-flow? true} + {:token-symbol token-symbol + :start-flow? true})] [quo/action-drawer [(cond->> [(when (ff/enabled? ::ff/wallet.assets-modal-manage-tokens) (action-manage-tokens watch-only?)) (when (ff/enabled? ::ff/wallet.assets-modal-hide) (action-hide))] (not watch-only?) (concat [(action-buy) - (action-send token-data) + (action-send send-params) (action-receive) (action-bridge token-data)]))]])) diff --git a/src/status_im/contexts/wallet/common/utils.cljs b/src/status_im/contexts/wallet/common/utils.cljs index 79c14bc8e1..4bf5846a1e 100644 --- a/src/status_im/contexts/wallet/common/utils.cljs +++ b/src/status_im/contexts/wallet/common/utils.cljs @@ -271,3 +271,10 @@ (str (get-in collectible [:id :contract-id :address]) ":" (get-in collectible [:id :token-id])))) + +(defn get-token-from-account + [db token-symbol address] + (let [address-tokens (-> db :wallet :accounts (get address) :tokens)] + (some #(when (= token-symbol (:symbol %)) + %) + address-tokens))) diff --git a/src/status_im/contexts/wallet/home/tabs/assets/view.cljs b/src/status_im/contexts/wallet/home/tabs/assets/view.cljs index 83eed69b15..9366b2ce78 100644 --- a/src/status_im/contexts/wallet/home/tabs/assets/view.cljs +++ b/src/status_im/contexts/wallet/home/tabs/assets/view.cljs @@ -2,13 +2,10 @@ (:require [quo.core :as quo] [react-native.core :as rn] + [status-im.contexts.wallet.common.token-value.view :as token-value] [status-im.contexts.wallet.home.tabs.assets.style :as style] [utils.re-frame :as rf])) -(defn- token-value - [item & _rest] - [quo/token-value item]) - (defn view [] (let [tokens-loading? (rf/sub [:wallet/tokens-loading?]) @@ -19,6 +16,6 @@ :parent-height 560 :animated? false}] [rn/flat-list - {:render-fn token-value + {:render-fn token-value/view :data tokens :content-container-style style/list-container}]))) diff --git a/src/status_im/contexts/wallet/send/events.cljs b/src/status_im/contexts/wallet/send/events.cljs index 643e323564..a57777faf8 100644 --- a/src/status_im/contexts/wallet/send/events.cljs +++ b/src/status_im/contexts/wallet/send/events.cljs @@ -4,6 +4,7 @@ [clojure.string :as string] [native-module.core :as native-module] [status-im.constants :as constants] + [status-im.contexts.wallet.collectible.utils :as collectible.utils] [status-im.contexts.wallet.common.utils :as utils] [status-im.contexts.wallet.common.utils.networks :as network-utils] [status-im.contexts.wallet.send.utils :as send-utils] @@ -136,13 +137,20 @@ receiver-networks (network-utils/resolve-receiver-networks {:prefix prefix :testnet-enabled? testnet-enabled? - :goerli-enabled? goerli-enabled?})] + :goerli-enabled? goerli-enabled?}) + collectible-tx? (= (-> db :wallet :ui :send :tx-type) :collectible) + collectible (when collectible-tx? + (-> db :wallet :ui :send :collectible)) + one-collectible? (when collectible-tx? + (= (collectible.utils/collectible-balance collectible) 1))] {:db (-> db (assoc-in [:wallet :ui :send :recipient] (or recipient address)) (assoc-in [:wallet :ui :send :to-address] to-address) (assoc-in [:wallet :ui :send :address-prefix] prefix) (assoc-in [:wallet :ui :send :receiver-networks] receiver-networks)) - :fx [[:dispatch + :fx [(when (and collectible-tx? one-collectible?) + [:dispatch [:wallet/get-suggested-routes {:amount 1}]]) + [:dispatch [:wallet/wizard-navigate-forward {:current-screen stack-id :start-flow? start-flow? @@ -163,12 +171,16 @@ :fx [[:dispatch [:wallet/get-suggested-routes {:amount amount}]]]}))) (rf/reg-event-fx - :wallet/send-select-token - (fn [{:keys [db]} [{:keys [token stack-id start-flow?]}]] - {:db (-> db - (update-in [:wallet :ui :send] dissoc :collectible) - (assoc-in [:wallet :ui :send :token] token) - (assoc-in [:wallet :ui :send :token-display-name] (:symbol token))) + :wallet/set-token-to-send + (fn [{:keys [db]} [{:keys [token-symbol token stack-id start-flow?]}]] + ;; `token` is a map extracted from the sender, but in the wallet home page we don't know the + ;; sender yet, so we only provide the `token-symbol`, later in + ;; `:wallet/select-from-account` the `token` key will be set. + {:db (cond-> db + :always (update-in [:wallet :ui :send] dissoc :collectible) + :always (assoc-in [:wallet :ui :send :token-display-name] (:symbol token)) + token (assoc-in [:wallet :ui :send :token] token) + token-symbol (assoc-in [:wallet :ui :send :token-symbol] token-symbol)) :fx [[:dispatch [:wallet/clean-suggested-routes]] [:dispatch [:wallet/wizard-navigate-forward @@ -198,38 +210,49 @@ :collectible :token-display-name :amount - (when (= transaction-type :collecible) :tx-type))}))) + (when (= transaction-type :collectible) :tx-type))}))) -(rf/reg-event-fx :wallet/send-collectibles-amount - (fn [{:keys [db]} [{:keys [collectible stack-id amount]}]] +(rf/reg-event-fx + :wallet/set-collectible-to-send + (fn [{db :db} [{:keys [collectible current-screen]}]] (let [collection-data (:collection-data collectible) collectible-data (:collectible-data collectible) collectible-id (get-in collectible [:id :token-id]) + one-collectible? (= (collectible.utils/collectible-balance collectible) 1) token-display-name (cond (and collectible (not (string/blank? (:name collectible-data)))) (:name collectible-data) collectible - (str (:name collection-data) " #" collectible-id))] - {:db (-> db - (update-in [:wallet :ui :send] dissoc :token) - (assoc-in [:wallet :ui :send :collectible] collectible) - (assoc-in [:wallet :ui :send :token-display-name] token-display-name) - (assoc-in [:wallet :ui :send :tx-type] :collectible) - (assoc-in [:wallet :ui :send :amount] amount)) - :fx [[:dispatch [:wallet/get-suggested-routes {:amount amount}]] - [:navigate-to-within-stack [:screen/wallet.transaction-confirmation stack-id]]]}))) + (str (:name collection-data) " #" collectible-id)) + collectible-tx (-> db + (update-in [:wallet :ui :send] dissoc :token) + (assoc-in [:wallet :ui :send :collectible] collectible) + (assoc-in [:wallet :ui :send :token-display-name] token-display-name) + (assoc-in [:wallet :ui :send :tx-type] :collectible)) + recipient-set? (-> db :wallet :ui :send :recipient)] + {:db (cond-> collectible-tx + one-collectible? (assoc-in [:wallet :ui :send :amount] 1)) + :fx [(when (and one-collectible? recipient-set?) + [:dispatch [:wallet/get-suggested-routes {:amount 1}]]) + [:dispatch + [:wallet/wizard-navigate-forward + {:current-screen current-screen + :flow-id :wallet-send-flow}]]]}))) -(rf/reg-event-fx :wallet/select-collectibles-amount - (fn [{:keys [db]} [{:keys [collectible stack-id]}]] - {:db (-> db - (update-in [:wallet :ui :send] dissoc :token) - (assoc-in [:wallet :ui :send :collectible] collectible) - (assoc-in [:wallet :ui :send :tx-type] :collectible)) - :fx [[:navigate-to-within-stack [:screen/wallet.select-collectible-amount stack-id]]]})) +(rf/reg-event-fx + :wallet/set-collectible-amount-to-send + (fn [{db :db} [{:keys [stack-id amount]}]] + {:db (assoc-in db [:wallet :ui :send :amount] amount) + :fx [[:dispatch [:wallet/get-suggested-routes {:amount amount}]] + [:dispatch + [:wallet/wizard-navigate-forward + {:current-screen stack-id + :flow-id :wallet-send-flow}]]]})) -(rf/reg-event-fx :wallet/send-select-amount +(rf/reg-event-fx + :wallet/set-token-amount-to-send (fn [{:keys [db]} [{:keys [amount stack-id start-flow?]}]] {:db (assoc-in db [:wallet :ui :send :amount] amount) :fx [[:dispatch @@ -503,10 +526,21 @@ (rf/reg-event-fx :wallet/select-from-account - (fn [_ [{:keys [address stack-id start-flow?]}]] - {:fx [[:dispatch [:wallet/switch-current-viewing-account address]] - [:dispatch - [:wallet/wizard-navigate-forward - {:current-screen stack-id - :start-flow? start-flow? - :flow-id :wallet-send-flow}]]]})) + (fn [{db :db} [{:keys [address stack-id start-flow?]}]] + (let [token-symbol (-> db :wallet :ui :send :token-symbol) + token (when token-symbol + ;; When this flow has started in the wallet home page, we know the + ;; token or collectible to send, but we don't know from which + ;; account, so we extract the token data from the picked account. + (utils/get-token-from-account db token-symbol address))] + {:db (if token-symbol + (-> db + (assoc-in [:wallet :ui :send :token] token) + (update-in [:wallet :ui :send] dissoc :token-symbol)) + db) + :fx [[:dispatch [:wallet/switch-current-viewing-account address]] + [:dispatch + [:wallet/wizard-navigate-forward + {:current-screen stack-id + :start-flow? start-flow? + :flow-id :wallet-send-flow}]]]}))) diff --git a/src/status_im/contexts/wallet/send/flow_config.cljs b/src/status_im/contexts/wallet/send/flow_config.cljs index 0ebe15f564..79e97fb1fc 100644 --- a/src/status_im/contexts/wallet/send/flow_config.cljs +++ b/src/status_im/contexts/wallet/send/flow_config.cljs @@ -1,13 +1,30 @@ (ns status-im.contexts.wallet.send.flow-config) +(defn- collectible-selected? + [db] + (let [collectible-stored (-> db :wallet :ui :send :collectible) + tx-type (-> db :wallet :ui :send :tx-type)] + (and (some? collectible-stored) + (= tx-type :collectible)))) + +(defn- token-selected? + [db] + (-> db :wallet :ui :send :token some?)) + (def steps [{:screen-id :screen/wallet.select-from :skip-step? (fn [db] (some? (get-in db [:wallet :current-viewing-account-address])))} {:screen-id :screen/wallet.select-address :skip-step? (fn [db] (some? (get-in db [:wallet :ui :send :recipient])))} {:screen-id :screen/wallet.select-asset - :skip-step? (fn [db] (some? (get-in db [:wallet :ui :send :token])))} + :skip-step? (fn [db] (or (token-selected? db) (collectible-selected? db)))} {:screen-id :screen/wallet.send-input-amount - :skip-step? (fn [db] (some? (get-in db [:wallet :ui :send :amount])))} + :skip-step? (fn [db] + (or (not (token-selected? db)) + (some? (get-in db [:wallet :ui :send :amount]))))} + {:screen-id :screen/wallet.select-collectible-amount + :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}]) 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 ab2a49e29e..727542c0c3 100644 --- a/src/status_im/contexts/wallet/send/input_amount/view.cljs +++ b/src/status_im/contexts/wallet/send/input_amount/view.cljs @@ -97,7 +97,7 @@ (let [[input-state set-input-state] (rn/use-state controlled-input/init-state) clear-input! #(set-input-state controlled-input/delete-all) handle-on-confirm (fn [] - (rf/dispatch [:wallet/send-select-amount + (rf/dispatch [:wallet/set-token-amount-to-send {:amount (controlled-input/input-value input-state) :stack-id current-screen-id}])) diff --git a/src/status_im/contexts/wallet/send/select_asset/view.cljs b/src/status_im/contexts/wallet/send/select_asset/view.cljs index 1911173945..0d030f3c52 100644 --- a/src/status_im/contexts/wallet/send/select_asset/view.cljs +++ b/src/status_im/contexts/wallet/send/select_asset/view.cljs @@ -4,7 +4,6 @@ [quo.core :as quo] [react-native.core :as rn] [reagent.core :as reagent] - [status-im.contexts.wallet.collectible.utils :as utils] [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.collectibles-tab.view :as collectibles-tab] @@ -34,15 +33,10 @@ {:collectibles collectibles :filtered? search-performed? :on-end-reached #(rf/dispatch [:wallet/request-collectibles-for-current-viewing-account]) - :on-collectible-press #(let [collectibles-count (utils/collectible-balance %)] - (if (> collectibles-count 1) - (rf/dispatch [:wallet/select-collectibles-amount - {:collectible % - :stack-id :screen/wallet.select-asset}]) - (rf/dispatch [:wallet/send-collectibles-amount - {:collectible % - :amount 1 - :stack-id :screen/wallet.select-asset}])))}])) + :on-collectible-press (fn [collectible] + (rf/dispatch [:wallet/set-collectible-to-send + {:collectible collectible + :current-screen :screen/wallet.select-asset}]))}])) (defn- tab-view [search-text selected-tab on-change-text] @@ -51,7 +45,7 @@ (and (= selected-tab :tab/collectibles) (seq unfiltered-collectibles))) on-token-press (fn [token] - (rf/dispatch [:wallet/send-select-token + (rf/dispatch [:wallet/set-token-to-send {:token token :stack-id :screen/wallet.select-asset}]))] [:<> diff --git a/src/status_im/contexts/wallet/send/select_collectible_amount/view.cljs b/src/status_im/contexts/wallet/send/select_collectible_amount/view.cljs index a73f626094..53a60b66f5 100644 --- a/src/status_im/contexts/wallet/send/select_collectible_amount/view.cljs +++ b/src/status_im/contexts/wallet/send/select_collectible_amount/view.cljs @@ -55,10 +55,10 @@ :status (if incorrect-value? :error :default)}] [quo/bottom-actions {:actions :one-action - :button-one-props {:on-press #(rf/dispatch [:wallet/send-collectibles-amount - {:collectible collectible - :amount value - :stack-id :screen/wallet.select-asset}]) + :button-one-props {:on-press #(rf/dispatch + [:wallet/set-collectible-amount-to-send + {:stack-id :screen/wallet.select-collectible-amount + :amount value}]) :disabled? incorrect-value?} :button-one-label (i18n/label :t/confirm)}] [quo/numbered-keyboard