Added address validation
This commit is contained in:
parent
9d8bd7d740
commit
5392b8d9a2
|
@ -69,7 +69,7 @@
|
||||||
(:label-font-large config)
|
(:label-font-large config)
|
||||||
(:label-font-small config)))
|
(:label-font-small config)))
|
||||||
:float-label? (if (s/blank? value) false true)}]
|
:float-label? (if (s/blank? value) false true)}]
|
||||||
(log/debug "component-will-mount")
|
;(log/debug "component-will-mount")
|
||||||
(r/set-state component data)))
|
(r/set-state component data)))
|
||||||
|
|
||||||
; Invoked once, only on the client (not on the server), immediately after the
|
; Invoked once, only on the client (not on the server), immediately after the
|
||||||
|
@ -79,7 +79,8 @@
|
||||||
; parent components.
|
; parent components.
|
||||||
(defn component-did-mount [component]
|
(defn component-did-mount [component]
|
||||||
(let [props (r/props component)]
|
(let [props (r/props component)]
|
||||||
(log/debug "component-did-mount:")))
|
;(log/debug "component-did-mount:")
|
||||||
|
))
|
||||||
|
|
||||||
; Invoked when a component is receiving new props. This method is not called for
|
; Invoked when a component is receiving new props. This method is not called for
|
||||||
; the initial render. Use this as an opportunity to react to a prop transition
|
; the initial render. Use this as an opportunity to react to a prop transition
|
||||||
|
@ -87,7 +88,8 @@
|
||||||
; The old props can be accessed via this.props. Calling this.setState() within
|
; The old props can be accessed via this.props. Calling this.setState() within
|
||||||
; this function will not trigger an additional render.
|
; this function will not trigger an additional render.
|
||||||
(defn component-will-receive-props [component new-props]
|
(defn component-will-receive-props [component new-props]
|
||||||
(log/debug "component-will-receive-props: new-props=" new-props))
|
;(log/debug "component-will-receive-props: new-props=" new-props)
|
||||||
|
)
|
||||||
|
|
||||||
; Invoked before rendering when new props or state are being received. This method
|
; Invoked before rendering when new props or state are being received. This method
|
||||||
; is not called for the initial render or when forceUpdate is used. Use this as
|
; is not called for the initial render or when forceUpdate is used. Use this as
|
||||||
|
@ -97,20 +99,22 @@
|
||||||
; until the next state change. In addition, componentWillUpdate and
|
; until the next state change. In addition, componentWillUpdate and
|
||||||
; componentDidUpdate will not be called.
|
; componentDidUpdate will not be called.
|
||||||
(defn should-component-update [component next-props next-state]
|
(defn should-component-update [component next-props next-state]
|
||||||
(log/debug "should-component-update: " next-props next-state)
|
;(log/debug "should-component-update: " next-props next-state)
|
||||||
true)
|
true)
|
||||||
|
|
||||||
; Invoked immediately before rendering when new props or state are being received.
|
; Invoked immediately before rendering when new props or state are being received.
|
||||||
; This method is not called for the initial render. Use this as an opportunity
|
; This method is not called for the initial render. Use this as an opportunity
|
||||||
; to perform preparation before an update occurs.
|
; to perform preparation before an update occurs.
|
||||||
(defn component-will-update [component next-props next-state]
|
(defn component-will-update [component next-props next-state]
|
||||||
(log/debug "component-will-update: " next-props next-state))
|
;(log/debug "component-will-update: " next-props next-state)
|
||||||
|
)
|
||||||
|
|
||||||
; Invoked immediately after the component's updates are flushed to the DOM.
|
; Invoked immediately after the component's updates are flushed to the DOM.
|
||||||
; This method is not called for the initial render. Use this as an opportunity
|
; This method is not called for the initial render. Use this as an opportunity
|
||||||
; to operate on the DOM when the component has been updated.
|
; to operate on the DOM when the component has been updated.
|
||||||
(defn component-did-update [component prev-props prev-state]
|
(defn component-did-update [component prev-props prev-state]
|
||||||
(log/debug "component-did-update: " prev-props prev-state))
|
;(log/debug "component-did-update: " prev-props prev-state)
|
||||||
|
)
|
||||||
|
|
||||||
(defn on-focus [{:keys [component animation onFocus]}]
|
(defn on-focus [{:keys [component animation onFocus]}]
|
||||||
(do
|
(do
|
||||||
|
@ -147,7 +151,7 @@
|
||||||
focusLineColor (if error errorColor focusLineColor)
|
focusLineColor (if error errorColor focusLineColor)
|
||||||
labelColor (if (and error (not float-label?)) errorColor labelColor)
|
labelColor (if (and error (not float-label?)) errorColor labelColor)
|
||||||
label (if error (str label " *") label)]
|
label (if error (str label " *") label)]
|
||||||
(log/debug "reagent-render: " data)
|
;(log/debug "reagent-render: " data)
|
||||||
[view (merge st/text-field-container wrapperStyle)
|
[view (merge st/text-field-container wrapperStyle)
|
||||||
[animated-text {:style (st/label label-top label-font-size labelColor)} label]
|
[animated-text {:style (st/label label-top label-font-size labelColor)} label]
|
||||||
[text-input {:style (merge st/text-input inputStyle)
|
[text-input {:style (merge st/text-input inputStyle)
|
||||||
|
@ -187,5 +191,5 @@
|
||||||
:component-did-update component-did-update
|
:component-did-update component-did-update
|
||||||
:display-name "text-field"
|
:display-name "text-field"
|
||||||
:reagent-render reagent-render}]
|
:reagent-render reagent-render}]
|
||||||
(log/debug "Creating text-field component: " data)
|
;(log/debug "Creating text-field component: " data)
|
||||||
(r/create-class component-data)))
|
(r/create-class component-data)))
|
|
@ -1,13 +1,21 @@
|
||||||
(ns status-im.contacts.validations
|
(ns status-im.contacts.validations
|
||||||
(:require [cljs.spec :as s]
|
(:require [cljs.spec :as s]
|
||||||
|
[cljsjs.web3]
|
||||||
[status-im.persistence.realm :as realm]))
|
[status-im.persistence.realm :as realm]))
|
||||||
|
|
||||||
|
(defn is-address? [s]
|
||||||
|
(.isAddress js/Web3.prototype s))
|
||||||
|
|
||||||
(defn unique-identity? [identity]
|
(defn unique-identity? [identity]
|
||||||
(println identity)
|
(println identity)
|
||||||
(not (realm/exists? :contacts :whisper-identity identity)))
|
(not (realm/exists? :contacts :whisper-identity identity)))
|
||||||
|
|
||||||
(defn valid-length? [identity]
|
(defn valid-length? [identity]
|
||||||
(= 132 (count identity)))
|
(let [length (count identity)]
|
||||||
|
(or
|
||||||
|
(= 130 length)
|
||||||
|
(= 132 length)
|
||||||
|
(is-address? identity))))
|
||||||
|
|
||||||
(s/def ::identity-length valid-length?)
|
(s/def ::identity-length valid-length?)
|
||||||
(s/def ::unique-identity unique-identity?)
|
(s/def ::unique-identity unique-identity?)
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
[status-im.components.text-field.view :refer [text-field]]
|
[status-im.components.text-field.view :refer [text-field]]
|
||||||
[status-im.utils.identicon :refer [identicon]]
|
[status-im.utils.identicon :refer [identicon]]
|
||||||
[status-im.components.toolbar :refer [toolbar]]
|
[status-im.components.toolbar :refer [toolbar]]
|
||||||
|
[status-im.utils.utils :refer [log on-error http-post toast]]
|
||||||
[status-im.components.styles :refer [color-purple
|
[status-im.components.styles :refer [color-purple
|
||||||
color-white
|
color-white
|
||||||
icon-search
|
icon-search
|
||||||
|
@ -43,12 +44,12 @@
|
||||||
:label (label :t/name)
|
:label (label :t/name)
|
||||||
:onChangeText #(dispatch [:set-in [:new-contact :name] %])}])
|
:onChangeText #(dispatch [:set-in [:new-contact :name] %])}])
|
||||||
|
|
||||||
(defview contact-whisper-id-input [whisper-identity]
|
(defview contact-whisper-id-input [whisper-identity error]
|
||||||
[]
|
[]
|
||||||
(let [error (if (str/blank? whisper-identity) "" nil)
|
(let [error (if (str/blank? whisper-identity) "" error)
|
||||||
error (if (s/valid? ::v/whisper-identity whisper-identity)
|
error (if (s/valid? ::v/whisper-identity whisper-identity)
|
||||||
error
|
error
|
||||||
"Please enter a valid address or scan a QR code")]
|
(label :t/enter-valid-address))]
|
||||||
[view button-input-container
|
[view button-input-container
|
||||||
[text-field
|
[text-field
|
||||||
{:error error
|
{:error error
|
||||||
|
@ -56,26 +57,52 @@
|
||||||
:value whisper-identity
|
:value whisper-identity
|
||||||
:wrapperStyle (merge button-input)
|
:wrapperStyle (merge button-input)
|
||||||
:label (label :t/address)
|
:label (label :t/address)
|
||||||
:onChangeText #(dispatch [:set-in [:new-contact :whisper-identity] %])}]
|
:onChangeText #(do
|
||||||
|
(dispatch [:set-in [:new-contact :whisper-identity] %])
|
||||||
|
(dispatch [:set :new-contact-address-error nil]))}]
|
||||||
[scan-button {:showLabel (zero? (count whisper-identity))
|
[scan-button {:showLabel (zero? (count whisper-identity))
|
||||||
:handler #(dispatch [:scan-qr-code {:toolbar-title (label :t/new-contact)} :set-new-contact-from-qr])}]]))
|
:handler #(dispatch [:scan-qr-code {:toolbar-title (label :t/new-contact)} :set-new-contact-from-qr])}]]))
|
||||||
|
|
||||||
|
(defn on-add-contact [whisper-identity new-contact]
|
||||||
|
(if (v/is-address? whisper-identity)
|
||||||
|
(http-post "get-contacts-by-address" {:addresses [whisper-identity]}
|
||||||
|
(fn [{:keys [contacts]}]
|
||||||
|
(if (> (count contacts) 0)
|
||||||
|
(let [contact (first contacts)
|
||||||
|
new-contact (merge
|
||||||
|
new-contact
|
||||||
|
{:address whisper-identity
|
||||||
|
:whisper-identity (:whisper-identity contact)})]
|
||||||
|
(dispatch [:add-new-contact new-contact]))
|
||||||
|
(dispatch [:set :new-contact-address-error (label :t/unknown-address)]))))
|
||||||
|
(dispatch [:add-new-contact new-contact])))
|
||||||
|
|
||||||
|
(defn toolbar-action [whisper-identity new-contact error]
|
||||||
|
(let [valid-contact? (and
|
||||||
|
(s/valid? ::v/contact new-contact)
|
||||||
|
(nil? error))]
|
||||||
|
{:image {:source {:uri (if valid-contact?
|
||||||
|
:icon_ok_blue
|
||||||
|
:icon_ok_disabled)}
|
||||||
|
:style icon-search}
|
||||||
|
:handler #(when valid-contact?
|
||||||
|
(let [contact (merge
|
||||||
|
{:photo-path (identicon whisper-identity)}
|
||||||
|
new-contact)]
|
||||||
|
(on-add-contact whisper-identity contact)))}))
|
||||||
|
|
||||||
(defview new-contact []
|
(defview new-contact []
|
||||||
[{:keys [name whisper-identity phone-number] :as new-contact} [:get :new-contact]]
|
[{:keys [name whisper-identity phone-number] :as new-contact} [:get :new-contact]
|
||||||
(let [valid-contact? (s/valid? ::v/contact new-contact)]
|
error [:get :new-contact-address-error]]
|
||||||
[view st/contact-form-container
|
[view st/contact-form-container
|
||||||
[toolbar {:background-color :white
|
[toolbar {:background-color :white
|
||||||
:nav-action {:image {:source {:uri :icon_back}
|
:nav-action {:image {:source {:uri :icon_back}
|
||||||
:style icon-back}
|
:style icon-back}
|
||||||
:handler #(dispatch [:navigate-back])}
|
:handler #(dispatch [:navigate-back])}
|
||||||
:custom-content toolbar-title
|
:custom-content toolbar-title
|
||||||
:action {:image {:source {:uri (if valid-contact?
|
:action (toolbar-action whisper-identity new-contact error)}]
|
||||||
:icon_ok_blue
|
|
||||||
:icon_ok_disabled)}
|
|
||||||
:style icon-search}
|
|
||||||
:handler #(when valid-contact? (dispatch [:add-new-contact (merge {:photo-path (identicon whisper-identity)} new-contact)]))}}]
|
|
||||||
[view st/form-container
|
[view st/form-container
|
||||||
[contact-name-input name]
|
[contact-name-input name]
|
||||||
[contact-whisper-id-input whisper-identity]]
|
[contact-whisper-id-input whisper-identity error]]
|
||||||
[view st/address-explication-container
|
[view st/address-explication-container
|
||||||
[text {:style st/address-explication} (label :t/address-explication)]]]))
|
[text {:style st/address-explication} (label :t/address-explication)]]])
|
||||||
|
|
|
@ -125,6 +125,9 @@
|
||||||
:name "Name"
|
:name "Name"
|
||||||
:whisper-identity "Whisper Identity"
|
:whisper-identity "Whisper Identity"
|
||||||
:address-explication "Maybe here should be some text explaining what an address is and where to look for it"
|
:address-explication "Maybe here should be some text explaining what an address is and where to look for it"
|
||||||
|
:enter-valid-address "Please enter a valid address or scan a QR code"
|
||||||
|
:unknown-address "Unknown address"
|
||||||
|
|
||||||
|
|
||||||
;login
|
;login
|
||||||
:recover-access "Recover access"
|
:recover-access "Recover access"
|
||||||
|
|
Loading…
Reference in New Issue