|
8 | 8 | [status-im.common.floating-button-page.view :as floating-button-page]
|
9 | 9 | [status-im.contexts.wallet.add-address-to-watch.style :as style]
|
10 | 10 | [status-im.contexts.wallet.common.validation :as validation]
|
| 11 | + [status-im.subs.wallet.add-account.address-to-watch] |
| 12 | + [utils.debounce :as debounce] |
11 | 13 | [utils.i18n :as i18n]
|
12 | 14 | [utils.re-frame :as rf]))
|
13 | 15 |
|
14 |
| -(defn validate-message |
15 |
| - [addresses] |
16 |
| - (fn [s] |
17 |
| - (cond |
18 |
| - (or (= s nil) (= s "")) nil |
19 |
| - (contains? addresses s) (i18n/label :t/address-already-in-use) |
20 |
| - (not (or (validation/eth-address? s) |
21 |
| - (validation/ens-name? s))) (i18n/label :t/invalid-address) |
22 |
| - :else nil))) |
| 16 | +(defn- validate-address |
| 17 | + [known-addresses user-input] |
| 18 | + (cond |
| 19 | + (or (nil? user-input) (= user-input "")) nil |
| 20 | + (contains? known-addresses user-input) (i18n/label :t/address-already-in-use) |
| 21 | + (not |
| 22 | + (or (validation/eth-address? user-input) |
| 23 | + (validation/ens-name? user-input))) (i18n/label :t/invalid-address))) |
23 | 24 |
|
24 | 25 | (defn- address-input
|
25 |
| - [{:keys [input-value validation-msg validate |
26 |
| - clear-input]}] |
| 26 | + [{:keys [input-value validation-msg validate clear-input]}] |
27 | 27 | (let [scanned-address (rf/sub [:wallet/scanned-address])
|
28 | 28 | empty-input? (and (string/blank? @input-value)
|
29 | 29 | (string/blank? scanned-address))
|
|
32 | 32 | (reset! input-value new-text)
|
33 | 33 | (reagent/flush)
|
34 | 34 | (if (and (not-empty new-text) (nil? (validate new-text)))
|
35 |
| - (rf/dispatch [:wallet/get-address-details new-text]) |
36 |
| - (rf/dispatch [:wallet/clear-address-activity-check])) |
| 35 | + (debounce/debounce-and-dispatch [:wallet/get-address-details new-text] |
| 36 | + 500) |
| 37 | + (rf/dispatch [:wallet/clear-address-activity])) |
37 | 38 | (when (and scanned-address (not= scanned-address new-text))
|
38 |
| - (rf/dispatch [:wallet/clear-address-activity-check]) |
| 39 | + (rf/dispatch [:wallet/clear-address-activity]) |
39 | 40 | (rf/dispatch [:wallet/clean-scanned-address])))
|
40 | 41 | paste-on-input #(clipboard/get-string
|
41 | 42 | (fn [clipboard-text]
|
|
44 | 45 | (when-not (string/blank? scanned-address)
|
45 | 46 | (on-change-text scanned-address)))
|
46 | 47 | [scanned-address])
|
47 |
| - [rn/view |
48 |
| - {:style style/input-container} |
| 48 | + [rn/view {:style style/input-container} |
49 | 49 | [quo/input
|
50 | 50 | {:accessibility-label :add-address-to-watch
|
51 | 51 | :placeholder (i18n/label :t/address-placeholder)
|
|
72 | 72 | :i/scan]]))
|
73 | 73 |
|
74 | 74 | (defn activity-indicator
|
75 |
| - [] |
76 |
| - (let [activity-state (rf/sub [:wallet/watch-address-activity-state]) |
77 |
| - {:keys [accessibility-label icon type message]} |
78 |
| - (case activity-state |
79 |
| - :has-activity {:accessibility-label :account-has-activity |
80 |
| - :icon :i/done |
81 |
| - :type :success |
82 |
| - :message :t/this-address-has-activity} |
83 |
| - :no-activity {:accessibility-label :account-has-no-activity |
84 |
| - :icon :i/info |
85 |
| - :type :warning |
86 |
| - :message :t/this-address-has-no-activity} |
87 |
| - {:accessibility-label :searching-for-activity |
88 |
| - :icon :i/pending-state |
89 |
| - :type :default |
90 |
| - :message :t/searching-for-activity})] |
| 75 | + [activity-state] |
| 76 | + (let [{:keys [message] |
| 77 | + :as props} (case activity-state |
| 78 | + :has-activity {:accessibility-label :account-has-activity |
| 79 | + :icon :i/done |
| 80 | + :type :success |
| 81 | + :message :t/this-address-has-activity} |
| 82 | + :no-activity {:accessibility-label :account-has-no-activity |
| 83 | + :icon :i/info |
| 84 | + :type :warning |
| 85 | + :message :t/this-address-has-no-activity} |
| 86 | + :invalid-ens {:accessibility-label :error-message |
| 87 | + :icon :i/info |
| 88 | + :type :error |
| 89 | + :message :t/invalid-address} |
| 90 | + :address-already-registered {:accessibility-label :error-message |
| 91 | + :icon :i/info |
| 92 | + :type :error |
| 93 | + :message :t/address-already-in-use} |
| 94 | + {:accessibility-label :searching-for-activity |
| 95 | + :icon :i/pending-state |
| 96 | + :type :default |
| 97 | + :message :t/searching-for-activity})] |
91 | 98 | (when activity-state
|
92 | 99 | [quo/info-message
|
93 |
| - {:accessibility-label accessibility-label |
94 |
| - :size :default |
95 |
| - :icon icon |
96 |
| - :type type |
97 |
| - :style style/info-message} |
| 100 | + (assoc props |
| 101 | + :style style/info-message |
| 102 | + :size :default) |
98 | 103 | (i18n/label message)])))
|
99 | 104 |
|
100 | 105 | (defn view
|
101 | 106 | []
|
102 | 107 | (let [addresses (rf/sub [:wallet/addresses])
|
103 | 108 | input-value (reagent/atom nil)
|
104 |
| - validate (validate-message (set addresses)) |
105 |
| - validation-msg (reagent/atom (validate |
106 |
| - @input-value)) |
| 109 | + validate #(validate-address (set addresses) %) |
| 110 | + validation-msg (reagent/atom nil) |
107 | 111 | clear-input (fn []
|
108 | 112 | (reset! input-value nil)
|
109 | 113 | (reset! validation-msg nil)
|
110 |
| - (rf/dispatch [:wallet/clear-address-activity-check]) |
| 114 | + (rf/dispatch [:wallet/clear-address-activity]) |
111 | 115 | (rf/dispatch [:wallet/clean-scanned-address]))
|
112 | 116 | customization-color (rf/sub [:profile/customization-color])]
|
113 | 117 | (rf/dispatch [:wallet/clean-scanned-address])
|
114 |
| - (rf/dispatch [:wallet/clear-address-activity-check]) |
| 118 | + (rf/dispatch [:wallet/clear-address-activity]) |
115 | 119 | (fn []
|
116 |
| - [rn/view |
117 |
| - {:style {:flex 1}} |
118 |
| - [floating-button-page/view |
119 |
| - {:header [quo/page-nav |
120 |
| - {:type :no-title |
121 |
| - :icon-name :i/close |
122 |
| - :on-press (fn [] |
123 |
| - (rf/dispatch [:wallet/clean-scanned-address]) |
124 |
| - (rf/dispatch [:wallet/clear-address-activity-check]) |
125 |
| - (rf/dispatch [:navigate-back]))}] |
126 |
| - :footer [quo/button |
127 |
| - {:customization-color customization-color |
128 |
| - :disabled? (or (string/blank? @input-value) |
129 |
| - (some? (validate @input-value))) |
130 |
| - :on-press (fn [] |
131 |
| - (rf/dispatch [:navigate-to |
132 |
| - :confirm-address-to-watch |
133 |
| - {:address @input-value}]) |
134 |
| - (clear-input)) |
135 |
| - :container-style {:z-index 2}} |
136 |
| - (i18n/label :t/continue)]} |
137 |
| - [quo/page-top |
138 |
| - {:container-style style/header-container |
139 |
| - :title (i18n/label :t/add-address) |
140 |
| - :description :text |
141 |
| - :description-text (i18n/label :t/enter-eth)}] |
142 |
| - [:f> address-input |
143 |
| - {:input-value input-value |
144 |
| - :validate validate |
145 |
| - :validation-msg validation-msg |
146 |
| - :clear-input clear-input}] |
147 |
| - (when @validation-msg |
148 |
| - [quo/info-message |
149 |
| - {:accessibility-label :error-message |
150 |
| - :size :default |
151 |
| - :icon :i/info |
152 |
| - :type :error |
153 |
| - :style style/info-message} |
154 |
| - @validation-msg]) |
155 |
| - [activity-indicator]]]))) |
| 120 | + (let [activity-state (rf/sub [:wallet/watch-address-activity-state]) |
| 121 | + validated-address (rf/sub [:wallet/watch-address-validated-address])] |
| 122 | + [rn/view {:style {:flex 1}} |
| 123 | + [floating-button-page/view |
| 124 | + {:header [quo/page-nav |
| 125 | + {:type :no-title |
| 126 | + :icon-name :i/close |
| 127 | + :on-press (fn [] |
| 128 | + (rf/dispatch [:wallet/clean-scanned-address]) |
| 129 | + (rf/dispatch [:wallet/clear-address-activity]) |
| 130 | + (rf/dispatch [:navigate-back]))}] |
| 131 | + :footer [quo/button |
| 132 | + {:customization-color customization-color |
| 133 | + :disabled? (or (string/blank? @input-value) |
| 134 | + (some? (validate @input-value)) |
| 135 | + (= activity-state :invalid-ens) |
| 136 | + (= activity-state :scanning) |
| 137 | + (not validated-address)) |
| 138 | + :on-press (fn [] |
| 139 | + (rf/dispatch [:navigate-to |
| 140 | + :confirm-address-to-watch |
| 141 | + {:address validated-address}]) |
| 142 | + (clear-input)) |
| 143 | + :container-style {:z-index 2}} |
| 144 | + (i18n/label :t/continue)]} |
| 145 | + [quo/page-top |
| 146 | + {:container-style style/header-container |
| 147 | + :title (i18n/label :t/add-address) |
| 148 | + :description :text |
| 149 | + :description-text (i18n/label :t/enter-eth)}] |
| 150 | + [:f> address-input |
| 151 | + {:input-value input-value |
| 152 | + :validate validate |
| 153 | + :validation-msg validation-msg |
| 154 | + :clear-input clear-input}] |
| 155 | + (if @validation-msg |
| 156 | + [quo/info-message |
| 157 | + {:accessibility-label :error-message |
| 158 | + :size :default |
| 159 | + :icon :i/info |
| 160 | + :type :error |
| 161 | + :style style/info-message} |
| 162 | + @validation-msg] |
| 163 | + [activity-indicator activity-state])]])))) |
0 commit comments