[#19410] extend wizard mechanism for collectibles and tokens (#19515)

* Fix typo `:collecible` -> `:collectible`

* Extend the wallet-send-flow for collectibles and tokens in all entry points
This commit is contained in:
Ulises Manuel 2024-05-13 18:01:31 -06:00 committed by GitHub
parent 947e2369d3
commit 88df60958c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 128 additions and 68 deletions

View File

@ -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

View File

@ -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)]))]]))

View File

@ -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)))

View File

@ -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}])))

View File

@ -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}]]]})))

View File

@ -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}])

View File

@ -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}]))

View File

@ -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}]))]
[:<>

View File

@ -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