Replace all text-inputs with quo component

This reverts commit db202f03bf.

Fix leftover get-ref for text input

Use uuid as a unique identifier for input

Generate a random uuid on mount, ensures that no stale ref are kept

Signed-off-by: Gheorghe Pinzaru <feross95@gmail.com>
This commit is contained in:
Gheorghe Pinzaru 2020-06-10 17:56:42 +03:00
parent db202f03bf
commit 3bc9a63c36
No known key found for this signature in database
GPG Key ID: C9A094959935A952
43 changed files with 579 additions and 832 deletions

View File

@ -153,8 +153,8 @@
:Text #js {}
:Extrapolate #js {:CLAMP nil}
:Code #js {}}
:Easing #js {:bezier nil
:linear nil}
:Easing #js {:bezier identity
:linear identity}
:clockRunning nil})
(def react-native-gesture-handler #js {:default #js {}
:State #js {:BEGAN nil
@ -203,6 +203,5 @@
"react-native-mail" react-native-mail
"react-native-image-resizer" image-resizer
"react-native-haptic-feedback" react-native-haptic-feedback
"reanimated-bottom-sheet" reanimated-bottom-sheet
"./fleets.js" default-fleets
nil))

View File

@ -5,15 +5,18 @@
[quo.react-native :as rn]
[reagent.core :as reagent]))
(defn text-style [{:keys [size align weight color style]}]
(defn text-style [{:keys [size align weight monospace color style]}]
;; NOTE(Ferossgo): or in destructoring will keep nil as a value
(merge (case (or weight :regular)
:regular typography/font-regular
:medium typography/font-medium
:semi-bold typography/font-semi-bold
:bold typography/font-bold
:monospace typography/monospace
:inherit nil)
(merge (if monospace
;; TODO(Ferossgp): Add all weights for monospace
typography/monospace
(case (or weight :regular)
:regular typography/font-regular
:medium typography/font-medium
:semi-bold typography/font-semi-bold
:bold typography/font-bold
:monospace typography/monospace ; DEPRECATED
:inherit nil))
(case (or color :main)
:main {:color (:text-01 @colors/theme)}
:secondary {:color (:text-02 @colors/theme)}

View File

@ -5,30 +5,36 @@
[quo.react-native :as rn]
;; TODO(Ferossgp): Move icon component to lib
[status-im.ui.components.icons.vector-icons :as icons]
;; TODO(Ferossgp): Move tooltip into lib
[quo.components.tooltip :as tooltip]
[quo.react :as react]
[quo.platform :as platform]
[quo.design-system.typography :as typography]
[quo.design-system.spacing :as spacing]
[quo.design-system.colors :as colors]
[quo.components.text :as text]))
;; NOTE(Ferossgp): Refactor with hooks when available
;; We track all currently mounted text input refs
;; in a ref-to-defaultValue map
;; so that we can clear them (restore their default values)
;; when global react-navigation's onWillBlur event is invoked
(defonce text-input-refs (atom {}))
(s/def ::multiline boolean?)
(s/def ::secure-text-entry boolean?)
(s/def ::show-cancel boolean?)
(s/def ::label (s/nilable string?))
(s/def ::label (s/nilable (s/or :string string? :component vector?)))
(s/def ::cancel-label (s/nilable string?))
(s/def ::default-value (s/nilable string?))
(s/def ::placeholder (s/nilable string?))
(s/def ::keyboard-type #{})
(s/def ::keyboard-type (s/nilable (s/or :string string? :keyword keyword?))) ; TODO: make set
(s/def ::accessibility-label (s/nilable (s/or :string string? :keyword keyword?)))
(s/def ::on-focus fn?)
(s/def ::on-blur fn?)
(s/def ::on-press fn?)
(s/def ::accessory (s/keys :req-un [::icon]
:opt-un [::on-press]))
(s/def ::accessory (s/keys :opt-un [::on-press
::icon
::component]))
(s/def ::after (s/nilable ::accessory))
(s/def ::before (s/nilable ::accessory))
@ -60,15 +66,13 @@
false)))
;; TODO(Ferossgp): Check performance for android layout animations
(when (and platform/android?
(aget rn/ui-manager "setLayoutAnimationEnabledExperimental"))
(ocall rn/ui-manager "setLayoutAnimationEnabledExperimental" true))
;; (when (and platform/android?
;; (aget rn/ui-manager "setLayoutAnimationEnabledExperimental"))
;; (ocall rn/ui-manager "setLayoutAnimationEnabledExperimental" true))
(def height 44) ; 22 line-height + 11*2 vertical padding
(def multiline-height 88) ; 3 * 22 three line-height + 11* vertical padding
(defn container-style [])
(defn label-style []
{:margin-bottom (:tiny spacing/spacing)})
@ -84,8 +88,10 @@
:background-color (:ui-01 @colors/theme)}
style))
(defn text-input-style [multiline input-style before after]
(merge typography/font-regular
(defn text-input-style [multiline input-style monospace before after]
(merge (if monospace
typography/monospace
typography/font-regular)
{:padding-top 11
:padding-bottom 11
:font-size 15
@ -115,7 +121,7 @@
{:flex 1
:justify-content :center}))
(defn accessory-element [{:keys [icon icon-opts style accessibility-label on-press]}]
(defn accessory-element [{:keys [icon component icon-opts style accessibility-label on-press]}]
(let [el (if on-press
rn/touchable-opacity
rn/view)]
@ -126,21 +132,29 @@
style)}
(when accessibility-label
{:accessibility-label accessibility-label}))
[icons/icon icon (merge {:color (:icon-01 @colors/theme)}
icon-opts)]]]))
(cond
icon
[icons/icon icon (merge {:color (:icon-01 @colors/theme)}
icon-opts)]
component
component
(defn text-input []
(let [focused (reagent/atom nil)
visible (reagent/atom false)
ref (react/create-ref)
on-cancel (fn []
(some-> (react/current-ref ref) (ocall "blur")))]
:else
nil)]]))
(defn text-input-raw []
(let [focused (reagent/atom nil)
visible (reagent/atom false)
ref (atom nil)
blur (fn []
(some-> @ref (ocall "blur")))]
(fn [{:keys [label multiline error style input-style keyboard-type before after
cancel-label on-focus on-blur show-cancel accessibility-label
bottom-value secure-text-entry container-style]
:or {cancel-label "Cancel"
show-cancel true}
:as props}]
bottom-value secure-text-entry container-style get-ref on-cancel
monospace]
:or {cancel-label "Cancel"
show-cancel true}
:as props}]
{:pre [(check-spec ::text-input props)]}
(let [after (cond
(and secure-text-entry @visible)
@ -152,7 +166,11 @@
:on-press #(reset! visible true)}
:else after)
secure (and secure-text-entry (not @visible))]
secure (and secure-text-entry (not @visible))
on-cancel (fn []
(when on-cancel
(on-cancel))
(blur))]
[rn/view {:style container-style}
(when label
[text/text {:style (label-style)}
@ -162,19 +180,23 @@
(when before
[accessory-element before])
[rn/text-input
(merge {:style (text-input-style multiline input-style before after)
:ref ref
(merge {:style (text-input-style multiline input-style monospace before after)
:ref (fn [r]
(reset! ref r)
(when get-ref (get-ref r)))
:placeholder-text-color (:text-02 @colors/theme)
:underline-color-android :transparent
:auto-capitalize :none
:secure-text-entry secure
:on-focus (fn [evt]
(when on-focus (on-focus evt))
(rn/configure-next (:ease-in-ease-out rn/layout-animation-presets))
(when (and platform/ios? show-cancel)
(rn/configure-next (:ease-in-ease-out rn/layout-animation-presets)))
(reset! focused true))
:on-blur (fn [evt]
(when on-blur (on-blur evt))
(rn/configure-next (:ease-in-ease-out rn/layout-animation-presets))
(when (and platform/ios? show-cancel)
(rn/configure-next (:ease-in-ease-out rn/layout-animation-presets)))
(reset! focused false))}
(when (and platform/ios? (not after))
{:clear-button-mode :while-editing})
@ -183,7 +205,7 @@
{:keyboard-type keyboard-type})
(dissoc props
:style :keyboard-type :on-focus :on-blur
:secure-text-entry :ref))]
:secure-text-entry :ref :get-ref))]
(when after
[accessory-element after])]
(when (and platform/ios?
@ -192,13 +214,35 @@
@focused)
[rn/touchable-opacity {:style (cancel-style)
:on-press on-cancel}
[text/text {:color :link} cancel-label]])]
(when error
[tooltip/tooltip (merge {:bottom-value (cond bottom-value bottom-value
label 30 ; 22 line height 8 margin
)}
(when accessibility-label
{:accessibility-label (str (name accessibility-label) "-error")}))
[text/text {:color :negative
:size :small}
error]])]))))
[text/text {:color :link} cancel-label]])
(when error
[tooltip/tooltip (merge {:bottom-value (cond bottom-value bottom-value
label 30 ; 22 line height 8 margin
)}
(when accessibility-label
{:accessibility-label (str (name accessibility-label) "-error")}))
[text/text {:color :negative
:align :center
:size :small}
error]])]]))))
;; TODO(Ferossgp): Refactor me when hooks available
(defn text-input [{:keys [preserve-input?]
:as props}]
(if preserve-input?
[text-input-raw props]
(let [id (random-uuid)]
(reagent/create-class
{:component-will-unmount
(fn []
(swap! text-input-refs dissoc id))
:reagent-render
(fn [{:keys [get-ref default-value]
:as props}]
[text-input-raw (merge props
{:get-ref (fn [r]
;; Store input and its defaultValue
;; one we receive a non-nil ref
(when r
(swap! text-input-refs assoc id {:ref r :value default-value}))
(when get-ref (get-ref r)))})])}))))

View File

@ -5,6 +5,7 @@
[quo.react-native :as rn]
[quo.design-system.colors :as colors]
[quo.design-system.spacing :as spacing]
[quo.platform :as platform]
[status-im.ui.components.icons.vector-icons :as vector-icons]))
(def ^:private initial-height 22)
@ -48,7 +49,8 @@
:height height})))]
(fn [{:keys [bottom-value]} & children]
[:<>
[animated/code {:exec (animated/set animation-v 1)}]
[animated/code {:exec (animated/cond* (animated/not* animation-v)
(animated/set animation-v 1))}]
[animated/view {:style (tooltip-style {:bottom-value (- (get @layout :height)
bottom-value)
:animation animation})
@ -58,7 +60,10 @@
(into [rn/view {:style (content-style)
:on-layout on-layout}]
children)
[vector-icons/icon :icons/tooltip-tip {:width 18
:height 8
:container-style {:elevation 3}
:color (:ui-background @colors/theme)}]]]])))
(when platform/ios?
;; NOTE(Ferossgp): Android does not show elevation for tooltip making it lost on white bg
[vector-icons/icon :icons/tooltip-tip {:width 18
:height 8
:container-style {:elevation 3}
:color (:ui-background @colors/theme)}])]]])))

View File

@ -6,13 +6,6 @@
:margin-horizontal 16
:margin-vertical 15})
(def input-container
{:margin-bottom 15})
(def network-type
{:flex-direction :row
:align-items :center})
(def bottom-container
{:flex-direction :row
:margin-horizontal 12

View File

@ -8,7 +8,7 @@
[status-im.ui.components.list.views :as list]
[status-im.ui.components.react :as react]
[status-im.ui.components.styles :as components.styles]
[status-im.ui.components.text-input.view :as text-input]
[quo.core :as quo]
[status-im.ui.components.topbar :as topbar])
(:require-macros [status-im.utils.views :as views]))
@ -33,31 +33,31 @@
[topbar/topbar {:title :t/add-network}]
[react/scroll-view
[react/view styles/edit-network-view
[text-input/text-input-with-label
{:label (i18n/label :t/name)
:placeholder (i18n/label :t/specify-name)
:container styles/input-container
:default-value (get-in manage-network [:name :value])
:on-change-text #(re-frame/dispatch [::network/input-changed :name %])
:auto-focus true}]
[text-input/text-input-with-label
{:label (i18n/label :t/rpc-url)
:placeholder (i18n/label :t/specify-rpc-url)
:container styles/input-container
:default-value (get-in manage-network [:url :value])
:on-change-text #(re-frame/dispatch [::network/input-changed :url (string/lower-case %)])}]
[react/i18n-text {:key :network-chain}]
[react/view styles/network-type
[react/view {:padding-vertical 8}
[quo/text-input
{:label (i18n/label :t/name)
:placeholder (i18n/label :t/specify-name)
:default-value (get-in manage-network [:name :value])
:on-change-text #(re-frame/dispatch [::network/input-changed :name %])
:auto-focus true}]]
[react/view {:padding-vertical 8}
[quo/text-input
{:label (i18n/label :t/rpc-url)
:placeholder (i18n/label :t/specify-rpc-url)
:default-value (get-in manage-network [:url :value])
:on-change-text #(re-frame/dispatch [::network/input-changed :url (string/lower-case %)])}]]
[react/view {:padding-vertical 8}
[react/i18n-text {:key :network-chain}]
[list/flat-list {:data [:mainnet :testnet :rinkeby :custom]
:key-fn (fn [_ i] (str i))
:separator list/base-separator
:render-fn #(render-network-type manage-network %)}]]
(when custom?
[text-input/text-input-with-label
{:label (i18n/label :t/network-id)
:container styles/input-container
:placeholder (i18n/label :t/specify-network-id)
:on-change-text #(re-frame/dispatch [::network/input-changed :network-id %])}])]]
[react/view {:padding-vertical 8}
[quo/text-input
{:label (i18n/label :t/network-id)
:placeholder (i18n/label :t/specify-network-id)
:on-change-text #(re-frame/dispatch [::network/input-changed :network-id %])}]])]]
[react/view styles/bottom-container
[react/view components.styles/flex]
[components.common/bottom-button

View File

@ -1,27 +0,0 @@
(ns status-im.ui.components.search-input.styles
(:require [status-im.ui.components.colors :as colors]
[status-im.utils.styles :as styles]))
(styles/def search-input
{:flex 1
:android {:margin 0
:padding 0}})
(def search-input-height 56)
(defn search-container []
{:height search-input-height
:flex-direction :row
:padding-horizontal 16
:background-color colors/white
:align-items :center
:justify-content :center})
(defn search-input-container []
{:background-color colors/gray-lighter
:flex 1
:flex-direction :row
:height 36
:align-items :center
:justify-content :center
:border-radius 8})

View File

@ -1,46 +1,34 @@
(ns status-im.ui.components.search-input.view
(:require [reagent.core :as reagent]
[status-im.i18n :as i18n]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.icons.vector-icons :as icons]
[status-im.ui.components.react :as react]
[status-im.ui.components.search-input.styles :as styles]))
[quo.core :as quo]
[quo.design-system.colors :as colors]))
(defn search-input [{:keys [search-active?]}]
(let [input-ref (atom nil)
search-active? (or search-active? (reagent/atom nil))]
(fn [{:keys [on-cancel on-focus on-change
search-container-style search-filter auto-focus]}]
[react/view {:style (or search-container-style (styles/search-container))}
[react/view {:style (styles/search-input-container)}
[icons/icon :main-icons/search {:color colors/gray
:container-style {:margin-left 6
:margin-right 2}}]
[react/text-input {:placeholder (i18n/label :t/search)
:blur-on-submit true
:multiline false
:ref #(reset! input-ref %)
:style styles/search-input
:default-value search-filter
:auto-focus auto-focus
:auto-correct false
:auto-capitalize :none
:on-focus #(do
(when on-focus
(on-focus search-filter))
(reset! search-active? true))
:on-change (fn [e]
(let [^js native-event (.-nativeEvent ^js e)
text (.-text native-event)]
(when on-change
(on-change text))))}]]
(when @search-active?
[react/touchable-highlight
{:on-press (fn []
(.clear ^js @input-ref)
(.blur ^js @input-ref)
(when on-cancel (on-cancel))
(reset! search-active? false))
:style {:margin-left 16}}
[react/text {:style {:color colors/blue}}
(i18n/label :t/cancel)]])])))
(fn [{:keys [on-focus on-change on-cancel search-filter auto-focus]}]
[quo/text-input {:placeholder (i18n/label :t/search)
:blur-on-submit true
:multiline false
:ref #(reset! input-ref %)
:default-value search-filter
:auto-focus auto-focus
:on-cancel on-cancel
:auto-correct false
:auto-capitalize :none
:input-style {:height 36}
:before {:icon :main-icons/search
:style {:padding-horizontal 8}
:on-press #(.focus ^js @input-ref)
:icon-opts {:color (:icon-02 @colors/theme)}}
:on-focus #(do
(when on-focus
(on-focus search-filter))
(reset! search-active? true))
:on-blur #(reset! search-active? false)
:on-change (fn [e]
(let [^js native-event (.-nativeEvent ^js e)
text (.-text native-event)]
(when on-change
(on-change text))))}])))

View File

@ -1,39 +0,0 @@
(ns status-im.ui.components.text-input.styles
(:require [status-im.ui.components.colors :as colors]
[status-im.utils.styles :as styles]))
(defn label [editable label-style]
(merge
{:margin-vertical 10}
label-style
(when-not editable {:color colors/gray})))
(defn input-container [height editable]
(merge
{:justify-content :center
:height (or height 52)
:border-radius 8
:background-color (when editable colors/gray-lighter)}
(when-not editable
{:border-color colors/gray-lighter
:border-width 1})))
(styles/def input
{:padding 16
:border-radius 8
:font-size 15
:line-height 22
:flex 1
:text-align-vertical :center
:desktop {:height 52}})
(defn error [bottom-value]
{:bottom-value bottom-value
:container-style {:shadow-offset {:width 0 :height 1}
:shadow-radius 6
:shadow-opacity 1
:shadow-color (if (colors/dark?)
"rgba(0, 0, 0, 0.75)"
"rgba(0, 34, 51)")
:elevation 2}
:font-size 12})

View File

@ -1,49 +0,0 @@
(ns status-im.ui.components.text-input.view
(:require [status-im.ui.components.react :as react]
[status-im.ui.components.text-input.styles :as styles]
[status-im.ui.components.colors :as colors]
[status-im.utils.platform :as platform]
[status-im.ui.components.tooltip.views :as tooltip]))
(defn merge-container-styles
[height container editable]
(let [merged-styles (merge (styles/input-container height editable) container)]
;; `:background-color` can't be nil; in this case the app will crash.
;; Nevertheless, we need to be able to remove background if necessary.
(if (nil? (:background-color merged-styles))
(dissoc merged-styles :background-color)
merged-styles)))
(defn text-input-with-label
[{:keys [label content error style height container accessibility-label
label-style parent-container bottom-value text editable keyboard-type]
:as props
:or {editable true}}]
[react/view {:style parent-container}
(when label
[react/text {:style (styles/label editable label-style)}
label])
[react/view {:style (merge-container-styles height container editable)}
[react/text-input
(merge
{:style (merge styles/input style)
:placeholder-text-color colors/gray
:auto-focus true
:auto-capitalize :none}
(cond-> (dissoc props :style :height)
;; error on ios
(and platform/ios? (= keyboard-type "visible-password"))
(dissoc :keyboard-type))
;; Workaround until `value` TextInput field is available on desktop:
;; https://github.com/status-im/react-native-desktop/issues/320
(when-not platform/desktop?
{:value text}))]
(when content content)]
(when error
[tooltip/tooltip error
(styles/error
(cond bottom-value bottom-value
label 20
:else 0))
(when accessibility-label
(str (name accessibility-label) "-error"))])])

View File

@ -10,8 +10,8 @@
[status-im.ui.components.react :as react]
[status-im.ui.components.topbar :as topbar]
[status-im.ui.screens.add-new.new-chat.styles :as styles]
[status-im.ui.screens.add-new.styles :as add-new.styles]
[status-im.utils.debounce :as debounce]
[quo.core :as quo]
[status-im.utils.utils :as utils])
(:require-macros [status-im.utils.views :as views]))
@ -26,13 +26,11 @@
(defn- icon-wrapper [color icon]
[react/view
{:style {:margin-right 16
:margin-top 11
:width 32
:height 32
:border-radius 25
:align-items :center
:justify-content :center
{:style {:width 32
:height 32
:border-radius 25
:align-items :center
:justify-content :center
:background-color color}}
icon])
@ -68,12 +66,14 @@
:modal? true
:accessories [{:icon :qr
:accessibility-label :scan-contact-code-button
:handler #(re-frame/dispatch [:qr-scanner.ui/scan-qr-code-pressed
{:title (i18n/label :t/new-contact)
:handler :contact/qr-code-scanned}])}]}]
[react/view add-new.styles/new-chat-container
[react/view (add-new.styles/new-chat-input-container)
[react/text-input
:handler #(re-frame/dispatch [:qr-scanner.ui/scan-qr-code-pressed
{:title (i18n/label :t/new-contact)
:handler :contact/qr-code-scanned}])}]}]
[react/view {:flex-direction :row
:padding 16}
[react/view {:flex 1
:padding-right 16}
[quo/text-input
{:on-change-text
#(do
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :searching])
@ -82,16 +82,13 @@
#(when (= state :valid)
(debounce/dispatch-and-chill [:contact.ui/contact-code-submitted] 3000))
:placeholder (i18n/label :t/enter-contact-code)
:style add-new.styles/input
;; This input is fine to preserve inputs
;; so its contents will not be erased
;; in onWillBlur navigation event handler
:preserve-input? true
:show-cancel false
:accessibility-label :enter-contact-code-input
:auto-capitalize :none
:auto-capitalize :none
:return-key-type :go}]]
[react/view {:width 16}]
[input-icon state]]
[react/view {:justify-content :center
:align-items :center}
[input-icon state]]]
[react/view {:min-height 30 :justify-content :flex-end}
[react/text {:style styles/message}
(cond (= state :error)

View File

@ -1,28 +1,9 @@
(ns status-im.ui.screens.add-new.new-public-chat.styles
(:require [status-im.ui.components.colors :as colors]))
(ns status-im.ui.screens.add-new.new-public-chat.styles)
(def group-chat-name-input
{:font-size 17
:padding-bottom 0})
(def topic-hash
(merge group-chat-name-input
{:margin-left 16
:margin-right 10
:font-size 24
:color colors/gray
:font-weight "500"}))
(def group-container
{:flex 1
:flex-direction :column})
(def input-container
{:padding 0
:padding-right 16
:background-color nil})
(def tooltip
{:bottom-value 15
:color colors/red-light
:font-size 12})
:flex-direction :column})

View File

@ -5,39 +5,37 @@
[status-im.react-native.resources :as resources]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.react :as react]
[status-im.ui.components.styles :as common.styles]
[status-im.ui.components.text-input.view :as text-input.view]
[status-im.ui.components.tooltip.views :as tooltip]
[quo.core :as quo]
[status-im.ui.components.topbar :as topbar]
[status-im.ui.screens.add-new.new-public-chat.db :as db]
[status-im.ui.screens.add-new.new-public-chat.styles :as styles]
[status-im.ui.screens.add-new.styles :as add-new.styles])
[status-im.ui.screens.add-new.new-public-chat.styles :as styles])
(:require-macros [status-im.utils.views :as views]))
(defn- start-chat [topic]
(re-frame/dispatch [:chat.ui/start-public-chat topic {:navigation-reset? true}])
(re-frame/dispatch [:set :public-group-topic nil]))
(defn- hash-icon []
[quo/text {:color :secondary
:weight :medium
:size :x-large}
"#"])
(defn- chat-name-input [topic error]
[react/view
[react/view (add-new.styles/input-container)
[react/text {:style styles/topic-hash} "#"]
[react/view common.styles/flex
[text-input.view/text-input-with-label
{:container styles/input-container
:on-change-text #(re-frame/dispatch [:set :public-group-topic %])
:on-submit-editing #(when (db/valid-topic? topic) (start-chat topic))
:auto-capitalize :none
:auto-focus false
:accessibility-label :chat-name-input
;; Set default-value as otherwise it will
;; be erased in global `onWillBlur` handler
:default-value topic
:placeholder "chat-name"
:return-key-type :go
:auto-correct false}]]]
(when error
[tooltip/tooltip error styles/tooltip])])
[quo/text-input
{:on-change-text #(re-frame/dispatch [:set :public-group-topic %])
:on-submit-editing #(when (db/valid-topic? topic) (start-chat topic))
:auto-capitalize :none
:auto-focus false
:accessibility-label :chat-name-input
:before {:component [hash-icon]}
;; Set default-value as otherwise it will
;; be erased in global `onWillBlur` handler
:default-value topic
:placeholder "chat-name"
:return-key-type :go
:auto-correct false
:error error}])
(defn render-topic [topic]
^{:key topic}

View File

@ -1,30 +1,10 @@
(ns status-im.ui.screens.add-new.styles
(:require [status-im.ui.components.colors :as colors]
[status-im.ui.components.styles :as components.styles]
[status-im.utils.styles :as styles]))
(def new-chat-container
{:flex-direction :row
:padding-top 16
:padding-left 16})
[status-im.ui.components.styles :as components.styles]))
(defn input-container []
{:flex-direction :row
:align-items :center
:margin-bottom 16
:border-radius components.styles/border-radius
:background-color colors/gray-lighter})
(defn new-chat-input-container []
(merge
(input-container)
{:flex 1}))
(styles/def input
{:flex 1
:height 52
:padding-horizontal 14
:desktop {:height 30
:width "100%"}
:android {:padding 0
:width "100%"}})
:background-color colors/gray-lighter})

View File

@ -3,21 +3,6 @@
[status-im.ui.components.styles :as components.styles]
[status-im.utils.styles :as styles]))
(def input-container
{:flex-direction :row
:align-items :center
:justify-content :space-between
:border-radius components.styles/border-radius
:height 52
:margin-top 15})
(styles/def input
{:flex 1
:android {:padding 0}})
(def qr-code
{:margin-right 14})
(def edit-bootnode-view
{:flex 1
:margin-horizontal 16

View File

@ -2,18 +2,14 @@
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.i18n :as i18n]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.common.common :as components.common]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.react :as react]
[status-im.ui.components.styles :as components.styles]
[status-im.ui.components.text-input.view :as text-input]
[status-im.ui.components.tooltip.views :as tooltip]
[quo.core :as quo]
[status-im.ui.components.topbar :as topbar]
[status-im.ui.screens.bootnodes-settings.edit-bootnode.styles
:as
styles]
[status-im.utils.platform :as platform])
styles])
(:require-macros [status-im.utils.views :as views]))
(defn delete-button [id]
@ -24,14 +20,6 @@
[react/text {:style styles/button-label}
(i18n/label :t/delete)]]]])
(def qr-code
[react/touchable-highlight {:on-press #(re-frame/dispatch [:qr-scanner.ui/scan-qr-code-pressed
{:title (i18n/label :t/add-bootnode)
:handler :bootnodes.callback/qr-code-scanned}])
:style styles/qr-code}
[react/view
[vector-icons/icon :main-icons/qr {:color colors/blue}]]])
(views/defview edit-bootnode []
(views/letsubs [manage-bootnode [:get-manage-bootnode]
validation-errors [:manage-bootnode-validation-errors]]
@ -45,33 +33,33 @@
[topbar/topbar {:title (if id :t/bootnode-details :t/add-bootnode)}]
[react/scroll-view {:keyboard-should-persist-taps :handled}
[react/view styles/edit-bootnode-view
[text-input/text-input-with-label
{:label (i18n/label :t/name)
:placeholder (i18n/label :t/specify-name)
:accessibility-label :bootnode-name
:style styles/input
:container styles/input-container
:default-value name
:on-change-text #(re-frame/dispatch [:bootnodes.ui/input-changed :name %])
:auto-focus true}]
[react/view {:padding-vertical 8}
[quo/text-input
{:label (i18n/label :t/name)
:placeholder (i18n/label :t/specify-name)
:accessibility-label :bootnode-name
:default-value name
:on-change-text #(re-frame/dispatch [:bootnodes.ui/input-changed :name %])
:auto-focus true}]]
[react/view
{:flex 1}
[text-input/text-input-with-label
{:flex 1
:padding-vertical 8}
[quo/text-input
(merge
{:label (i18n/label :t/bootnode-address)
:placeholder (i18n/label :t/bootnode-format)
:style styles/input
:accessibility-label :bootnode-address
:container styles/input-container
:default-value url
:on-change-text #(re-frame/dispatch [:bootnodes.ui/input-changed :url %])}
(when-not platform/desktop? {:content qr-code}))]
(when (and (not (string/blank? url)) invalid-url?)
[tooltip/tooltip (i18n/label :t/invalid-format
{:format (i18n/label :t/bootnode-format)})
{:color colors/red-light
:font-size 12
:bottom-value 25}])]
:show-cancel false
:on-change-text #(re-frame/dispatch [:bootnodes.ui/input-changed :url %])
:error (when (and (not (string/blank? url)) invalid-url?)
(i18n/label :t/invalid-format
{:format (i18n/label :t/bootnode-format)}))
:bottom-value 0
:after {:icon :main-icons/qr
:on-press #(re-frame/dispatch [:qr-scanner.ui/scan-qr-code-pressed
{:title (i18n/label :t/add-bootnode)
:handler :bootnodes.callback/qr-code-scanned}])}})]]
(when id
[delete-button id])]]
[react/view styles/bottom-container

View File

@ -115,9 +115,6 @@
{:padding-top 3
:padding-left 3})
(def message-activity-indicator
{:padding-top 4})
(defn emoji-message
[{:keys [incoming-group]}]
{:font-size 28

View File

@ -32,18 +32,20 @@
[react/view {:flex 1}
[topbar/topbar {:title :t/main-currency}]
[react/view {:flex 1}
[search-input/search-input
{:search-active? search-active?
:search-filter search-filter
:on-cancel #(re-frame/dispatch [:search/currency-filter-changed nil])
:on-focus (fn [search-filter]
(when-not search-filter
(re-frame/dispatch [:search/currency-filter-changed ""])))
:on-change (fn [text]
(re-frame/dispatch [:search/currency-filter-changed text]))}]
[list/flat-list {:data (->> currencies
vals
(sort #(compare (:code %1) (:code %2))))
:key-fn :code
:render-fn (render-currency currency-id)
[react/view {:padding-horizontal 16
:padding-vertical 10}
[search-input/search-input
{:search-active? search-active?
:search-filter search-filter
:on-cancel #(re-frame/dispatch [:search/currency-filter-changed nil])
:on-focus (fn [search-filter]
(when-not search-filter
(re-frame/dispatch [:search/currency-filter-changed ""])))
:on-change (fn [text]
(re-frame/dispatch [:search/currency-filter-changed text]))}]]
[list/flat-list {:data (->> currencies
vals
(sort #(compare (:code %1) (:code %2))))
:key-fn :code
:render-fn (render-currency currency-id)
:keyboardShouldPersistTaps :always}]]]))

View File

@ -24,7 +24,9 @@
(defn search-container []
{:border-bottom-color colors/gray-lighter
:border-bottom-width 1})
:border-bottom-width 1
:padding-horizontal 16
:padding-vertical 10})
(defn members-title []
{:color colors/gray

View File

@ -21,8 +21,8 @@
[status-im.ui.components.toolbar :as bottom-toolbar]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.components.topbar :as topbar]
[status-im.ui.screens.add-new.styles :as add-new.styles]
[status-im.ui.screens.group.styles :as styles]
[quo.core :as quo]
[status-im.utils.debounce :as debounce]
[status-im.utils.platform :as platform])
(:require-macros [status-im.utils.views :as views]))
@ -125,16 +125,14 @@
:max constants/max-group-chat-participants})]]]]
[react/view {:style {:padding-top 16
:flex 1}}
:flex 1}}
[react/view {:style {:padding-horizontal 16}}
[react/view (add-new.styles/input-container)
[react/text-input
{:auto-focus true
:on-change-text #(re-frame/dispatch [:set :new-chat-name %])
:default-value group-name
:placeholder (i18n/label :t/set-a-topic)
:style add-new.styles/input
:accessibility-label :chat-name-input}]]
[quo/text-input
{:auto-focus true
:on-change-text #(re-frame/dispatch [:set :new-chat-name %])
:default-value group-name
:placeholder (i18n/label :t/set-a-topic)
:accessibility-label :chat-name-input}]
[react/text {:style (styles/members-title)}
(i18n/label :t/members-title)]]
[react/view {:style {:margin-top 8
@ -242,18 +240,16 @@
[topbar/topbar
{:title :t/edit-group
:modal? true}]
[react/view {:style {:padding 16
:flex 1}}
[react/view {:style (add-new.styles/input-container)}
[react/text-input
{:on-change-text #(reset! new-group-chat-name %)
:default-value name
:on-submit-editing #(when (seq @new-group-chat-name)
(re-frame/dispatch [:group-chats.ui/name-changed chat-id @new-group-chat-name]))
:placeholder (i18n/label :t/enter-contact-code)
:style add-new.styles/input
:accessibility-label :new-chat-name
:return-key-type :go}]]]
[react/scroll-view {:style {:padding 16
:flex 1}}
[quo/text-input
{:on-change-text #(reset! new-group-chat-name %)
:default-value name
:on-submit-editing #(when (seq @new-group-chat-name)
(re-frame/dispatch [:group-chats.ui/name-changed chat-id @new-group-chat-name]))
:placeholder (i18n/label :t/enter-contact-code)
:accessibility-label :new-chat-name
:return-key-type :go}]]
[react/view {:style {:flex 1}}]
[bottom-toolbar/toolbar
{:show-border? true

View File

@ -57,10 +57,6 @@
:height 22
:margin-top 5})
(def pin-indicator-group-container
{:flex-direction :row
:justify-content :space-between})
(defn pin-indicator [pressed? error?]
{:width 8
:height 8
@ -81,9 +77,6 @@
:border-radius 50
:margin-horizontal 5})
(def waiting-indicator-container
{:margin-top 26})
(def numpad-container
{:margin-top 18})

View File

@ -86,15 +86,17 @@
(defonce search-active? (reagent/atom false))
(defn search-input-wrapper [search-filter]
[search-input/search-input
{:search-active? search-active?
:search-filter search-filter
:on-cancel #(re-frame/dispatch [:search/home-filter-changed nil])
:on-focus (fn [search-filter]
(when-not search-filter
(re-frame/dispatch [:search/home-filter-changed ""])))
:on-change (fn [text]
(re-frame/dispatch [:search/home-filter-changed text]))}])
[react/view {:padding-horizontal 16
:padding-vertical 10}
[search-input/search-input
{:search-active? search-active?
:search-filter search-filter
:on-cancel #(re-frame/dispatch [:search/home-filter-changed nil])
:on-focus (fn [search-filter]
(when-not search-filter
(re-frame/dispatch [:search/home-filter-changed ""])))
:on-change (fn [text]
(re-frame/dispatch [:search/home-filter-changed text]))}]])
(views/defview chats-list []
(views/letsubs [loading? [:chats/loading?]

View File

@ -11,7 +11,6 @@
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.radio :as radio]
[status-im.ui.components.react :as react]
[status-im.ui.components.text-input.view :as text-input]
[status-im.ui.components.topbar :as topbar]
[status-im.ui.screens.intro.styles :as styles]
[status-im.utils.config :as config]
@ -19,6 +18,7 @@
[status-im.utils.identicon :as identicon]
[status-im.utils.platform :as platform]
[status-im.utils.security :as security]
[quo.core :as quo]
[status-im.utils.utils :as utils])
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
@ -230,24 +230,23 @@
:max-height 16}}]
[storage-entry (second storage-types) selected-storage-type]]]]))
(defn password-container [confirm-failure? view-width]
(defn password-container [confirm-failure? _]
(let [horizontal-margin 16]
[react/view {:style {:flex 1
:justify-content :space-between
:align-items :center :margin-horizontal horizontal-margin}}
[react/view {:style {:justify-content :center :flex 1}}
[react/view {:style {:flex 1
:justify-content :space-between
:margin-horizontal horizontal-margin}}
[react/view
[react/text {:style (assoc styles/wizard-text :color colors/red
:margin-bottom 16)}
(if confirm-failure? (i18n/label :t/password_error1) " ")]
[react/text-input {:secure-text-entry true
:auto-capitalize :none
:auto-focus true
:accessibility-label :password-input
:text-align :center
:placeholder ""
:style (styles/password-text-input (- view-width (* 2 horizontal-margin)))
:on-change-text #(re-frame/dispatch [:intro-wizard/code-symbol-pressed %])}]]
(if confirm-failure? (i18n/label :t/password_error1) " ")]]
[react/view {:padding 16}
[quo/text-input {:secure-text-entry true
:auto-capitalize :none
:auto-focus true
:show-cancel false
:accessibility-label :password-input
:placeholder ""
:on-change-text #(re-frame/dispatch [:intro-wizard/code-symbol-pressed %])}]]
[react/text {:style (assoc styles/wizard-text :margin-bottom 16)} (i18n/label :t/password-description)]]))
(defn create-code [{:keys [confirm-failure? view-width]}]
@ -362,69 +361,45 @@
next-button-disabled?
passphrase-error]}]
[react/keyboard-avoiding-view {:flex 1
:justify-content :flex-start
:background-color colors/white}
[text-input/text-input-with-label
{:on-change-text #(re-frame/dispatch [:multiaccounts.recover/enter-phrase-input-changed (security/mask-data %)])
:auto-focus true
:error (when passphrase-error (i18n/label passphrase-error))
:accessibility-label :passphrase-input
:placeholder nil
:bottom-value 40
:multiline true
:auto-correct false
:keyboard-type "visible-password"
:parent-container {:flex 1
:justify-content :center}
:container (merge {:background-color colors/white
:flex 1
:justify-content :center
:min-height 90}
(when platform/ios?
{:max-height 150}))
:style {:background-color colors/white
:text-align :center
:text-align-vertical :center
:min-width 40
:font-size 16
:font-weight "700"}}]
[react/view {:align-items :center}
(if passphrase-word-count
[react/view {:flex-direction :row
:margin-bottom 4
:min-height 24
:max-height 24
:align-items :center}
[react/nested-text {:style {:font-size 14
:padding-right 4
:text-align :center
:color colors/gray}}
(str (i18n/label :t/word-count) ": ")
[{:style {:font-weight "500"
:color colors/black}}
(i18n/label-pluralize passphrase-word-count :t/words-n)]]
[react/view {:background-color colors/white
:flex 1
:justify-content :center
:padding-horizontal 16}
[quo/text-input
{:on-change-text #(re-frame/dispatch [:multiaccounts.recover/enter-phrase-input-changed (security/mask-data %)])
:auto-focus true
:error (when passphrase-error (i18n/label passphrase-error))
:accessibility-label :passphrase-input
:placeholder (i18n/label :t/seed-phrase-placeholder)
:show-cancel false
:bottom-value 40
:multiline true
:auto-correct false
:monospace true}]
[react/view {:align-items :flex-end}
[react/view {:flex-direction :row
:align-items :center
:padding-vertical 8
:opacity (if passphrase-word-count 1 0)}
[quo/text {:color (if next-button-disabled? :secondary :main)
:size :small}
(when-not next-button-disabled?
[react/view {:style {:background-color colors/green-transparent-10
:border-radius 12
:width 24
:justify-content :center
:align-items :center
:height 24}}
[vector-icons/tiny-icon :tiny-icons/tiny-check {:color colors/green}]])]
[react/view {:align-self :stretch :margin-bottom 4
:max-height 24 :min-height 24}])
"✓ ")
(i18n/label-pluralize passphrase-word-count :t/words-n)]]]]
[react/view {:align-items :center}
[react/text {:style {:color colors/gray
:font-size 14
:margin-bottom 8
:text-align :center}}
(i18n/label :t/multiaccounts-recover-enter-phrase-text)]]
(when processing?
[react/view {:flex 1 :align-items :center}
[react/activity-indicator {:size :large
:animating true}]
[react/text {:style {:color colors/gray
:margin-top 8}}
(i18n/label :t/processing)]])])
(i18n/label :t/multiaccounts-recover-enter-phrase-text)]
(when processing?
[react/view {:flex 1 :align-items :center}
[react/activity-indicator {:size :large
:animating true}]
[react/text {:style {:color colors/gray
:margin-top 8}}
(i18n/label :t/processing)]])]])
(defn recovery-success [pubkey name photo-path]
[react/view {:flex 1

View File

@ -8,12 +8,12 @@
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.react :as react]
[status-im.ui.components.styles :as components.styles]
[status-im.ui.components.text-input.view :as text-input]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.components.tooltip.views :as tooltip]
[status-im.ui.components.topbar :as topbar]
[status-im.ui.screens.hardwallet.pin.views :as pin.views]
[status-im.ui.screens.keycard.styles :as styles]
[quo.core :as quo]
[status-im.constants :as constants])
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
@ -324,9 +324,9 @@
[toolbar/toolbar
{:transparent? true}
[toolbar/nav-text
{:handler #(re-frame/dispatch [::hardwallet.onboarding/cancel-pressed])
{:handler #(re-frame/dispatch [::hardwallet.onboarding/cancel-pressed])
:accessibility-label :cancel-keycard-setup
:style {:padding-left 21}}
:style {:padding-left 21}}
(i18n/label :t/cancel)]
[react/text {:style {:color colors/gray}}
(i18n/label :t/step-i-of-n {:step 3 :number 3})]]
@ -348,20 +348,17 @@
:accessibility-label :word-number}
(i18n/label :t/word-n {:number (inc idx)})]]]
[react/view
[text-input/text-input-with-label
[react/view {:flex 1
:padding 16
:justify-content :center}
[quo/text-input
{:on-change-text #(re-frame/dispatch [:keycard.onboarding.recovery-phrase-confirm-word.ui/input-changed %])
:auto-focus true
:on-submit-editing #(re-frame/dispatch [:keycard.onboarding.recovery-phrase-confirm-word.ui/input-submitted])
:placeholder nil
:placeholder (i18n/label :t/word-n {:number (inc idx)})
:auto-correct false
:keyboard-type "visible-password"
:accessibility-label :enter-word
:container {:background-color colors/white}
:style {:background-color colors/white
:text-align :center
:height 52
:typography :header}}]
:monospace true}]
[react/view {:margin-top 5
:width 250}
[tooltip/tooltip error]]]
@ -380,5 +377,5 @@
{:on-press #(re-frame/dispatch [:keycard.onboarding.recovery-phrase-confirm-word.ui/next-pressed])
:label (i18n/label :t/next)
:accessibility-label :next
:disabled? (empty? input-word)
:forward? true}]]]]])))
:disabled? (empty? input-word)
:forward? true}]]]]])))

View File

@ -7,7 +7,6 @@
[status-im.ui.components.common.common :as components.common]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.react :as react]
[status-im.ui.components.text-input.view :as text-input]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.components.tooltip.views :as tooltip]
[status-im.ui.components.topbar :as topbar]
@ -16,6 +15,7 @@
[status-im.utils.core :as utils.core]
[status-im.utils.gfycat.core :as gfy]
[status-im.constants :as constants]
[quo.core :as quo]
[status-im.ui.screens.keycard.views :as keycard.views]
[status-im.utils.identicon :as identicon])
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
@ -147,16 +147,15 @@
:color (if (> 3 free-pairing-slots) colors/red colors/gray)}}
(i18n/label :t/keycard-free-pairing-slots {:n free-pairing-slots})]])]
[react/view
[text-input/text-input-with-label
{:on-change-text #(re-frame/dispatch [:keycard.onboarding.pair.ui/input-changed %])
:auto-focus true
:on-submit-editing #(re-frame/dispatch [:keycard.onboarding.pair.ui/input-submitted])
:placeholder nil
:text-align :center
:container {:background-color colors/white}
:style {:background-color colors/white
:height 24
:typography :header}}]
[react/view {:flex 1
:padding 16
:justify-content :center}
[quo/text-input
{:on-change-text #(re-frame/dispatch [:keycard.onboarding.pair.ui/input-changed %])
:auto-focus true
:on-submit-editing #(re-frame/dispatch [:keycard.onboarding.pair.ui/input-submitted])
:placeholder (i18n/label :t/pair-code-placeholder)
:monospace true}]]
[react/view {:margin-top 5
:width 250}
[tooltip/tooltip error]]]

View File

@ -6,13 +6,13 @@
[status-im.ui.components.colors :as colors]
[status-im.ui.components.common.common :as components.common]
[status-im.ui.components.react :as react]
[status-im.ui.components.text-input.view :as text-input]
[status-im.ui.screens.chat.photos :as photos]
[status-im.ui.screens.multiaccounts.login.styles :as styles]
[status-im.ui.screens.multiaccounts.styles :as ast]
[status-im.utils.platform :as platform]
[status-im.utils.security :as security]
[status-im.utils.utils :as utils]
[quo.core :as quo]
[status-im.ui.components.icons.vector-icons :as icons]
[status-im.ui.components.topbar :as topbar])
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
@ -53,11 +53,12 @@
:important-for-accessibility :no-hide-descendants}
[react/view {:flex-direction :row :align-items :center}
[react/view {:flex 1}
[text-input/text-input-with-label
[quo/text-input
{:placeholder (i18n/label :t/enter-your-password)
:ref #(reset! password-text-input %)
:get-ref #(reset! password-text-input %)
:auto-focus (= view-id :login)
:accessibility-label :password-input
:show-cancel false
:on-submit-editing (when sign-in-enabled?
#(login-multiaccount @password-text-input))
:on-change-text #(do

View File

@ -1,6 +1,5 @@
(ns status-im.ui.screens.offline-messaging-settings.edit-mailserver.styles
(:require [status-im.ui.components.styles :as components.styles]
[status-im.ui.components.colors :as colors]
(:require [status-im.ui.components.colors :as colors]
[status-im.utils.styles :as styles]))
(def edit-mailserver-view
@ -8,14 +7,6 @@
:margin-horizontal 16
:margin-vertical 15})
(def input-container
{:flex-direction :row
:align-items :center
:justify-content :space-between
:border-radius components.styles/border-radius
:height 52
:margin-bottom 15})
(def qr-code
{:padding 16})

View File

@ -8,10 +8,9 @@
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.styles :as components.styles]
[status-im.ui.components.common.common :as components.common]
[status-im.ui.components.text-input.view :as text-input]
[status-im.ui.screens.offline-messaging-settings.edit-mailserver.styles :as styles]
[status-im.ui.components.tooltip.views :as tooltip]
[clojure.string :as string]
[quo.core :as quo]
[status-im.ui.components.topbar :as topbar]))
(defn connect-button [id]
@ -54,29 +53,26 @@
[topbar/topbar {:title (if id :t/mailserver-details :t/add-mailserver)}]
[react/scroll-view {:keyboard-should-persist-taps :handled}
[react/view styles/edit-mailserver-view
[text-input/text-input-with-label
{:label (i18n/label :t/name)
:placeholder (i18n/label :t/specify-name)
:container styles/input-container
:default-value name
:on-change-text #(re-frame/dispatch [:mailserver.ui/input-changed :name %])
:auto-focus true}]
[react/view
{:flex 1}
[text-input/text-input-with-label
[react/view {:padding-vertical 8}
[quo/text-input
{:label (i18n/label :t/name)
:placeholder (i18n/label :t/specify-name)
:default-value name
:on-change-text #(re-frame/dispatch [:mailserver.ui/input-changed :name %])
:auto-focus true}]]
[react/view {:flex 1
:padding-vertical 8}
[quo/text-input
{:label (i18n/label :t/mailserver-address)
:placeholder (i18n/label :t/mailserver-format)
:content qr-code
:container styles/input-container
:default-value url
:on-change-text #(re-frame/dispatch [:mailserver.ui/input-changed :url %])}]
(when (and (not (string/blank? url))
invalid-url?)
[tooltip/tooltip (i18n/label :t/invalid-format
{:format (i18n/label :t/mailserver-format)})
{:color colors/red-light
:font-size 12
:bottom-value 25}])]
:on-change-text #(re-frame/dispatch [:mailserver.ui/input-changed :url %])
:bottom-value 0
:error (when (and (not (string/blank? url))
invalid-url?)
(i18n/label :t/invalid-format
{:format (i18n/label :t/mailserver-format)}))}]]
(when (and id
(not connected?))
[react/view

View File

@ -1,6 +1,5 @@
(ns status-im.ui.screens.pairing.styles
(:require [status-im.ui.components.colors :as colors]
[status-im.ui.components.styles :as components.styles]
[status-im.utils.styles :as styles]))
(def wrapper
@ -76,16 +75,4 @@
(def bottom-container
{:flex-direction :row
:margin-horizontal 12
:margin-vertical 15})
(def input-container
{:flex-direction :row
:align-items :center
:justify-content :space-between
:border-radius components.styles/border-radius
:height 52
:margin-top 15})
(styles/def input
{:flex 1
:android {:padding 0}})
:margin-vertical 15})

View File

@ -12,7 +12,7 @@
[status-im.ui.components.checkbox.view :as checkbox.views]
[status-im.ui.components.list.views :as list]
[status-im.ui.components.react :as react]
[status-im.ui.components.text-input.view :as text-input]
[quo.core :as quo]
[status-im.ui.screens.pairing.styles :as styles]
[status-im.ui.components.topbar :as topbar]))
@ -138,15 +138,13 @@
[react/keyboard-avoiding-view styles/edit-installation
[react/scroll-view {:keyboard-should-persist-taps :handled}
[react/view
[react/text (i18n/label :t/pairing-please-set-a-name)]]
[text-input/text-input-with-label
{:placeholder (i18n/label :t/specify-name)
:style styles/input
:accessibility-label :device-name
:container styles/input-container
:default-value @installation-name
:on-change-text #(reset! installation-name %)
:auto-focus true}]]
[quo/text-input
{:placeholder (i18n/label :t/specify-name)
:label (i18n/label :t/pairing-please-set-a-name)
:accessibility-label :device-name
:default-value @installation-name
:on-change-text #(reset! installation-name %)
:auto-focus true}]]]
[react/view styles/bottom-container
[react/view components.styles/flex]
[components.common/bottom-button

View File

@ -3,38 +3,6 @@
;; profile header elements
(def profile-header-display
{:flex-direction :row
:justify-content :flex-start
:align-items :center})
(def profile-name-text
{:typography :header
:line-height 28
:text-align :left})
(def profile-name-text-with-subtitle
{:margin-vertical 5
:typography :header
:line-height 28
:text-align :left})
(def profile-three-words
{:color colors/gray})
(def profile-header-name-container
{:flex 1
:justify-content :center
:align-items :flex-start
:margin-left 16})
(def profile-header-name-container-with-subtitle
{:flex 1
:justify-content :flex-start
:align-items :flex-start
:align-self :stretch
:margin-left 16})
;; settings items elements
(def settings-item

View File

@ -71,17 +71,6 @@
{:flex 1
:padding 16})
(def enter-word-row
{:flex-direction :row})
(def enter-word-label
{:font-size 14})
(def enter-word-n
{:margin-left 8
:font-size 14
:color colors/gray})
(def enter-word-n-description
{:font-size 14
:color colors/gray})

View File

@ -7,13 +7,13 @@
[status-im.ui.components.common.common :as components.common]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im.ui.components.text-input.view :as text-input]
[status-im.ui.components.icons.vector-icons :as icons]
[status-im.ui.components.common.styles :as components.common.styles]
[clojure.string :as string]
[status-im.utils.utils :as utils]
[status-im.ui.screens.profile.seed.styles :as styles]
[status-im.i18n :as i18n]
[quo.core :as quo]
[status-im.utils.platform :as platform]))
(def steps-numbers
@ -77,10 +77,15 @@
{:forward? true
:on-press #(re-frame/dispatch [:my-profile/enter-two-random-words])}]]]))
(defview input [error next-handler]
(defview input [error next-handler idx]
(letsubs [ref (reagent/atom nil)]
[text-input/text-input-with-label
[quo/text-input
{:placeholder (i18n/label :t/enter-word)
:label [:<>
(i18n/label :t/check-your-recovery-phrase)
" "
[quo/text {:color :secondary}
(i18n/label :t/word-n {:number (inc idx)})]]
:ref (partial reset! ref)
:auto-focus true
:auto-correct false
@ -106,12 +111,8 @@
(defn enter-word [step [idx word] error entered-word]
^{:key word}
[react/view {:style styles/enter-word-container}
[react/view {:style styles/enter-word-row}
[react/text {:style styles/enter-word-label}
(i18n/label :t/check-your-recovery-phrase)]
[react/text {:style styles/enter-word-n}
(i18n/label :t/word-n {:number (inc idx)})]]
[input error (next-handler word entered-word step)]
[react/view {:padding-bottom 8}
[input error (next-handler word entered-word step) idx]]
[react/text {:style styles/enter-word-n-description}
(i18n/label :t/word-n-description {:number (inc idx)})]
[react/view styles/twelve-words-spacer]

View File

@ -10,6 +10,8 @@
[taoensso.timbre :as log]
[status-im.utils.platform :as platform]
[status-im.ui.components.react :as react]
;; NOTE(Ferossgp): This is temporary to mimic the behaviour of old input
[quo.components.text-input :as quo]
[oops.core :refer [ocall oget]]))
(def navigation-container (reagent/adapt-react-class NavigationContainer))
@ -57,6 +59,9 @@
(fn []
;; Reset currently mounted text inputs to their default values
;; on navigating away; this is a privacy measure
(println @quo/text-input-refs)
(doseq [[_ {:keys [ref value]}] @quo/text-input-refs]
(.setNativeProps ^js ref (clj->js {:text value})))
(doseq [[^js text-input default-value] @react/text-input-refs]
(.setNativeProps text-input (clj->js {:text default-value}))))))
#js [navigation]))

View File

@ -2,7 +2,7 @@
(:require-macros [status-im.utils.views :as views])
(:require [status-im.ui.components.react :as react]
[re-frame.core :as re-frame]
[status-im.ui.components.text-input.view :as text-input]
[quo.core :as quo]
[status-im.i18n :as i18n]
[status-im.ui.components.button :as button]
[status-im.ui.components.colors :as colors]))
@ -12,9 +12,11 @@
[react/view
[react/view {:style {:margin-horizontal 16 :margin-top 8}}
[react/text {:style {:typography :title-bold}} (i18n/label :t/network-fee)]
[react/view {:style {:flex-direction :row :margin-top 8}}
[react/view {:style {:flex-direction :row
:margin-top 8
:align-items :flex-end}}
[react/view {:flex 1}
[text-input/text-input-with-label
[quo/text-input
{:on-change-text #(re-frame/dispatch [:signing.edit-fee.ui/edit-value :gas %])
:label (i18n/label :t/gas-limit)
:error (:error gas-edit)
@ -22,9 +24,11 @@
:keyboard-type :numeric
:auto-capitalize :none
:placeholder "0"
:show-cancel false
:auto-focus false}]]
[react/view {:flex 1 :margin-left 33}
[text-input/text-input-with-label
[react/view {:flex 1
:padding-left 16}
[quo/text-input
{:label (i18n/label :t/gas-price)
:on-change-text #(re-frame/dispatch [:signing.edit-fee.ui/edit-value :gasPrice %])
:error (:error gas-price-edit)
@ -32,9 +36,12 @@
:keyboard-type :numeric
:auto-capitalize :none
:placeholder "0.000"
:show-cancel false
:auto-focus false}]]
[react/view {:margin-top 58 :margin-left 10}
[react/view {:padding-left 8
:padding-bottom 12}
[react/text (i18n/label :t/gwei)]]]
[react/view {:margin-vertical 16 :align-items :center}
[react/text {:style {:color colors/gray}} (i18n/label :t/wallet-transaction-total-fee)]
[react/view {:height 8}]
@ -51,4 +58,4 @@
{:type :secondary
:on-press #(re-frame/dispatch [:signing.edit-fee.ui/submit])
:disabled? (or (:error gas-edit) (:error gas-price-edit))
:label :t/update}]]]))
:label :t/update}]]]))

View File

@ -57,23 +57,4 @@
:padding-left 16
:color (if disabled? colors/black colors/white-persist)
:padding-horizontal 16
:padding-vertical 10})
(defn sheet-title [small-screen?]
{:font-weight "500"
:font-size (if small-screen? 16 19)
:margin-top 16})
(defn sheet-subtitle [small-screen?]
{:font-size (if small-screen? 16 19)
:text-align :center
:margin-bottom 12
:color colors/gray})
(defn sheet-icon [bg-color]
{:height 64
:width 64
:border-radius 32
:justify-content :center
:align-items :center
:background-color bg-color})
:padding-vertical 10})

View File

@ -13,7 +13,7 @@
[status-im.ui.screens.keycard.keycard-interaction :as keycard-sheet]
[status-im.ui.components.chat-icon.screen :as chat-icon]
[status-im.ui.components.icons.vector-icons :as icons]
[status-im.ui.components.text-input.view :as text-input]
[quo.core :as quo]
[status-im.i18n :as i18n]
[status-im.utils.security :as security]
[status-im.ui.screens.signing.sheets :as sheets]
@ -258,15 +258,17 @@
:password
[react/view {:padding-top 8 :padding-bottom 8}
[signing-phrase-view phrase]
[text-input/text-input-with-label
{:secure-text-entry true
:placeholder (i18n/label :t/enter-password)
:on-change-text #(re-frame/dispatch [:signing.ui/password-is-changed (security/mask-data %)])
:accessibility-label :enter-password-input
:auto-capitalize :none
:editable (not in-progress?)
:error error
:container {:margin-top 12 :margin-bottom 12 :margin-horizontal 16}}]
[react/view {:padding-horizontal 16
:padding-vertical 12}
[quo/text-input
{:secure-text-entry true
:placeholder (i18n/label :t/enter-password)
:on-change-text #(re-frame/dispatch [:signing.ui/password-is-changed (security/mask-data %)])
:accessibility-label :enter-password-input
:auto-capitalize :none
:editable (not in-progress?)
:error error
:show-cancel false}]]
[react/view {:align-items :center :height 60}
(if in-progress?
[react/activity-indicator {:animating true

View File

@ -1,7 +1,6 @@
(ns status-im.ui.screens.wallet.account-settings.views
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [status-im.ui.components.react :as react]
[status-im.ui.components.text-input.view :as text-input]
[re-frame.core :as re-frame]
[status-im.i18n :as i18n]
[status-im.ui.components.icons.vector-icons :as icons]
@ -9,6 +8,7 @@
[status-im.ui.components.toolbar :as toolbar]
[status-im.ui.components.copyable-text :as copyable-text]
[reagent.core :as reagent]
[quo.core :as quo]
[status-im.ui.components.list-item.views :as list-item]
[status-im.ui.components.topbar :as topbar]))
@ -57,14 +57,13 @@
:style {:flex 1}}
[react/view {:padding-bottom 28 :padding-top 10}
[react/view {:margin-horizontal 16}
[text-input/text-input-with-label
[quo/text-input
{:label (i18n/label :t/account-name)
:label-style {:color colors/gray}
:auto-focus false
:default-value (:name account)
:accessibility-label :enter-account-name
:on-change-text #(swap! new-account assoc :name %)}]
[react/text {:style {:margin-top 30 :color colors/gray}} (i18n/label :t/account-color)]
[react/text {:style {:margin-top 16 :color colors/gray}} (i18n/label :t/account-color)]
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:show-popover
{:view [colors-popover color

View File

@ -11,13 +11,12 @@
[status-im.ui.components.toolbar :as toolbar]
[status-im.ui.components.topbar :as topbar]
[status-im.utils.utils :as utils.utils]
[status-im.ui.components.text-input.view :as text-input]
[status-im.ui.components.icons.vector-icons :as icons]
[status-im.ui.screens.wallet.account-settings.views :as account-settings]
[status-im.ethereum.core :as ethereum]
[status-im.utils.security :as security]
[clojure.string :as string]
[status-im.utils.platform :as platform]
[quo.core :as quo]
[status-im.ui.components.bottom-panel.views :as bottom-panel]))
(defn- request-camera-permissions []
@ -48,8 +47,8 @@
:handler #(request-camera-permissions)}]}))]))
(defn common-settings [account]
[react/view {:margin-horizontal 16 :margin-top 30}
[text-input/text-input-with-label
[react/view {:margin-horizontal 16}
[quo/text-input
{:label (i18n/label :t/account-name)
:auto-focus false
:default-value (:name account)
@ -65,24 +64,25 @@
(re-frame/dispatch [:set-in [:add-account :account :color] new-color])
(re-frame/dispatch [:hide-popover]))]
:style {:max-height "60%"}}])}
[react/view {:height 52 :margin-top 12 :background-color (:color account) :border-radius 8
:align-items :flex-end :justify-content :center :padding-right 12}
[react/view {:height 52 :margin-top 12 :background-color (:color account) :border-radius 8
:align-items :flex-end :justify-content :center :padding-right 12}
[icons/icon :main-icons/dropdown {:color colors/white}]]]])
(defn settings [{:keys [type scanned-address password-error account-error]}
entered-password]
[react/view {:margin-horizontal 16}
[react/view {:padding-horizontal 16
:padding-vertical 16}
(if (= type :watch)
[text-input/text-input-with-label
[quo/text-input
{:label (i18n/label :t/wallet-key-title)
:auto-focus false
:default-value scanned-address
:placeholder (i18n/label :t/enter-address)
:accessibility-label :add-account-enter-watch-address
:on-change-text #(re-frame/dispatch [:set-in [:add-account :address] %])}]
[text-input/text-input-with-label
[quo/text-input
{:label (i18n/label :t/password)
:parent-container {:margin-top 30}
:show-cancel false
:auto-focus false
:placeholder (i18n/label :t/enter-your-password)
:secure-text-entry true
@ -93,39 +93,37 @@
(re-frame/dispatch [:set-in [:add-account :password-error] nil])
(reset! entered-password %))}])
(when (= type :seed)
[text-input/text-input-with-label
{:parent-container {:margin-top 30}
:label (i18n/label :t/recovery-phrase)
:auto-focus false
:placeholder (i18n/label :t/multiaccounts-recover-enter-phrase-title)
:auto-correct false
:keyboard-type "visible-password"
:multiline true
:style (when platform/android?
{:flex 1})
:height 95
:error account-error
:accessibility-label :add-account-enter-seed
:on-change-text
#(do
(re-frame/dispatch [:set-in [:add-account :account-error] nil])
(re-frame/dispatch [:set-in [:add-account :seed] (security/mask-data (string/lower-case %))]))}])
[react/view {:padding-top 16}
[quo/text-input
{:label (i18n/label :t/recovery-phrase)
:auto-focus false
:placeholder (i18n/label :t/multiaccounts-recover-enter-phrase-title)
:auto-correct false
:keyboard-type "visible-password"
:multiline true
:height 95
:error account-error
:accessibility-label :add-account-enter-seed
:on-change-text
#(do
(re-frame/dispatch [:set-in [:add-account :account-error] nil])
(re-frame/dispatch [:set-in [:add-account :seed] (security/mask-data (string/lower-case %))]))}]])
(when (= type :key)
[text-input/text-input-with-label
{:parent-container {:margin-top 30}
:label (i18n/label :t/private-key)
:auto-focus false
:placeholder (i18n/label :t/enter-a-private-key)
:auto-correct false
:keyboard-type "visible-password"
:error account-error
:secure-text-entry true
:accessibility-label :add-account-enter-private-key
:text-content-type :none
:on-change-text
#(do
(re-frame/dispatch [:set-in [:add-account :account-error] nil])
(re-frame/dispatch [:set-in [:add-account :private-key] (security/mask-data %)]))}])])
[react/view {:margin-top 30}
[quo/text-input
{:label (i18n/label :t/private-key)
:auto-focus false
:placeholder (i18n/label :t/enter-a-private-key)
:auto-correct false
:keyboard-type "visible-password"
:error account-error
:secure-text-entry true
:accessibility-label :add-account-enter-private-key
:text-content-type :none
:on-change-text
#(do
(re-frame/dispatch [:set-in [:add-account :account-error] nil])
(re-frame/dispatch [:set-in [:add-account :private-key] (security/mask-data %)]))}]])])
(defview pin []
(letsubs [pin [:hardwallet/pin]

View File

@ -6,7 +6,7 @@
[status-im.ui.components.react :as react]
[status-im.ui.components.toolbar.view :as topbar]
[status-im.ui.screens.wallet.components.styles :as styles]
[status-im.ui.components.text-input.view :as text-input]
[quo.core :as quo]
[status-im.ui.components.colors :as colors]
[status-im.utils.debounce :as debounce])
(:require-macros [status-im.utils.views :as views]))
@ -37,10 +37,9 @@
[react/view {:padding-horizontal 16
:padding-vertical 24
:flex 1}
[text-input/text-input-with-label
[quo/text-input
{:multiline true
:container {:height 98
:padding-vertical 8}
:height 98
:placeholder (i18n/label :t/recipient-code-placeholder)
:text-align-vertical :top
:on-change-text #(reset! content %)

View File

@ -3,10 +3,10 @@
(:require [re-frame.core :as re-frame]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.react :as react]
[status-im.ui.components.text-input.view :as text-input]
[status-im.ui.components.common.common :as components.common]
[clojure.string :as string]
[status-im.i18n :as i18n]
[quo.core :as quo]
[status-im.ui.components.list-item.views :as list-item]
[status-im.ui.components.topbar :as topbar]))
@ -25,58 +25,66 @@
[:wallet/custom-token-screen]]
[react/keyboard-avoiding-view {:flex 1 :background-color colors/white}
[topbar/topbar {:title :t/add-custom-token}]
[react/scroll-view {:keyboard-should-persist-taps :handled :style {:flex 1 :margin-top 8 :padding-horizontal 16}}
[react/view {:style {:flex-direction :row :justify-content :space-between :padding-vertical 10}}
[react/text (i18n/label :t/contract-address)]
(when in-progress?
[react/view {:flex-direction :row :justify-content :center}
[react/view {:height 20}
[react/activity-indicator {:width 24 :height 24 :animating true}]]
[react/text {:style {:color colors/gray :margin-left 5}}
(i18n/label :t/processing)]])]
(when-not in-progress?
;;tooltip covers button
[react/view {:position :absolute :z-index 1000 :right 0 :top 10}
[react/touchable-highlight {:on-press #(re-frame/dispatch [:wallet.custom-token.ui/contract-address-paste])}
[react/text {:style {:color colors/blue}}
(i18n/label :t/paste)]]])
[text-input/text-input-with-label
{:on-change-text #(debounce-and-save :contract %)
:error error
:default-value contract
:multiline true
:height 78
:auto-focus false
:placeholder (i18n/label :t/specify-address)}]
[react/view {:height 16}]
[text-input/text-input-with-label
{:on-change-text #(debounce-and-save :name %)
:label (i18n/label :t/name)
:default-value name
:error error-name
:auto-focus false
:placeholder (i18n/label :t/name-of-token)}]
[react/view {:height 16}]
[react/view {:style {:flex-direction :row}}
[react/view {:flex 1}
[text-input/text-input-with-label
{:on-change-text #(debounce-and-save :symbol %)
:label (i18n/label :t/symbol)
:error error-symbol
:default-value symbol
:auto-focus false
:placeholder "ABC"}]]
[react/view {:flex 1 :margin-left 33}
[text-input/text-input-with-label
{:label (i18n/label :t/decimals)
:on-change-text #(debounce-and-save :decimals %)
:default-value decimals
:keyboard-type :number-pad
:max-length 2
:auto-focus false
:placeholder "18"}]]]
[react/view {:height 16}]
#_[text-input/text-input-with-label
[react/scroll-view {:keyboard-should-persist-taps :handled
:style {:flex 1
:padding-horizontal 16}}
[react/view {:padding-vertical 8}
[react/view {:style {:flex-direction :row
:justify-content :space-between
:padding-vertical 10}}
[react/text (i18n/label :t/contract-address)]
(when in-progress?
[react/view {:flex-direction :row :justify-content :center}
[react/view {:height 20}
[react/activity-indicator {:width 24 :height 24 :animating true}]]
[react/text {:style {:color colors/gray :margin-left 5}}
(i18n/label :t/processing)]])]
(when-not in-progress?
;;tooltip covers button
[react/view {:position :absolute :z-index 1000 :right 0 :top 10}
[react/touchable-highlight {:on-press #(re-frame/dispatch [:wallet.custom-token.ui/contract-address-paste])}
[react/text {:style {:color colors/blue}}
(i18n/label :t/paste)]]])
[quo/text-input
{:on-change-text #(debounce-and-save :contract %)
:error error
:default-value contract
:multiline true
:height 78
:auto-focus false
:placeholder (i18n/label :t/specify-address)}]]
[react/view {:padding-vertical 8}
[quo/text-input
{:on-change-text #(debounce-and-save :name %)
:label (i18n/label :t/name)
:default-value name
:error error-name
:auto-focus false
:placeholder (i18n/label :t/name-of-token)}]]
[react/view {:padding-vertical 8}
[react/view {:style {:flex-direction :row}}
[react/view {:flex 1
:padding-right 8}
[quo/text-input
{:on-change-text #(debounce-and-save :symbol %)
:label (i18n/label :t/symbol)
:error error-symbol
:default-value symbol
:auto-focus false
:show-cancel false
:placeholder "ABC"}]]
[react/view {:flex 1
:padding-left 8}
[quo/text-input
{:label (i18n/label :t/decimals)
:on-change-text #(debounce-and-save :decimals %)
:default-value decimals
:keyboard-type :number-pad
:max-length 2
:auto-focus false
:show-cancel false
:placeholder "18"}]]]]
#_[quo/text-input
{:label (i18n/label :t/balance)
:default-value (when (and balance decimals)
(wallet.utils/format-amount balance decimals))
@ -105,35 +113,39 @@
[react/keyboard-avoiding-view {:flex 1 :background-color colors/white}
[topbar/topbar {:title name}]
[react/scroll-view {:keyboard-should-persist-taps :handled
:style {:flex 1 :margin-top 8}}
:style {:flex 1}}
[react/view {:padding-horizontal 16}
[text-input/text-input-with-label
{:label (i18n/label :t/contract-address)
:default-value address
:multiline true
:height 78
:editable false}]
[react/view {:height 16}]
[text-input/text-input-with-label
{:label (i18n/label :t/name)
:default-value name
:editable false}]
[react/view {:height 16}]
[react/view {:style {:flex-direction :row}}
[react/view {:flex 1}
[text-input/text-input-with-label
{:label (i18n/label :t/symbol)
:editable false
:default-value symbol}]]
[react/view {:flex 1 :margin-left 33}
[text-input/text-input-with-label
{:label (i18n/label :t/decimals)
:default-value (str decimals)
:editable false}]]]]
[react/view {:padding-vertical 8}
[quo/text-input
{:label (i18n/label :t/contract-address)
:default-value address
:multiline true
:height 78
:editable false}]]
[react/view {:padding-vertical 8}
[quo/text-input
{:label (i18n/label :t/name)
:default-value name
:editable false}]]
[react/view {:padding-vertical 8}
[react/view {:style {:flex-direction :row}}
[react/view {:flex 1
:padding-right 8}
[quo/text-input
{:label (i18n/label :t/symbol)
:editable false
:show-cancel false
:default-value symbol}]]
[react/view {:flex 1 :padding-left 8}
[quo/text-input
{:label (i18n/label :t/decimals)
:show-cancel false
:default-value (str decimals)
:editable false}]]]]]
[react/view {:height 24}]
(when custom?
[list-item/list-item
{:theme :action-destructive
:title :t/remove-token
:icon :main-icons/delete
:on-press #(re-frame/dispatch [:wallet.custom-token.ui/remove-pressed token true])}])]]))
{:theme :action-destructive
:title :t/remove-token
:icon :main-icons/delete
:on-press #(re-frame/dispatch [:wallet.custom-token.ui/remove-pressed token true])}])]]))

View File

@ -74,7 +74,7 @@
[render-token token])
(defview manage-assets []
(letsubs [{search-filter :search-filter
(letsubs [{search-filter :search-filter
{custom-tokens true default-tokens nil} :tokens} [:wallet/filtered-grouped-chain-tokens]]
{:component-will-unmount #(do
(re-frame/dispatch [:search/token-filter-changed nil])
@ -82,33 +82,35 @@
[react/view (merge components.styles/flex {:background-color colors/white})
[toolbar]
[react/view {:style components.styles/flex}
[search-input/search-input
{:search-active? search-active?
:search-filter search-filter
:on-cancel #(re-frame/dispatch [:search/token-filter-changed nil])
:on-focus (fn [search-filter]
(when-not search-filter
(re-frame/dispatch [:search/token-filter-changed ""])))
:on-change (fn [text]
(re-frame/dispatch [:search/token-filter-changed text]))}]
[react/view {:padding-horizontal 16
:padding-vertical 10}
[search-input/search-input
{:search-active? search-active?
:search-filter search-filter
:on-cancel #(re-frame/dispatch [:search/token-filter-changed nil])
:on-focus (fn [search-filter]
(when-not search-filter
(re-frame/dispatch [:search/token-filter-changed ""])))
:on-change (fn [text]
(re-frame/dispatch [:search/token-filter-changed text]))}]]
[list/section-list
{:header
[react/view {:margin-top 16}
[list-item/list-item
{:theme :action
:title :t/add-custom-token
:icon :main-icons/add
{:theme :action
:title :t/add-custom-token
:icon :main-icons/add
:on-press
#(re-frame/dispatch [:navigate-to :wallet-add-custom-token])}]]
:sections (concat
(when (seq custom-tokens)
[{:title (i18n/label :t/custom)
:data custom-tokens}])
[{:title (i18n/label :t/default)
:data default-tokens}])
:key-fn :address
:sections (concat
(when (seq custom-tokens)
[{:title (i18n/label :t/custom)
:data custom-tokens}])
[{:title (i18n/label :t/default)
:data default-tokens}])
:key-fn :address
:stickySectionHeadersEnabled false
:render-section-header-fn
(fn [{:keys [title]}]
[list-item/list-item {:type :section-header :title title}])
:render-fn render-token-wrapper}]]]))
:render-fn render-token-wrapper}]]]))

View File

@ -414,6 +414,7 @@
"enter-address": "Enter address",
"enter-contact-code": "Enter ENS username or chat key",
"enter-pair-code": "Enter your pairing code",
"pair-code-placeholder": "Pair code...",
"enter-pair-code-description": "Pairing code was displayed to you during the Keycard setup",
"enter-password": "Enter password",
"enter-pin": "Enter 6-digit passcode",
@ -1081,6 +1082,7 @@
"welcome-to-status": "Welcome to Status!",
"welcome-to-status-description": "Set up your crypto wallet, invite friends to chat and browse decentralized apps",
"welcome-blank-message": "Your chats will appear here. To start new chats press the ⊕ button",
"seed-phrase-placeholder": "Seed phrase...",
"word-count": "Word count",
"word-n": "Word #{{number}}",
"word-n-description": "In order to check if you have backed up your seed phrase correctly, enter the word #{{number}} above.",