[#8458] [#8448] developed popover, share accounts and signing phrase popovers

This commit is contained in:
Andrey Shovkoplyas 2019-07-08 13:38:47 +02:00
parent d92eb8374f
commit a71901d897
No known key found for this signature in database
GPG Key ID: EAAB7C8622D860A4
22 changed files with 243 additions and 99 deletions

View File

@ -5,13 +5,13 @@
[status-im.ethereum.stateofus :as stateofus]
[status-im.i18n :as i18n]
[status-im.native-module.core :as native-module]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.build :as build]
[status-im.utils.config :as config]
[status-im.utils.fx :as fx]
[status-im.utils.gfycat.core :as gfycat]
[status-im.utils.platform :as platform]
[status-im.utils.utils :as utils]))
[status-im.utils.utils :as utils]
[status-im.utils.handlers :as handlers]))
(defn displayed-name [account]
(let [name (or (:preferred-name account) (:name account))]
@ -46,19 +46,9 @@
(not (:in-progress? transaction))
(:from-chat? transaction)))
(fx/defn continue-after-wallet-onboarding [{:keys [db] :as cofx} modal?]
(let [transaction (get-in db [:wallet :send-transaction])]
(if modal?
{:dispatch [:navigate-to-clean :wallet-send-transaction-modal]}
(if-not (chat-send? transaction)
(navigation/navigate-to-cofx cofx :wallet nil)
(navigation/navigate-to-cofx cofx :wallet-send-transaction-modal nil)))))
(fx/defn confirm-wallet-set-up
[{:keys [db] :as cofx} modal?]
(fx/merge cofx
(continue-after-wallet-onboarding modal?)
(accounts.update/account-update {:wallet-set-up-passed? true} {})))
[cofx]
(accounts.update/account-update cofx {:wallet-set-up-passed? true} {}))
(fx/defn update-dev-server-state
[_ dev-mode?]

View File

@ -68,7 +68,8 @@
[status-im.web3.core :as web3]
[taoensso.timbre :as log]
[status-im.chat.commands.sending :as commands.sending]
[status-im.utils.money :as money]))
[status-im.utils.money :as money]
status-im.popover.core))
;; init module
@ -245,8 +246,8 @@
(handlers/register-handler-fx
:accounts.ui/wallet-set-up-confirmed
(fn [cofx [_ modal?]]
(accounts/confirm-wallet-set-up cofx modal?)))
(fn [cofx _]
(accounts/confirm-wallet-set-up cofx)))
;; accounts create module
@ -1963,6 +1964,7 @@
(assert public-key)
(let [request-command (get-in db [:id->command ["request" #{:personal-chats}]])]
(fx/merge cofx
(navigation/navigate-back)
(chat/start-chat public-key nil)
(commands.sending/send public-key
request-command

View File

@ -0,0 +1,14 @@
(ns status-im.popover.core
(:require [status-im.utils.fx :as fx]
[status-im.utils.handlers :as handlers]))
(fx/defn show-popover
{:events [:show-popover]}
[{:keys [db]} value]
{:db (assoc db :popover/popover value)
:dismiss-keyboard nil})
(fx/defn hide-popover
{:events [:hide-popover]}
[{:keys [db]}]
{:db (dissoc db :popover/popover)})

View File

@ -167,9 +167,11 @@
(fx/defn show-sign [{:keys [db] :as cofx}]
(let [{:signing/keys [queue]} db
{{:keys [gas gasPrice] :as tx-obj} :tx-obj {:keys [data typed?] :as message} :message :as tx} (last queue)
keycard-account? (boolean (get-in db [:account/account :keycard-instance-uid]))]
keycard-account? (boolean (get-in db [:account/account :keycard-instance-uid]))
wallet-set-up-passed? (get-in db [:account/account :wallet-set-up-passed?])
updated-db (if wallet-set-up-passed? db (assoc db :popover/popover {:view :signing-phrase}))]
(if message
{:db (assoc db
{:db (assoc updated-db
:signing/in-progress? true
:signing/queue (drop-last queue)
:signing/tx tx
@ -177,10 +179,10 @@
:formatted-data (if typed? (types/json->clj data) (ethereum/hex-to-utf8 data))})}
(fx/merge cofx
{:db
(assoc db
(assoc updated-db
:signing/in-progress? true
:signing/queue (drop-last queue)
:signing/tx (prepare-tx db tx))
:signing/tx (prepare-tx updated-db tx))
:dismiss-keyboard
nil}
#(when-not gas

View File

@ -181,6 +181,8 @@
;;intro-wizard
(reg-root-key-sub :intro-wizard :intro-wizard)
(reg-root-key-sub :popover/popover :popover/popover)
;;GENERAL ==============================================================================================================
(re-frame/reg-sub

View File

@ -11,23 +11,26 @@
(rn-dependencies/qr-code)
(clj->js (merge {:inverted true} props))))
(defn qr-code-view [size value]
(when size
[react/view {:style (styles/qr-code-container size)
:accessibility-label :qr-code-image}
[qr-code {:value value
:size size}]]))
(defview qr-code-viewer-component
[{:keys [style hint-style footer-style footer-button value hint legend
show-tribute-to-talk-warning?]}]
(letsubs [{:keys [width]} [:dimensions/window]]
[react/scroll-view {:content-container-style {:align-items :center
:margin-top 16
:justify-content :center}
:style (merge {:flex 1} style)}
[react/scroll-view {:content-container-style {:align-items :center
:margin-top 16
:justify-content :center}
:style (merge {:flex 1} style)}
(when show-tribute-to-talk-warning?
[react/view {:style {:margin-horizontal 16}}
[tribute-to-talk/enabled-note]])
(when width
(let [size (int (min width styles/qr-code-max-width))]
[react/view {:style (styles/qr-code-container size)
:accessibility-label :qr-code-image}
[qr-code {:value value
:size size}]]))
[qr-code-view (int (min width styles/qr-code-max-width)) value])
[react/text {:style (merge styles/qr-code-hint hint-style)}
hint]
[react/view styles/footer
@ -43,7 +46,7 @@
(defn qr-code-viewer
[{:keys [style hint-style footer-style footer-button value hint legend]
:as params}]
:as params}]
(if value
[qr-code-viewer-component params]
[react/view [react/text "no value"]]))

View File

@ -62,7 +62,6 @@
:recent-recipients {:type :wallet}
:contact-code {:type :wallet}
:wallet-send-transaction-request {:type :wallet}
:wallet-request-transaction {:type :wallet-tab}
:wallet-settings-assets {:type :main}
:wallet-account {:type :main}
:wallet-add-custom-token {:type :main}

View File

@ -211,6 +211,8 @@
(spec/def :signing/sign (spec/nilable map?))
(spec/def :signing/edit-fee (spec/nilable map?))
(spec/def :popover/popover (spec/nilable map?))
(spec/def ::db (spec/keys :opt [:contacts/contacts
:contacts/new-identity
:contacts/new-identity-error
@ -291,7 +293,8 @@
:signing/queue
:signing/sign
:signing/tx
:signing/edit-fee]
:signing/edit-fee
:popover/popover]
:opt-un [::modal
::was-modal?
::rpc-url

View File

@ -0,0 +1,92 @@
(ns status-im.ui.screens.popover.views
(:require-macros [status-im.utils.views :as views])
(:require [status-im.ui.components.animation :as anim]
[reagent.core :as reagent]
[status-im.ui.components.react :as react]
[re-frame.core :as re-frame]
[status-im.ui.screens.wallet.signing-phrase.views :as signing-phrase]
[status-im.ui.screens.wallet.request.views :as request]))
(defn hide-panel-anim
[bottom-anim-value alpha-value window-height]
(anim/start
(anim/parallel
[(anim/spring bottom-anim-value {:toValue (- window-height)
:useNativeDriver true})
(anim/timing alpha-value {:toValue 0
:duration 500
:useNativeDriver true})])))
(defn show-panel-anim
[bottom-anim-value alpha-value]
(anim/start
(anim/parallel
[(anim/spring bottom-anim-value {:toValue 0
:useNativeDriver true})
(anim/timing alpha-value {:toValue 0.4
:duration 500
:useNativeDriver true})])))
(defn popover-view [popover window-height]
(let [bottom-anim-value (anim/create-value window-height)
alpha-value (anim/create-value 0)
clear-timeout (atom nil)
current-popover (reagent/atom nil)
update? (reagent/atom nil)]
(reagent/create-class
{:component-will-update (fn [_ [_ popover _]]
(when @clear-timeout (js/clearTimeout @clear-timeout))
(cond
@update?
(do (reset! update? false)
(show-panel-anim bottom-anim-value alpha-value))
(and @current-popover popover)
(do (reset! update? true)
(js/setTimeout #(reset! current-popover popover) 600)
(hide-panel-anim bottom-anim-value alpha-value (- window-height)))
popover
(do (reset! current-popover popover)
(show-panel-anim bottom-anim-value alpha-value))
:else
(do (reset! clear-timeout (js/setTimeout #(reset! current-popover nil) 500))
(hide-panel-anim bottom-anim-value alpha-value (- window-height)))))
:reagent-render (fn []
(when @current-popover
(let [view (:view @current-popover)]
[react/view {:position :absolute :top 0 :bottom 0 :left 0 :right 0}
[react/animated-view {:style {:flex 1 :background-color :black :opacity alpha-value}}]
[react/animated-view {:style
{:position :absolute
:height window-height
:left 0
:right 0
:transform [{:translateY bottom-anim-value}]}}
[react/touchable-highlight {:style {:flex 1} :on-press #(re-frame/dispatch [:hide-popover])}
[react/view {:flex 1 :align-items :center :justify-content :center}
[react/view {:background-color :white
:border-radius 16
:margin 32
:shadow-offset {:width 0 :height 2}
:shadow-radius 8
:shadow-opacity 1
:shadow-color "rgba(0, 9, 26, 0.12)"}
(cond
(vector? view)
view
(= :signing-phrase view)
[signing-phrase/signing-phrase]
(= :share-account view)
[request/share-address]
:else
[view])]]]]])))})))
(views/defview popover []
(views/letsubs [popover [:popover/popover]
{window-height :height} [:dimensions/window]]
[popover-view popover window-height]))

View File

@ -1,18 +1,7 @@
(ns status-im.ui.screens.routing.modals)
(def modal-screens
[;; this route is broken after
;; https://github.com/status-im/status-react/commit/7de2941f26bbfaa4f5948f32dd2ffa4409e1bdcc#diff-290267c339459950d383066cd474a69aL5
#_{:name :wallet-send-modal-stack
:screens [:hardwallet-connect-modal
:enter-pin-modal]
:config {:initialRouteName :wallet-send-transaction-modal}}
{:name :wallet-send-modal-stack-with-onboarding
:screens [:wallet-onboarding-setup-modal
:hardwallet-connect-modal
:enter-pin-modal]
:config {:initialRouteName :wallet-onboarding-setup-modal}}
:chat-modal
[:chat-modal
:show-extension-modal
:stickers-pack-modal
:tribute-learn-more
@ -22,4 +11,4 @@
:wallet-transactions-filter
:profile-qr-viewer
:welcome
:keycard-welcome])
:keycard-welcome])

View File

@ -128,7 +128,6 @@
:recent-recipients wallet.components/recent-recipients
:recipient-qr-code wallet.components/recipient-qr-code
:wallet-send-assets wallet.components/send-assets
:wallet-request-transaction request/request-transaction
:wallet-send-transaction-request request/send-transaction-request
:wallet-request-assets wallet.components/request-assets
:unsigned-transactions wallet-transactions/transactions

View File

@ -15,8 +15,7 @@
:recipient-qr-code
:wallet-send-assets]}
{:name :request-transaction-stack
:screens [:wallet-request-transaction
:wallet-send-transaction-request
:screens [:wallet-send-transaction-request
:wallet-request-assets
:recent-recipients]}
:unsigned-transactions

View File

@ -16,6 +16,7 @@
[status-im.ui.screens.home.sheet.views :as home.sheet]
[status-im.ui.screens.routing.core :as routing]
[status-im.ui.screens.signing.views :as signing]
[status-im.ui.screens.popover.views :as popover]
[status-im.utils.dimensions :as dimensions]
status-im.ui.screens.wallet.collectibles.etheremon.views
status-im.ui.screens.wallet.collectibles.cryptostrikers.views
@ -146,4 +147,5 @@
:persistNavigationState (when js/goog.DEBUG persist-state)
:loadNavigationState (when js/goog.DEBUG load-state)}]
[signing/signing]
[bottom-sheet]]))})))
[bottom-sheet]
[popover/popover]]))})))

View File

@ -58,14 +58,14 @@
:color (colors/alpha colors/white 0.7)}}
(ethereum/normalized-address address)]]
[react/view {:position :absolute :top 12 :right 12}
[react/touchable-highlight {:on-press #(re-frame/dispatch [:wallet.accounts/share])}
[react/touchable-highlight {:on-press #(re-frame/dispatch [:show-popover {:view :share-account}])}
[icons/icon :main-icons/share {:color colors/white
:accessibility-label :share-wallet-address-icon}]]]
[react/view {:height 52 :background-color (colors/alpha colors/black 0.2)
:border-bottom-right-radius 8 :border-bottom-left-radius 8 :flex-direction :row}
[button (i18n/label :t/wallet-send) :main-icons/send #(re-frame/dispatch [:navigate-to :wallet-send-transaction])]
[react/view {:style styles/divider}]
[button (i18n/label :t/receive) :main-icons/receive #(re-frame/dispatch [:navigate-to :wallet-request-transaction])]]]))
[button (i18n/label :t/receive) :main-icons/receive #(re-frame/dispatch [:show-popover {:view :share-account}])]]]))
(views/defview transactions []
(views/letsubs [{:keys [transaction-history-sections]}

View File

@ -22,9 +22,10 @@
:icon-opts {:color :blue}
:accessibility-label :wallet-set-currency
:on-press #(hide-sheet-and-dispatch [:navigate-to :currency-settings])}]
[action-button/action-button-disabled {:label (i18n/label :t/view-signing)
:icon :main-icons/info
:icon-opts {:color :blue}}]
[action-button/action-button {:label (i18n/label :t/view-signing)
:icon :main-icons/info
:on-press #(hide-sheet-and-dispatch [:show-popover {:view :signing-phrase}])
:icon-opts {:color :blue}}]
(when-not seed-backed-up?
[action-button/action-button {:label (i18n/label :t/wallet-backup-recovery-title)
:icon :main-icons/security
@ -45,7 +46,7 @@
:icon :main-icons/receive
:accessibility-label :receive-transaction-button
:icon-opts {:color :blue}
:on-press #(hide-sheet-and-dispatch [:navigate-to :wallet-request-transaction])}]])
:on-press #(hide-sheet-and-dispatch [:show-popover {:view :share-account}])}]])
(defn add-account []
[react/view

View File

@ -38,7 +38,7 @@
[{:style {:color colors/white}} portfolio-value]
" "
(:code currency)]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:wallet.accounts/share])}
[react/touchable-highlight {:on-press #(re-frame/dispatch [:show-popover {:view :share-account}])}
[icons/icon :main-icons/share {:color colors/white}]]]
[react/view
[react/text {:style {:color colors/white :font-weight "500" :line-height 22}} name]

View File

@ -1,12 +1,20 @@
(ns status-im.ui.screens.wallet.navigation
(:require [status-im.constants :as constants]
[status-im.ui.screens.navigation :as navigation]))
[status-im.ui.screens.navigation :as navigation]
[status-im.ui.screens.wallet.signing-phrase.views :as signing-phrase]))
(def transaction-send-default
{:method constants/web3-send-transaction
:symbol :ETH})
(defmethod navigation/preload-data! :wallet-request-transaction
(defmethod navigation/preload-data! :wallet-stack
[db [event]]
(let [wallet-set-up-passed? (get-in db [:account/account :wallet-set-up-passed?])]
(if (or (= event :navigate-back) wallet-set-up-passed?)
db
(assoc db :popover/popover {:view [signing-phrase/signing-phrase]}))))
(defmethod navigation/preload-data! :wallet-send-transaction-request
[db [event]]
(if (= event :navigate-back)
db

View File

@ -8,25 +8,26 @@
[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.styles :as components.styles]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.screens.wallet.components.views :as wallet.components]
[status-im.ui.screens.wallet.request.styles :as styles]
[status-im.wallet.utils :as wallet.utils]
[status-im.utils.utils :as utils])
[status-im.utils.utils :as utils]
[status-im.ui.components.colors :as colors]
[reagent.core :as reagent]
[status-im.ui.components.common.common :as components.common])
(:require-macros [status-im.utils.views :as views]))
(views/defview send-transaction-request []
;; TODO(jeluard) both send and request flows should be merged
(views/letsubs [chain [:ethereum/chain-keyword]
(views/letsubs [chain [:ethereum/chain-keyword]
{:keys [amount amount-error amount-text symbol to
to-name public-key]} [:wallet.request/transaction]
network-status [:network-status]
all-tokens [:wallet/all-tokens]
scroll (atom nil)]
to-name public-key]} [:wallet.request/transaction]
network-status [:network-status]
all-tokens [:wallet/all-tokens]
scroll (atom nil)]
(let [{:keys [decimals] :as token} (tokens/asset-for all-tokens chain symbol)]
[wallet.components/simple-screen {:avoid-keyboard? true}
[wallet.components/toolbar (i18n/label :t/new-request)]
@ -52,7 +53,7 @@
:on-change-text #(re-frame/dispatch [:wallet.request/set-and-validate-amount % symbol decimals])}}
token]]]
[bottom-buttons/bottom-buttons styles/bottom-buttons
nil ;; Force a phantom button to ensure consistency with other transaction screens which define 2 buttons
nil ;; Force a phantom button to ensure consistency with other transaction screens which define 2 buttons
[button/button {:disabled? (or amount-error (not (and to amount)))
:on-press #(re-frame/dispatch [:wallet-send-request public-key amount
(wallet.utils/display-symbol token) decimals])
@ -61,29 +62,29 @@
(i18n/label :t/send-request)
[vector-icons/icon :main-icons/next {:color :white}]]]]])))
(defn send-transaction-request-button [value]
[button/primary-button {:on-press #(re-frame/dispatch [:navigate-to :wallet-send-transaction-request])
:style styles/send-request
:accessibility-label :sent-transaction-request-button}
(i18n/label :t/send-transaction-request)])
(views/defview request-transaction []
(views/defview share-address []
(views/letsubs [address-hex [:account/hex-address]
chain-id [:get-network-id]]
[wallet.components/simple-screen
[wallet.components/toolbar {:transparent? true}
wallet.components/default-action
(i18n/label :t/receive)
[toolbar/actions [{:icon :main-icons/share
:icon-opts {:color :white
:accessibility-label :share-button}
:handler #(list-selection/open-share {:message (eip55/address->checksum address-hex)})}]]]
[react/view {:flex 1}
[common/network-info {:text-color :white}]
[qr-code-viewer/qr-code-viewer
{:hint-style styles/hint
:footer-style styles/footer
:footer-button send-transaction-request-button
:value (eip681/generate-uri address-hex {:chain-id chain-id})
:hint (i18n/label :t/request-qr-legend)
:legend (eip55/address->checksum address-hex)}]]]))
chain-id [:get-network-id]
width (reagent/atom nil)]
[react/view
[react/view {:style {:padding-top 16 :padding-left 16 :padding-right 16}}
(when @width
[qr-code-viewer/qr-code-view (- @width 32) (eip681/generate-uri address-hex {:chain-id chain-id})])
[react/text {:style {:font-size 13 :color colors/gray :margin-top 12 :margin-bottom 4}}
(i18n/label :t/ens-wallet-address)]
[react/view {:on-layout #(reset! width (-> % .-nativeEvent .-layout .-width))}
[react/text {:number-of-lines 1 :ellipsize-mode :middle
:style {:line-height 22 :font-size 15
:font-family "monospace"}}
(eip55/address->checksum address-hex)]]]
[react/view {:height 1 :background-color colors/gray-lighter :margin-top 8}]
[react/view {:padding-bottom 16}
[components.common/button {:on-press #(re-frame/dispatch [:wallet.accounts/share])
:button-style {:margin-vertical 20 :margin-horizontal 16}
:label (i18n/label :t/share-address)}]
[components.common/button {:on-press #(do
(re-frame/dispatch [:hide-popover])
(re-frame/dispatch [:navigate-to :wallet-send-transaction-request]))
:accessibility-label :sent-transaction-request-button
:label (i18n/label :t/send-transaction-request)
:background? false}]]]))

View File

@ -0,0 +1,35 @@
(ns status-im.ui.screens.wallet.signing-phrase.views
(:require-macros [status-im.utils.views :as views])
(:require [status-im.ui.components.react :as react]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.icons.vector-icons :as icons]
[status-im.ui.components.common.common :as components.common]
[status-im.i18n :as i18n]
[re-frame.core :as re-frame]))
(views/defview signing-phrase []
(views/letsubs [phrase [:signing/phrase]
{:keys [wallet-set-up-passed?]} [:account/account]]
[react/view
[react/view {:margin-top 24 :margin-horizontal 24 :align-items :center}
[react/view {:background-color colors/blue-light :width 32 :height 32 :border-radius 16
:align-items :center :justify-content :center}
[icons/icon :main-icons/security {:color colors/blue}]]
[react/text {:style {:typography :title-bold :margin-top 16 :margin-bottom 8}}
(i18n/label :t/this-is-you-signing)]
[react/text {:style {:color colors/gray :text-align :center}} (i18n/label :t/three-words-description)]]
[react/view {:margin-vertical 16 :height 52 :background-color colors/gray-lighter :align-items :center :justify-content :center}
[react/text phrase]]
[react/view {:margin-bottom 24 :margin-horizontal 24 :align-items :center}
[react/text {:style {:color colors/gray :text-align :center}} (i18n/label :t/three-words-description-2)]
(when-not wallet-set-up-passed?
[components.common/button {:on-press #(re-frame/dispatch [:hide-popover])
:button-style {:margin-top 24}
:label (i18n/label :t/remind-me-later)}])
[components.common/button {:on-press #(do
(when-not wallet-set-up-passed?
(re-frame/dispatch [:accounts.ui/wallet-set-up-confirmed]))
(re-frame/dispatch [:hide-popover]))
:button-style {:margin-top 24}
:background? false
:label (i18n/label :t/ok-got-it)}]]]))

View File

@ -84,11 +84,8 @@
(extensions.module/load cofx url false))
(fx/defn handle-eip681 [cofx url]
(let [wallet-set-up-passed? (get-in cofx [:db :account/account :wallet-set-up-passed?])]
(if (not wallet-set-up-passed?)
{:dispatch [:navigate-to :wallet-onboarding-setup]}
{:dispatch-n [[:navigate-to :wallet-send-transaction]
[:wallet/fill-request-from-url url :deep-link]]})))
{:dispatch-n [[:navigate-to :wallet-send-transaction]
[:wallet/fill-request-from-url url :deep-link]]})
(defn handle-not-found [full-url]
(log/info "universal-links: no handler for " full-url))

View File

@ -3,7 +3,8 @@
[status-im.ethereum.core :as ethereum]
[status-im.utils.fx :as fx]
[status-im.ethereum.eip55 :as eip55]
[status-im.ui.components.list-selection :as list-selection]))
[status-im.ui.components.list-selection :as list-selection]
[status-im.utils.handlers :as handlers]))
(re-frame/reg-fx
:list.selection/open-share

View File

@ -1199,7 +1199,12 @@
"set-currency" : "Set currency",
"view-signing" : "View signing phrase",
"history" : "History",
"share-address": "Share address",
"no-collectibles" : "No collectibles available",
"this-is-you-signing": "This is your signing phrase",
"three-words-description": "You should see these 3 words before signing each transaction",
"three-words-description-2": "If you see a different combo, cancel the transaction and logout.",
"remind-me-later": "Remind me later",
"keycard-onboarding-intro-header": "Store your key on Keycard",
"keycard-onboarding-intro-text": "A secure, contactless, open source Hardwallet. Android only.",
"learn-more-about-keycard": "Learn more about Keycard",