[ISSUE #2883] Migrate wallet/request to latest mockups
Signed-off-by: Goran Jovic <goranjovic@gmail.com>
This commit is contained in:
parent
96f08abc7d
commit
748b0fcf09
|
@ -53,8 +53,8 @@
|
|||
[toolbar/toolbar {}
|
||||
(when-not (or show-actions? creating?)
|
||||
(if (empty? accounts)
|
||||
[toolbar/nav-clear-text (i18n/label :t/recover)
|
||||
#(re-frame/dispatch [:navigate-to-modal :recover-modal])]
|
||||
[toolbar/nav-clear-text {:handler #(re-frame/dispatch [:navigate-to-modal :recover-modal])}
|
||||
(i18n/label :t/recover)]
|
||||
toolbar/default-nav-back))
|
||||
[toolbar-content/toolbar-content-view]
|
||||
[toolbar-action show-actions?]]
|
||||
|
|
|
@ -318,8 +318,10 @@
|
|||
:wallet-manage-assets "Manage Assets"
|
||||
:signing-phrase-description "Sign the transaction by entering your password. Make sure that the words above match your secret signing phrase"
|
||||
:wallet-insufficient-funds "Insufficient funds"
|
||||
:request-transaction "Request transaction"
|
||||
:receive "Receive"
|
||||
:request-qr-legend "Share this code to receive assets"
|
||||
:send-request "Send request"
|
||||
:send-transaction-request "Send a transaction request"
|
||||
:share "Share"
|
||||
:eth "ETH"
|
||||
:gwei "Gwei"
|
||||
|
@ -352,6 +354,8 @@
|
|||
:sign-later-text "Check the transaction history to sign this transaction"
|
||||
:not-applicable "Not applicable for unsigned transactions"
|
||||
:send-transaction "Send transaction"
|
||||
:new-request "New request"
|
||||
:request-transaction "Request transaction"
|
||||
:receive-transaction "Receive transaction"
|
||||
:new-transaction "New Transaction"
|
||||
:transaction-history "Transaction History"
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
(def white-transparent "rgba(255, 255, 255, 0.2)") ;; Used as icon color on dark background
|
||||
(def white-lighter-transparent "rgba(255, 255, 255, 0.6)") ;; Used for input placeholder color
|
||||
(def black "#000000") ;; Used as the default text color
|
||||
(def black-transparent "#00000020") ;; Used as background color for rounded button on dark background
|
||||
(def gray "#939ba1") ;; Used as a background for a light foreground and as section header and secondary text color
|
||||
(def gray-light "#d9dae1") ;; Used as divider color
|
||||
(def gray-lighter "#eef2f5") ;; Used as a background or shadow
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
(ns status-im.ui.components.common.common
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [status-im.ui.components.react :as react]
|
||||
(:require [status-im.i18n :as i18n]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.context-menu :as context-menu]
|
||||
[status-im.ui.components.common.styles :as styles]
|
||||
[status-im.utils.ethereum.core :as ethereum]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.i18n :as i18n]))
|
||||
[status-im.utils.platform :as platform]))
|
||||
|
||||
(defn top-shadow []
|
||||
(when platform/android?
|
||||
|
@ -72,15 +72,3 @@
|
|||
(if (ethereum/testnet? network-id)
|
||||
(i18n/label :t/testnet-text {:testnet (get-in ethereum/chains [(ethereum/chain-id->chain-keyword network-id) :name] "Unknown")})
|
||||
(i18n/label :t/mainnet-text))]]]))
|
||||
|
||||
(defn icon-or-label
|
||||
"Renders a touchable icon on Android or a label or iOS."
|
||||
[action-opts label-kw label-style icon-id icon-opts]
|
||||
[react/touchable-highlight action-opts
|
||||
(if platform/ios?
|
||||
[react/view
|
||||
[react/text {:style (merge styles/label-action-text label-style)}
|
||||
(i18n/label label-kw)]]
|
||||
[react/view styles/icon-action
|
||||
[vector-icons/icon icon-id icon-opts]])])
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
(def gradient-top
|
||||
{:flexDirection :row
|
||||
:height 3
|
||||
:backgroundColor styles/color-light-gray})
|
||||
:backgroundColor colors/gray-lighter})
|
||||
|
||||
(def gradient-top-colors
|
||||
["rgba(25, 53, 76, 0.01)"
|
||||
|
@ -15,19 +15,19 @@
|
|||
(def gradient-bottom
|
||||
{:flexDirection :row
|
||||
:height 2
|
||||
:backgroundColor styles/color-light-gray})
|
||||
:backgroundColor colors/gray-lighter})
|
||||
|
||||
(def gradient-bottom-colors
|
||||
["rgba(25, 53, 76, 0.1)"
|
||||
"rgba(25, 53, 76, 0.01)"])
|
||||
|
||||
(def separator-wrapper
|
||||
{:background-color styles/color-white})
|
||||
{:background-color colors/white})
|
||||
|
||||
(defstyle separator
|
||||
{:android {:height 0}
|
||||
:ios {:height 1
|
||||
:background-color styles/color-gray5
|
||||
:background-color colors/gray-light
|
||||
:opacity 0.5}})
|
||||
|
||||
(def list-separator
|
||||
|
@ -41,20 +41,20 @@
|
|||
:padding-right 16
|
||||
:flex 1
|
||||
:flex-direction :row
|
||||
:ios {:background-color styles/color-white
|
||||
:ios {:background-color colors/white
|
||||
:padding-top 19
|
||||
:padding-bottom 15
|
||||
:margin-top 16}
|
||||
:android {:background-color styles/color-light-gray
|
||||
:android {:background-color colors/gray-lighter
|
||||
:padding-top 20
|
||||
:padding-bottom 17
|
||||
:margin-top 8}})
|
||||
|
||||
(defstyle form-title-extend-container
|
||||
{:ios {:margin-top 16
|
||||
:background-color styles/color-white}
|
||||
:background-color colors/white}
|
||||
:android {:margin-top 8
|
||||
:background-color styles/color-light-gray}})
|
||||
:background-color colors/gray-lighter}})
|
||||
|
||||
(def form-title-extend-button
|
||||
{:padding 16})
|
||||
|
@ -80,7 +80,7 @@
|
|||
:android {:height 11}})
|
||||
|
||||
(defstyle list-header-footer-spacing
|
||||
{:android {:background-color styles/color-white
|
||||
{:android {:background-color colors/white
|
||||
:height 8}})
|
||||
|
||||
(def network-container
|
||||
|
@ -91,7 +91,7 @@
|
|||
|
||||
(defn network-text [text-color]
|
||||
{:flex 1
|
||||
:color (or text-color styles/color-black)
|
||||
:color (or text-color colors/black)
|
||||
:letter-spacing -0.2
|
||||
:font-size 14
|
||||
:margin-left 16})
|
||||
|
@ -109,10 +109,3 @@
|
|||
:color colors/blue
|
||||
:ios {:font-size 15}
|
||||
:android {:font-size 14}})
|
||||
|
||||
(def icon-action
|
||||
{:width 40
|
||||
:height 40
|
||||
:margin-right 4
|
||||
:align-items :center
|
||||
:justify-content :center})
|
|
@ -4,25 +4,21 @@
|
|||
|
||||
(def qr-code-hint
|
||||
{:color colors/gray
|
||||
:padding-bottom 24
|
||||
:padding-top 24
|
||||
:padding-bottom 22
|
||||
:text-align :center})
|
||||
|
||||
(def qr-code-padding
|
||||
15)
|
||||
|
||||
(defn qr-code-container [dimensions]
|
||||
(defn qr-code-container [width]
|
||||
{:background-color colors/white
|
||||
:width (:width dimensions)
|
||||
:width width
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:padding qr-code-padding
|
||||
:border-radius 8})
|
||||
|
||||
(def toolbar-done-text-ios
|
||||
{:color colors/blue
|
||||
:letter-spacing -0.2
|
||||
:font-size 17})
|
||||
|
||||
(defstyle name-container
|
||||
{:flex 0.6
|
||||
:flex-direction :column
|
||||
|
@ -47,7 +43,6 @@
|
|||
(def toolbar-action-icon-container
|
||||
{:width 40
|
||||
:height 40
|
||||
:margin-right 16
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
|
@ -66,16 +61,14 @@
|
|||
:justify-content :center})
|
||||
|
||||
(def qr-code
|
||||
{:background-color colors/gray-lighter
|
||||
:flex-grow 1
|
||||
{:flex-grow 1
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
(def footer
|
||||
{:background-color colors/gray-lighter
|
||||
:flex-direction :row
|
||||
{:flex-direction :row
|
||||
:justify-content :center
|
||||
:padding-bottom 50})
|
||||
:padding-top 22})
|
||||
|
||||
(def wallet-info
|
||||
{:align-items :center
|
||||
|
|
|
@ -1,59 +1,29 @@
|
|||
(ns status-im.ui.components.qr-code-viewer.views
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.status-bar.view :as status-bar]
|
||||
[status-im.ui.components.list-selection :as list-selection]
|
||||
[status-im.ui.components.qr-code-viewer.styles :as styles]
|
||||
[status-im.ui.components.common.common :as common]
|
||||
[status-im.ui.components.common.styles :as common.styles]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.i18n :as i18n]
|
||||
(:require [reagent.core :as reagent]
|
||||
[status-im.react-native.js-dependencies :as rn-dependencies]
|
||||
[reagent.core :as r])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
[status-im.ui.components.qr-code-viewer.styles :as styles]
|
||||
[status-im.ui.components.react :as react]))
|
||||
|
||||
(defn qr-code [props]
|
||||
(r/create-element
|
||||
(reagent/create-element
|
||||
rn-dependencies/qr-code
|
||||
(clj->js (merge {:inverted true} props))))
|
||||
|
||||
(defn qr-viewer-toolbar [name qr-value]
|
||||
[react/view styles/account-toolbar
|
||||
[react/view styles/toolbar-contents
|
||||
[react/view styles/toolbar-action-container
|
||||
[common/icon-or-label {:on-press #(re-frame/dispatch [:navigate-back])}
|
||||
:t/done styles/toolbar-done-text-ios :icons/close {:color :black}]]
|
||||
[react/view styles/name-container
|
||||
[react/text {:style styles/name-text
|
||||
:number-of-lines 1} name]]
|
||||
[react/view styles/toolbar-action-container
|
||||
[react/touchable-highlight {:on-press #(list-selection/open-share {:message qr-value})}
|
||||
[react/view styles/toolbar-action-icon-container
|
||||
[vector-icons/icon :icons/share {:color :black}]]]]]])
|
||||
|
||||
(defn qr-viewer-body [qr-value dimensions]
|
||||
[react/view {:style styles/qr-code
|
||||
:on-layout #(let [layout (.. % -nativeEvent -layout)]
|
||||
(re-frame/dispatch [:set-in [:qr-modal :dimensions] {:width (* 0.7 (.-width layout))
|
||||
:height (.-height layout)}]))}
|
||||
[react/text {:style styles/qr-code-hint} (i18n/label :t/qr-code-public-key-hint)]
|
||||
(when (:width dimensions)
|
||||
[react/view {:style (styles/qr-code-container dimensions)}
|
||||
[qr-code {:value qr-value
|
||||
:size (- (min (:width dimensions)
|
||||
(:height dimensions))
|
||||
(* 2 styles/qr-code-padding))}]])])
|
||||
|
||||
(defn qr-viewer-footer [qr-value]
|
||||
(defn- footer [style value]
|
||||
[react/view styles/footer
|
||||
[react/view styles/wallet-info
|
||||
[react/text {:style styles/hash-value-text} qr-value]]])
|
||||
[react/text {:style (merge styles/hash-value-text style)}
|
||||
value]]])
|
||||
|
||||
(defview qr-viewer []
|
||||
(letsubs [{:keys [qr-value dimensions contact]} [:get :qr-modal]]
|
||||
[react/view styles/wallet-qr-code
|
||||
[status-bar/status-bar {:type :modal}]
|
||||
[qr-viewer-toolbar (:name contact) qr-value]
|
||||
[qr-viewer-body qr-value dimensions]
|
||||
[qr-viewer-footer qr-value]]))
|
||||
(defn qr-code-viewer [{:keys [hint-style footer-style]} value hint legend]
|
||||
{:pre [(not (nil? value))]}
|
||||
(let [{:keys [width height]} (react/get-dimensions "window")]
|
||||
[react/view {:style styles/qr-code}
|
||||
[react/text {:style (merge styles/qr-code-hint hint-style)}
|
||||
hint]
|
||||
(when width
|
||||
(let [size (int (* 0.7 (min width height)))]
|
||||
[react/view {:style (styles/qr-code-container size)}
|
||||
[qr-code {:value value
|
||||
:size (- size (* 2 styles/qr-code-padding))}]]))
|
||||
[footer footer-style legend]]))
|
||||
|
|
|
@ -39,23 +39,23 @@
|
|||
;; :modal
|
||||
(defstyle status-bar-modal
|
||||
{:ios (create-status-bar-style {:background-color "#2f3031"})
|
||||
:android (create-status-bar-style {:background-color styles/color-black})})
|
||||
:android (create-status-bar-style {:background-color colors/black})})
|
||||
|
||||
(defstyle view-modal
|
||||
{:ios (create-view-style {:background-color "#2f3031"})
|
||||
:android (create-view-style {:background-color styles/color-black
|
||||
:android (create-view-style {:background-color colors/black
|
||||
:height 0})})
|
||||
|
||||
;; :modal-white
|
||||
(defstyle status-bar-modal-white
|
||||
{:ios (create-status-bar-style {:background-color colors/white
|
||||
:bar-style "default"})
|
||||
:android (create-status-bar-style {:background-color styles/color-black
|
||||
:android (create-status-bar-style {:background-color colors/black
|
||||
:bar-style "light-content"})})
|
||||
|
||||
(defstyle view-modal-white
|
||||
{:ios (create-view-style {:background-color colors/white})
|
||||
:android (create-view-style {:background-color styles/color-black
|
||||
:android (create-view-style {:background-color colors/black
|
||||
:height 0})})
|
||||
|
||||
;; :modal-wallet
|
||||
|
@ -90,8 +90,8 @@
|
|||
|
||||
;; :wallet
|
||||
(defstyle status-bar-wallet
|
||||
{:ios (create-status-bar-style {:background-color colors/blue})
|
||||
:android (create-status-bar-style {:translucent? true})})
|
||||
{:ios (create-status-bar-style {:background-color colors/blue})
|
||||
:android (create-status-bar-style {:translucent? true})})
|
||||
|
||||
(def view-wallet
|
||||
(create-view-style {:background-color styles/color-blue4
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
:modal-wallet [styles/status-bar-modal-wallet styles/view-modal-wallet]
|
||||
:transaction [styles/status-bar-transaction styles/view-transaction]
|
||||
:wallet [styles/status-bar-wallet styles/view-wallet]
|
||||
:wallet-tab [styles/status-bar-wallet-tab styles/view-wallet-tab]
|
||||
:wallet-tab [styles/status-bar-wallet-tab styles/view-wallet-tab]
|
||||
[styles/status-bar-default styles/view-default])]
|
||||
[react/view
|
||||
[react/status-bar status-bar-style]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(ns status-im.ui.components.toolbar.view
|
||||
(:require [reagent.core :as reagent]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.list-selection :as list-selection]
|
||||
|
@ -28,20 +29,30 @@
|
|||
[vector-icons/icon icon icon-opts]])
|
||||
|
||||
(defn nav-text
|
||||
([text] (nav-text text nil))
|
||||
([props text] (nav-text props text nil))
|
||||
([props text handler]
|
||||
[react/text (utils/deep-merge {:style (merge styles/item styles/item-text) :on-press (or handler #(re-frame/dispatch [:navigate-back]))}
|
||||
([text] (nav-text nil text))
|
||||
([{:keys [handler] :as props} text]
|
||||
[react/text (utils/deep-merge {:style (merge styles/item styles/item-text)
|
||||
:on-press (or handler #(re-frame/dispatch [:navigate-back]))}
|
||||
props)
|
||||
text]))
|
||||
|
||||
(defn nav-clear-text
|
||||
([text] (nav-clear-text text nil))
|
||||
([text handler]
|
||||
(nav-text styles/item-text-white-background text handler)))
|
||||
([text] (nav-clear-text nil text))
|
||||
([props text]
|
||||
(nav-text (merge props styles/item-text-white-background) text)))
|
||||
|
||||
(def default-nav-back [nav-button actions/default-back])
|
||||
|
||||
(defn default-done
|
||||
"Renders a touchable icon on Android or a label or iOS."
|
||||
[{:keys [icon] :as props}]
|
||||
(if platform/ios?
|
||||
[react/view
|
||||
[nav-text props
|
||||
(i18n/label :t/done)]]
|
||||
[react/view
|
||||
[nav-button (merge props {:icon (or icon :icons/close)})]]))
|
||||
|
||||
;; Content
|
||||
|
||||
(defn content-wrapper [content]
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
(ns status-im.ui.screens.main-tabs.views
|
||||
(:require-macros [status-im.utils.views :as views])
|
||||
(:require [status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
(:require [status-im.i18n :as i18n]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.status-bar.view :as status-bar.view]
|
||||
[status-im.ui.components.styles :as common.styles]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.screens.home.views :as home.views]
|
||||
[status-im.ui.screens.profile.views :as profile.views]
|
||||
[status-im.ui.screens.wallet.main.views :as wallet.views]
|
||||
[status-im.ui.screens.main-tabs.styles :as styles]
|
||||
[re-frame.core :as re-frame]))
|
||||
[status-im.ui.screens.home.views :as home]
|
||||
[status-im.ui.screens.profile.views :as profile]
|
||||
[status-im.ui.screens.wallet.views :as wallet]
|
||||
[status-im.ui.screens.main-tabs.styles :as styles]))
|
||||
|
||||
(def tabs-list-data
|
||||
[{:view-id :home
|
||||
|
@ -37,7 +37,7 @@
|
|||
|
||||
(def tabs-list (map #(update % :content tab-content) tabs-list-data))
|
||||
|
||||
(defn tab [view-id content active?]
|
||||
(defn- tab [view-id content active?]
|
||||
[react/touchable-highlight {:style common.styles/flex
|
||||
:disabled active?
|
||||
:on-press #(re-frame/dispatch [:navigate-to-tab view-id])}
|
||||
|
@ -59,7 +59,7 @@
|
|||
{:enabled? (= :home view-id)
|
||||
:preview [react/view {}]}
|
||||
[react/navigation-wrapper
|
||||
{:component home.views/home
|
||||
{:component home/home
|
||||
:views :home
|
||||
:current-view view-id}]]
|
||||
|
||||
|
@ -67,7 +67,7 @@
|
|||
{:enabled? (= :wallet view-id)
|
||||
:preview [react/view {}]}
|
||||
[react/navigation-wrapper
|
||||
{:component wallet.views/wallet
|
||||
{:component wallet/wallet
|
||||
:views :wallet
|
||||
:current-view view-id}]]
|
||||
|
||||
|
@ -75,7 +75,7 @@
|
|||
{:enabled? (= :my-profile view-id)
|
||||
:preview [react/view {}]}
|
||||
[react/navigation-wrapper
|
||||
{:component profile.views/my-profile
|
||||
{:component profile/my-profile
|
||||
:views :my-profile
|
||||
:current-view view-id}]]
|
||||
[tabs view-id]]]))
|
||||
|
|
|
@ -3,10 +3,9 @@
|
|||
|
||||
;;TODO(goranjovic) - replace this with an atomic navigation event that calls functions, not dispatch
|
||||
;; possibly use the generic event, see https://github.com/status-im/status-react/issues/2987
|
||||
(defmethod navigation/preload-data! :qr-viewer
|
||||
[{:accounts/keys [current-account-id] :as db} [_ _ {:keys [contact qr-source qr-value]}]]
|
||||
(update db :qr-modal #(merge % {:contact (or contact
|
||||
(get-in db [:accounts/accounts current-account-id]))
|
||||
:qr-source qr-source
|
||||
:qr-value qr-value})))
|
||||
(defmethod navigation/preload-data! :profile-qr-viewer
|
||||
[{:accounts/keys [current-account-id] :as db} [_ _ {:keys [contact source value]}]]
|
||||
(update db :qr-modal #(merge % {:contact (or contact (get-in db [:accounts/accounts current-account-id]))
|
||||
:source source
|
||||
:value value})))
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
(ns status-im.ui.screens.profile.views
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.action-button.action-button :as action-button]
|
||||
[status-im.ui.components.action-button.styles :as action-button.styles]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
|
||||
|
@ -8,6 +10,7 @@
|
|||
[status-im.ui.components.common.styles :as common.styles]
|
||||
[status-im.ui.components.context-menu :as context-menu]
|
||||
[status-im.ui.components.list-selection :as list-selection]
|
||||
[status-im.ui.components.qr-code-viewer.views :as qr-code-viewer]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.status-bar.view :as status-bar]
|
||||
|
@ -15,7 +18,6 @@
|
|||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.toolbar.actions :as actions]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.screens.profile.styles :as styles]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.utils.utils :as utils]
|
||||
|
@ -23,10 +25,7 @@
|
|||
[status-im.utils.datetime :as time]
|
||||
[status-im.utils.config :as config]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.protocol.core :as protocol]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ui.components.camera :as camera])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
[status-im.protocol.core :as protocol]))
|
||||
|
||||
(defn my-profile-toolbar []
|
||||
[toolbar/toolbar {}
|
||||
|
@ -42,8 +41,9 @@
|
|||
[toolbar/toolbar {}
|
||||
nil
|
||||
[toolbar/content-title ""]
|
||||
[common/icon-or-label {:on-press #(re-frame/dispatch [:my-profile/save-profile])}
|
||||
:t/done {} :icons/ok {:color colors/blue}]])
|
||||
[toolbar/default-done {:handler #(re-frame/dispatch [:my-profile/save-profile])
|
||||
:icon :icons/ok
|
||||
:icon-opts {:color colors/blue}}]])
|
||||
|
||||
(defn profile-toolbar [contact]
|
||||
[toolbar/toolbar {}
|
||||
|
@ -154,10 +154,27 @@
|
|||
nil
|
||||
styles/profile-info-item-button])])
|
||||
|
||||
(defn show-qr [contact qr-source qr-value]
|
||||
#(re-frame/dispatch [:navigate-to :qr-viewer {:contact contact
|
||||
:qr-source qr-source
|
||||
:qr-value qr-value}]))
|
||||
(defn- toolbar [label value]
|
||||
[toolbar/toolbar {}
|
||||
[toolbar/default-done {:icon-opts {:color colors/black}}]
|
||||
[toolbar/content-title label]
|
||||
[toolbar/actions [{:icon :icons/share
|
||||
:icon-opts {:color :black}
|
||||
:handler #(list-selection/open-share {:message value})}]]])
|
||||
|
||||
(defview qr-viewer []
|
||||
(letsubs [{:keys [value contact]} [:get :qr-modal]]
|
||||
[react/view {:flex-grow 1
|
||||
:flex-direction :column}
|
||||
[status-bar/status-bar {:type :modal}]
|
||||
[toolbar (:name contact) value]
|
||||
[qr-code-viewer/qr-code-viewer {}
|
||||
value (i18n/label :t/qr-code-public-key-hint) (str value)]]))
|
||||
|
||||
(defn- show-qr [contact source value]
|
||||
#(re-frame/dispatch [:navigate-to :profile-qr-viewer {:contact contact
|
||||
:source source
|
||||
:value value}]))
|
||||
|
||||
(defn profile-options [contact k text]
|
||||
(into []
|
||||
|
|
|
@ -31,11 +31,9 @@
|
|||
|
||||
[status-im.ui.screens.profile.views :as profile]
|
||||
[status-im.ui.screens.profile.photo-capture.views :refer [profile-photo-capture]]
|
||||
[status-im.ui.components.qr-code-viewer.views :as qr-code-viewer]
|
||||
|
||||
[status-im.ui.screens.wallet.send.views :refer [send-transaction send-transaction-modal]]
|
||||
[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.request.views :refer [request-transaction send-transaction-request]]
|
||||
[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]
|
||||
|
@ -141,6 +139,7 @@
|
|||
:wallet-send-transaction send-transaction
|
||||
:wallet-transaction-sent transaction-sent
|
||||
:wallet-request-transaction request-transaction
|
||||
:wallet-send-transaction-request send-transaction-request
|
||||
(:transactions-history :unsigned-transactions) wallet-transactions/transactions
|
||||
:wallet-transaction-details wallet-transactions/transaction-details
|
||||
:wallet-send-assets wallet.components/send-assets
|
||||
|
@ -177,7 +176,7 @@
|
|||
:recent-recipients recent-recipients
|
||||
:recipient-qr-code recipient-qr-code
|
||||
:contact-code contact-code
|
||||
:qr-viewer qr-code-viewer/qr-viewer
|
||||
:profile-qr-viewer profile/qr-viewer
|
||||
(throw (str "Unknown view: " current-view)))]
|
||||
[(if android? menu-context view) common-styles/flex
|
||||
[view common-styles/flex
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
toggled-state (if (= :on flashlight-state) :off :on)]
|
||||
(assoc-in db [:wallet :send-transaction :camera-flashlight] toggled-state))))
|
||||
|
||||
(defn- fill-request-details [db {:keys [address name value symbol gas gasPrice]}]
|
||||
(defn- fill-request-details [db {:keys [address name value symbol gas gasPrice whisper-identity]}]
|
||||
{:pre [(not (nil? address))]}
|
||||
(update-in
|
||||
db [:wallet :send-transaction]
|
||||
#(cond-> (assoc % :to address :to-name name)
|
||||
#(cond-> (assoc % :to address :to-name name :whisper-identity whisper-identity)
|
||||
value (assoc :amount value)
|
||||
symbol (assoc :symbol symbol)
|
||||
gas (assoc :gas (money/bignumber gas))
|
||||
|
@ -50,6 +50,6 @@
|
|||
|
||||
(handlers/register-handler-fx
|
||||
:wallet/fill-request-from-contact
|
||||
(fn [{db :db} [_ {:keys [address name]}]]
|
||||
{:db (fill-request-details db {:address address :name name})
|
||||
(fn [{db :db} [_ {:keys [address name whisper-identity]}]]
|
||||
{:db (fill-request-details db {:address address :name name :whisper-identity whisper-identity})
|
||||
:dispatch [:navigate-back]}))
|
||||
|
|
|
@ -24,18 +24,30 @@
|
|||
props)
|
||||
text])
|
||||
|
||||
(defn- toolbar [action title]
|
||||
[toolbar/toolbar {:style styles/toolbar}
|
||||
[toolbar/nav-button action]
|
||||
[toolbar/content-title {:color :white}
|
||||
title]])
|
||||
(def default-action (actions/back-white actions/default-handler))
|
||||
|
||||
(defn simple-screen [title content]
|
||||
[react/view {:flex 1 :background-color colors/blue}
|
||||
[status-bar/status-bar {:type :wallet}]
|
||||
[toolbar (actions/back-white actions/default-handler)
|
||||
title]
|
||||
content])
|
||||
(defn- toolbar
|
||||
([title] (toolbar default-action title))
|
||||
([action title] (toolbar action title nil))
|
||||
([action title options]
|
||||
[toolbar/toolbar {:style styles/toolbar}
|
||||
[toolbar/nav-button action]
|
||||
[toolbar/content-title {:color :white}
|
||||
title]
|
||||
options]))
|
||||
|
||||
(defn- top-view [avoid-keyboard?]
|
||||
(if avoid-keyboard?
|
||||
react/keyboard-avoiding-view
|
||||
react/view))
|
||||
|
||||
(defn simple-screen
|
||||
([toolbar content] (simple-screen nil toolbar content))
|
||||
([{:keys [avoid-keyboard? status-bar-type]} toolbar content]
|
||||
[(top-view avoid-keyboard?) {:flex 1 :background-color colors/blue}
|
||||
[status-bar/status-bar {:type (or status-bar-type :wallet)}]
|
||||
toolbar
|
||||
content]))
|
||||
|
||||
(defn- cartouche-content [{:keys [disabled?]} content]
|
||||
[react/view {:style (styles/cartouche-content-wrapper disabled?)}
|
||||
|
@ -67,9 +79,6 @@
|
|||
s])
|
||||
|
||||
(defn cartouche-text-content [primary secondary]
|
||||
[react/view {:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:padding-horizontal 15
|
||||
:padding-vertical 15}
|
||||
[react/view styles/cartouche-text-wrapper
|
||||
[cartouche-primary-text primary]
|
||||
[cartouche-secondary-text secondary]])
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
[status-im.ui.screens.wallet.components.animations :as animations]
|
||||
[status-im.ui.screens.wallet.components.styles :as styles]
|
||||
[status-im.ui.screens.wallet.choose-recipient.views :as choose-recipient]
|
||||
[status-im.ui.screens.wallet.main.views :as main]
|
||||
[status-im.ui.screens.wallet.views :as wallet]
|
||||
[status-im.ui.screens.wallet.utils :as wallet.utils]
|
||||
[status-im.utils.ethereum.core :as ethereum]
|
||||
[status-im.utils.ethereum.tokens :as tokens]
|
||||
|
@ -66,10 +66,11 @@
|
|||
(views/letsubs [network [:network]
|
||||
visible-tokens [:wallet.settings/visible-tokens]
|
||||
balance [:balance]]
|
||||
[components/simple-screen (i18n/label :t/wallet-assets)
|
||||
[components/simple-screen
|
||||
[components/toolbar (i18n/label :t/wallet-assets)]
|
||||
[react/view {:style (assoc components.styles/flex :background-color :white)}
|
||||
[list/flat-list {:default-separator? true
|
||||
:data (concat [tokens/ethereum] (main/current-tokens visible-tokens network))
|
||||
:data (concat [tokens/ethereum] (wallet/current-tokens visible-tokens network))
|
||||
:render-fn #(render-token % balance type)}]]]))
|
||||
|
||||
(defn send-assets []
|
||||
|
@ -130,7 +131,7 @@
|
|||
(views/defview recent-recipients []
|
||||
(views/letsubs [contacts [:contacts-filtered :all-added-people-contacts]]
|
||||
[components/simple-screen
|
||||
(i18n/label :t/recipient)
|
||||
[components/toolbar (i18n/label :t/recipient)]
|
||||
[react/view styles/recent-recipients
|
||||
[list/flat-list {:data contacts
|
||||
:render-fn render-contact}]]]))
|
||||
|
@ -138,19 +139,18 @@
|
|||
(defn contact-code []
|
||||
(let [content (reagent/atom nil)]
|
||||
(fn []
|
||||
[react/view components.styles/flex
|
||||
[components/simple-screen
|
||||
(i18n/label :t/recipient)
|
||||
[react/view components.styles/flex
|
||||
[components/cartouche {}
|
||||
(i18n/label :t/recipient)
|
||||
[components/text-input {:multiline true
|
||||
:placeholder (i18n/label :t/recipient-code)
|
||||
:on-change-text #(reset! content %)}]]
|
||||
[bottom-buttons/bottom-button
|
||||
[button/button {:disabled? (string/blank? @content)
|
||||
:on-press #(re-frame/dispatch [:wallet/fill-request-from-url @content])}
|
||||
(i18n/label :t/done)]]]]])))
|
||||
[components/simple-screen {:avoid-keyboard? true}
|
||||
[components/toolbar (i18n/label :t/recipient)]
|
||||
[react/view components.styles/flex
|
||||
[components/cartouche {}
|
||||
(i18n/label :t/recipient)
|
||||
[components/text-input {:multiline true
|
||||
:placeholder (i18n/label :t/recipient-code)
|
||||
:on-change-text #(reset! content %)}]]
|
||||
[bottom-buttons/bottom-button
|
||||
[button/button {:disabled? (string/blank? @content)
|
||||
:on-press #(re-frame/dispatch [:wallet/fill-request-from-url @content])}
|
||||
(i18n/label :t/done)]]]])))
|
||||
|
||||
(defn recipient-qr-code []
|
||||
[choose-recipient/choose-recipient])
|
||||
|
@ -159,17 +159,19 @@
|
|||
(re-frame/dispatch [:request-permissions [:camera]
|
||||
#(re-frame/dispatch [:navigate-to :recipient-qr-code])]))
|
||||
|
||||
(defn- on-choose-recipient []
|
||||
(defn- on-choose-recipient [contact-only?]
|
||||
(list-selection/show {:title (i18n/label :t/wallet-choose-recipient)
|
||||
:options [{:label (i18n/label :t/recent-recipients)
|
||||
:action #(re-frame/dispatch [:navigate-to :recent-recipients])}
|
||||
{:label (i18n/label :t/scan-qr)
|
||||
:action request-camera-permissions}
|
||||
{:label (i18n/label :t/enter-contact-code)
|
||||
:action #(re-frame/dispatch [:navigate-to :contact-code])}]}))
|
||||
:options (concat
|
||||
[{:label (i18n/label :t/recent-recipients)
|
||||
:action #(re-frame/dispatch [:navigate-to :recent-recipients])}]
|
||||
(when-not contact-only?
|
||||
[{:label (i18n/label :t/scan-qr)
|
||||
:action request-camera-permissions}
|
||||
{:label (i18n/label :t/enter-contact-code)
|
||||
:action #(re-frame/dispatch [:navigate-to :contact-code])}]))}))
|
||||
|
||||
(defn recipient-selector [{:keys [name address disabled?]}]
|
||||
[components/cartouche {:on-press on-choose-recipient :disabled? disabled? :icon :icons/dots-horizontal}
|
||||
(defn recipient-selector [{:keys [name address disabled? contact-only?]}]
|
||||
[components/cartouche {:on-press #(on-choose-recipient contact-only?) :disabled? disabled? :icon :icons/dots-horizontal}
|
||||
(i18n/label :t/wallet-choose-recipient)
|
||||
(if name
|
||||
[recipient-contact address name]
|
||||
|
|
|
@ -6,22 +6,15 @@
|
|||
status-im.ui.screens.wallet.send.db
|
||||
[status-im.utils.money :as money]))
|
||||
|
||||
;; (angusiguess) If we add more error types we can treat them as 'one-of' the following
|
||||
(spec/def :wallet/error #{:error})
|
||||
|
||||
(spec/def :wallet.send/recipient string?)
|
||||
|
||||
(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 :wallet/request-transaction]))
|
||||
(spec/def :wallet/wallet (spec/keys :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.
|
||||
|
||||
;; TODO(oskarth): spec for balance as BigNumber
|
||||
;; TODO(oskarth): Spec for prices as as: {:from ETH, :to USD, :price 290.11, :last-day 304.17}
|
||||
|
||||
(defn- too-precise-amount? [amount]
|
||||
(let [amount-splited (string/split amount #"[.]")]
|
||||
(and (= (count amount-splited) 2) (> (count (last amount-splited)) 18))))
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
(ns status-im.ui.screens.wallet.events
|
||||
(:require [re-frame.core :as re-frame :refer [dispatch reg-fx]]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.native-module.core :as status]
|
||||
[status-im.ui.screens.wallet.db :as wallet.db]
|
||||
[status-im.ui.screens.wallet.navigation]
|
||||
[status-im.utils.ethereum.core :as ethereum]
|
||||
[status-im.utils.ethereum.erc20 :as erc20]
|
||||
|
@ -10,7 +8,6 @@
|
|||
[status-im.utils.handlers :as handlers]
|
||||
[status-im.utils.prices :as prices]
|
||||
[status-im.utils.transactions :as transactions]
|
||||
[status-im.utils.utils :as utils]
|
||||
[taoensso.timbre :as log]
|
||||
status-im.ui.screens.wallet.request.events))
|
||||
|
||||
|
@ -51,8 +48,8 @@
|
|||
(fn [{:keys [web3 account-id success-event error-event]}]
|
||||
(get-balance {:web3 web3
|
||||
:account-id account-id
|
||||
:on-success #(dispatch [success-event %])
|
||||
:on-error #(dispatch [error-event %])})))
|
||||
:on-success #(re-frame/dispatch [success-event %])
|
||||
:on-error #(re-frame/dispatch [error-event %])})))
|
||||
|
||||
(reg-fx
|
||||
:get-tokens-balance
|
||||
|
@ -62,16 +59,16 @@
|
|||
(get-token-balance {:web3 web3
|
||||
:contract contract
|
||||
:account-id account-id
|
||||
:on-success #(dispatch [success-event symbol %])
|
||||
:on-error #(dispatch [error-event %])})))))
|
||||
:on-success #(re-frame/dispatch [success-event symbol %])
|
||||
:on-error #(re-frame/dispatch [error-event %])})))))
|
||||
|
||||
(reg-fx
|
||||
:get-transactions
|
||||
(fn [{:keys [network account-id success-event error-event]}]
|
||||
(transactions/get-transactions network
|
||||
account-id
|
||||
#(dispatch [success-event %])
|
||||
#(dispatch [error-event %]))))
|
||||
#(re-frame/dispatch [success-event %])
|
||||
#(re-frame/dispatch [error-event %]))))
|
||||
|
||||
;; TODO(oskarth): At some point we want to get list of relevant assets to get prices for
|
||||
(reg-fx
|
||||
|
@ -79,8 +76,8 @@
|
|||
(fn [{:keys [from to success-event error-event]}]
|
||||
(prices/get-prices from
|
||||
to
|
||||
#(dispatch [success-event %])
|
||||
#(dispatch [error-event %]))))
|
||||
#(re-frame/dispatch [success-event %])
|
||||
#(re-frame/dispatch [error-event %]))))
|
||||
|
||||
;; Handlers
|
||||
|
||||
|
@ -200,7 +197,7 @@
|
|||
|
||||
(handlers/register-handler-fx
|
||||
:wallet/discard-unsigned-transaction-with-confirmation
|
||||
(fn [cofx [_ transaction-id]]
|
||||
(fn [_ [_ transaction-id]]
|
||||
{:show-confirmation {:title (i18n/label :t/transactions-delete)
|
||||
:content (i18n/label :t/transactions-delete-content)
|
||||
:confirm-button-text (i18n/label :t/confirm)
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
(ns status-im.ui.screens.wallet.main.styles
|
||||
(:require-macros [status-im.utils.styles :refer [defstyle]])
|
||||
(:require [status-im.ui.components.styles :as styles]
|
||||
[status-im.ui.components.colors :as colors]))
|
||||
|
||||
;; Toolbar
|
||||
|
||||
(def toolbar-title-container
|
||||
{:flex-direction :row})
|
||||
|
||||
(def toolbar-title-text
|
||||
{:flex -1
|
||||
:color colors/white
|
||||
:font-size 17})
|
||||
|
||||
(def toolbar-icon
|
||||
{:width 24
|
||||
:height 24})
|
||||
|
||||
(def toolbar-title-icon
|
||||
(merge toolbar-icon {:opacity 0.4}))
|
||||
|
||||
;; Main section
|
||||
|
||||
(def main-section
|
||||
{:background-color colors/blue})
|
||||
|
||||
(def total-balance-container
|
||||
{:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
(def total-balance
|
||||
{:flex-direction :row})
|
||||
|
||||
(def total-balance-value
|
||||
{:font-size 37
|
||||
:color colors/white})
|
||||
|
||||
(def total-value
|
||||
{:font-size 14
|
||||
:color styles/color-white-transparent})
|
||||
|
||||
(defstyle total-balance-currency
|
||||
{:font-size 37
|
||||
:margin-left 9
|
||||
:color styles/color-white-transparent-5
|
||||
:android {:letter-spacing 1.5}
|
||||
:ios {:letter-spacing 1.16}})
|
||||
|
||||
(defstyle buttons
|
||||
{:margin-top 34
|
||||
:android {:margin-horizontal 21}
|
||||
:ios {:margin-horizontal 30}})
|
||||
|
||||
(defstyle main-button-text
|
||||
{:padding-vertical 13
|
||||
:padding-horizontal nil
|
||||
:android {:font-size 13
|
||||
:letter-spacing 0.46}
|
||||
:ios {:font-size 15
|
||||
:letter-spacing -0.2}})
|
||||
|
||||
;; Actions section
|
||||
|
||||
(def action-section
|
||||
{:background-color colors/blue})
|
||||
|
||||
(def action
|
||||
{:background-color colors/white-transparent
|
||||
:border-radius 50})
|
||||
|
||||
(def action-label
|
||||
{:color :white})
|
||||
|
||||
(def action-separator
|
||||
{:height 1
|
||||
:background-color colors/white-light-transparent
|
||||
:margin-left 70})
|
||||
|
||||
;; Assets section
|
||||
|
||||
(def asset-section
|
||||
{:flex 1
|
||||
:padding-vertical 16})
|
||||
|
||||
(def asset-section-title
|
||||
{:font-size 14
|
||||
:margin-left 16
|
||||
:color styles/color-gray4})
|
||||
|
||||
(def asset-item-value-container
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(def asset-item-value
|
||||
{:flex -1
|
||||
:font-size 16
|
||||
:color styles/color-black})
|
||||
|
||||
(defstyle add-asset-icon
|
||||
{:flex 1
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:width 40
|
||||
:height 40
|
||||
:border-radius 32
|
||||
:ios {:background-color styles/color-blue4-transparent}})
|
||||
|
||||
(defstyle add-asset-text
|
||||
{:font-size 16
|
||||
:ios {:color colors/blue}
|
||||
:android {:color styles/color-black}})
|
||||
|
||||
(def asset-item-currency
|
||||
{:font-size 16
|
||||
:color styles/color-gray4
|
||||
:margin-left 6})
|
|
@ -1,110 +0,0 @@
|
|||
(ns status-im.ui.screens.wallet.main.views
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.styles :as components.styles]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.toolbar.actions :as act]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[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.screens.wallet.views :as wallet.views]
|
||||
[status-im.utils.config :as config]
|
||||
[status-im.utils.ethereum.core :as ethereum]
|
||||
[status-im.utils.ethereum.tokens :as tokens]
|
||||
[status-im.utils.platform :as platform]))
|
||||
|
||||
(defn toolbar-view []
|
||||
[toolbar/toolbar {:style wallet.styles/toolbar :flat? true}
|
||||
nil
|
||||
[toolbar/content-wrapper]
|
||||
[toolbar/actions
|
||||
[(assoc (act/opts [{:label (i18n/label :t/wallet-manage-assets)
|
||||
:action #(re-frame/dispatch [:navigate-to-modal :wallet-settings-assets])}])
|
||||
:icon-opts {:color :white})]]])
|
||||
|
||||
(defn- total-section [usd-value syncing? error-message]
|
||||
[react/view {:style styles/main-section}
|
||||
(if syncing?
|
||||
wallet.views/wallet-syncing
|
||||
(when error-message
|
||||
wallet.views/error-message-view))
|
||||
[react/view {:style styles/total-balance-container}
|
||||
[react/view {:style styles/total-balance}
|
||||
[react/text {:style styles/total-balance-value} usd-value]
|
||||
[react/text {:style styles/total-balance-currency} (i18n/label :t/usd-currency)]]
|
||||
[react/text {:style styles/total-value} (i18n/label :t/wallet-total-value)]]])
|
||||
|
||||
(defn- render-action [{:keys [label icon action]}]
|
||||
[react/touchable-highlight {:on-press action}
|
||||
[react/view
|
||||
[list/item
|
||||
[list/item-icon {:icon icon :style styles/action :icon-opts {:color :white}}]
|
||||
[list/item-primary-only {:style styles/action-label}
|
||||
label]
|
||||
list/item-icon-forward]]])
|
||||
|
||||
(def actions
|
||||
[{:label (i18n/label :t/send-transaction)
|
||||
:icon :icons/arrow-right
|
||||
:action #(re-frame/dispatch [:navigate-to :wallet-send-transaction])}
|
||||
{:label (i18n/label :t/receive-transaction)
|
||||
:icon :icons/arrow-left
|
||||
:action #(re-frame/dispatch [:navigate-to :wallet-request-transaction])}
|
||||
{:label (i18n/label :t/transaction-history)
|
||||
:icon :icons/transaction-history
|
||||
:action #(re-frame/dispatch [:navigate-to :transactions-history])}])
|
||||
|
||||
(defn- action-section []
|
||||
[react/view styles/action-section
|
||||
[list/flat-list
|
||||
{:separator (when platform/ios? [react/view styles/action-separator])
|
||||
:data actions
|
||||
:render-fn render-action}]])
|
||||
|
||||
(defn- render-asset [{:keys [symbol icon decimals amount]}]
|
||||
[react/view
|
||||
[list/item
|
||||
[list/item-image icon]
|
||||
[react/view {:style styles/asset-item-value-container}
|
||||
[react/text {:style styles/asset-item-value
|
||||
:number-of-lines 1
|
||||
:ellipsize-mode :tail}
|
||||
(wallet.utils/format-amount amount decimals)]
|
||||
[react/text {:style styles/asset-item-currency
|
||||
:uppercase? true
|
||||
: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 (current-tokens visible-tokens network)
|
||||
assets (map #(assoc % :amount (get balance (:symbol %))) (concat [tokens/ethereum] tokens))]
|
||||
[react/view styles/asset-section
|
||||
[react/text {:style styles/asset-section-title} (i18n/label :t/wallet-assets)]
|
||||
[list/flat-list
|
||||
{:default-separator? true
|
||||
:data assets
|
||||
:render-fn render-asset
|
||||
:on-refresh #(re-frame/dispatch [:update-wallet (map :symbol tokens)])
|
||||
:refreshing (boolean (or prices-loading? balance-loading?))}]]))
|
||||
|
||||
(defview wallet []
|
||||
(letsubs [network [:network]
|
||||
balance [:balance]
|
||||
visible-tokens [:wallet.settings/visible-tokens]
|
||||
portfolio-value [:portfolio-value]
|
||||
prices-loading? [:prices-loading?]
|
||||
syncing? [:syncing?]
|
||||
balance-loading? [:wallet/balance-loading?]
|
||||
error-message [:wallet/error-message?]]
|
||||
[react/view {:style wallet.styles/wallet-container}
|
||||
[toolbar-view]
|
||||
[react/view components.styles/flex
|
||||
[total-section portfolio-value syncing? error-message]
|
||||
[action-section]
|
||||
[asset-section network balance visible-tokens prices-loading? balance-loading?]]]))
|
|
@ -19,7 +19,9 @@
|
|||
[db [event]]
|
||||
(if (= event :navigate-back)
|
||||
db
|
||||
(update db :wallet dissoc :request-transaction)))
|
||||
(-> db
|
||||
(update :wallet dissoc :request-transaction)
|
||||
(assoc-in [:wallet :send-transaction] db/transaction-send-default))))
|
||||
|
||||
(defmethod navigation/preload-data! :wallet-send-transaction
|
||||
[db [event]]
|
||||
|
|
|
@ -18,13 +18,19 @@
|
|||
(handlers/register-handler-fx
|
||||
:wallet-send-request
|
||||
[re-frame/trim-v]
|
||||
(fn [{{:keys [wallet]} :db} [{:keys [whisper-identity]}]]
|
||||
(fn [_ [whisper-identity amount]]
|
||||
(assert whisper-identity)
|
||||
{:dispatch-n [[:navigate-back]
|
||||
[:navigate-to-clean :home]
|
||||
[:add-chat-loaded-event whisper-identity
|
||||
[::wallet-send-chat-request (some-> wallet :request-transaction :amount money/wei->ether str)]]
|
||||
[::wallet-send-chat-request (str (money/wei->ether amount))]]
|
||||
[:start-chat whisper-identity]]}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:wallet.request/set-recipient
|
||||
(fn [{:keys [db]} [_ s]]
|
||||
{:db (assoc-in db [:wallet :request-transaction :to] s)}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:wallet.request/set-and-validate-amount
|
||||
(fn [{:keys [db]} [_ amount]]
|
||||
|
@ -32,8 +38,3 @@
|
|||
{:db (-> db
|
||||
(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)}))
|
|
@ -1,16 +1,25 @@
|
|||
(ns status-im.ui.screens.wallet.request.styles
|
||||
(:require-macros [status-im.utils.styles :refer [defstyle]])
|
||||
(:require [status-im.ui.components.styles :as styles]))
|
||||
(:require [status-im.ui.components.colors :as colors]))
|
||||
|
||||
(def network-container
|
||||
{:flex 1
|
||||
:align-items :center})
|
||||
(def hint
|
||||
{:color colors/white-lighter-transparent})
|
||||
|
||||
(def qr-container
|
||||
{:margin-top 8
|
||||
:padding 16
|
||||
:background-color styles/color-white
|
||||
:border-radius 8})
|
||||
(def footer
|
||||
{:color colors/white})
|
||||
|
||||
(def share-icon-container
|
||||
{:margin-right 8})
|
||||
(def bottom-buttons
|
||||
{:background-color colors/blue})
|
||||
|
||||
(def request-wrapper
|
||||
{:flex 1
|
||||
:flex-direction :column
|
||||
:margin-horizontal 16})
|
||||
|
||||
;; Request panel
|
||||
|
||||
(def request-details-wrapper
|
||||
{:padding-bottom 60})
|
||||
|
||||
(def send-request
|
||||
{:background-color colors/black-transparent
|
||||
:margin-bottom 12})
|
||||
|
|
|
@ -1,23 +1,6 @@
|
|||
(ns status-im.ui.screens.wallet.request.subs
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.utils.ethereum.tokens :as tokens]))
|
||||
(:require [re-frame.core :as re-frame]))
|
||||
|
||||
(re-frame/reg-sub ::request-transaction
|
||||
(re-frame/reg-sub :wallet.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]]
|
||||
:<- [:wallet.request/symbol]
|
||||
(fn [[amount amount-error symbol]]
|
||||
(and
|
||||
(or (nil? symbol) (tokens/ethereum? symbol))
|
||||
(nil? amount-error)
|
||||
(not (nil? amount)))))
|
|
@ -2,80 +2,79 @@
|
|||
(:require-macros [status-im.utils.views :as views])
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.bottom-buttons.view :as bottom-buttons]
|
||||
[status-im.ui.components.button.view :as button]
|
||||
[status-im.ui.components.common.common :as common]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.list-selection :as list-selection]
|
||||
[status-im.ui.components.qr-code-viewer.views :as qr-code-viewer]
|
||||
[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.components.qr-code-viewer.views :as qr-code-viewer]
|
||||
[status-im.ui.components.toolbar.actions :as actions]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.screens.wallet.components.views :as components]
|
||||
[status-im.ui.screens.wallet.request.styles :as styles]
|
||||
[status-im.ui.screens.wallet.styles :as wallet.styles]
|
||||
[status-im.ui.components.styles :as components.styles]
|
||||
[status-im.ui.screens.wallet.components :as comp]
|
||||
[status-im.ui.screens.wallet.components.views :as components]
|
||||
[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.utils :as utils]))
|
||||
|
||||
(defn toolbar-view []
|
||||
[toolbar/toolbar {:style wallet.styles/toolbar}
|
||||
[toolbar/nav-button (actions/back-white actions/default-handler)]
|
||||
[toolbar/content-title {:color :white} (i18n/label :t/request-transaction)]])
|
||||
;; Request screen
|
||||
|
||||
(defn send-request []
|
||||
(re-frame/dispatch [:navigate-to-modal
|
||||
:contact-list-modal
|
||||
{:handler #(re-frame/dispatch [:wallet-send-request %1])
|
||||
:action :request
|
||||
:params {:hide-actions? true}}]))
|
||||
(views/defview send-transaction-request []
|
||||
;; TODO(jeluard) both send and request flows should be merged
|
||||
(views/letsubs [{:keys [to to-name whisper-identity]} [:wallet.send/transaction]
|
||||
{:keys [amount amount-error]} [:wallet.request/transaction]
|
||||
scroll (atom nil)]
|
||||
[comp/simple-screen {:avoid-keyboard? true}
|
||||
[comp/toolbar (i18n/label :t/new-request)]
|
||||
[react/view components.styles/flex
|
||||
[common/network-info {:text-color :white}]
|
||||
[react/scroll-view {:ref #(reset! scroll %) :keyboardShouldPersistTaps :always}
|
||||
[react/view styles/request-details-wrapper
|
||||
[components/recipient-selector {:contact-only? true
|
||||
:address to
|
||||
:name to-name}]
|
||||
[components/asset-selector {:disabled? true
|
||||
:symbol :ETH}]
|
||||
[components/amount-selector {:error amount-error
|
||||
:input-options {:default-value (str (money/to-fixed (money/wei->ether amount)))
|
||||
:max-length 21
|
||||
:on-focus (fn [] (when @scroll (utils/set-timeout #(.scrollToEnd @scroll) 100)))
|
||||
:on-change-text #(re-frame/dispatch [:wallet.request/set-and-validate-amount %])}}]]]
|
||||
[bottom-buttons/bottom-buttons styles/bottom-buttons
|
||||
nil ;; Force a phantom button to ensure consistency with other transaction screens which define 2 buttons
|
||||
[button/button {:disabled? (not (and to amount))
|
||||
:on-press #(re-frame/dispatch [:wallet-send-request whisper-identity amount])
|
||||
:text-style {:padding-horizontal 0}}
|
||||
(i18n/label :t/send-request)
|
||||
[vector-icons/icon :icons/forward {:color :white}]]]]]))
|
||||
|
||||
(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)))
|
||||
;; Main screen
|
||||
|
||||
(views/defview qr-code [amount symbol]
|
||||
(views/letsubs [account [:get-current-account]
|
||||
chain-id [:get-network-id]]
|
||||
[qr-code-viewer/qr-code
|
||||
(let [address (ethereum/normalized-address (:address account))
|
||||
params {:chain-id chain-id :value amount :symbol (or symbol :ETH)}]
|
||||
{:value (generate-value address params)
|
||||
:size 256})]))
|
||||
(defn- qr-code [address chain-id]
|
||||
(let [address (ethereum/normalized-address address)]
|
||||
[qr-code-viewer/qr-code-viewer {:hint-style styles/hint :footer-style styles/footer}
|
||||
(eip681/generate-uri address {:chain-id chain-id})
|
||||
(i18n/label :t/request-qr-legend)
|
||||
address]))
|
||||
|
||||
(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 [:wallet.request/symbol]
|
||||
request-enabled? [:wallet.request/request-enabled?]
|
||||
scroll (atom nil)]
|
||||
[react/keyboard-avoiding-view wallet.styles/wallet-modal-container
|
||||
[status-bar/status-bar {:type :wallet}]
|
||||
[toolbar-view]
|
||||
[common/network-info {:text-color :white}]
|
||||
[react/scroll-view {:ref #(reset! scroll %)}
|
||||
[react/view components.styles/flex
|
||||
[react/view styles/network-container
|
||||
[react/view styles/qr-container
|
||||
[react/with-activity-indicator
|
||||
{:style wallet.styles/qr-code-preview}
|
||||
[qr-code amount symbol]]]]
|
||||
[components/amount-selector
|
||||
{:error amount-error
|
||||
:input-options {:on-focus (fn [] (when @scroll (utils/set-timeout #(.scrollToEnd @scroll) 100)))
|
||||
:on-change-text #(re-frame/dispatch [:wallet.request/set-and-validate-amount %])}}]
|
||||
[components/asset-selector {:type :request
|
||||
:symbol symbol}]]]
|
||||
[components/separator]
|
||||
[react/view wallet.styles/buttons-container
|
||||
[react/touchable-highlight {:style wallet.styles/button :disabled true}
|
||||
[react/view (wallet.styles/button-container false)
|
||||
[vector-icons/icon :icons/share {:color :white :container-style styles/share-icon-container}]
|
||||
[components/button-text (i18n/label :t/share)]]]
|
||||
[react/view components.styles/flex]
|
||||
[react/touchable-highlight {:style wallet.styles/button :disabled (not request-enabled?) :on-press send-request}
|
||||
[react/view (wallet.styles/button-container request-enabled?)
|
||||
[components/button-text (i18n/label :t/send-request)]
|
||||
[vector-icons/icon :icons/forward {:color :white :container-style wallet.styles/forward-icon-container}]]]]]))
|
||||
(views/letsubs [{:keys [address]} [:get-current-account]
|
||||
chain-id [:get-network-id]]
|
||||
[comp/simple-screen
|
||||
[comp/toolbar comp/default-action
|
||||
(i18n/label :t/receive)
|
||||
[toolbar/actions [{:icon :icons/share
|
||||
:icon-opts {:color :white}
|
||||
:handler #(list-selection/open-share {:message address})}]]]
|
||||
[react/view {:flex 1}
|
||||
[common/network-info {:text-color :white}]
|
||||
[react/scroll-view styles/request-wrapper
|
||||
[qr-code address chain-id]
|
||||
[button/primary-button {:on-press #(re-frame/dispatch [:navigate-to :wallet-send-transaction-request])
|
||||
:style styles/send-request}
|
||||
(i18n/label :t/send-transaction-request)]]]]))
|
||||
|
|
|
@ -22,10 +22,11 @@
|
|||
(spec/def ::gas (spec/nilable money/valid?))
|
||||
(spec/def ::gas-price (spec/nilable money/valid?))
|
||||
(spec/def ::advanced? boolean?)
|
||||
(spec/def ::whisper-identity (spec/nilable string?))
|
||||
|
||||
(spec/def :wallet/send-transaction (allowed-keys
|
||||
:opt-un [::amount ::to ::to-name ::amount-error ::password
|
||||
::waiting-signal? ::signing? ::id ::later?
|
||||
::camera-flashlight ::in-progress?
|
||||
::wrong-password? ::from-chat? ::symbol ::advanced?
|
||||
::gas ::gas-price]))
|
||||
::gas ::gas-price ::whisper-identity]))
|
||||
|
|
|
@ -143,7 +143,7 @@
|
|||
;;TRANSACTION FAILED signal from status-go
|
||||
(handlers/register-handler-fx
|
||||
:transaction-failed
|
||||
(fn [{{:keys [view-id modal] :as db} :db} [_ {:keys [id error_code error_message] :as event}]]
|
||||
(fn [{{:keys [view-id modal] :as db} :db} [_ {:keys [id error_code error_message]}]]
|
||||
(let [send-transaction (get-in db [:wallet :send-transaction])]
|
||||
(case error_code
|
||||
|
||||
|
@ -200,7 +200,7 @@
|
|||
:accounts/keys [accounts current-account-id] :as db} :db} [_ later?]]
|
||||
(let [db' (assoc-in db [:wallet :send-transaction :wrong-password?] false)
|
||||
network (:network db)
|
||||
{:keys [amount id password to symbol gas gas-price] :as m} (get-in db [:wallet :send-transaction])]
|
||||
{:keys [amount id password to symbol gas gas-price]} (get-in db [:wallet :send-transaction])]
|
||||
(if id
|
||||
{::accept-transaction {:id id
|
||||
:password password
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
[button/button {:style (wallet.styles/button-container sign-enabled?)
|
||||
:on-press sign-handler}
|
||||
(i18n/label :t/transactions-sign-transaction)
|
||||
[vector-icons/icon :icons/forward {:color :white :container-style wallet.styles/forward-icon-container}]]]))
|
||||
[vector-icons/icon :icons/forward {:color :white}]]]))
|
||||
|
||||
(defn- sign-enabled? [amount-error to amount]
|
||||
(and
|
||||
|
@ -87,7 +87,7 @@
|
|||
:on-press #(re-frame/dispatch [:wallet.send/set-signing? true])
|
||||
:text-style {:color :white}}
|
||||
(i18n/label :t/transactions-sign-transaction)
|
||||
[vector-icons/icon :icons/forward {:color (if immediate-sign-enabled? :white :gray) :container-style wallet.styles/forward-icon-container}]]]))
|
||||
[vector-icons/icon :icons/forward {:color (if immediate-sign-enabled? :white :gray)}]]]))
|
||||
|
||||
(defn handler [discard?]
|
||||
(if discard?
|
||||
|
@ -163,11 +163,11 @@
|
|||
|
||||
(defn- send-transaction-panel [{:keys [modal? transaction scroll advanced? symbol]}]
|
||||
(let [{:keys [amount amount-error signing? to to-name sufficient-funds? in-progress? from-chat?]} transaction]
|
||||
[react/keyboard-avoiding-view wallet.styles/wallet-modal-container
|
||||
[wallet.components/simple-screen {:avoid-keyboard? true
|
||||
:status-bar-type (if modal? :modal-wallet :wallet)}
|
||||
[toolbar from-chat? (if modal? act/close-white act/back-white)
|
||||
(i18n/label :t/send-transaction)]
|
||||
[react/view components.styles/flex
|
||||
[status-bar/status-bar {:type (if modal? :modal-wallet :wallet)}]
|
||||
[toolbar from-chat? (if modal? act/close-white act/back-white)
|
||||
(i18n/label :t/send-transaction)]
|
||||
[common/network-info {:text-color :white}]
|
||||
[react/scroll-view (merge {:keyboardShouldPersistTaps :always} (when-not modal? {:ref #(reset! scroll %)}))
|
||||
[react/view send.styles/send-transaction-form
|
||||
|
|
|
@ -3,65 +3,11 @@
|
|||
(:require [status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.styles :as styles]))
|
||||
|
||||
;; errors
|
||||
|
||||
(defstyle error-container
|
||||
{:align-self :center
|
||||
:justify-content :center
|
||||
:ios {:border-radius 20
|
||||
:margin-top 6}
|
||||
:android {
|
||||
:margin-top 18}
|
||||
:background-color colors/blue})
|
||||
|
||||
(defstyle error-message-container
|
||||
{:flex-direction :row
|
||||
:align-items :center
|
||||
:padding-horizontal 15
|
||||
:ios {:padding-vertical 8}
|
||||
:android {:padding-vertical 10}})
|
||||
|
||||
|
||||
(defn exclamation [color]
|
||||
{:background-color color
|
||||
:border-radius 100
|
||||
:width 16
|
||||
:height 16
|
||||
:margin-right 6})
|
||||
|
||||
(def error-message
|
||||
{:color colors/white
|
||||
:font-size 13})
|
||||
|
||||
(def error-exclamation
|
||||
(exclamation styles/color-red-2))
|
||||
|
||||
(def warning-exclamation
|
||||
(exclamation :gold))
|
||||
|
||||
;; wallet
|
||||
|
||||
(def wallet-container
|
||||
{:flex 1})
|
||||
|
||||
(def toolbar
|
||||
{:background-color colors/blue})
|
||||
|
||||
(defstyle toolbar-modal
|
||||
{:background-color colors/blue
|
||||
:android {:elevation 2}})
|
||||
|
||||
(def buttons-container
|
||||
{:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(def button
|
||||
{:padding-vertical 15
|
||||
:padding-horizontal 12})
|
||||
|
||||
(def forward-icon-container
|
||||
{:margin-left 8})
|
||||
|
||||
(defn button-container [enabled?]
|
||||
(merge {:flex-direction :row
|
||||
:align-items :center}
|
||||
|
@ -72,11 +18,7 @@
|
|||
{:flex 1
|
||||
:background-color colors/blue})
|
||||
|
||||
(def amount-container
|
||||
{:margin-top 16
|
||||
:margin-bottom 16
|
||||
:margin-horizontal 15
|
||||
:flex-direction :row})
|
||||
;; Components
|
||||
|
||||
(def cartouche-container
|
||||
{:flex 1
|
||||
|
@ -104,12 +46,88 @@
|
|||
:justify-content :space-between
|
||||
:align-items :center})
|
||||
|
||||
(def cartouche-text-wrapper
|
||||
{:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:padding-horizontal 15
|
||||
:padding-vertical 15})
|
||||
|
||||
(def cartouche-primary-text
|
||||
{:color styles/color-white})
|
||||
|
||||
(def cartouche-secondary-text
|
||||
{:color styles/color-white-transparent})
|
||||
|
||||
;; Main section
|
||||
|
||||
(def main-section
|
||||
{:background-color colors/blue})
|
||||
|
||||
(def total-balance-container
|
||||
{:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
(def total-balance
|
||||
{:flex-direction :row})
|
||||
|
||||
(def total-balance-value
|
||||
{:font-size 37
|
||||
:color colors/white})
|
||||
|
||||
(def total-value
|
||||
{:font-size 14
|
||||
:color styles/color-white-transparent})
|
||||
|
||||
(defstyle total-balance-currency
|
||||
{:font-size 37
|
||||
:margin-left 9
|
||||
:color styles/color-white-transparent-5
|
||||
:android {:letter-spacing 1.5}
|
||||
:ios {:letter-spacing 1.16}})
|
||||
|
||||
;; Actions section
|
||||
|
||||
(def action-section
|
||||
{:background-color colors/blue})
|
||||
|
||||
(def action
|
||||
{:background-color colors/white-transparent
|
||||
:border-radius 50})
|
||||
|
||||
(def action-label
|
||||
{:color :white})
|
||||
|
||||
(def action-separator
|
||||
{:height 1
|
||||
:background-color colors/white-light-transparent
|
||||
:margin-left 70})
|
||||
|
||||
;; Assets section
|
||||
|
||||
(def asset-section
|
||||
{:flex 1
|
||||
:padding-vertical 16})
|
||||
|
||||
(def asset-section-title
|
||||
{:font-size 14
|
||||
:margin-left 16
|
||||
:color styles/color-gray4})
|
||||
|
||||
(def asset-item-value-container
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(def asset-item-value
|
||||
{:flex -1
|
||||
:font-size 16
|
||||
:color styles/color-black})
|
||||
|
||||
(def asset-item-currency
|
||||
{:font-size 16
|
||||
:color styles/color-gray4
|
||||
:margin-left 6})
|
||||
|
||||
(def qr-code-preview
|
||||
{:width 256
|
||||
:height 256
|
||||
|
|
|
@ -19,12 +19,6 @@
|
|||
(fn [db]
|
||||
(get-in db [:prices :last-day])))
|
||||
|
||||
(reg-sub :wallet/error-message?
|
||||
:<- [:wallet]
|
||||
(fn [wallet]
|
||||
(or (get-in wallet [:errors :balance-update])
|
||||
(get-in wallet [:errors :prices-update]))))
|
||||
|
||||
(reg-sub :portfolio-value
|
||||
:<- [:balance]
|
||||
:<- [:price]
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
(defn- mark-all-checked [filters]
|
||||
(update filters :type #(map (fn [m] (assoc m :checked? true)) %)))
|
||||
|
||||
(defn- mark-checked [filters {:keys [type] :as m} checked?]
|
||||
(defn- mark-checked [filters {:keys [type]} checked?]
|
||||
(update filters :type #(map (fn [{:keys [id] :as m}] (if (= type id) (assoc m :checked? checked?) m)) %)))
|
||||
|
||||
(defn- update-filters [db f]
|
||||
|
@ -18,4 +18,4 @@
|
|||
(handlers/register-handler-db
|
||||
:wallet.transactions/filter-all
|
||||
(fn [db]
|
||||
(update-filters db mark-all-checked)))
|
||||
(update-filters db mark-all-checked)))
|
||||
|
|
|
@ -4,20 +4,6 @@
|
|||
[status-im.ui.components.styles :as styles]
|
||||
[status-im.ui.screens.main-tabs.styles :as tabs.styles]))
|
||||
|
||||
(def error-container
|
||||
{:align-self :center
|
||||
:justify-content :center
|
||||
:border-radius 8
|
||||
:padding-vertical 4
|
||||
:flex-direction :row
|
||||
:background-color styles/color-gray9})
|
||||
|
||||
(def error-message
|
||||
{:color styles/color-black
|
||||
:padding-top 3
|
||||
:padding-right 10
|
||||
:font-size 13})
|
||||
|
||||
(defnstyle tab [active?]
|
||||
{:flex 1
|
||||
:height tabs.styles/tab-height
|
||||
|
@ -112,14 +98,6 @@
|
|||
:margin-horizontal 12
|
||||
:border-radius 8})
|
||||
|
||||
(def sign-all-popup-sign-phrase
|
||||
{:border-radius 8
|
||||
:margin-top 12
|
||||
:margin-horizontal 12
|
||||
:text-align :center
|
||||
:padding-vertical 9
|
||||
:background-color styles/color-light-gray})
|
||||
|
||||
(def sign-all-popup-text
|
||||
{:margin-top 8
|
||||
:margin-horizontal 12})
|
||||
|
|
|
@ -2,27 +2,21 @@
|
|||
(:require [re-frame.core :refer [reg-sub subscribe]]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.utils.datetime :as datetime]
|
||||
[status-im.utils.hex :as utils.hex]
|
||||
[status-im.utils.money :as money]
|
||||
[status-im.utils.transactions :as transactions]
|
||||
[status-im.utils.hex :as utils.hex]))
|
||||
[status-im.utils.transactions :as transactions]))
|
||||
|
||||
(reg-sub :wallet.transactions/transactions-loading?
|
||||
:<- [:wallet]
|
||||
(fn [wallet]
|
||||
(:transactions-loading? wallet)))
|
||||
|
||||
(reg-sub :wallet.transactions/error-message?
|
||||
:<- [:wallet]
|
||||
(fn [wallet]
|
||||
(get-in wallet [:errors :transactions-update])))
|
||||
|
||||
(reg-sub :wallet.transactions/current-tab
|
||||
:<- [:wallet]
|
||||
(fn [wallet]
|
||||
(get wallet :current-tab 0)))
|
||||
|
||||
(defn enrich-transaction [{:keys [type to from timestamp] :as transaction} contacts]
|
||||
;; TODO (yenda) proper wallet logic when wallet switching is implemented
|
||||
(let [[contact-address key-contact key-wallet] (if (= type :inbound)
|
||||
[from :from-contact :to-wallet]
|
||||
[to :to-contact :from-wallet])
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
[status-im.ui.components.toolbar.actions :as actions]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.screens.wallet.transactions.styles :as styles]
|
||||
[status-im.ui.screens.wallet.views :as wallet.views]
|
||||
[status-im.utils.money :as money]))
|
||||
|
||||
(defn on-delete-transaction
|
||||
|
@ -102,11 +101,8 @@
|
|||
(defview history-list []
|
||||
(letsubs [transactions-history-list [:wallet.transactions/transactions-history-list]
|
||||
transactions-loading? [:wallet.transactions/transactions-loading?]
|
||||
error-message [:wallet.transactions/error-message?]
|
||||
filter-data [:wallet.transactions/filters]]
|
||||
[react/view components.styles/flex
|
||||
(when error-message
|
||||
[wallet.views/error-message-view styles/error-container styles/error-message])
|
||||
[list/section-list {:sections (map #(update-transactions % filter-data) transactions-history-list)
|
||||
:render-fn render-transaction
|
||||
:empty-component [react/text {:style styles/empty-text}
|
||||
|
|
|
@ -1,17 +1,101 @@
|
|||
(ns status-im.ui.screens.wallet.views
|
||||
(:require [status-im.ui.components.react :as react]
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.styles :as components.styles]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.toolbar.actions :as act]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.screens.wallet.styles :as styles]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.i18n :as i18n]))
|
||||
[status-im.ui.screens.wallet.utils :as wallet.utils]
|
||||
[status-im.utils.ethereum.core :as ethereum]
|
||||
[status-im.utils.ethereum.tokens :as tokens]
|
||||
[status-im.utils.platform :as platform]))
|
||||
|
||||
(defn- message-view [icon-container-style label]
|
||||
[react/view {:style styles/error-container}
|
||||
[react/view {:style styles/error-message-container}
|
||||
[vector-icons/icon :icons/exclamation_mark {:color :white
|
||||
:container-style icon-container-style}]
|
||||
[react/text {:style styles/error-message}
|
||||
label]]])
|
||||
(defn toolbar-view []
|
||||
[toolbar/toolbar {:style styles/toolbar :flat? true}
|
||||
nil
|
||||
[toolbar/content-wrapper]
|
||||
[toolbar/actions
|
||||
[(assoc (act/opts [{:label (i18n/label :t/wallet-manage-assets)
|
||||
:action #(re-frame/dispatch [:navigate-to-modal :wallet-settings-assets])}])
|
||||
:icon-opts {:color :white})]]])
|
||||
|
||||
(def error-message-view [message-view styles/error-exclamation (i18n/label :t/wallet-error)])
|
||||
(defn- total-section [usd-value]
|
||||
[react/view {:style styles/main-section}
|
||||
[react/view {:style styles/total-balance-container}
|
||||
[react/view {:style styles/total-balance}
|
||||
[react/text {:style styles/total-balance-value} usd-value]
|
||||
[react/text {:style styles/total-balance-currency} (i18n/label :t/usd-currency)]]
|
||||
[react/text {:style styles/total-value} (i18n/label :t/wallet-total-value)]]])
|
||||
|
||||
(def wallet-syncing [message-view styles/warning-exclamation (i18n/label :t/sync-in-progress)])
|
||||
(defn- render-action [{:keys [label icon action]}]
|
||||
[react/touchable-highlight {:on-press action}
|
||||
[react/view
|
||||
[list/item
|
||||
[list/item-icon {:icon icon :style styles/action :icon-opts {:color :white}}]
|
||||
[list/item-primary-only {:style styles/action-label}
|
||||
label]
|
||||
list/item-icon-forward]]])
|
||||
|
||||
(def actions
|
||||
[{:label (i18n/label :t/send-transaction)
|
||||
:icon :icons/arrow-right
|
||||
:action #(re-frame/dispatch [:navigate-to :wallet-send-transaction])}
|
||||
{:label (i18n/label :t/receive-transaction)
|
||||
:icon :icons/arrow-left
|
||||
:action #(re-frame/dispatch [:navigate-to :wallet-request-transaction])}
|
||||
{:label (i18n/label :t/transaction-history)
|
||||
:icon :icons/transaction-history
|
||||
:action #(re-frame/dispatch [:navigate-to :transactions-history])}])
|
||||
|
||||
(defn- action-section []
|
||||
[react/view styles/action-section
|
||||
[list/flat-list
|
||||
{:separator (when platform/ios? [react/view styles/action-separator])
|
||||
:data actions
|
||||
:render-fn render-action}]])
|
||||
|
||||
(defn- render-asset [{:keys [symbol icon decimals amount]}]
|
||||
[react/view
|
||||
[list/item
|
||||
[list/item-image icon]
|
||||
[react/view {:style styles/asset-item-value-container}
|
||||
[react/text {:style styles/asset-item-value
|
||||
:number-of-lines 1
|
||||
:ellipsize-mode :tail}
|
||||
(wallet.utils/format-amount amount decimals)]
|
||||
[react/text {:style styles/asset-item-currency
|
||||
:uppercase? true
|
||||
: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 (current-tokens visible-tokens network)
|
||||
assets (map #(assoc % :amount (get balance (:symbol %))) (concat [tokens/ethereum] tokens))]
|
||||
[react/view styles/asset-section
|
||||
[react/text {:style styles/asset-section-title} (i18n/label :t/wallet-assets)]
|
||||
[list/flat-list
|
||||
{:default-separator? true
|
||||
:data assets
|
||||
:render-fn render-asset
|
||||
:on-refresh #(re-frame/dispatch [:update-wallet (map :symbol tokens)])
|
||||
:refreshing (boolean (or prices-loading? balance-loading?))}]]))
|
||||
|
||||
(defview wallet []
|
||||
(letsubs [network [:network]
|
||||
balance [:balance]
|
||||
visible-tokens [:wallet.settings/visible-tokens]
|
||||
portfolio-value [:portfolio-value]
|
||||
prices-loading? [:prices-loading?]
|
||||
balance-loading? [:wallet/balance-loading?]]
|
||||
[react/view {:style components.styles/flex}
|
||||
[toolbar-view]
|
||||
[react/view components.styles/flex
|
||||
[total-section portfolio-value]
|
||||
[action-section]
|
||||
[asset-section network balance visible-tokens prices-loading? balance-loading?]]]))
|
||||
|
|
|
@ -392,4 +392,4 @@
|
|||
(defn asset-for [chain symbol]
|
||||
(if (= (:symbol ethereum) symbol)
|
||||
ethereum
|
||||
(symbol->token chain symbol)))
|
||||
(symbol->token chain symbol)))
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
[status-im.test.contacts.events]
|
||||
[status-im.test.accounts.events]
|
||||
[status-im.test.data-store.realm.core]
|
||||
[status-im.test.wallet.events]
|
||||
[status-im.test.wallet.transactions.subs]
|
||||
[status-im.test.wallet.transactions.views]
|
||||
[status-im.test.profile.events]
|
||||
|
@ -39,7 +38,6 @@
|
|||
'status-im.test.accounts.events
|
||||
'status-im.test.contacts.events
|
||||
'status-im.test.profile.events
|
||||
'status-im.test.wallet.events
|
||||
'status-im.test.data-store.realm.core
|
||||
'status-im.test.bots.events
|
||||
'status-im.test.wallet.transactions.subs
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
(ns status-im.test.wallet.events
|
||||
(:require [cljs.test :refer [deftest is testing]]
|
||||
reagent.core
|
||||
[re-frame.core :as re-frame]
|
||||
[day8.re-frame.test :refer [run-test-sync]]
|
||||
status-im.ui.screens.db
|
||||
status-im.ui.screens.subs
|
||||
[status-im.ui.screens.events :as events]
|
||||
[status-im.ui.screens.wallet.events :as wallet-events]))
|
||||
|
||||
(deftest wallet-events
|
||||
"update-balance-fail
|
||||
update-prices-fail
|
||||
clear-error"
|
||||
(run-test-sync
|
||||
(re-frame/reg-fx ::events/init-store #())
|
||||
(re-frame/reg-fx :get-prices #())
|
||||
(re-frame/reg-fx :get-balance #())
|
||||
(re-frame/dispatch [:initialize-db])
|
||||
(let [error (re-frame/subscribe [:wallet/error-message?])
|
||||
message "failed balance update"]
|
||||
(re-frame/dispatch [:update-balance-fail message])
|
||||
(is (= message @error)))
|
||||
(let [error (re-frame/subscribe [:wallet/error-message?])]
|
||||
(re-frame/dispatch [:update-wallet])
|
||||
(is (nil? @error)))
|
||||
(let [error (re-frame/subscribe [:wallet/error-message?])
|
||||
message "failed price update"]
|
||||
(re-frame/dispatch [:update-prices-fail message])
|
||||
(is (= message @error)))
|
||||
(let [error (re-frame/subscribe [:wallet/error-message?])]
|
||||
(re-frame/dispatch [:update-wallet])
|
||||
(is (nil? @error)))))
|
Loading…
Reference in New Issue