[Fix #3394] Add accessibility labels for Wallet screens
Signed-off-by: Julien Eluard <julien.eluard@gmail.com>
This commit is contained in:
parent
25ac067375
commit
2653cebd7d
|
@ -3,12 +3,14 @@
|
|||
[status-im.ui.components.react :as react]
|
||||
[status-im.utils.platform :as platform]))
|
||||
|
||||
(defn button [{:keys [on-press style disabled? fit-to-text? text-style] :or {fit-to-text? true}} label icon]
|
||||
(defn button [{:keys [on-press style disabled? fit-to-text? text-style accessibility-label] :or {fit-to-text? true}} label icon]
|
||||
[react/touchable-highlight (merge {:underlay-color styles/border-color-high}
|
||||
(when-not fit-to-text?
|
||||
{:style styles/button-container})
|
||||
(when (and on-press (not disabled?))
|
||||
{:on-press on-press}))
|
||||
{:on-press on-press})
|
||||
(when accessibility-label
|
||||
{:accessibility-label accessibility-label}))
|
||||
[react/view {:style (merge styles/button
|
||||
style)}
|
||||
[react/text {:style (merge styles/button-text
|
||||
|
|
|
@ -3,12 +3,14 @@
|
|||
[status-im.ui.components.react :as react]
|
||||
[status-im.utils.platform :as platform]))
|
||||
|
||||
(defn checkbox [{:keys [on-value-change checked?]}]
|
||||
(defn checkbox [{:keys [on-value-change checked? accessibility-label] :or {accessibility-label :checkbox}}]
|
||||
(if platform/android?
|
||||
[react/view {:style styles/wrapper}
|
||||
[react/check-box {:on-value-change on-value-change
|
||||
:value checked?}]]
|
||||
[react/touchable-highlight (merge {:style styles/wrapper}
|
||||
[react/check-box {:on-value-change on-value-change
|
||||
:value checked?
|
||||
:accessibility-label accessibility-label}]]
|
||||
[react/touchable-highlight (merge {:style styles/wrapper
|
||||
:accessibility-label accessibility-label}
|
||||
(when on-value-change {:on-press #(on-value-change (not checked?))}))
|
||||
[react/view (styles/icon-check-container checked?)
|
||||
(when checked?
|
||||
|
|
|
@ -60,13 +60,17 @@
|
|||
:style (merge styles/item-image image-style)}]])
|
||||
|
||||
(defn item-primary
|
||||
[primary]
|
||||
[react/text {:style styles/primary-text} primary])
|
||||
([s] (item-primary nil s))
|
||||
([{:keys [style] :as props} s]
|
||||
[react/text (merge {:style styles/primary-text}
|
||||
(dissoc props :style))
|
||||
s]))
|
||||
|
||||
(defn item-primary-only
|
||||
([s] (item-primary-only nil s))
|
||||
([{:keys [style]} s]
|
||||
[react/text {:style (merge styles/primary-text-only style)}
|
||||
([{:keys [style] :as props} s]
|
||||
[react/text (merge {:style (merge styles/primary-text-only style)}
|
||||
(dissoc props :style))
|
||||
s]))
|
||||
|
||||
(defn item-secondary
|
||||
|
@ -176,10 +180,10 @@
|
|||
:renderSectionHeader (wrap-render-section-header-fn render-section-header-fn)}
|
||||
(when platform/ios? {:SectionSeparatorComponent (fn [] (reagent/as-element section-separator))}))])
|
||||
|
||||
(defn- render-action [{:keys [label icon action disabled?]}
|
||||
(defn- render-action [{:keys [label accessibility-label icon action disabled?]}
|
||||
{:keys [action-style action-label-style icon-opts]}]
|
||||
[react/touchable-highlight {:on-press action}
|
||||
[react/view
|
||||
[react/view {:accessibility-label accessibility-label}
|
||||
[item
|
||||
[item-icon {:icon icon
|
||||
:style (merge styles/action
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
(defn- footer [style value]
|
||||
[react/view styles/footer
|
||||
[react/view styles/wallet-info
|
||||
[react/text {:style (merge styles/hash-value-text style)}
|
||||
[react/text {:style (merge styles/hash-value-text style)
|
||||
:accessibility-label :address-text}
|
||||
value]]])
|
||||
|
||||
(defn qr-code-viewer [{:keys [style hint-style footer-style]} value hint legend]
|
||||
|
@ -23,7 +24,8 @@
|
|||
hint]
|
||||
(when width
|
||||
(let [size (int (* 0.7 (min width height)))]
|
||||
[react/view {:style (styles/qr-code-container size)}
|
||||
[react/view {:style (styles/qr-code-container size)
|
||||
:accessibility-label :qr-code-image}
|
||||
[qr-code {:value value
|
||||
:size (- size (* 2 styles/qr-code-padding))}]]))
|
||||
[footer footer-style legend]]))
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
(defn back [handler]
|
||||
{:icon :icons/back
|
||||
:handler handler
|
||||
:accessibility-label :toolbar-back-button})
|
||||
:accessibility-label :back-button})
|
||||
|
||||
(def default-handler #(re-frame/dispatch [:navigate-back]))
|
||||
|
||||
|
@ -22,9 +22,10 @@
|
|||
(back default-handler))
|
||||
|
||||
(defn back-white [handler]
|
||||
{:icon :icons/back
|
||||
:icon-opts {:color :white}
|
||||
:handler handler})
|
||||
{:icon :icons/back
|
||||
:icon-opts {:color :white}
|
||||
:handler handler
|
||||
:accessibility-label :back-button})
|
||||
|
||||
(defn close [handler]
|
||||
{:icon :icons/close
|
||||
|
|
|
@ -72,11 +72,13 @@
|
|||
|
||||
;; Actions
|
||||
|
||||
(defn text-action [{:keys [style handler disabled?]} title]
|
||||
[react/text {:style (merge styles/item styles/item-text-action style
|
||||
(when disabled? styles/toolbar-text-action-disabled))
|
||||
:on-press (when-not disabled? handler)
|
||||
:uppercase? components.styles/uppercase?}
|
||||
(defn text-action [{:keys [style handler disabled? accessibility-label]} title]
|
||||
[react/text (cond-> {:style (merge styles/item styles/item-text style
|
||||
(when disabled? styles/toolbar-text-action-disabled))
|
||||
:on-press (when-not disabled? handler)
|
||||
:uppercase? components.styles/uppercase?}
|
||||
accessibility-label
|
||||
(assoc :accessibility-label accessibility-label))
|
||||
title])
|
||||
|
||||
(def blank-action [react/view {:style (merge styles/item styles/toolbar-action)}])
|
||||
|
|
|
@ -50,7 +50,8 @@
|
|||
[react/view {:style styles/qr-code}
|
||||
[status-bar/status-bar {:type :transparent}]
|
||||
[toolbar-view camera-flashlight]
|
||||
[react/text {:style (styles/qr-code-text dimensions)}
|
||||
[react/text {:style (styles/qr-code-text dimensions)
|
||||
:accessibility-label :scan-qr-code-with-wallet-address-text}
|
||||
(i18n/label :t/scan-qr-code)]
|
||||
[react/view {:style styles/qr-container
|
||||
:pointer-events :none}
|
||||
|
@ -63,5 +64,7 @@
|
|||
:onBarCodeRead #(re-frame/dispatch [:wallet/fill-request-from-url (camera/get-qr-code-data %) nil])}]]
|
||||
[viewfinder dimensions (size dimensions)]]
|
||||
[bottom-buttons/bottom-button
|
||||
[button/button {:disabled? false :on-press #(re-frame/dispatch [:navigate-back])}
|
||||
[button/button {:disabled? false
|
||||
:on-press #(re-frame/dispatch [:navigate-back])
|
||||
:accessibility-label :cancel-button}
|
||||
(i18n/label :t/cancel)]]]))
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
[react/view {:flex 1}
|
||||
content]])
|
||||
|
||||
(defn cartouche [{:keys [disabled? on-press icon] :or {icon :icons/forward} :as m} header content]
|
||||
(defn cartouche [{:keys [disabled? on-press icon icon-opts] :or {icon :icons/forward} :as m} header content]
|
||||
[react/view {:style styles/cartouche-container}
|
||||
[react/text {:style styles/cartouche-header}
|
||||
header]
|
||||
|
@ -69,7 +69,7 @@
|
|||
[react/view styles/cartouche-icon-wrapper
|
||||
[react/view {:flex 1} ;; Let content shrink if needed
|
||||
content]
|
||||
[vector-icons/icon icon {:color :white}]]
|
||||
[vector-icons/icon icon (merge {:color :white} icon-opts)]]
|
||||
content)]]])])
|
||||
|
||||
(defn- cartouche-primary-text [s]
|
||||
|
|
|
@ -80,7 +80,8 @@
|
|||
(let [{:keys [name icon decimals]} (tokens/asset-for (ethereum/network->chain-keyword network) symbol)]
|
||||
[components/cartouche {:disabled? disabled? :on-press #(re-frame/dispatch [:navigate-to (type->view type)])}
|
||||
(i18n/label :t/wallet-asset)
|
||||
[react/view styles/asset-content-container
|
||||
[react/view {:style styles/asset-content-container
|
||||
:accessibility-label :choose-asset-button}
|
||||
[list/item-image (assoc icon :style styles/asset-icon :image-style {:width 32 :height 32})]
|
||||
[react/view styles/asset-text-content
|
||||
[react/view styles/asset-label-content
|
||||
|
@ -92,20 +93,23 @@
|
|||
(str (wallet.utils/format-amount (symbol balance) decimals))]]]])))
|
||||
|
||||
(defn- recipient-address [address]
|
||||
[react/text {:style (merge styles/recipient-address (when-not address styles/recipient-no-address))}
|
||||
[react/text {:style (merge styles/recipient-address (when-not address styles/recipient-no-address))
|
||||
:accessibility-label :recipient-address-text}
|
||||
(or (ethereum/normalized-address address) (i18n/label :t/specify-recipient))])
|
||||
|
||||
(views/defview recipient-contact [address name]
|
||||
(views/defview recipient-contact [address name request?]
|
||||
(views/letsubs [contact [:contact/by-address address]]
|
||||
(let [address? (and (not (nil? address)) (not= address ""))]
|
||||
[react/view styles/recipient-container
|
||||
[react/view styles/recipient-icon
|
||||
[chat-icon/chat-icon (:photo-path contact) {:size list.styles/image-size}]]
|
||||
[react/view styles/recipient-name
|
||||
[react/text {:style (styles/participant true)
|
||||
:number-of-lines 1}
|
||||
[react/view {:style styles/recipient-name}
|
||||
[react/text {:style (styles/participant true)
|
||||
:accessibility-label (if request? :contact-name-text :recipient-name-text)
|
||||
:number-of-lines 1}
|
||||
name]
|
||||
[react/text {:style (styles/participant (and (not name) address?))}
|
||||
[react/text {:style (styles/participant (and (not name) address?))
|
||||
:accessibility-label (if request? :contact-address-text :recipient-address-text)}
|
||||
(ethereum/normalized-address address)]]])))
|
||||
|
||||
(defn render-contact [contact]
|
||||
|
@ -113,8 +117,10 @@
|
|||
[list/item
|
||||
[chat-icon/chat-icon (:photo-path contact) {:size list.styles/image-size}]
|
||||
[list/item-content
|
||||
[list/item-primary (:name contact)]
|
||||
[react/text {:style list.styles/secondary-text}
|
||||
[list/item-primary {:accessibility-label :contact-name-text}
|
||||
(:name contact)]
|
||||
[react/text {:style list.styles/secondary-text
|
||||
:accessibility-label :contact-address-text}
|
||||
(ethereum/normalized-address (:address contact))]]]])
|
||||
|
||||
(views/defview recent-recipients []
|
||||
|
@ -135,10 +141,11 @@
|
|||
[react/view components.styles/flex
|
||||
[components/cartouche {}
|
||||
(i18n/label :t/recipient)
|
||||
[components/text-input {:multiline true
|
||||
:style styles/contact-code-text-input
|
||||
:placeholder (i18n/label :t/recipient-code)
|
||||
:on-change-text #(reset! content %)}]]
|
||||
[components/text-input {:multiline true
|
||||
:style styles/contact-code-text-input
|
||||
:placeholder (i18n/label :t/recipient-code)
|
||||
:on-change-text #(reset! content %)
|
||||
:accessibility-label :recipient-address-input}]]
|
||||
[bottom-buttons/bottom-button
|
||||
[button/button {:disabled? (string/blank? @content)
|
||||
:on-press #(re-frame/dispatch [:wallet/fill-request-from-url @content])}
|
||||
|
@ -162,22 +169,28 @@
|
|||
{:label (i18n/label :t/recipient-code)
|
||||
:action #(re-frame/dispatch [:navigate-to :contact-code])}]))}))
|
||||
|
||||
(defn recipient-selector [{:keys [name address disabled? contact-only?]}]
|
||||
[components/cartouche {:on-press #(on-choose-recipient contact-only?) :disabled? disabled? :icon :icons/dots-horizontal}
|
||||
(defn recipient-selector [{:keys [name address disabled? contact-only? request?]}]
|
||||
[components/cartouche {:on-press #(on-choose-recipient contact-only?)
|
||||
:disabled? disabled?
|
||||
:icon :icons/dots-horizontal
|
||||
:icon-opts {:accessibility-label :choose-contact-button}}
|
||||
(i18n/label :t/wallet-choose-recipient)
|
||||
(if name
|
||||
[recipient-contact address name]
|
||||
[recipient-address address])])
|
||||
[react/view {:accessibility-label :choose-recipient-button}
|
||||
(if name
|
||||
[recipient-contact address name request?]
|
||||
[recipient-address address])]])
|
||||
|
||||
(defn- amount-input [{:keys [input-options disabled?]}]
|
||||
[react/view components.styles/flex
|
||||
[react/view {:style components.styles/flex
|
||||
:accessibility-label :specify-amount-button}
|
||||
[components/text-input
|
||||
(merge
|
||||
(if disabled?
|
||||
{:editable false}
|
||||
{:keyboard-type :numeric
|
||||
:placeholder (i18n/label :t/amount-placeholder)
|
||||
:style components.styles/flex})
|
||||
{:keyboard-type :numeric
|
||||
:placeholder (i18n/label :t/amount-placeholder)
|
||||
:style components.styles/flex
|
||||
:accessibility-label :amount-input})
|
||||
input-options)]])
|
||||
|
||||
(defn amount-selector [{:keys [error disabled?] :as m}]
|
||||
|
|
|
@ -37,7 +37,8 @@
|
|||
[react/view styles/request-details-wrapper
|
||||
[components/recipient-selector {:contact-only? true
|
||||
:address to
|
||||
:name to-name}]
|
||||
:name to-name
|
||||
:request? true}]
|
||||
[components/asset-selector {:disabled? true
|
||||
:symbol :ETH}]
|
||||
[components/amount-selector {:error amount-error
|
||||
|
@ -47,9 +48,10 @@
|
|||
: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}}
|
||||
[button/button {:disabled? (not (and to amount))
|
||||
:on-press #(re-frame/dispatch [:wallet-send-request whisper-identity amount])
|
||||
:text-style {:padding-horizontal 0}
|
||||
:accessibility-label :sent-request-button}
|
||||
(i18n/label :t/send-request)
|
||||
[vector-icons/icon :icons/forward {:color :white}]]]]]))
|
||||
|
||||
|
@ -70,12 +72,14 @@
|
|||
comp/default-action
|
||||
(i18n/label :t/receive)
|
||||
[toolbar/actions [{:icon :icons/share
|
||||
:icon-opts {:color :white}
|
||||
:icon-opts {:color :white
|
||||
:accessibility-label :share-button}
|
||||
: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}
|
||||
[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)]]]]))
|
||||
|
|
|
@ -18,8 +18,9 @@
|
|||
[react/view styles/transaction-sent-container
|
||||
[react/view styles/ok-icon-container
|
||||
[vi/icon :icons/ok {:color components.styles/color-blue4}]]
|
||||
[react/text {:style styles/transaction-sent
|
||||
:font (if platform/android? :medium :default)}
|
||||
[react/text {:style styles/transaction-sent
|
||||
:font (if platform/android? :medium :default)
|
||||
:accessibility-label :transaction-sent-text}
|
||||
(i18n/label :t/transaction-sent)]
|
||||
[react/view styles/gap]
|
||||
[react/text {:style styles/transaction-sent-description} (i18n/label :t/transaction-description)]]
|
||||
|
@ -27,14 +28,15 @@
|
|||
;; TODO (andrey) uncomment when will be implemented
|
||||
#_[react/touchable-highlight {:on-press #()}; TODO (andrey) #(re-frame/dispatch [:navigate-to-clean :wallet-transaction-details])}
|
||||
[react/view styles/transaction-details-container
|
||||
[react/text {:style styles/transaction-details
|
||||
[react/text {:style styles/transaction-details
|
||||
:font (if platform/android? :medium :default)
|
||||
:uppercase? (get-in platform/platform-specific [:uppercase?])}
|
||||
(i18n/label :t/view-transaction-details)]]]
|
||||
[components/separator]
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch close-transaction-screen-event)}
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch close-transaction-screen-event)
|
||||
:accessibility-label :got-it-button}
|
||||
[react/view styles/got-it-container
|
||||
[react/text {:style styles/got-it
|
||||
[react/text {:style styles/got-it
|
||||
:font (if platform/android? :medium :default)
|
||||
:uppercase? (get-in platform/platform-specific [:uppercase?])}
|
||||
(i18n/label :t/got-it)]]]]))
|
||||
|
|
|
@ -41,7 +41,9 @@
|
|||
[react/animated-view {:style (styles/animated-sign-panel bottom-value)}
|
||||
[react/animated-view {:style (styles/sign-panel opacity-value)}
|
||||
[react/view styles/signing-phrase-container
|
||||
[react/text {:style styles/signing-phrase} signing-phrase]]
|
||||
[react/text {:style styles/signing-phrase
|
||||
:accessibility-label :signing-phrase-text}
|
||||
signing-phrase]]
|
||||
[react/text {:style styles/signing-phrase-description} (i18n/label :t/signing-phrase-description)]
|
||||
[react/view styles/password-container
|
||||
[react/text-input
|
||||
|
@ -50,7 +52,8 @@
|
|||
:placeholder (i18n/label :t/enter-password)
|
||||
:placeholder-text-color components.styles/color-gray4
|
||||
:on-change-text #(re-frame/dispatch [:wallet.send/set-password %])
|
||||
:style styles/password}]]]
|
||||
:style styles/password
|
||||
:accessibility-label :enter-password-input}]]]
|
||||
(when wrong-password?
|
||||
[tooltip/tooltip (i18n/label :t/wrong-password)])]))
|
||||
|
||||
|
@ -59,11 +62,13 @@
|
|||
(letsubs [sign-enabled? [:wallet.send/sign-password-enabled?]]
|
||||
[bottom-buttons/bottom-buttons
|
||||
styles/sign-buttons
|
||||
[button/button {:style components.styles/flex
|
||||
:on-press cancel-handler}
|
||||
[button/button {:style components.styles/flex
|
||||
:on-press cancel-handler
|
||||
:accessibility-label :cancel-button}
|
||||
(i18n/label :t/cancel)]
|
||||
[button/button {:style (wallet.styles/button-container sign-enabled?)
|
||||
:on-press sign-handler}
|
||||
[button/button {:style (wallet.styles/button-container sign-enabled?)
|
||||
:on-press sign-handler
|
||||
:accessibility-label :sign-transaction-button}
|
||||
(i18n/label :t/transactions-sign-transaction)
|
||||
[vector-icons/icon :icons/forward {:color :white}]]]))
|
||||
|
||||
|
@ -80,13 +85,15 @@
|
|||
[bottom-buttons/bottom-buttons
|
||||
styles/sign-buttons
|
||||
(when sign-enabled?
|
||||
[button/button {:style components.styles/flex
|
||||
:on-press sign-later-handler}
|
||||
[button/button {:style components.styles/flex
|
||||
:on-press sign-later-handler
|
||||
:accessibility-label :sign-later-button}
|
||||
(i18n/label :t/transactions-sign-later)])
|
||||
[button/button {:style components.styles/flex
|
||||
:disabled? (not immediate-sign-enabled?)
|
||||
:on-press #(re-frame/dispatch [:wallet.send/set-signing? true])
|
||||
:text-style {:color :white}}
|
||||
[button/button {:style components.styles/flex
|
||||
:disabled? (not immediate-sign-enabled?)
|
||||
:on-press #(re-frame/dispatch [:wallet.send/set-signing? true])
|
||||
:text-style {:color :white}
|
||||
:accessibility-label :sign-transaction-button}
|
||||
(i18n/label :t/transactions-sign-transaction)
|
||||
[vector-icons/icon :icons/forward {:color (if immediate-sign-enabled? :white :gray)}]]]))
|
||||
|
||||
|
@ -117,14 +124,16 @@
|
|||
[wallet.components/cartouche {}
|
||||
(i18n/label :t/gas-limit)
|
||||
[react/text-input (merge styles/transaction-fee-input
|
||||
{:on-change-text #(re-frame/dispatch [:wallet.send/edit-gas %])
|
||||
:default-value (str (money/to-fixed gas))})]]
|
||||
{:on-change-text #(re-frame/dispatch [:wallet.send/edit-gas %])
|
||||
:default-value (str (money/to-fixed gas))
|
||||
:accessibility-label :gas-limit-input})]]
|
||||
[wallet.components/cartouche {}
|
||||
(i18n/label :t/gas-price)
|
||||
[react/view styles/advanced-options-wrapper
|
||||
[react/text-input (merge styles/transaction-fee-input
|
||||
{:on-change-text #(re-frame/dispatch [:wallet.send/edit-gas-price (money/->wei :gwei %)])
|
||||
:default-value (str (money/to-fixed (money/wei-> :gwei gas-price)))})]
|
||||
{:on-change-text #(re-frame/dispatch [:wallet.send/edit-gas-price (money/->wei :gwei %)])
|
||||
:default-value (str (money/to-fixed (money/wei-> :gwei gas-price)))
|
||||
:accessibility-label :gas-price-input})]
|
||||
[wallet.components/cartouche-secondary-text
|
||||
(i18n/label :t/gwei)]]]]
|
||||
[react/view styles/transaction-fee-info
|
||||
|
@ -134,18 +143,22 @@
|
|||
[react/view styles/transaction-fee-block-wrapper
|
||||
[wallet.components/cartouche {:disabled? true}
|
||||
(i18n/label :t/amount)
|
||||
[wallet.components/cartouche-text-content
|
||||
(str (money/to-fixed (money/wei->ether amount)))
|
||||
(name symbol)]]
|
||||
[react/view {:accessibility-label :amount-input}
|
||||
[wallet.components/cartouche-text-content
|
||||
(str (money/to-fixed (money/wei->ether amount)))
|
||||
(name symbol)]]]
|
||||
[wallet.components/cartouche {:disabled? true}
|
||||
(i18n/label :t/wallet-transaction-total-fee)
|
||||
[wallet.components/cartouche-text-content
|
||||
(str (money/to-fixed (max-fee gas gas-price)))
|
||||
(i18n/label :t/eth)]]]
|
||||
[react/view {:accessibility-label :total-fee-input}
|
||||
[wallet.components/cartouche-text-content
|
||||
(str (money/to-fixed (max-fee gas gas-price)))
|
||||
(i18n/label :t/eth)]]]]
|
||||
[bottom-buttons/bottom-buttons styles/fee-buttons
|
||||
[button/button {:on-press #(re-frame/dispatch [:wallet.send/reset-gas-default])}
|
||||
[button/button {:on-press #(re-frame/dispatch [:wallet.send/reset-gas-default])
|
||||
:accessibility-label :reset-to-default-button}
|
||||
(i18n/label :t/reset-default)]
|
||||
[button/button {:on-press #(do (re-frame/dispatch [:wallet.send/set-gas-details gas gas-price]) (act/default-handler))}
|
||||
[button/button {:on-press #(do (re-frame/dispatch [:wallet.send/set-gas-details gas gas-price]) (act/default-handler))
|
||||
:accessibility-label :done-button}
|
||||
(i18n/label :t/done)]]]])))
|
||||
|
||||
(defn- advanced-cartouche [{:keys [gas gas-price]} modal?]
|
||||
|
@ -154,7 +167,8 @@
|
|||
:on-press #(do (re-frame/dispatch [:wallet.send/clear-gas])
|
||||
(re-frame/dispatch [:navigate-to-modal :wallet-transaction-fee]))}
|
||||
(i18n/label :t/wallet-transaction-fee)
|
||||
[react/view styles/advanced-options-text-wrapper
|
||||
[react/view {:style styles/advanced-options-text-wrapper
|
||||
:accessibility-label :transaction-fee-button}
|
||||
[react/text {:style styles/advanced-fees-text}
|
||||
(str (money/to-fixed (max-fee gas gas-price)) " " (i18n/label :t/eth))]
|
||||
[react/text {:style styles/advanced-fees-details-text}
|
||||
|
@ -164,7 +178,8 @@
|
|||
[react/view {:style styles/advanced-wrapper}
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:wallet.send/toggle-advanced (not advanced?)])}
|
||||
[react/view {:style styles/advanced-button-wrapper}
|
||||
[react/view {:style styles/advanced-button}
|
||||
[react/view {:style styles/advanced-button
|
||||
:accessibility-label :advanced-button}
|
||||
[react/text {:style (merge wallet.components.styles/label styles/advanced-label)}
|
||||
(i18n/label :t/wallet-advanced)]
|
||||
[vector-icons/icon (if advanced? :icons/up :icons/down) {:color :white}]]]]
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
[react/view (merge components.styles/flex {:background-color :white})
|
||||
[status-bar/status-bar {:type :modal-wallet}]
|
||||
[toolbar/toolbar #_{} {:style wallet.styles/toolbar}
|
||||
[toolbar/nav-text {:style {:color :white}}
|
||||
[toolbar/nav-text {:style {:color :white}
|
||||
:accessibility-label :done-button}
|
||||
(i18n/label :t/done)]
|
||||
[toolbar/content-title {:color :white}
|
||||
(i18n/label :t/wallet-assets)]]
|
||||
|
|
|
@ -18,10 +18,11 @@
|
|||
(re-frame/dispatch [:wallet/discard-unsigned-transaction-with-confirmation id]))
|
||||
|
||||
(defn history-action [filter?]
|
||||
(merge
|
||||
{:icon :icons/filter
|
||||
:handler #(re-frame/dispatch [:navigate-to-modal :wallet-transactions-filter])}
|
||||
(when filter? {:icon-opts {:overlay-style styles/corner-dot}})))
|
||||
(cond->
|
||||
{:icon :icons/filter
|
||||
:icon-opts {:accessibility-label :filters-button}
|
||||
:handler #(re-frame/dispatch [:navigate-to-modal :wallet-transactions-filter])}
|
||||
filter? (assoc-in [:icon-opts :overlay-style] styles/corner-dot)))
|
||||
|
||||
(defn- all-checked? [filter-data]
|
||||
(and (every? :checked? (:type filter-data))
|
||||
|
@ -39,10 +40,12 @@
|
|||
|
||||
(defn action-buttons [{:keys [id] :as transaction}]
|
||||
[react/view {:style styles/action-buttons}
|
||||
[button/primary-button {:style {:margin-right 12}
|
||||
:on-press #(re-frame/dispatch [:wallet/show-sign-transaction id])}
|
||||
[button/primary-button {:style {:margin-right 12}
|
||||
:on-press #(re-frame/dispatch [:wallet/show-sign-transaction id])
|
||||
:accessibility-label :sign-button}
|
||||
(i18n/label :t/transactions-sign)]
|
||||
[button/secondary-button {:on-press #(on-delete-transaction transaction)}
|
||||
[button/secondary-button {:on-press #(on-delete-transaction transaction)
|
||||
:accessibility-label :delete-button}
|
||||
(i18n/label :t/delete)]])
|
||||
|
||||
(defn- inbound? [type] (= :inbound type))
|
||||
|
@ -62,36 +65,46 @@
|
|||
(throw (str "Unknown transaction type: " k))))
|
||||
|
||||
(defn render-transaction [{:keys [hash from-contact to-contact to from type value time-formatted] :as transaction}]
|
||||
(let [[label contact address] (if (inbound? type)
|
||||
[(i18n/label :t/from) from-contact from]
|
||||
[(i18n/label :t/to) to-contact to])]
|
||||
(let [[label contact address
|
||||
contact-accessibility-label
|
||||
address-accessibility-label] (if (inbound? type)
|
||||
[(i18n/label :t/from) from-contact from :sender-text :sender-address-text]
|
||||
[(i18n/label :t/to) to-contact to :recipient-name-text :recipient-address-text])
|
||||
unsigned? (unsigned? type)]
|
||||
[list/touchable-item #(re-frame/dispatch [:show-transaction-details hash])
|
||||
[react/view
|
||||
[react/view {:accessibility-label (if unsigned? :unsigned-transaction-item :transaction-item)}
|
||||
[list/item
|
||||
[list/item-icon (transaction-type->icon (keyword type))]
|
||||
[list/item-content
|
||||
[react/view {:style styles/amount-time}
|
||||
[react/text {:style styles/tx-amount
|
||||
:ellipsize-mode "tail"
|
||||
[react/text {:style styles/tx-amount
|
||||
:ellipsize-mode "tail"
|
||||
:number-of-lines 1}
|
||||
(money/wei->str :eth value)]
|
||||
[react/text {:accessibility-label :amount-text}
|
||||
(->> value (money/wei-> :eth) money/to-fixed str)]
|
||||
" "
|
||||
[react/text {:accessibility-label :currency-text}
|
||||
(clojure.string/upper-case (name :eth))]]
|
||||
[react/text {:style styles/tx-time}
|
||||
time-formatted]]
|
||||
[react/view {:style styles/address-row}
|
||||
[react/text {:style styles/address-label}
|
||||
label]
|
||||
(when contact
|
||||
[react/text {:style styles/address-contact}
|
||||
[react/text {:style styles/address-contact
|
||||
:accessibility-label contact-accessibility-label}
|
||||
contact])
|
||||
[react/text {:style styles/address-hash
|
||||
:ellipsize-mode "middle"
|
||||
:number-of-lines 1}
|
||||
[react/text {:style styles/address-hash
|
||||
:ellipsize-mode "middle"
|
||||
:number-of-lines 1
|
||||
:accessibility-label address-accessibility-label}
|
||||
address]]
|
||||
(when (unsigned? type)
|
||||
(when unsigned?
|
||||
[action-buttons transaction])]
|
||||
[list/item-icon {:icon :icons/forward
|
||||
:style {:margin-top 10}
|
||||
:icon-opts styles/forward}]]]]))
|
||||
[list/item-icon {:icon :icons/forward
|
||||
:style {:margin-top 10}
|
||||
:icon-opts (merge styles/forward
|
||||
{:accessibility-label :show-transaction-button})}]]]]))
|
||||
|
||||
(defn filtered-transaction? [transaction filter-data]
|
||||
(:checked? (some #(when (= (:type transaction) (:id %)) %) (:type filter-data))))
|
||||
|
@ -119,23 +132,26 @@
|
|||
[react/view {:style components.styles/flex}
|
||||
[list/flat-list {:data transactions
|
||||
:render-fn render-transaction
|
||||
:empty-component [react/text {:style styles/empty-text}
|
||||
:empty-component [react/text {:style styles/empty-text
|
||||
:accessibility-label :no-unsigned-transactions-text}
|
||||
(i18n/label :t/transactions-unsigned-empty)]}]]))
|
||||
|
||||
;; Filter history
|
||||
|
||||
(defn- item-filter [{:keys [icon checked? path]} content]
|
||||
[list/list-item-with-checkbox
|
||||
{:checked? checked?
|
||||
:on-value-change #(re-frame/dispatch [:wallet.transactions/filter path %])}
|
||||
[list/item
|
||||
[list/item-icon icon]
|
||||
content]])
|
||||
[react/view {:accessibility-label :filter-item}
|
||||
[list/list-item-with-checkbox
|
||||
{:checked? checked?
|
||||
:on-value-change #(re-frame/dispatch [:wallet.transactions/filter path %])}
|
||||
[list/item
|
||||
[list/item-icon icon]
|
||||
content]]])
|
||||
|
||||
(defn- render-item-filter [{:keys [id label checked?]}]
|
||||
[item-filter {:icon (transaction-type->icon id) :checked? checked? :path {:type id}}
|
||||
[list/item-content
|
||||
[list/item-primary-only label]]])
|
||||
[list/item-primary-only {:accessibility-label :filter-name-text}
|
||||
label]]])
|
||||
|
||||
(defn- wrap-filter-data [m]
|
||||
[{:title (i18n/label :t/transactions-filter-type)
|
||||
|
@ -148,27 +164,31 @@
|
|||
[react/view styles/filter-container
|
||||
[status-bar/status-bar {:type :modal-white}]
|
||||
[toolbar/toolbar {}
|
||||
[toolbar/nav-clear-text (i18n/label :t/done)]
|
||||
[toolbar/nav-clear-text {:accessibility-label :done-button} (i18n/label :t/done)]
|
||||
[toolbar/content-title (i18n/label :t/transactions-filter-title)]
|
||||
[toolbar/text-action {:handler #(re-frame/dispatch [:wallet.transactions/filter-all])
|
||||
:disabled? (all-checked? filter-data)}
|
||||
[toolbar/text-action {:handler #(re-frame/dispatch [:wallet.transactions/filter-all])
|
||||
:disabled? (all-checked? filter-data)
|
||||
:accessibility-label :select-all-button}
|
||||
(i18n/label :t/transactions-filter-select-all)]]
|
||||
[react/view {:style (merge {:background-color :white} components.styles/flex)}
|
||||
[react/view {:style (merge {:background-color :white} components.styles/flex)}
|
||||
[list/section-list {:sections (wrap-filter-data filter-data)}]]]))
|
||||
|
||||
(defn history-tab [active?]
|
||||
[react/text {:uppercase? true
|
||||
:style (styles/tab-title active?)}
|
||||
[react/text {:uppercase? true
|
||||
:style (styles/tab-title active?)
|
||||
:accessibility-label :history-button}
|
||||
(i18n/label :t/transactions-history)])
|
||||
|
||||
(defview unsigned-tab [active?]
|
||||
(letsubs [unsigned-transactions-count [:wallet.transactions/unsigned-transactions-count]]
|
||||
[react/view {:flex-direction :row}
|
||||
[react/text {:style (styles/tab-title active?)
|
||||
:uppercase? true}
|
||||
[react/text {:style (styles/tab-title active?)
|
||||
:uppercase? true
|
||||
:accessibility-label :unsigned-transactions-button}
|
||||
(i18n/label :t/transactions-unsigned)]
|
||||
(when (pos? unsigned-transactions-count)
|
||||
[react/text {:style styles/tab-unsigned-transactions-count}
|
||||
[react/text {:style styles/tab-unsigned-transactions-count
|
||||
:accessibility-label :unsigned-transactions-counter-text}
|
||||
(str " " unsigned-transactions-count)])]))
|
||||
|
||||
(def tabs-list
|
||||
|
@ -201,11 +221,16 @@
|
|||
:unsigned-transactions unsigned-list
|
||||
react/view)]]))
|
||||
|
||||
(defn- pretty-print-asset [symbol amount]
|
||||
(case symbol
|
||||
;; TODO (jeluard) Format tokens amount once tokens history is supported
|
||||
:ETH (if amount (money/wei->str :eth amount) "...")
|
||||
(throw (str "Unknown asset symbol: " symbol))))
|
||||
(defn- pretty-print-asset [symbol amount & [with-currency?]]
|
||||
(let [token (case symbol
|
||||
;; TODO (jeluard) Format tokens amount once tokens history is supported
|
||||
:ETH :eth
|
||||
(throw (str "Unknown asset symbol: " symbol)))]
|
||||
(if amount
|
||||
(if with-currency?
|
||||
(money/wei->str token amount)
|
||||
(->> amount (money/wei-> token) money/to-fixed str))
|
||||
"...")))
|
||||
|
||||
|
||||
(defn details-header [{:keys [value date type symbol]}]
|
||||
|
@ -213,7 +238,12 @@
|
|||
[react/view {:style styles/details-header-icon}
|
||||
[list/item-icon (transaction-type->icon type)]]
|
||||
[react/view {:style styles/details-header-infos}
|
||||
[react/text {:style styles/details-header-value} (pretty-print-asset symbol value)]
|
||||
[react/text {:style styles/details-header-value}
|
||||
[react/text {:accessibility-label :amount-text}
|
||||
(pretty-print-asset symbol value)]
|
||||
" "
|
||||
[react/text {:accessibility-label :currency-text}
|
||||
(clojure.string/upper-case (name symbol))]]
|
||||
[react/text {:style styles/details-header-date} date]]])
|
||||
|
||||
(defn progress-bar [progress]
|
||||
|
@ -230,14 +260,22 @@
|
|||
(i18n/label :t/confirmations-helper-text)]])
|
||||
|
||||
(defn details-list-row
|
||||
([label value]
|
||||
(details-list-row label value nil))
|
||||
([label value extra-value]
|
||||
[react/view {:style styles/details-row}
|
||||
[react/text {:style styles/details-item-label} (i18n/label label)]
|
||||
[react/view {:style styles/details-item-value-wrapper}
|
||||
[react/text {:style styles/details-item-value} (str value)]
|
||||
[react/text {:style styles/details-item-extra-value} (str extra-value)]]]))
|
||||
([label props-value]
|
||||
(details-list-row label props-value nil))
|
||||
([label props-value extra-props-value]
|
||||
(let [[props value] (if (string? props-value)
|
||||
[nil props-value]
|
||||
props-value)
|
||||
[extra-props extra-value] (if (string? extra-props-value)
|
||||
[nil extra-props-value]
|
||||
extra-props-value)]
|
||||
[react/view {:style styles/details-row}
|
||||
[react/text {:style styles/details-item-label} (i18n/label label)]
|
||||
[react/view {:style styles/details-item-value-wrapper}
|
||||
[react/text (merge {:style styles/details-item-value} props)
|
||||
(str value)]
|
||||
[react/text (merge {:style styles/details-item-extra-value} extra-props)
|
||||
(str extra-value)]]])))
|
||||
|
||||
(defn details-list [{:keys [block hash
|
||||
from from-wallet from-contact
|
||||
|
@ -247,11 +285,17 @@
|
|||
[details-list-row :t/block block]
|
||||
[details-list-row :t/hash hash]
|
||||
[details-list-row :t/from
|
||||
(or from-wallet from-contact from)
|
||||
(when (or from-wallet from-contact) from)]
|
||||
[{:accessibility-label (if from-wallet :sender-name-text :sender-address-text)}
|
||||
(or from-wallet from-contact from)]
|
||||
(when (or from-wallet from-contact)
|
||||
[{:accessibility-label :sender-address-text}
|
||||
from])]
|
||||
[details-list-row :t/to
|
||||
(or to-wallet to-contact to)
|
||||
(when (or to-wallet to-contact) to)]
|
||||
[{:accessibility-label (if to-wallet :recipient-name-text :recipient-address-text)}
|
||||
(or to-wallet to-contact to)]
|
||||
(when (or to-wallet to-contact)
|
||||
[{:accessibility-label :recipient-address-text}
|
||||
to])]
|
||||
[details-list-row :t/gas-limit gas-limit]
|
||||
[details-list-row :t/gas-price gas-price-gwei gas-price-eth]
|
||||
[details-list-row :t/gas-used gas-used]
|
||||
|
|
|
@ -20,35 +20,44 @@
|
|||
[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})]]])
|
||||
:icon-opts {:color :white
|
||||
:accessibility-label :options-menu-button})]]])
|
||||
|
||||
(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-balance-value
|
||||
:accessibility-label :total-amount-value-text}
|
||||
usd-value]
|
||||
[react/text {:style styles/total-balance-currency
|
||||
:accessibility-label :total-amount-currency-text}
|
||||
(i18n/label :t/usd-currency)]]
|
||||
[react/text {:style styles/total-value} (i18n/label :t/wallet-total-value)]]])
|
||||
|
||||
(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])}])
|
||||
[{:label (i18n/label :t/send-transaction)
|
||||
:accessibility-label :send-transaction-button
|
||||
:icon :icons/arrow-right
|
||||
:action #(re-frame/dispatch [:navigate-to :wallet-send-transaction])}
|
||||
{:label (i18n/label :t/receive-transaction)
|
||||
:accessibility-label :receive-transaction-button
|
||||
:icon :icons/arrow-left
|
||||
:action #(re-frame/dispatch [:navigate-to :wallet-request-transaction])}
|
||||
{:label (i18n/label :t/transaction-history)
|
||||
:accessibility-label :transaction-history-button
|
||||
:icon :icons/transaction-history
|
||||
:action #(re-frame/dispatch [:navigate-to :transactions-history])}])
|
||||
|
||||
(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}
|
||||
[react/text {:style styles/asset-item-value
|
||||
:number-of-lines 1
|
||||
:ellipsize-mode :tail
|
||||
:accessibility-label (str (-> symbol name clojure.string/lower-case) "-asset-value-text")}
|
||||
(wallet.utils/format-amount amount decimals)]
|
||||
[react/text {:style styles/asset-item-currency
|
||||
:uppercase? true
|
||||
|
|
|
@ -23,11 +23,14 @@
|
|||
content
|
||||
;; Styles are only relevant on iOS. On Android first button is 'neutral' and second is 'positive'
|
||||
(clj->js
|
||||
(vector (merge {:text (i18n/label :t/cancel) :style "cancel"}
|
||||
(vector (merge {:text (i18n/label :t/cancel)
|
||||
:style "cancel"
|
||||
:accessibility-label :cancel-button}
|
||||
(when on-cancel {:onPress on-cancel}))
|
||||
{:text (or confirm-button-text "OK")
|
||||
:onPress on-accept
|
||||
:style "destructive"})))))
|
||||
{:text (or confirm-button-text "OK")
|
||||
:onPress on-accept
|
||||
:style "destructive"
|
||||
:accessibility-label :confirm-button})))))
|
||||
|
||||
(defn show-question
|
||||
([title content on-accept]
|
||||
|
@ -37,9 +40,12 @@
|
|||
title
|
||||
content
|
||||
(clj->js
|
||||
(vector (merge {:text (i18n/label :t/no)}
|
||||
(vector (merge {:text (i18n/label :t/no)
|
||||
:accessibility-label :no-button}
|
||||
(when on-cancel {:onPress on-cancel}))
|
||||
{:text (i18n/label :t/yes) :onPress on-accept})))))
|
||||
{:text (i18n/label :t/yes)
|
||||
:onPress on-accept
|
||||
:accessibility-label :yes-button})))))
|
||||
|
||||
(defn http-post
|
||||
"Performs an HTTP POST request"
|
||||
|
|
Loading…
Reference in New Issue