|
2 | 2 | (:require
|
3 | 3 | [clojure.string :as string]
|
4 | 4 | [quo.core :as quo]
|
5 |
| - [quo.theme :as quo.theme] |
6 |
| - [re-frame.core :as re-frame] |
7 | 5 | [react-native.clipboard :as clipboard]
|
8 | 6 | [react-native.core :as rn]
|
9 | 7 | [reagent.core :as reagent]
|
10 | 8 | [status-im2.contexts.wallet.add-address-to-watch.style :as style]
|
| 9 | + [status-im2.contexts.wallet.common.validation :as validation] |
11 | 10 | [utils.i18n :as i18n]
|
12 | 11 | [utils.re-frame :as rf]))
|
13 | 12 |
|
14 |
| -(defn view-internal |
| 13 | +(defn validate-message |
| 14 | + [addresses] |
| 15 | + (fn [s] |
| 16 | + (cond |
| 17 | + (or (= s nil) (= s "")) nil |
| 18 | + (contains? addresses s) (i18n/label :t/address-already-in-use) |
| 19 | + (not (or (validation/eth-address? s) |
| 20 | + (validation/ens-name? s))) (i18n/label :t/invalid-address) |
| 21 | + :else nil))) |
| 22 | + |
| 23 | +(defn- address-input |
| 24 | + [{:keys [input-value validation-msg validate |
| 25 | + clear-input]}] |
| 26 | + (let [scanned-address (rf/sub [:wallet/scanned-address]) |
| 27 | + empty-input? (and (string/blank? @input-value) |
| 28 | + (string/blank? scanned-address)) |
| 29 | + |
| 30 | + on-change-text (fn [new-text] |
| 31 | + (reset! validation-msg (validate new-text)) |
| 32 | + (reset! input-value new-text) |
| 33 | + (when (and scanned-address (not= scanned-address new-text)) |
| 34 | + (rf/dispatch [:wallet/clean-scanned-address]))) |
| 35 | + paste-on-input #(clipboard/get-string |
| 36 | + (fn [clipboard-text] |
| 37 | + (on-change-text clipboard-text)))] |
| 38 | + (rn/use-effect (fn [] |
| 39 | + (when-not (string/blank? scanned-address) |
| 40 | + (on-change-text scanned-address))) |
| 41 | + [scanned-address]) |
| 42 | + [rn/view |
| 43 | + {:style style/input-container} |
| 44 | + [quo/input |
| 45 | + {:accessibility-label :add-address-to-watch |
| 46 | + :placeholder (i18n/label :t/address-placeholder) |
| 47 | + :container-style style/input |
| 48 | + :label (i18n/label :t/eth-or-ens) |
| 49 | + :auto-capitalize :none |
| 50 | + :multiline? true |
| 51 | + :on-clear clear-input |
| 52 | + :return-key-type :done |
| 53 | + :clearable? (not empty-input?) |
| 54 | + :on-change-text on-change-text |
| 55 | + :button (when empty-input? |
| 56 | + {:on-press paste-on-input |
| 57 | + :text (i18n/label :t/paste)}) |
| 58 | + :value @input-value}] |
| 59 | + [quo/button |
| 60 | + {:type :outline |
| 61 | + :on-press (fn [] |
| 62 | + (rn/dismiss-keyboard!) |
| 63 | + (rf/dispatch [:open-modal :scan-address])) |
| 64 | + :container-style style/scan |
| 65 | + :size 40 |
| 66 | + :icon-only? true} |
| 67 | + :i/scan]])) |
| 68 | + |
| 69 | +(defn view |
15 | 70 | []
|
16 |
| - (let [input-value (reagent/atom "") |
| 71 | + (let [addresses (rf/sub [:wallet/addresses]) |
| 72 | + input-value (reagent/atom nil) |
| 73 | + validate (validate-message (set addresses)) |
| 74 | + validation-msg (reagent/atom (validate |
| 75 | + @input-value)) |
| 76 | + clear-input (fn [] |
| 77 | + (reset! input-value nil) |
| 78 | + (reset! validation-msg nil) |
| 79 | + (rf/dispatch [:wallet/clean-scanned-address])) |
17 | 80 | customization-color (rf/sub [:profile/customization-color])]
|
| 81 | + (rf/dispatch [:wallet/clean-scanned-address]) |
18 | 82 | (fn []
|
19 | 83 | [rn/view
|
20 | 84 | {:style {:flex 1}}
|
21 | 85 | [quo/page-nav
|
22 | 86 | {:type :no-title
|
23 | 87 | :icon-name :i/close
|
24 |
| - :on-press #(rf/dispatch [:navigate-back])}] |
| 88 | + :on-press (fn [] |
| 89 | + (rf/dispatch [:wallet/clean-scanned-address]) |
| 90 | + (rf/dispatch [:navigate-back]))}] |
25 | 91 | [quo/text-combinations
|
26 | 92 | {:container-style style/header-container
|
27 | 93 | :title (i18n/label :t/add-address)
|
28 | 94 | :description (i18n/label :t/enter-eth)}]
|
29 |
| - [rn/view {:style style/input-container} |
30 |
| - [quo/input |
31 |
| - {:label (i18n/label :t/eth-or-ens) |
32 |
| - :button {:on-press (fn [] (clipboard/get-string #(reset! input-value %))) |
33 |
| - :text (i18n/label :t/paste)} |
34 |
| - :placeholder (str "0x123abc... " (string/lower-case (i18n/label :t/or)) " bob.eth") |
35 |
| - :container-style {:margin-right 12 |
36 |
| - :flex 1} |
37 |
| - :weight :monospace |
38 |
| - :on-change-text #(reset! input-value %) |
39 |
| - :default-value @input-value}] |
40 |
| - [quo/button |
41 |
| - {:icon-only? true |
42 |
| - :type :outline} :i/scan]] |
| 95 | + [:f> address-input |
| 96 | + {:input-value input-value |
| 97 | + :validate validate |
| 98 | + :validation-msg validation-msg |
| 99 | + :clear-input clear-input}] |
| 100 | + (when @validation-msg |
| 101 | + [quo/info-message |
| 102 | + {:accessibility-label :error-message |
| 103 | + :size :default |
| 104 | + :icon :i/info |
| 105 | + :type :error |
| 106 | + :style style/info-message} |
| 107 | + @validation-msg]) |
43 | 108 | [quo/button
|
44 | 109 | {:customization-color customization-color
|
45 |
| - :disabled? (clojure.string/blank? @input-value) |
46 |
| - :on-press #(re-frame/dispatch [:navigate-to |
47 |
| - :confirm-address-to-watch |
48 |
| - {:address @input-value}]) |
| 110 | + :disabled? (string/blank? @input-value) |
| 111 | + :on-press #(rf/dispatch [:navigate-to |
| 112 | + :confirm-address-to-watch |
| 113 | + {:address @input-value}]) |
49 | 114 | :container-style style/button-container}
|
50 | 115 | (i18n/label :t/continue)]])))
|
51 |
| - |
52 |
| -(def view (quo.theme/with-theme view-internal)) |
|
0 commit comments