[BUG#2882] Improved wallet asset selection

This commit is contained in:
Julien Eluard 2018-01-09 15:59:43 +01:00
parent b1f49a7730
commit 7cb9e09c08
21 changed files with 202 additions and 145 deletions

View File

@ -298,6 +298,7 @@
:wallet-send-token "Send {{symbol}}"
:wallet-request "Request"
:wallet-exchange "Exchange"
:wallet-asset "Asset"
:wallet-assets "Assets"
:wallet-add-asset "Add asset"
:wallet-total-value "Total value"
@ -313,6 +314,7 @@
:eth "ETH"
:currency "Currency"
:usd-currency "USD"
:amount-placeholder "Specify amount"
:transactions "Transactions"
:transaction-details "Transaction details"
:transaction-failed "Transaction failed"

View File

@ -6,9 +6,10 @@
(def item
{:flex-direction :row})
(def item-text-view
{:flex 1
:flex-direction :column})
(def item-content-view
{:flex 1
:flex-direction :column
:justify-content :center})
(def item-checkbox
{:flex 1

View File

@ -53,10 +53,10 @@
[vector-icons/icon icon (merge icon-opts {:style styles/item-icon})]])
(defn item-image
[{:keys[source style]}]
[{:keys[source style image-style]}]
[react/view {:style style}
[react/image {:source source
:style styles/item-image}]])
:style (merge styles/item-image image-style)}]])
(defn item-primary
[primary]
@ -72,7 +72,7 @@
(defn item-content
[& children]
(into [react/view {:style styles/item-text-view}] (keep identity children)))
(into [react/view {:style styles/item-content-view}] (keep identity children)))
(defn item-checkbox
[{:keys [style] :as props}]

View File

@ -119,7 +119,6 @@
:my-profile/drawer
:my-profile/profile
:my-profile/default-name
:wallet/request-transaction
:networks/selected-network
:networks/networks
:node/after-start

View File

@ -39,6 +39,7 @@
[status-im.ui.screens.wallet.choose-recipient.views :refer [choose-recipient]]
[status-im.ui.screens.wallet.request.views :refer [request-transaction]]
[status-im.ui.screens.wallet.wallet-list.views :refer [wallet-list-screen]]
[status-im.ui.screens.wallet.components.views :as wallet.components]
[status-im.ui.screens.wallet.send.views :as wallet.send]
[status-im.ui.screens.wallet.settings.views :as wallet-settings]
[status-im.ui.screens.wallet.transactions.views :as wallet-transactions]
@ -82,6 +83,8 @@
(:transactions-history :unsigned-transactions) wallet-transactions/transactions
:wallet-transaction-details wallet-transactions/transaction-details
(:wallet-my-token :wallet-market-value) wallet-assets/my-token-main
:wallet-send-assets wallet.components/send-assets
:wallet-request-assets wallet.components/request-assets
:new-chat new-chat
:new-group new-group
:edit-contact-group edit-contact-group

View File

@ -2,15 +2,27 @@
(:require-macros [status-im.utils.styles :refer [defnstyle defstyle]])
(:require [status-im.ui.components.styles :as styles]))
(def text-content
{:color :white})
(def text-secondary-content
{:color styles/color-white-transparent})
(def text
{:margin-right 10})
(def text-list-primary-content
(merge text {:color styles/color-black}))
(def text-input
{:color :white
:padding-left 14
:padding-right 14
:font-size 15
:padding-bottom 0
:padding-top 0
:height 52
:letter-spacing -0.2})
(merge text-content
{:padding-left 14
:padding-right 14
:font-size 15
:padding-bottom 0
:padding-top 0
:height 52
:letter-spacing -0.2}))
(defstyle label
{:color :white
@ -48,17 +60,37 @@
:align-items :center
:justify-content :center})
(defstyle currency-container
{:margin-top 8
:height 52
;;TODO disabled
:border-width 1
:border-color styles/color-white-transparent-4
;:background-color styles/color-white-transparent-3
:justify-content :center
:padding 14
:ios {:border-radius 8}
:android {:border-radius 4}})
(defstyle asset-container
{:margin-top 8
:height 52
:background-color styles/color-white-transparent-3
:justify-content :center
:padding-left 14
:padding-vertical 14
:padding-right 8
:ios {:border-radius 8}
:android {:border-radius 4}})
(def asset-content-container
{:flex-direction :row
:align-items :center})
(def asset-icon
{:background-color styles/color-gray9
:border-radius 50})
(def asset-text-content
{:flex 1
:flex-direction :row
:justify-content :space-between
:align-items :center})
(def asset-label-content
{:flex-direction :row
:margin-horizontal 10})
(def asset-label
{:margin-right 10})
(defstyle container-disabled
{:border-width 1

View File

@ -1,18 +1,21 @@
(ns status-im.ui.screens.wallet.components.views
(:require-macros [status-im.utils.views :as views])
(:require [re-frame.core :as re-frame]
[reagent.core :as reagent]
(:require [reagent.core :as reagent]
[re-frame.core :as re-frame]
[status-im.ui.components.react :as react]
[status-im.ui.components.status-bar.view :as status-bar]
[status-im.ui.components.styles :as components.styles]
[status-im.ui.screens.wallet.components.styles :as styles]
[status-im.i18n :as i18n]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.animation :as animation]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.list.views :as list]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.utils.ethereum.core :as ethereum]
[status-im.utils.ethereum.tokens :as tokens]
[status-im.utils.money :as money]
[status-im.utils.platform :as platform]
[status-im.ui.screens.wallet.components.animations :as animations]
[status-im.ui.screens.wallet.main.views :as main]
[status-im.ui.screens.wallet.utils :as wallet.utils]))
(views/defview tooltip [label & [style]]
@ -39,10 +42,9 @@
(if disabled?
{:editable false}
{:keyboard-type :numeric
:auto-capitalize "none"
:placeholder "0.000"
:placeholder-text-color "#ffffff66"
:selection-color :white
:placeholder (i18n/label :t/amount-placeholder)
:placeholder-text-color components.styles/color-white-transparent
:selection-color components.styles/color-white
:style styles/text-input
:on-focus #(do (reset! active? true)
(when on-focus (on-focus)))
@ -52,27 +54,81 @@
(when-not (nil? error)
[tooltip error])]]))))
(views/defview view-currency [style]
(views/letsubs [visible-tokens [:wallet.settings/visible-tokens]
symbol [:wallet.send/symbol]]
[react/view
[react/text {:style styles/label} (i18n/label :t/currency)]
[react/view (merge styles/currency-container
style)
[react/text
(name symbol)]]]))
(views/defview view-asset [symbol]
[react/view
[react/text {:style styles/label}
(i18n/label :t/wallet-asset)]
[react/view styles/asset-container
[react/text
(name symbol)]]])
(views/defview choose-currency [{:keys [style on-change value]}]
(views/letsubs [visible-tokens [:wallet.settings/visible-tokens]]
[react/view
[react/text {:style styles/label} (i18n/label :t/currency)]
[react/view (merge styles/currency-container
style)
[react/picker {:selected value
:style {:color "white"}
:item-style styles/wallet-name
:on-change on-change}
(map (fn [s] {:value (name s) :color "white"}) (conj visible-tokens (:symbol tokens/ethereum)))]]]))
(defn- type->handler [k]
(case k
:send :wallet.send/set-symbol
:request :wallet.request/set-symbol
(throw (str "Unknown type: " k))))
(defn- render-token [{:keys [symbol name icon decimals]} balance type]
[list/touchable-item #(do (re-frame/dispatch [(type->handler type) symbol])
(re-frame/dispatch [:navigate-back]))
[react/view
[list/item
[list/item-image icon]
[list/item-content
[react/view {:flex-direction :row}
[react/text {:style (merge styles/text-list-primary-content)
:number-of-lines 1}
name]
[react/text {:uppercase? true
:number-of-lines 1}
(clojure.core/name symbol)]]
[list/item-secondary (wallet.utils/format-amount (symbol balance) decimals)]]]]])
(views/defview assets [type]
(views/letsubs [network [:network]
visible-tokens [:wallet.settings/visible-tokens]
balance [:balance]]
[react/view components.styles/flex
[status-bar/status-bar {}]
[toolbar/toolbar {}
[toolbar/nav-clear-text (i18n/label :t/done)]
[toolbar/content-title (i18n/label :t/wallet-assets)]]
[react/view {:style components.styles/flex}
[list/flat-list {:data (concat [tokens/ethereum] (main/current-tokens visible-tokens network))
:render-fn #(render-token % balance type)}]]]))
(defn send-assets []
[assets :send])
(defn request-assets []
[assets :request])
(defn- type->view [k]
(case k
:send :wallet-send-assets
:request :wallet-request-assets
(throw (str "Unknown type: " k))))
(views/defview choose-asset [{:keys [type symbol]}]
(views/letsubs [balance [:balance]
network [:network]]
(let [{:keys [name icon decimals]} (tokens/asset-for (ethereum/network->chain-keyword network) symbol)]
[react/view
[react/text {:style styles/label}
(i18n/label :t/wallet-asset)]
[react/touchable-highlight {:style styles/asset-container
:on-press #(re-frame/dispatch [:navigate-to (type->view type)])}
[react/view styles/asset-content-container
[list/item-image (assoc icon :style styles/asset-icon :image-style {:width 32 :height 32})]
[react/view styles/asset-text-content
[react/view styles/asset-label-content
[react/text {:style (merge styles/text-content styles/asset-label)}
name]
[react/text {:style styles/text-secondary-content}
(clojure.core/name symbol)]]
[react/text {:style (merge styles/text-secondary-content styles/asset-label)}
(str (wallet.utils/format-amount (symbol balance) decimals))]]
[vector-icons/icon :icons/forward {:color :white}]]]])))
(defn choose-recipient-content [{:keys [address name on-press style]}]
(let [address? (and (not (nil? address)) (not= address ""))]
@ -102,28 +158,6 @@
[react/view
[choose-recipient-content m]]))
(views/defview choose-wallet [& [style]]
(views/letsubs [network [:network]
balance [:balance]
symbol [:wallet.send/symbol]]
(let [amount (get balance symbol)
decimals (:decimals (tokens/asset-for (ethereum/network->chain-keyword network) symbol))]
[react/view
[react/text {:style styles/label} (i18n/label :t/wallet)]
[react/view (merge styles/wallet-container
style)
[react/text {:style styles/wallet-name} (i18n/label :t/main-wallet)]
(if amount
[react/view {:style styles/wallet-value-container}
[react/text {:style (merge styles/wallet-value styles/wallet-value-amount)
:number-of-lines 1
:ellipsize-mode :tail}
(wallet.utils/format-amount amount decimals)]
[react/text {:style styles/wallet-value}
(name symbol)]]
[react/text {:style styles/wallet-value}
"..."])]])))
(defn separator []
[react/view styles/separator])

View File

@ -14,7 +14,7 @@
(spec/def :wallet/send (spec/keys :req-un [:wallet.send/recipient]))
(spec/def :wallet/wallet (spec/keys :opt [:wallet/error]
:opt-un [ :wallet/send-transaction]))
:opt-un [:wallet/send-transaction :wallet/request-transaction]))
;; Placeholder namespace for wallet specs, which are a WIP depending on data
;; model we decide on for balances, prices, etc.

View File

@ -5,20 +5,16 @@
[status-im.ui.components.drawer.view :as drawer]
[status-im.ui.components.list.views :as list]
[status-im.ui.components.react :as react]
[status-im.ui.components.icons.vector-icons :as vi]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.components.toolbar.actions :as act]
[status-im.i18n :as i18n]
[status-im.utils.config :as config]
[status-im.utils.ethereum.core :as ethereum]
[status-im.utils.ethereum.tokens :as tokens]
[status-im.utils.money :as money]
[status-im.utils.utils :as utils]
[status-im.ui.screens.wallet.main.styles :as styles]
[status-im.ui.screens.wallet.styles :as wallet.styles]
[status-im.ui.screens.wallet.utils :as wallet.utils]
[status-im.ui.components.styles :as components.styles]
[status-im.ui.screens.wallet.components.views :as components]
[status-im.ui.components.button.styles :as button.styles]
[status-im.ui.screens.wallet.views :as wallet.views]))
@ -45,7 +41,7 @@
:icon-opts {:color :white})
transaction-history-action]]])
(defn main-section [usd-value change syncing? error-message]
(defn main-section [usd-value syncing? error-message]
[react/view {:style styles/main-section}
(if syncing?
wallet.views/wallet-syncing
@ -67,7 +63,7 @@
[btn/button {:disabled? true :style (button.styles/button-bar :last) :text-style styles/main-button-text}
(i18n/label :t/wallet-exchange)]]]])
(defn- render-asset [{:keys [name symbol icon decimals amount] :as asset}]
(defn- render-asset [{:keys [symbol icon decimals amount]}]
[react/view
[list/item
[list/item-image icon]
@ -81,8 +77,11 @@
:number-of-lines 1}
(clojure.core/name symbol)]]]])
(defn current-tokens [visible-tokens network]
(filter #(contains? visible-tokens (:symbol %)) (tokens/tokens-for (ethereum/network->chain-keyword network))))
(defn asset-section [network balance visible-tokens prices-loading? balance-loading?]
(let [tokens (filter #(contains? visible-tokens (:symbol %)) (tokens/tokens-for (ethereum/network->chain-keyword network)))
(let [tokens (current-tokens visible-tokens network)
assets (map #(assoc % :amount (get balance (:symbol %))) (concat [tokens/ethereum] (when config/erc20-enabled? tokens)))]
[react/view {:style styles/asset-section}
[react/text {:style styles/asset-section-title} (i18n/label :t/wallet-assets)]
@ -97,7 +96,6 @@
balance [:balance]
visible-tokens [:wallet.settings/visible-tokens]
portfolio-value [:portfolio-value]
portfolio-change [:portfolio-change]
prices-loading? [:prices-loading?]
syncing? [:syncing?]
balance-loading? [:wallet/balance-loading?]
@ -105,5 +103,5 @@
[react/view {:style wallet.styles/wallet-container}
[toolbar-view]
[react/view components.styles/flex
[main-section portfolio-value portfolio-change syncing? error-message]
[main-section portfolio-value syncing? error-message]
[asset-section network balance visible-tokens prices-loading? balance-loading?]]]))

View File

@ -16,8 +16,10 @@
db)
(defmethod navigation/preload-data! :wallet-request-transaction
[db _]
(dissoc db :wallet/request-transaction))
[db [event]]
(if (= event :navigate-back)
db
(update db :wallet dissoc :request-transaction)))
(defn- dissoc-transaction-details [m]
(apply dissoc m (apply disj (set (keys m)) (keys db/transaction-send-default))))

View File

@ -18,11 +18,11 @@
(handlers/register-handler-fx
:wallet-send-request
[re-frame/trim-v]
(fn [{{:wallet/keys [request-transaction]} :db} [{:keys [whisper-identity]}]]
(fn [{{:keys [wallet]} :db} [{:keys [whisper-identity]}]]
{:dispatch-n [[:navigate-back]
[:navigate-to-clean :chat-list]
[:add-chat-loaded-event whisper-identity
[::wallet-send-chat-request (some-> request-transaction :amount money/wei->ether str)]]
[::wallet-send-chat-request (some-> wallet :request-transaction :amount money/wei->ether str)]]
[:start-chat whisper-identity]]}))
(handlers/register-handler-fx
@ -30,10 +30,10 @@
(fn [{:keys [db]} [_ amount]]
(let [{:keys [value error]} (wallet-db/parse-amount amount)]
{:db (-> db
(assoc-in [:wallet/request-transaction :amount] (money/ether->wei value))
(assoc-in [:wallet/request-transaction :amount-error] error))})))
(assoc-in [:wallet :request-transaction :amount] (money/ether->wei value))
(assoc-in [:wallet :request-transaction :amount-error] error))})))
(handlers/register-handler-fx
:wallet.request/set-symbol
(fn [{:keys [db]} [_ s]]
{:db (assoc-in db [:wallet/request-transaction :symbol] s)}))
{:db (assoc-in db [:wallet :request-transaction :symbol] s)}))

View File

@ -2,11 +2,20 @@
(:require [re-frame.core :as re-frame]
[status-im.utils.ethereum.tokens :as tokens]))
(re-frame/reg-sub ::request-transaction
:<- [:wallet]
:request-transaction)
(re-frame/reg-sub :wallet.request/symbol
:<- [::request-transaction]
(fn [transaction]
(or (:symbol transaction) :ETH)))
(re-frame/reg-sub
:wallet.request/request-enabled?
:<- [:get-in [:wallet/request-transaction :amount]]
:<- [:get-in [:wallet/request-transaction :amount-error]]
:<- [:get-in [:wallet/request-transaction :symbol]]
:<- [:get-in [:wallet :request-transaction :amount]]
:<- [:get-in [:wallet :request-transaction :amount-error]]
:<- [:wallet.request/symbol]
(fn [[amount amount-error symbol]]
(and
(or (nil? symbol) (tokens/ethereum? symbol))

View File

@ -13,11 +13,9 @@
[status-im.ui.screens.wallet.request.styles :as styles]
[status-im.ui.components.styles :as components.styles]
[status-im.i18n :as i18n]
[status-im.utils.platform :as platform]
[status-im.utils.ethereum.core :as ethereum]
[status-im.utils.ethereum.eip681 :as eip681]
[status-im.utils.ethereum.tokens :as tokens]
[status-im.utils.money :as money]))
[status-im.utils.ethereum.tokens :as tokens]))
(defn toolbar-view []
[toolbar/toolbar {:style wallet.styles/toolbar :hide-border? true}
@ -31,7 +29,7 @@
:action :request
:params {:hide-actions? true}}]))
(defn- generate-value [address {:keys [symbol chain-id] :as m}]
(defn- generate-value [address {:keys [symbol] :as m}]
(if (tokens/ethereum? symbol)
(eip681/generate-uri address (dissoc m :symbol))
(eip681/generate-erc20-uri address m)))
@ -47,9 +45,9 @@
(views/defview request-transaction []
;;Because input field is in the end of view we will scroll to the end on input focus event
(views/letsubs [amount [:get-in [:wallet/request-transaction :amount]]
amount-error [:get-in [:wallet/request-transaction :amount-error]]
symbol [:get-in [:wallet/request-transaction :symbol]]
(views/letsubs [amount [:get-in [:wallet :request-transaction :amount]]
amount-error [:get-in [:wallet :request-transaction :amount-error]]
symbol [:wallet.request/symbol]
request-enabled? [:wallet.request/request-enabled?]
scroll (atom nil)]
[react/keyboard-avoiding-view wallet.styles/wallet-modal-container
@ -61,17 +59,14 @@
[react/view styles/network-container
[react/view styles/qr-container
[qr-code amount symbol]]]
[react/view wallet.styles/choose-wallet-container
[components/choose-wallet]]
[react/view wallet.styles/amount-container
[components/amount-input
{:error amount-error
:input-options {:on-focus (fn [] (when @scroll (js/setTimeout #(.scrollToEnd @scroll) 100)))
:on-change-text #(re-frame/dispatch [:wallet.request/set-and-validate-amount %])}}]
[react/view wallet.styles/choose-currency-container
[components/choose-currency {:style wallet.styles/choose-currency
:on-change #(re-frame/dispatch [:wallet.request/set-symbol (keyword %)])
:value (name (or symbol :ETH))}]]]]]
:on-change-text #(re-frame/dispatch [:wallet.request/set-and-validate-amount %])}}]]
[react/view wallet.styles/choose-asset-container
[components/choose-asset {:type :request
:symbol symbol}]]]]
[components/separator]
[react/view wallet.styles/buttons-container
[react/touchable-highlight {:style wallet.styles/button :disabled true}

View File

@ -82,7 +82,8 @@
{:flex-direction :row
:background-color styles/color-blue6
:border-radius 50
:padding 8})
:padding 8
:align-items :center})
(def advanced-button-wrapper
{:align-items :center})
@ -92,12 +93,16 @@
(def advanced-options-wrapper
{:height 52
:background-color styles/color-white-transparent-4
:background-color styles/color-white-transparent-3
:border-radius 4
:margin-top 16
:margin-bottom 16
:align-items :center
:flex-direction :row})
:flex-direction :row
:padding-vertical 14
:padding-right 8
:ios {:border-radius 8}
:android {:border-radius 4}})
(def advanced-options-text-wrapper
{:flex 1

View File

@ -1,6 +1,5 @@
(ns status-im.ui.screens.wallet.send.subs
(:require [re-frame.core :as re-frame]
[status-im.i18n :as i18n]
[status-im.utils.money :as money]
[status-im.utils.hex :as utils.hex]))

View File

@ -203,8 +203,11 @@
:name to-name}
(when-not modal?
{:on-press request-camera-permissions}))]]
[react/view wallet.styles/choose-wallet-container
[components/choose-wallet]]
[react/view wallet.styles/choose-asset-container
(if modal?
[components/view-asset symbol]
[components/choose-asset {:type :send
:symbol symbol}])]
[react/view wallet.styles/amount-container
[components/amount-input
(merge
@ -214,14 +217,7 @@
:on-focus (fn [] (when @scroll (js/setTimeout #(.scrollToEnd @scroll) 100)))
:on-change-text #(re-frame/dispatch [:wallet.send/set-and-validate-amount %])}}
(when modal?
{:disabled? true}))]
(if modal?
[react/view wallet.styles/choose-currency-container
[components/view-currency wallet.styles/choose-currency]]
[react/view wallet.styles/choose-currency-container
[components/choose-currency {:style wallet.styles/choose-currency
:on-change #(re-frame/dispatch [:wallet.send/set-symbol (keyword %)])
:value (name symbol)}]])]
{:disabled? true}))]]
[react/view {:style send.styles/advanced-wrapper}
[react/touchable-highlight {:on-press #(re-frame/dispatch [:wallet.send/toggle-advanced (not advanced?)])}
[react/view {:style send.styles/advanced-button-wrapper}

View File

@ -73,18 +73,12 @@
{:margin-top 16
:margin-horizontal 15})
(def choose-wallet-container
{:margin-top 16
:margin-horizontal 15})
(def amount-container
{:margin-top 16
:margin-bottom 16
:margin-horizontal 15
:flex-direction :row})
(def choose-currency-container
{:margin-left 8})
(def choose-currency
{:width 116})
(def choose-asset-container
{:margin-top 16
:margin-horizontal 15})

View File

@ -36,18 +36,6 @@
str)
"...")))
(reg-sub :portfolio-change
:<- [:price]
:<- [:last-day]
:<- [:balance]
(fn [[price last-day balance]]
(when (and price last-day)
(if (> (get balance :ETH) 0) ;; TODO(jeluard) Modify to consider tokens
(-> (money/percent-change price last-day)
(money/with-precision 2)
.toNumber)
0))))
(reg-sub :prices-loading?
(fn [db]
(:prices-loading? db)))