Compare commits
22
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0699cf846b | ||
|
|
7780fa0b20 | ||
|
|
42b1444e0c | ||
|
|
a7c17685fe | ||
|
|
e5d10f5585 | ||
|
|
423a6f7521 | ||
|
|
1c78004b08 | ||
|
|
f99d1bbaed | ||
|
|
ec38cb3d72 | ||
|
|
e9c15373e5 | ||
|
|
395ea5d507 | ||
|
|
1b3c8c1e54 | ||
|
|
e76434edab | ||
|
|
31a22cd339 | ||
|
|
6a88a34d34 | ||
|
|
3be1532b32 | ||
|
|
44846c80c8 | ||
|
|
a405de62e6 | ||
|
|
06dc9ea1d3 | ||
|
|
32a4bb1153 | ||
|
|
418053b21e | ||
|
|
2528efb538 |
@@ -62,7 +62,10 @@
|
||||
|
||||
(defn <-color
|
||||
[value]
|
||||
(if (string/starts-with? value "#") value (keyword value)))
|
||||
(if (and (some? value)
|
||||
(string/starts-with? value "#"))
|
||||
value
|
||||
(keyword value)))
|
||||
|
||||
(defn <-rpc
|
||||
[chat]
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
size 40
|
||||
customization-color (if (= type :primary) :blue nil)}}
|
||||
children]
|
||||
(when (string? children) (js/console.log "button - " children))
|
||||
(let [[pressed-state? set-pressed-state] (rn/use-state false)
|
||||
theme (theme/use-theme-value)
|
||||
{:keys [icon-color background-color label-color border-color blur-type
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
(h/fire-event :on-blur (h/get-by-label-text :address-text-input))
|
||||
(h/has-prop (h/get-by-label-text :address-text-input)
|
||||
:placeholder-text-color
|
||||
colors/neutral-30))))))
|
||||
colors/neutral-40))))))
|
||||
|
||||
(h/test "on blur with text blur? true"
|
||||
(with-redefs [clipboard/get-string #(% "")]
|
||||
@@ -75,7 +75,7 @@
|
||||
(h/fire-event :on-blur (h/get-by-label-text :address-text-input))
|
||||
(h/has-prop (h/get-by-label-text :address-text-input)
|
||||
:placeholder-text-color
|
||||
colors/neutral-80-opa-20))))))
|
||||
colors/neutral-80-opa-40))))))
|
||||
|
||||
(h/test "on blur with no text and blur? false"
|
||||
(with-redefs [clipboard/get-string #(% "")]
|
||||
|
||||
@@ -58,78 +58,64 @@
|
||||
[{:keys [default-value blur? on-change-text on-blur on-focus on-clear on-scan
|
||||
on-detect-ens on-detect-address on-detect-unclassified address-regex ens-regex
|
||||
valid-ens-or-address? container-style]}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
[status set-status] (rn/use-state :default)
|
||||
value (rn/use-ref-atom nil)
|
||||
[_ trigger-render-value] (rn/use-state @value)
|
||||
[focused? set-focused] (rn/use-state false)
|
||||
on-change (rn/use-callback
|
||||
(fn [text]
|
||||
(let [address? (when address-regex
|
||||
(boolean (re-matches address-regex text)))
|
||||
ens? (when ens-regex
|
||||
(boolean (re-matches ens-regex text)))]
|
||||
(reset! value text)
|
||||
(if (> (count text) 0)
|
||||
(set-status :typing)
|
||||
(set-status :active))
|
||||
(when on-change-text
|
||||
(on-change-text text))
|
||||
(when (and on-detect-ens ens?)
|
||||
(set-status :loading)
|
||||
(on-detect-ens text #(set-status :typing)))
|
||||
(when (and address? on-detect-address)
|
||||
(set-status :loading)
|
||||
(on-detect-address text))
|
||||
(when (and (not address?)
|
||||
(not ens?)
|
||||
on-detect-unclassified)
|
||||
(on-detect-unclassified text)))))
|
||||
set-value (rn/use-callback
|
||||
(fn [new-value]
|
||||
(reset! value new-value)
|
||||
(on-change new-value)
|
||||
(trigger-render-value new-value)))
|
||||
on-paste (rn/use-callback
|
||||
(fn []
|
||||
(clipboard/get-string
|
||||
(fn [clipboard]
|
||||
(when-not (empty? clipboard)
|
||||
(set-value clipboard))))))
|
||||
on-clear (rn/use-callback
|
||||
(fn []
|
||||
(set-value "")
|
||||
(set-status (if focused? :active :default))
|
||||
(when on-change-text
|
||||
(on-change-text ""))
|
||||
(when on-clear
|
||||
(on-clear)))
|
||||
[focused?])
|
||||
on-clear (rn/use-callback
|
||||
(fn []
|
||||
(set-value "")
|
||||
(set-status (if focused? :active :default))
|
||||
(when on-change-text
|
||||
(on-change-text ""))
|
||||
(when on-clear
|
||||
(on-clear)))
|
||||
[focused?])
|
||||
on-scan (when on-scan (rn/use-callback #(on-scan set-value)))
|
||||
on-focus (rn/use-callback
|
||||
(fn []
|
||||
(when (= (count @value) 0)
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
[status set-status] (rn/use-state :default)
|
||||
[value set-value] (rn/use-state nil)
|
||||
[focused? set-focused] (rn/use-state false)
|
||||
on-change (rn/use-callback
|
||||
(fn [text]
|
||||
(let [address? (when address-regex
|
||||
(boolean (re-matches address-regex text)))
|
||||
ens? (when ens-regex
|
||||
(boolean (re-matches ens-regex text)))]
|
||||
(set-value text)
|
||||
(if (> (count text) 0)
|
||||
(set-status :typing)
|
||||
(set-status :active))
|
||||
(set-focused true)
|
||||
(when on-focus (on-focus))))
|
||||
on-blur (rn/use-callback
|
||||
(fn []
|
||||
(when (= status :active)
|
||||
(set-status :default))
|
||||
(set-focused false)
|
||||
(when on-blur (on-blur)))
|
||||
[status])
|
||||
placeholder-text-color (rn/use-memo #(get-placeholder-text-color status theme blur?)
|
||||
[status theme blur?])]
|
||||
(when on-change-text
|
||||
(on-change-text text))
|
||||
(when (and on-detect-ens ens?)
|
||||
(set-status :loading)
|
||||
(on-detect-ens text #(set-status :typing)))
|
||||
(when (and address? on-detect-address)
|
||||
(set-status :loading)
|
||||
(on-detect-address text))
|
||||
(when (and (not address?)
|
||||
(not ens?)
|
||||
on-detect-unclassified)
|
||||
(on-detect-unclassified text)))))
|
||||
on-paste (rn/use-callback
|
||||
(fn []
|
||||
(clipboard/get-string
|
||||
(fn [clipboard]
|
||||
(when-not (empty? clipboard)
|
||||
(on-change clipboard))))))
|
||||
on-clear (rn/use-callback
|
||||
(fn []
|
||||
(on-change "")
|
||||
(set-status (if focused? :active :default))
|
||||
(when on-change-text
|
||||
(on-change-text ""))
|
||||
(when on-clear
|
||||
(on-clear)))
|
||||
[focused?])
|
||||
on-scan (rn/use-callback #(when on-scan (on-scan on-change))
|
||||
[on-scan])
|
||||
on-focus (rn/use-callback
|
||||
(fn []
|
||||
(when (= (count value) 0)
|
||||
(set-status :active))
|
||||
(set-focused true)
|
||||
(when on-focus (on-focus))))
|
||||
on-blur (rn/use-callback
|
||||
(fn []
|
||||
(when (= status :active)
|
||||
(set-status :default))
|
||||
(set-focused false)
|
||||
(when on-blur (on-blur)))
|
||||
[status])
|
||||
placeholder-text-color (rn/use-memo #(get-placeholder-text-color status theme blur?)
|
||||
[status theme blur?])]
|
||||
(rn/use-mount #(on-change (or default-value "")))
|
||||
[rn/view {:style (style/container container-style)}
|
||||
[rn/text-input
|
||||
@@ -137,7 +123,7 @@
|
||||
:style (style/input-text theme)
|
||||
:placeholder (i18n/label :t/name-ens-or-address)
|
||||
:placeholder-text-color placeholder-text-color
|
||||
:value @value
|
||||
:value value
|
||||
:auto-complete (when platform/ios? :off)
|
||||
:auto-capitalize :none
|
||||
:auto-correct false
|
||||
|
||||
@@ -57,14 +57,19 @@
|
||||
"Custom properties that must be removed from properties map passed to InputText."
|
||||
[:type :blur? :error? :right-icon :left-icon :disabled? :small? :button
|
||||
:label :char-limit :on-char-limit-reach :icon-name :multiline? :on-focus :on-blur
|
||||
:container-style])
|
||||
:container-style :ref])
|
||||
|
||||
(defn- base-input
|
||||
[{:keys [blur? error? right-icon left-icon disabled? small? button
|
||||
label char-limit multiline? clearable? on-focus on-blur container-style
|
||||
on-change-text on-char-limit-reach weight default-value]
|
||||
on-change-text on-char-limit-reach weight default-value on-clear]
|
||||
:as props}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
ref (rn/use-ref-atom nil)
|
||||
on-ref (rn/use-callback (fn [value]
|
||||
(when (:ref props)
|
||||
((:ref props) value))
|
||||
(reset! ref value)))
|
||||
[status set-status] (rn/use-state :default)
|
||||
internal-on-focus (rn/use-callback #(set-status :focus))
|
||||
internal-on-blur (rn/use-callback #(set-status :default))
|
||||
@@ -93,6 +98,15 @@
|
||||
:else status)
|
||||
colors-by-status (style/status-colors status-kw blur? theme)
|
||||
variant-colors (style/variants-colors blur? theme)
|
||||
clear-on-press (rn/use-callback (fn []
|
||||
(.clear ^js @ref)
|
||||
(when on-clear (on-clear)))
|
||||
[on-clear])
|
||||
right-icon (or right-icon
|
||||
(when clearable?
|
||||
{:style-fn style/clear-icon
|
||||
:icon-name :i/clear
|
||||
:on-press clear-on-press}))
|
||||
clean-props (apply dissoc props custom-props)]
|
||||
[rn/view {:style container-style}
|
||||
(when (or label char-limit)
|
||||
@@ -108,7 +122,8 @@
|
||||
:small? small?
|
||||
:icon-name icon-name}])
|
||||
[rn/text-input
|
||||
(cond-> {:style (style/input colors-by-status small? multiple-lines? weight)
|
||||
(cond-> {:ref on-ref
|
||||
:style (style/input colors-by-status small? multiple-lines? weight)
|
||||
:accessibility-label :input
|
||||
:placeholder-text-color (:placeholder colors-by-status)
|
||||
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
||||
@@ -147,7 +162,10 @@
|
||||
[{:keys [default-shown?]
|
||||
:or {default-shown? false}
|
||||
:as props}]
|
||||
(let [[password-shown? set-password-shown] (rn/use-state default-shown?)]
|
||||
(let [[password-shown?
|
||||
set-password-shown] (rn/use-state default-shown?)
|
||||
on-press (rn/use-callback #(set-password-shown (not password-shown?))
|
||||
[password-shown?])]
|
||||
[base-input
|
||||
(assoc props
|
||||
:accessibility-label :password-input
|
||||
@@ -156,7 +174,7 @@
|
||||
:secure-text-entry (not password-shown?)
|
||||
:right-icon {:style-fn style/password-icon
|
||||
:icon-name (if password-shown? :i/hide-password :i/reveal)
|
||||
:on-press #(set-password-shown (not password-shown?))})]))
|
||||
:on-press on-press})]))
|
||||
|
||||
(defn input
|
||||
"This input supports the following properties:
|
||||
@@ -182,15 +200,11 @@
|
||||
- :on-change-text
|
||||
...
|
||||
"
|
||||
[{:keys [type clearable? on-clear icon-name]
|
||||
[{:keys [type icon-name]
|
||||
:or {type :text}
|
||||
:as props}]
|
||||
(let [base-props (cond-> props
|
||||
icon-name (assoc-in [:left-icon :icon-name] icon-name)
|
||||
clearable? (assoc :right-icon
|
||||
{:style-fn style/clear-icon
|
||||
:icon-name :i/clear
|
||||
:on-press #(when on-clear (on-clear))}))]
|
||||
icon-name (assoc-in [:left-icon :icon-name] icon-name))]
|
||||
(if (= type :password)
|
||||
[password-input base-props]
|
||||
[base-input base-props])))
|
||||
|
||||
@@ -26,14 +26,20 @@
|
||||
:padding-vertical 8
|
||||
:padding-horizontal 12}))
|
||||
|
||||
(def right-side-container {:flex 1})
|
||||
(def right-side-container
|
||||
{:flex 1
|
||||
:justify-content :center})
|
||||
|
||||
(defn title
|
||||
[override-theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 theme)})
|
||||
|
||||
(defn text
|
||||
[override-theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 theme)})
|
||||
|
||||
(def avatar-container {:margin-right 8 :margin-top 4})
|
||||
(defn avatar-container
|
||||
[{:keys [multiline?]}]
|
||||
{:margin-right 8
|
||||
:align-self (when-not multiline? :center)
|
||||
:margin-top (if multiline? 4 0)})
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
(ns quo.components.notifications.notification.view
|
||||
(:require
|
||||
[quo.components.avatars.user-avatar.view :as user-avatar]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.notifications.notification.style :as style]
|
||||
[quo.theme]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
@@ -15,33 +17,33 @@
|
||||
[into [rn/view {:accessibility-label :notification-body}] children])
|
||||
|
||||
(defn avatar-container
|
||||
[& children]
|
||||
[{:keys [multiline?]} & children]
|
||||
[into
|
||||
[rn/view
|
||||
{:style style/avatar-container
|
||||
{:style (style/avatar-container {:multiline? multiline?})
|
||||
:accessibility-label :notification-avatar}]
|
||||
children])
|
||||
|
||||
(defn title
|
||||
([text weight] (title text weight nil))
|
||||
([text weight override-theme]
|
||||
([{:keys [text weight theme multiline?]}]
|
||||
[text/text
|
||||
{:size :paragraph-1
|
||||
:weight (or weight :semi-bold)
|
||||
:style (style/title override-theme)
|
||||
:weight (or weight (if multiline? :semi-bold :medium))
|
||||
:style (style/title theme)
|
||||
:accessibility-label :notification-title}
|
||||
text]))
|
||||
|
||||
(defn message
|
||||
[text override-theme]
|
||||
[text theme]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style (style/text override-theme)
|
||||
:weight :medium
|
||||
:style (style/text theme)
|
||||
:accessibility-label :notification-content}
|
||||
text])
|
||||
|
||||
(defn- notification-container
|
||||
[{:keys [avatar header body container-style override-theme]}]
|
||||
[{:keys [avatar header body container-style theme]}]
|
||||
[rn/view
|
||||
{:style (merge style/box-container container-style)}
|
||||
[blur/view
|
||||
@@ -51,7 +53,7 @@
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent}]
|
||||
[rn/view
|
||||
{:style (style/content-container override-theme)}
|
||||
{:style (style/content-container theme)}
|
||||
avatar
|
||||
[rn/view
|
||||
{:style style/right-side-container}
|
||||
@@ -59,17 +61,27 @@
|
||||
body]]])
|
||||
|
||||
(defn notification
|
||||
[{title-text :title :keys [avatar header title-weight text body container-style override-theme]}]
|
||||
(let [header (or header
|
||||
(when title-text
|
||||
[title title-text title-weight override-theme]))
|
||||
header (when header [header-container header])
|
||||
body (or body (when text [message text override-theme]))
|
||||
body (when body [body-container body])
|
||||
avatar (when avatar [avatar-container avatar])]
|
||||
[notification-container
|
||||
{:avatar avatar
|
||||
:header header
|
||||
:body body
|
||||
:container-style container-style
|
||||
:override-theme override-theme}]))
|
||||
[{title-text :title :keys [avatar user header title-weight text body container-style theme]}]
|
||||
(let [theme (or theme (quo.theme/get-theme))
|
||||
body (or body (when text [message text theme]))
|
||||
header (or header
|
||||
(when title-text
|
||||
[title
|
||||
{:text title-text
|
||||
:weight title-weight
|
||||
:theme theme
|
||||
:multiline? (some? body)}]))
|
||||
header (when header [header-container header])
|
||||
body (when body [body-container body])
|
||||
user-avatar (or avatar (when user (user-avatar/user-avatar user)))
|
||||
avatar (when user-avatar
|
||||
[avatar-container
|
||||
{:multiline? (and header body)}
|
||||
user-avatar])]
|
||||
[quo.theme/provider {:theme theme}
|
||||
[notification-container
|
||||
{:avatar avatar
|
||||
:header header
|
||||
:body body
|
||||
:container-style container-style
|
||||
:theme theme}]]))
|
||||
|
||||
@@ -62,23 +62,26 @@
|
||||
([server username password]
|
||||
(save-credentials server username password identity))
|
||||
([server username password callback]
|
||||
(-> (.setInternetCredentials ^js react-native-keychain
|
||||
(string/lower-case server)
|
||||
username
|
||||
password
|
||||
keychain-secure-hardware
|
||||
keychain-restricted-availability)
|
||||
(.then callback))))
|
||||
(when-not (empty? server)
|
||||
(-> (.setInternetCredentials ^js react-native-keychain
|
||||
(string/lower-case server)
|
||||
username
|
||||
password
|
||||
keychain-secure-hardware
|
||||
keychain-restricted-availability)
|
||||
(.then callback)))))
|
||||
|
||||
(defn get-credentials
|
||||
"Gets the credentials for a specified server from the Keychain"
|
||||
([server]
|
||||
(get-credentials server identity))
|
||||
([server callback]
|
||||
(-> (.getInternetCredentials ^js react-native-keychain (string/lower-case server))
|
||||
(.then callback))))
|
||||
(when-not (empty? server)
|
||||
(-> (.getInternetCredentials ^js react-native-keychain (string/lower-case server))
|
||||
(.then callback)))))
|
||||
|
||||
(defn reset-credentials
|
||||
[server]
|
||||
(-> (.resetInternetCredentials ^js react-native-keychain (string/lower-case server))
|
||||
(.then #(when-not % (log/error (str "Error while clearing saved password."))))))
|
||||
(when-not (empty? server)
|
||||
(-> (.resetInternetCredentials ^js react-native-keychain (string/lower-case server))
|
||||
(.then #(when-not % (log/error (str "Error while clearing saved password.")))))))
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
[{:keys [on-press allow-multiple-presses? throttle-duration]} throttle-id]
|
||||
(if allow-multiple-presses?
|
||||
on-press
|
||||
(fn []
|
||||
(fn [event]
|
||||
(let [id @throttle-id]
|
||||
(when (and id (not (get @throttle id)))
|
||||
(swap! throttle assoc id true)
|
||||
(on-press)
|
||||
(on-press event)
|
||||
(js/setTimeout
|
||||
#(swap! throttle dissoc id)
|
||||
(or throttle-duration 500)))))))
|
||||
|
||||
@@ -148,28 +148,26 @@
|
||||
(reset! search-text ""))
|
||||
|
||||
(defn f-view
|
||||
[{:keys [search-text on-change-text clear-states active-category scroll-ref theme]
|
||||
[{:keys [search-active? on-change-text clear-states active-category scroll-ref theme]
|
||||
:as sheet-opts}]
|
||||
(let [search-active? (pos? (count @search-text))]
|
||||
[rn/keyboard-avoiding-view
|
||||
{:style style/flex-spacer
|
||||
:keyboard-vertical-offset 8}
|
||||
[rn/view {:style style/flex-spacer}
|
||||
[rn/view {:style style/search-input-container}
|
||||
[quo/input
|
||||
{:small? true
|
||||
:placeholder (i18n/label :t/emoji-search-placeholder)
|
||||
:icon-name :i/search
|
||||
:value @search-text
|
||||
:on-change-text on-change-text
|
||||
:clearable? search-active?
|
||||
:on-clear clear-states}]]
|
||||
[render-list sheet-opts]
|
||||
(when-not search-active?
|
||||
[footer
|
||||
{:theme theme
|
||||
:active-category active-category
|
||||
:scroll-ref scroll-ref}])]]))
|
||||
[rn/keyboard-avoiding-view
|
||||
{:style style/flex-spacer
|
||||
:keyboard-vertical-offset 8}
|
||||
[rn/view {:style style/flex-spacer}
|
||||
[rn/view {:style style/search-input-container}
|
||||
[quo/input
|
||||
{:small? true
|
||||
:placeholder (i18n/label :t/emoji-search-placeholder)
|
||||
:icon-name :i/search
|
||||
:on-change-text on-change-text
|
||||
:clearable? search-active?
|
||||
:on-clear clear-states}]]
|
||||
[render-list sheet-opts]
|
||||
(when-not search-active?
|
||||
[footer
|
||||
{:theme theme
|
||||
:active-category active-category
|
||||
:scroll-ref scroll-ref}])]])
|
||||
|
||||
(defn- view-internal
|
||||
[_]
|
||||
@@ -202,7 +200,7 @@
|
||||
(fn [sheet-opts]
|
||||
[:f> f-view
|
||||
(assoc sheet-opts
|
||||
:search-text search-text
|
||||
:search-active? (pos? (count @search-text))
|
||||
:on-change-text on-change-text
|
||||
:clear-states clear-states
|
||||
:filtered-data @filtered-data
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
(reset! ratom height))))
|
||||
|
||||
(defn- init-keyboard-listeners
|
||||
[{:keys [on-did-show]}]
|
||||
[{:keys [on-did-show scroll-view-ref]}]
|
||||
(let [keyboard-will-show? (reagent/atom false)
|
||||
keyboard-did-show? (reagent/atom false)
|
||||
add-listener (fn [listener callback]
|
||||
@@ -41,7 +41,10 @@
|
||||
(reset! keyboard-did-show? true)
|
||||
(when on-did-show (on-did-show e))))
|
||||
will-hide-listener (add-listener "keyboardWillHide"
|
||||
#(reset! keyboard-will-show? false))
|
||||
(fn []
|
||||
(reset! keyboard-will-show? false)
|
||||
(reagent/flush)
|
||||
(.scrollTo @scroll-view-ref #js {:x 0 :y 0 :animated true})))
|
||||
did-hide-listener (add-listener "keyboardDidHide"
|
||||
#(reset! keyboard-did-show? false))
|
||||
remove-listeners (fn []
|
||||
@@ -55,9 +58,11 @@
|
||||
(defn view
|
||||
[{:keys [header footer customization-color footer-container-padding header-container-style
|
||||
gradient-cover?]
|
||||
:or {footer-container-padding (safe-area/get-top)}} &
|
||||
children]
|
||||
(reagent/with-let [window-height (:height (rn/get-window))
|
||||
:or {footer-container-padding (safe-area/get-top)}}
|
||||
& children]
|
||||
(reagent/with-let [scroll-view-ref (atom nil)
|
||||
set-scroll-ref #(reset! scroll-view-ref %)
|
||||
window-height (:height (rn/get-window))
|
||||
footer-container-height (reagent/atom 0)
|
||||
header-height (reagent/atom 0)
|
||||
content-container-height (reagent/atom 0)
|
||||
@@ -66,7 +71,8 @@
|
||||
{:keys [keyboard-will-show?
|
||||
keyboard-did-show?
|
||||
remove-listeners]} (init-keyboard-listeners
|
||||
{:on-did-show
|
||||
{:scroll-view-ref scroll-view-ref
|
||||
:on-did-show
|
||||
(fn [e]
|
||||
(reset! keyboard-height
|
||||
(oops/oget e "endCoordinates.height")))})
|
||||
@@ -85,16 +91,22 @@
|
||||
:header-height @header-height
|
||||
:keyboard-shown? keyboard-shown?})]
|
||||
[:<>
|
||||
(when gradient-cover? [quo/gradient-cover {:customization-color customization-color}])
|
||||
(when gradient-cover?
|
||||
[quo/gradient-cover {:customization-color customization-color}])
|
||||
[rn/view {:style style/page-container}
|
||||
[rn/view
|
||||
{:on-layout set-header-height
|
||||
:style header-container-style}
|
||||
header]
|
||||
[gesture/scroll-view
|
||||
{:on-scroll set-content-y-scroll
|
||||
:scroll-event-throttle 64
|
||||
:content-container-style {:flex-grow 1}}
|
||||
{:ref set-scroll-ref
|
||||
:on-scroll set-content-y-scroll
|
||||
:scroll-event-throttle 64
|
||||
:content-container-style {:flex-grow 1
|
||||
:padding-bottom (when @keyboard-did-show?
|
||||
@footer-container-height)}
|
||||
:always-bounce-vertical @keyboard-did-show?
|
||||
:shows-vertical-scroll-indicator false}
|
||||
(into [rn/view {:on-layout set-content-container-height}]
|
||||
children)]
|
||||
[rn/keyboard-avoiding-view
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
[quo.core :as quo]
|
||||
[react-native.clipboard :as clipboard]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.contexts.chat.home.add-new-contact.style :as style]
|
||||
[utils.address :as address]
|
||||
[utils.debounce :as debounce]
|
||||
@@ -51,57 +50,66 @@
|
||||
|
||||
(defn- search-input
|
||||
[]
|
||||
(reagent/with-let [input-value (reagent/atom nil)
|
||||
input-ref (atom nil)
|
||||
clear-input (fn []
|
||||
(reset! input-value nil)
|
||||
(rf/dispatch [:contacts/clear-new-identity]))
|
||||
paste-on-input #(clipboard/get-string
|
||||
(fn [clipboard-text]
|
||||
(reset! input-value clipboard-text)
|
||||
(rf/dispatch [:contacts/set-new-identity
|
||||
{:input clipboard-text}])))]
|
||||
(let [{:keys [scanned] contact-public-key :id} (rf/sub [:contacts/new-identity])
|
||||
contact-public-key-or-scanned (or contact-public-key scanned)
|
||||
empty-input? (and (string/blank? @input-value)
|
||||
(string/blank? contact-public-key-or-scanned))]
|
||||
[rn/view {:style style/input-and-scan-container}
|
||||
[quo/input
|
||||
{:accessibility-label :enter-contact-code-input
|
||||
:ref #(reset! input-ref %)
|
||||
:container-style {:flex 1}
|
||||
:auto-capitalize :none
|
||||
:multiline? true
|
||||
:blur-on-submit true
|
||||
:return-key-type :done
|
||||
:label (i18n/label :t/ens-or-chat-key)
|
||||
:placeholder (i18n/label :t/type-some-chat-key)
|
||||
:clearable? (not empty-input?)
|
||||
:on-clear clear-input
|
||||
:button (when empty-input?
|
||||
{:on-press paste-on-input
|
||||
:text (i18n/label :t/paste)})
|
||||
;; NOTE: `contact-public-key-or-scanned` has priority over `@input-value`,
|
||||
;; we clean it when the input is updated so that it's `nil` and
|
||||
;; `@input-value`is shown. To fastly clean it, we use `dispatch-sync`.
|
||||
;; This call could be avoided if `::qr-scanner/scan-code` were able to
|
||||
;; receive a callback function, not only a re-frame event as callback.
|
||||
:value (or contact-public-key-or-scanned @input-value)
|
||||
:on-change-text (fn [new-text]
|
||||
(reset! input-value new-text)
|
||||
(as-> [:contacts/set-new-identity {:input new-text}] $
|
||||
(if (string/blank? contact-public-key-or-scanned)
|
||||
(debounce/debounce-and-dispatch $ 600)
|
||||
(rf/dispatch-sync $))))}]
|
||||
[rn/view {:style style/scan-button-container}
|
||||
[quo/button
|
||||
{:type :outline
|
||||
:icon-only? true
|
||||
:size 40
|
||||
:on-press #(rf/dispatch [:open-modal :scan-profile-qr-code])}
|
||||
:i/scan]]])
|
||||
(finally
|
||||
(rf/dispatch [:contacts/clear-new-identity]))))
|
||||
(let [[input-value set-input-value] (rn/use-state nil)
|
||||
input-ref (rn/use-ref-atom nil)
|
||||
on-ref (rn/use-callback #(reset! input-ref %))
|
||||
{:keys [scanned]
|
||||
contact-public-key :id} (rf/sub [:contacts/new-identity])
|
||||
contact-public-key-or-scanned (or contact-public-key scanned)
|
||||
empty-input? (and (string/blank? input-value)
|
||||
(string/blank? contact-public-key-or-scanned))
|
||||
clear-input (rn/use-callback
|
||||
(fn []
|
||||
(set-input-value nil)
|
||||
(rf/dispatch [:contacts/clear-new-identity])))
|
||||
paste-on-input (rn/use-callback
|
||||
(fn []
|
||||
(clipboard/get-string
|
||||
(fn [clipboard-text]
|
||||
(set-input-value clipboard-text)
|
||||
(rf/dispatch [:contacts/set-new-identity
|
||||
{:input clipboard-text}])))))
|
||||
on-change-text (rn/use-callback
|
||||
(fn [new-text]
|
||||
(set-input-value new-text)
|
||||
(if (string/blank? contact-public-key-or-scanned)
|
||||
(debounce/debounce-and-dispatch [:contacts/set-new-identity
|
||||
{:input new-text}]
|
||||
600)
|
||||
(rf/dispatch-sync [:contacts/set-new-identity
|
||||
{:input new-text}])))
|
||||
[contact-public-key-or-scanned])]
|
||||
(rn/use-unmount #(rf/dispatch [:contacts/clear-new-identity]))
|
||||
[rn/view {:style style/input-and-scan-container}
|
||||
[quo/input
|
||||
{:accessibility-label :enter-contact-code-input
|
||||
:ref on-ref
|
||||
:container-style {:flex 1}
|
||||
:auto-capitalize :none
|
||||
:multiline? true
|
||||
:blur-on-submit true
|
||||
:return-key-type :done
|
||||
:label (i18n/label :t/ens-or-chat-key)
|
||||
:placeholder (i18n/label :t/type-some-chat-key)
|
||||
:clearable? (not empty-input?)
|
||||
:on-clear clear-input
|
||||
:button (when empty-input?
|
||||
{:on-press paste-on-input
|
||||
:text (i18n/label :t/paste)})
|
||||
;; NOTE: `contact-public-key-or-scanned` has priority over `input-value`,
|
||||
;; we clean it when the input is updated so that it's `nil` and
|
||||
;; `input-value`is shown. To fastly clean it, we use `dispatch-sync`.
|
||||
;; This call could be avoided if `::qr-scanner/scan-code` were able to
|
||||
;; receive a callback function, not only a re-frame event as callback.
|
||||
:value (or contact-public-key-or-scanned input-value)
|
||||
:on-change-text on-change-text}]
|
||||
[rn/view {:style style/scan-button-container}
|
||||
[quo/button
|
||||
{:type :outline
|
||||
:icon-only? true
|
||||
:size 40
|
||||
:on-press #(rf/dispatch [:open-modal :scan-profile-qr-code])}
|
||||
:i/scan]]]))
|
||||
|
||||
(defn- invalid-text
|
||||
[message]
|
||||
|
||||
@@ -20,6 +20,13 @@
|
||||
has-permissions? (rf/sub [:communities/has-permissions? id])
|
||||
airdrop-account (rf/sub [:communities/airdrop-account id])
|
||||
revealed-accounts (rf/sub [:communities/accounts-to-reveal id])
|
||||
revealed-accounts-count (count revealed-accounts)
|
||||
wallet-accounts-count (count (rf/sub [:wallet/accounts-without-watched-accounts]))
|
||||
addresses-shared-text (if (= revealed-accounts-count wallet-accounts-count)
|
||||
(i18n/label :t/all-addresses)
|
||||
(i18n/label-pluralize
|
||||
revealed-accounts-count
|
||||
:t/address-count))
|
||||
{:keys [highest-permission-role]} (rf/sub [:community/token-gated-overview id])
|
||||
highest-role-text (i18n/label (communities.utils/role->translation-key
|
||||
highest-permission-role
|
||||
@@ -108,7 +115,7 @@
|
||||
:label :preview
|
||||
:label-props {:type :accounts
|
||||
:data revealed-accounts}
|
||||
:description-props {:text (i18n/label :t/all-addresses)}}
|
||||
:description-props {:text addresses-shared-text}}
|
||||
{:title (i18n/label :t/for-airdrops)
|
||||
:on-press show-airdrop-addresses
|
||||
:description :text
|
||||
|
||||
@@ -153,7 +153,7 @@
|
||||
@full-name
|
||||
(i18n/label :t/your-name))
|
||||
:customization-color @custom-color}
|
||||
:title-input-props {:default-value @full-name
|
||||
:title-input-props {:default-value display-name
|
||||
:auto-focus true
|
||||
:max-length c/profile-name-max-length
|
||||
:on-change-text on-change-text}}]]
|
||||
|
||||
@@ -30,12 +30,11 @@
|
||||
[]
|
||||
[notification-button
|
||||
"Notification: with title(header)"
|
||||
{:avatar [quo/user-avatar
|
||||
{:full-name "A Y"
|
||||
:status-indicator? true
|
||||
:online? true
|
||||
:size :small
|
||||
:customization-color :blue}]
|
||||
{:user {:full-name "A Y"
|
||||
:status-indicator? true
|
||||
:online? true
|
||||
:size :small
|
||||
:customization-color :blue}
|
||||
:title "Alisher Yakupov accepted your contact request"
|
||||
:duration 4000
|
||||
:title-weight :medium
|
||||
@@ -45,12 +44,11 @@
|
||||
[]
|
||||
[notification-button
|
||||
"with title and body"
|
||||
{:avatar [quo/user-avatar
|
||||
{:full-name "A Y"
|
||||
:status-indicator? true
|
||||
:online? true
|
||||
:size :small
|
||||
:customization-color :blue}]
|
||||
{:user {:full-name "A Y"
|
||||
:status-indicator? true
|
||||
:online? true
|
||||
:size :small
|
||||
:customization-color :blue}
|
||||
:title "Default to semibold title"
|
||||
:text "The quick brown fox jumped over the lazy dog and ate a potatoe."
|
||||
:duration 4000
|
||||
@@ -60,12 +58,11 @@
|
||||
[]
|
||||
[notification-button
|
||||
"with anything as header & body"
|
||||
{:avatar [quo/user-avatar
|
||||
{:full-name "A Y"
|
||||
:status-indicator? true
|
||||
:online? true
|
||||
:size :small
|
||||
:customization-color :blue}]
|
||||
{:user {:full-name "A Y"
|
||||
:status-indicator? true
|
||||
:online? true
|
||||
:size :small
|
||||
:customization-color :blue}
|
||||
:header [rn/view
|
||||
[quo/info-message
|
||||
{:type :success
|
||||
|
||||
@@ -2,12 +2,17 @@
|
||||
(:require [clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[reagent.ratom]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.profile.contact.contact-request.style :as style]
|
||||
[status-im.contexts.profile.utils :as profile.utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn example-component [props]
|
||||
(js/console.log "example component render" (clj->js props))
|
||||
[rn/text "Hello"])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{:keys [public-key customization-color]
|
||||
@@ -17,7 +22,9 @@
|
||||
full-name (profile.utils/displayed-name profile)
|
||||
profile-picture (profile.utils/photo profile)
|
||||
[message set-message] (rn/use-state "")
|
||||
on-message-change (rn/use-callback #(set-message %))
|
||||
on-message-change (rn/use-callback #(do
|
||||
(set-message %)))
|
||||
on-press-test (rn/use-callback #(rf/dispatch [:contacts/update-nickname public-key "Example nickname"]))
|
||||
on-message-submit (rn/use-callback (fn []
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(rf/dispatch [:contact.ui/send-contact-request
|
||||
@@ -28,7 +35,10 @@
|
||||
:text (i18n/label
|
||||
:t/contact-request-was-sent)}]))
|
||||
[public-key message])]
|
||||
(js/console.log "contact request view render")
|
||||
[:<>
|
||||
[quo/button {} "Example static button"]
|
||||
[example-component {:on-test on-press-test}]
|
||||
[quo/drawer-top
|
||||
{:type :context-tag
|
||||
:context-tag-type :default
|
||||
@@ -50,10 +60,14 @@
|
||||
:label (i18n/label :t/message)
|
||||
:on-change-text on-message-change}]]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
{:actions :two-actions
|
||||
:button-one-props {:disabled? (string/blank? message)
|
||||
:accessibility-label :send-contact-request
|
||||
:customization-color customization-color
|
||||
:on-press on-message-submit}
|
||||
:button-one-label (i18n/label :t/send-contact-request)}]]))
|
||||
:button-one-label "Test Button One"
|
||||
:button-two-props {:accessibility-label :test-button
|
||||
:customization-color :danger
|
||||
:on-press on-press-test}
|
||||
:button-two-label "Test Button Two"}]]))
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
(:require
|
||||
[legacy.status-im.data-store.activities :as activities]
|
||||
[legacy.status-im.data-store.chats :as data-store.chats]
|
||||
[quo.foundations.colors :as colors]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[status-im.common.toasts.events :as toasts]
|
||||
@@ -544,9 +543,9 @@
|
||||
(not accepted)
|
||||
(not dismissed))
|
||||
(toasts/upsert cofx
|
||||
{:user user-avatar
|
||||
{:type :notification
|
||||
:user user-avatar
|
||||
:user-public-key author
|
||||
:icon-color colors/primary-50-opa-40
|
||||
:title (i18n/label :t/contact-request-sent-toast
|
||||
{:name name})
|
||||
:text (get-in message [:content :text])})
|
||||
@@ -556,10 +555,10 @@
|
||||
accepted
|
||||
(not dismissed))
|
||||
(toasts/upsert cofx
|
||||
{:user user-avatar
|
||||
{:type :notification
|
||||
:user user-avatar
|
||||
;; user public key who accepted the request
|
||||
:user-public-key chat-id
|
||||
:icon-color colors/success-50-opa-40
|
||||
:title (i18n/label :t/contact-request-accepted-toast
|
||||
{:name (or name (:alias message))})})
|
||||
:else
|
||||
|
||||
@@ -14,24 +14,19 @@
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{:keys [address]} (rf/sub [:get-screen-params])
|
||||
number-of-accounts (count (rf/sub [:wallet/watch-only-accounts]))
|
||||
account-name (reagent/atom "")
|
||||
placeholder (i18n/label :t/default-watched-address-placeholder
|
||||
{:number (inc number-of-accounts)})
|
||||
account-color (reagent/atom (rand-nth colors/account-colors))
|
||||
account-emoji (reagent/atom (emoji-picker.utils/random-emoji))
|
||||
on-change-name #(reset! account-name %)
|
||||
on-change-color #(reset! account-color %)
|
||||
on-change-emoji #(reset! account-emoji %)]
|
||||
(let [{:keys [address]} (rf/sub [:get-screen-params])
|
||||
placeholder (i18n/label :t/default-watched-address-placeholder)
|
||||
account-name (reagent/atom "")
|
||||
account-color (reagent/atom (rand-nth colors/account-colors))
|
||||
account-emoji (reagent/atom (emoji-picker.utils/random-emoji))
|
||||
on-change-name #(reset! account-name %)
|
||||
on-change-color #(reset! account-color %)
|
||||
on-change-emoji #(reset! account-emoji %)]
|
||||
(fn []
|
||||
[rn/view {:style style/container}
|
||||
[create-or-edit-account/view
|
||||
{:page-nav-right-side [{:icon-name :i/info
|
||||
:on-press
|
||||
#(js/alert
|
||||
"Get info (to be
|
||||
implemented)")}]
|
||||
:on-press #(js/alert "Get info (to be implemented)")}]
|
||||
:placeholder placeholder
|
||||
:account-name @account-name
|
||||
:account-emoji @account-emoji
|
||||
|
||||
@@ -14,19 +14,16 @@
|
||||
on-change-name
|
||||
on-change-color
|
||||
on-change-emoji section-label
|
||||
hide-bottom-action?
|
||||
bottom-action-label bottom-action-props
|
||||
custom-bottom-action watch-only?]} & children]
|
||||
(let [{window-width :width} (rn/get-window)
|
||||
footer (when-not hide-bottom-action?
|
||||
(if custom-bottom-action
|
||||
custom-bottom-action
|
||||
[quo/button
|
||||
(merge
|
||||
{:size 40
|
||||
:type :primary}
|
||||
bottom-action-props)
|
||||
(i18n/label bottom-action-label)]))]
|
||||
footer (if custom-bottom-action
|
||||
custom-bottom-action
|
||||
[quo/button
|
||||
(merge {:size 40
|
||||
:type :primary}
|
||||
bottom-action-props)
|
||||
(i18n/label bottom-action-label)])]
|
||||
[floating-button-page/view
|
||||
{:header [quo/page-nav
|
||||
{:type :no-title
|
||||
|
||||
@@ -29,9 +29,4 @@
|
||||
{:margin-top 12
|
||||
:margin-bottom 8})
|
||||
|
||||
(defn slide-button-container
|
||||
[bottom]
|
||||
{:position :absolute
|
||||
:bottom (+ bottom 12)
|
||||
:left 20
|
||||
:right 20})
|
||||
(def slide-button-container {:z-index 1})
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.common.emoji-picker.utils :as emoji-picker.utils]
|
||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||
[status-im.common.standard-authentication.core :as standard-auth]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
@@ -20,7 +21,6 @@
|
||||
[utils.security.core :as security]
|
||||
[utils.string]))
|
||||
|
||||
|
||||
(defn- get-keypair-data
|
||||
[{:keys [title primary-keypair? new-keypair? derivation-path customization-color]}]
|
||||
[{:title title
|
||||
@@ -48,22 +48,24 @@
|
||||
:description-props {:text (string/replace derivation-path #"/" " / ")}}])
|
||||
|
||||
(defn- f-view
|
||||
[{:keys [theme]}]
|
||||
(let [account-name (reagent/atom "")
|
||||
account-color (reagent/atom (rand-nth colors/account-colors))
|
||||
emoji (reagent/atom (emoji-picker.utils/random-emoji))]
|
||||
(fn []
|
||||
(let [top (safe-area/get-top)
|
||||
bottom (safe-area/get-bottom)
|
||||
{window-width :width} (rn/get-window)
|
||||
number-of-accounts (count (rf/sub
|
||||
[_]
|
||||
(let [top (safe-area/get-top)
|
||||
bottom (safe-area/get-bottom)
|
||||
{window-width :width} (rn/get-window)
|
||||
account-color (reagent/atom (rand-nth colors/account-colors))
|
||||
emoji (reagent/atom (emoji-picker.utils/random-emoji))
|
||||
account-name (reagent/atom "")
|
||||
on-change-text #(reset! account-name %)
|
||||
show-account-origin #(rf/dispatch [:show-bottom-sheet
|
||||
{:content account-origin/view}])]
|
||||
(fn [{:keys [theme]}]
|
||||
(let [number-of-accounts (count (rf/sub
|
||||
[:wallet/accounts-without-watched-accounts]))
|
||||
{:keys [address customization-color]} (rf/sub [:profile/profile])
|
||||
{:keys [new-keypair]} (rf/sub [:wallet/create-account])
|
||||
keypairs (rf/sub [:wallet/keypairs])
|
||||
selected-keypair-uid (rf/sub [:wallet/selected-keypair-uid])
|
||||
placeholder (i18n/label :t/default-account-placeholder
|
||||
{:number (inc number-of-accounts)})
|
||||
placeholder (i18n/label :t/default-account-placeholder)
|
||||
derivation-path (utils/get-derivation-path
|
||||
number-of-accounts)
|
||||
keypair (some #(when (= (:key-uid %) selected-keypair-uid)
|
||||
@@ -94,20 +96,32 @@
|
||||
{:name (:name keypair)})
|
||||
(:name keypair)))]
|
||||
(rn/use-unmount #(rf/dispatch [:wallet/clear-new-keypair]))
|
||||
[rn/view {:style {:flex 1}}
|
||||
[quo/page-nav
|
||||
{:type :no-title
|
||||
:background :blur
|
||||
:right-side [{:icon-name :i/info
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content account-origin/view}])}]
|
||||
:icon-name :i/close
|
||||
:on-press #(rf/dispatch [:navigate-back])}]
|
||||
[quo/gradient-cover
|
||||
{:customization-color @account-color
|
||||
:container-style {:top (- top)}}]
|
||||
[rn/view
|
||||
{:style style/account-avatar-container}
|
||||
[floating-button-page/view
|
||||
{:gradient-cover? true
|
||||
:footer-container-padding 0
|
||||
:header-container-style {:padding-top top}
|
||||
:customization-color @account-color
|
||||
:header [quo/page-nav
|
||||
{:type :no-title
|
||||
:background :blur
|
||||
:right-side [{:icon-name :i/info
|
||||
:on-press show-account-origin}]
|
||||
:icon-name :i/close
|
||||
:on-press #(rf/dispatch [:navigate-back])}]
|
||||
:footer [standard-auth/slide-button
|
||||
{:size :size-48
|
||||
:track-text (i18n/label :t/slide-to-create-account)
|
||||
:customization-color @account-color
|
||||
:on-auth-success (fn [password]
|
||||
(if new-keypair
|
||||
(create-new-keypair-account password)
|
||||
(create-existing-keypair-account
|
||||
password)))
|
||||
:auth-button-label (i18n/label :t/confirm)
|
||||
:disabled? (empty? @account-name)
|
||||
:container-style (style/slide-button-container bottom)
|
||||
:dependencies [new-keypair]}]}
|
||||
[rn/view {:style style/account-avatar-container}
|
||||
[quo/account-avatar
|
||||
{:customization-color @account-color
|
||||
:size 80
|
||||
@@ -121,19 +135,19 @@
|
||||
:on-press #(rf/dispatch [:emoji-picker/open
|
||||
{:on-select (fn [selected-emoji]
|
||||
(reset! emoji selected-emoji))}])
|
||||
:container-style style/reaction-button-container} :i/reaction]]
|
||||
:container-style style/reaction-button-container}
|
||||
:i/reaction]]
|
||||
[quo/title-input
|
||||
{:customization-color @account-color
|
||||
:placeholder placeholder
|
||||
:on-change-text #(reset! account-name %)
|
||||
:on-change-text on-change-text
|
||||
:max-length constants/wallet-account-name-max-length
|
||||
:blur? true
|
||||
:disabled? false
|
||||
:default-value @account-name
|
||||
:container-style style/title-input-container}]
|
||||
[quo/divider-line]
|
||||
[rn/view
|
||||
{:style style/color-picker-container}
|
||||
[rn/view {:style style/color-picker-container}
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
@@ -153,19 +167,7 @@
|
||||
:primary-keypair? primary-keypair?
|
||||
:new-keypair? (boolean new-keypair)
|
||||
:derivation-path derivation-path
|
||||
:customization-color customization-color})}]
|
||||
[standard-auth/slide-button
|
||||
{:size :size-48
|
||||
:track-text (i18n/label :t/slide-to-create-account)
|
||||
:customization-color @account-color
|
||||
:on-auth-success (fn [password]
|
||||
(if new-keypair
|
||||
(create-new-keypair-account password)
|
||||
(create-existing-keypair-account password)))
|
||||
:auth-button-label (i18n/label :t/confirm)
|
||||
:disabled? (empty? @account-name)
|
||||
:container-style (style/slide-button-container bottom)
|
||||
:dependencies [new-keypair]}]]))))
|
||||
:customization-color customization-color})}]]))))
|
||||
|
||||
(defn- view-internal
|
||||
[]
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
(ns status-im.contexts.wallet.edit-account.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.hooks :as hooks]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.contexts.wallet.common.screen-base.create-or-edit-account.view
|
||||
:as create-or-edit-account]
|
||||
@@ -53,16 +52,15 @@
|
||||
:new-value @edited-account-name}))]
|
||||
(fn []
|
||||
(let [{:keys [name emoji address color watch-only? default-account?]
|
||||
:as account} (rf/sub [:wallet/current-viewing-account])
|
||||
network-details (rf/sub [:wallet/network-preference-details])
|
||||
test-networks-enabled? (rf/sub [:profile/test-networks-enabled?])
|
||||
network-preferences-key (if test-networks-enabled?
|
||||
:test-preferred-chain-ids
|
||||
:prod-preferred-chain-ids)
|
||||
account-name (or @edited-account-name name)
|
||||
button-disabled? (or (nil? @edited-account-name)
|
||||
(= name @edited-account-name))
|
||||
{:keys [keyboard-shown]} (hooks/use-keyboard)]
|
||||
:as account} (rf/sub [:wallet/current-viewing-account])
|
||||
network-details (rf/sub [:wallet/network-preference-details])
|
||||
test-networks-enabled? (rf/sub [:profile/test-networks-enabled?])
|
||||
network-preferences-key (if test-networks-enabled?
|
||||
:test-preferred-chain-ids
|
||||
:prod-preferred-chain-ids)
|
||||
account-name (or @edited-account-name name)
|
||||
button-disabled? (or (nil? @edited-account-name)
|
||||
(= name @edited-account-name))]
|
||||
[create-or-edit-account/view
|
||||
{:page-nav-right-side [(when-not default-account?
|
||||
{:icon-name :i/delete
|
||||
@@ -77,7 +75,6 @@
|
||||
:on-change-color #(on-change-color % account)
|
||||
:on-change-emoji #(on-change-emoji % account)
|
||||
:section-label :t/account-info
|
||||
:hide-bottom-action? (and button-disabled? (not keyboard-shown))
|
||||
:bottom-action-label :t/confirm
|
||||
:bottom-action-props {:customization-color color
|
||||
:disabled? button-disabled?
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
(:require [status-im.common.scan-qr-code.view :as scan-qr-code]
|
||||
[status-im.constants :as constants]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.i18n :as i18n]))
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- contains-address?
|
||||
[s]
|
||||
@@ -14,11 +15,15 @@
|
||||
|
||||
(defn view
|
||||
[]
|
||||
[scan-qr-code/view
|
||||
{:title (i18n/label :t/scan-qr)
|
||||
:subtitle (i18n/label :t/scan-an-account-qr-code)
|
||||
:error-message (i18n/label :t/oops-this-qr-does-not-contain-an-address)
|
||||
:validate-fn #(contains-address? %)
|
||||
:on-success-scan #(debounce/debounce-and-dispatch [:wallet/scan-address-success
|
||||
(extract-address %)]
|
||||
300)}])
|
||||
(let [{:keys [on-result]} (rf/sub [:get-screen-params])]
|
||||
[scan-qr-code/view
|
||||
{:title (i18n/label :t/scan-qr)
|
||||
:subtitle (i18n/label :t/scan-an-account-qr-code)
|
||||
:error-message (i18n/label :t/oops-this-qr-does-not-contain-an-address)
|
||||
:validate-fn #(contains-address? %)
|
||||
:on-success-scan (fn [result]
|
||||
(let [address (extract-address result)]
|
||||
(when on-result (on-result address))
|
||||
(debounce/debounce-and-dispatch
|
||||
[:wallet/scan-address-success address]
|
||||
300)))}]))
|
||||
|
||||
@@ -35,10 +35,11 @@
|
||||
[quo/address-input
|
||||
{:on-focus #(reset! input-focused? true)
|
||||
:on-blur #(reset! input-focused? false)
|
||||
:on-scan (fn []
|
||||
:on-scan (fn [on-result]
|
||||
(rn/dismiss-keyboard!)
|
||||
(rf/dispatch [:wallet/clean-scanned-address])
|
||||
(rf/dispatch [:open-modal :screen/wallet.scan-address]))
|
||||
(rf/dispatch [:open-modal :screen/wallet.scan-address
|
||||
{:on-result on-result}]))
|
||||
:ens-regex constants/regx-ens
|
||||
:scanned-value (or (when recipient-plain-address? send-address) scanned-address)
|
||||
:address-regex constants/regx-multichain-address
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
[legacy.status-im.ui.screens.profile.visibility-status.utils :as visibility-status-utils]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.utils :as wallet.utils]
|
||||
[utils.i18n :as i18n]))
|
||||
[utils.i18n :as i18n]
|
||||
[utils.money :as money]))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities/fetching-community
|
||||
@@ -306,12 +306,13 @@
|
||||
[checking-permissions?
|
||||
token-images
|
||||
{:keys [satisfied criteria]}]
|
||||
(let [sym (:symbol criteria)
|
||||
amount (:amount criteria)]
|
||||
(let [sym (:symbol criteria)
|
||||
amount-in-wei (:amountInWei criteria)
|
||||
decimals (:decimals criteria)]
|
||||
{:symbol sym
|
||||
:sufficient? satisfied
|
||||
:loading? checking-permissions?
|
||||
:amount (wallet.utils/remove-trailing-zeroes amount)
|
||||
:amount (money/to-fixed (money/token->unit amount-in-wei decimals))
|
||||
:img-src (get token-images sym)}))
|
||||
|
||||
(re-frame/reg-sub
|
||||
|
||||
@@ -289,19 +289,23 @@
|
||||
checks {:checking? checking-permissions?
|
||||
:check
|
||||
{:satisfied true
|
||||
:highestRole {:type constants/community-token-permission-become-admin
|
||||
:criteria [{:tokenRequirement [{:satisfied true
|
||||
:criteria {:contract_addresses
|
||||
{:5 "0x0"}
|
||||
:type 1
|
||||
:symbol "DAI"
|
||||
:amount "5.0"
|
||||
:decimals 18}}]}
|
||||
{:tokenRequirement [{:satisfied false
|
||||
:criteria {:type 1
|
||||
:symbol "ETH"
|
||||
:amount "0.002"
|
||||
:decimals 18}}]}]}
|
||||
:highestRole
|
||||
{:type constants/community-token-permission-become-admin
|
||||
:criteria [{:tokenRequirement [{:satisfied true
|
||||
:criteria {:contract_addresses
|
||||
{:5 "0x0"}
|
||||
:type 1
|
||||
:symbol "DAI"
|
||||
:amountInWei
|
||||
"5000000000000000000"
|
||||
:amount "5.0"
|
||||
:decimals 18}}]}
|
||||
{:tokenRequirement [{:satisfied false
|
||||
:criteria {:type 1
|
||||
:symbol "ETH"
|
||||
:amountInWei "2000000000000000"
|
||||
:amount "0.002"
|
||||
:decimals 18}}]}]}
|
||||
|
||||
:permissions
|
||||
{:a3dd5b6b-d93b-452c-b22a-09a8f42ec566 {:criteria [true false
|
||||
|
||||
@@ -450,8 +450,8 @@
|
||||
"decline": "Decline",
|
||||
"decryption-failed-content": "An error occured decrypting your data. You might need to erase your old data and generate a new account. Tap “Apply” to erase or “Cancel” to try again",
|
||||
"default": "Default",
|
||||
"default-account-placeholder": "Account {{number}}",
|
||||
"default-watched-address-placeholder": "Watched address {{number}}",
|
||||
"default-account-placeholder": "Account Name",
|
||||
"default-watched-address-placeholder": "Watched address",
|
||||
"delete": "Delete",
|
||||
"delete-and-leave-group": "Delete and leave group",
|
||||
"delete-bootnode": "Delete bootnode",
|
||||
@@ -2558,5 +2558,9 @@
|
||||
"ledger-live": "Ledger live",
|
||||
"keep-key": "KeepKey",
|
||||
"type-your-path": "Type your own derivation path",
|
||||
"default-format": "Default format"
|
||||
"default-format": "Default format",
|
||||
"address-count": {
|
||||
"one": "1 address",
|
||||
"other": "{{count}} addresses"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user