[Fix #3394] Add accessibility labels for Wallet screens

Signed-off-by: Julien Eluard <julien.eluard@gmail.com>
This commit is contained in:
Foo Pang 2018-03-04 10:56:39 +08:00 committed by Julien Eluard
parent 25ac067375
commit 2653cebd7d
No known key found for this signature in database
GPG Key ID: 6FD7DB5437FCBEF6
16 changed files with 276 additions and 166 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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