Profile validations (#235)

Former-commit-id: 80ec3eeef3
This commit is contained in:
alwxndr 2016-09-23 16:22:35 +03:00 committed by Alexander Pantyuhov
parent 0f91e23798
commit 08f17909f6
25 changed files with 260 additions and 195 deletions

View File

@ -27,7 +27,8 @@
"react-native-image-resizer", "react-native-image-resizer",
"react-native-image-crop-picker", "react-native-image-crop-picker",
"react-native-webview-bridge", "react-native-webview-bridge",
"react-native-drawer-layout" "react-native-drawer-layout",
"homoglyph-finder"
], ],
"imageDirs": [ "imageDirs": [
"images" "images"

View File

@ -18,6 +18,7 @@
"dns.js": "^1.0.1", "dns.js": "^1.0.1",
"domain-browser": "^1.1.7", "domain-browser": "^1.1.7",
"events": "^1.1.1", "events": "^1.1.1",
"homoglyph-finder": "^1.1.1",
"https-browserify": "0.0.1", "https-browserify": "0.0.1",
"identicon.js": "github:status-im/identicon.js", "identicon.js": "github:status-im/identicon.js",
"os-browserify": "^0.1.2", "os-browserify": "^0.1.2",

View File

@ -14,7 +14,8 @@
status-im.accounts.recover.handlers status-im.accounts.recover.handlers
[clojure.string :as str] [clojure.string :as str]
[status-im.utils.datetime :as time] [status-im.utils.datetime :as time]
[status-im.utils.handlers :as u])) [status-im.utils.handlers :as u]
[status-im.constants :refer [console-chat-id]]))
(defn save-account [_ [_ account]] (defn save-account [_ [_ account]]
@ -117,7 +118,7 @@
:content (label :t/keypair-generated)} :content (label :t/keypair-generated)}
:content-type content-type-command-request :content-type content-type-command-request
:outgoing false :outgoing false
:from "console" :from console-chat-id
:to "me"}]) :to "me"}])
db)) db))

View File

@ -26,7 +26,8 @@
[status-im.utils.listview :as lw] [status-im.utils.listview :as lw]
[status-im.accounts.views.account :refer [account-view]] [status-im.accounts.views.account :refer [account-view]]
[status-im.i18n :refer [label]] [status-im.i18n :refer [label]]
[status-im.accounts.styles :as st])) [status-im.accounts.styles :as st]
[status-im.constants :refer [console-chat-id]]))
(defn toolbar-title [] (defn toolbar-title []
(let [style (merge toolbar-title-text {:color color-white})] (let [style (merge toolbar-title-text {:color color-white})]
@ -46,7 +47,7 @@
(dispatch-sync [:reset-app]) (dispatch-sync [:reset-app])
; add accounts screen to history ( maybe there is a better way ? ) ; add accounts screen to history ( maybe there is a better way ? )
(dispatch [:navigate-to-clean :accounts]) (dispatch [:navigate-to-clean :accounts])
(dispatch [:navigate-to :chat "console"])) (dispatch [:navigate-to :chat console-chat-id]))
(defview accounts [] (defview accounts []
[accounts [:get :accounts] [accounts [:get :accounts]

View File

@ -3,17 +3,19 @@
[status-im.utils.utils :as u])) [status-im.utils.utils :as u]))
(def component-styles (def component-styles
{:status-bar {:default {:height 0 {:status-bar {:default {:height 0
:bar-style "default" :bar-style "default"
:color styles/color-gray} :color styles/color-gray}
:main {:height 0 :main {:height 0
:bar-style "default" :bar-style "default"
:color styles/color-gray} :color styles/color-gray}
:transparent {:height 20 :transparent {:height 20
:bar-style "default" :bar-style "default"
:translucent? true :translucent? true
:color styles/color-transparent}} :color styles/color-transparent}}
:bottom-gradient {:height 3}}) :bottom-gradient {:height 3}
:input-label {:left 4}
:input-error-text {:margin-left 4}})
(def fonts (def fonts
{:default {:font-family "sans-serif"} {:default {:font-family "sans-serif"}

View File

@ -25,6 +25,7 @@
[status-im.utils.types :refer [json->clj]] [status-im.utils.types :refer [json->clj]]
[status-im.chat.handlers.commands :refer [command-prefix]] [status-im.chat.handlers.commands :refer [command-prefix]]
[status-im.chat.utils :refer [console? not-console?]] [status-im.chat.utils :refer [console? not-console?]]
[status-im.constants :refer [console-chat-id]]
status-im.chat.handlers.animation status-im.chat.handlers.animation
status-im.chat.handlers.requests status-im.chat.handlers.requests
status-im.chat.handlers.unviewed-messages status-im.chat.handlers.unviewed-messages
@ -142,7 +143,7 @@
(str command-prefix text) (str command-prefix text)
text)] text)]
(dispatch [::stage-command-with-content command text'])) (dispatch [::stage-command-with-content command text']))
(dispatch [::check-suggestions "console" text]))))) (dispatch [::check-suggestions console-chat-id text])))))
(register-handler ::stage-command-with-content (register-handler ::stage-command-with-content
(u/side-effect! (u/side-effect!
@ -172,9 +173,8 @@
(defn init-console-chat (defn init-console-chat
[{:keys [chats] :as db} existing-account?] [{:keys [chats] :as db} existing-account?]
(let [chat-id "console" (let [new-chat sign-up-service/console-chat]
new-chat sign-up-service/console-chat] (if (chats console-chat-id)
(if (chats chat-id)
db db
(do (do
(chats/create-chat new-chat) (chats/create-chat new-chat)
@ -183,9 +183,9 @@
(sign-up-service/start-signup)) (sign-up-service/start-signup))
(-> db (-> db
(assoc :new-chat new-chat) (assoc :new-chat new-chat)
(update :chats assoc chat-id new-chat) (update :chats assoc console-chat-id new-chat)
(update :chats-ids conj chat-id) (update :chats-ids conj console-chat-id)
(assoc :current-chat-id "console")))))) (assoc :current-chat-id console-chat-id))))))
(register-handler :init-console-chat (register-handler :init-console-chat
(fn [db _] (fn [db _]

View File

@ -1,10 +1,11 @@
(ns status-im.chat.handlers.wallet-chat (ns status-im.chat.handlers.wallet-chat
(:require [re-frame.core :refer [after enrich path dispatch]] (:require [re-frame.core :refer [after enrich path dispatch]]
[status-im.utils.handlers :refer [register-handler] :as u])) [status-im.utils.handlers :refer [register-handler] :as u]
[status-im.constants :refer [wallet-chat-id]]))
(register-handler :init-wallet-chat (register-handler :init-wallet-chat
(u/side-effect! (u/side-effect!
(fn [] (fn []
(dispatch [:add-chat "wallet" {:name "Wallet" (dispatch [:add-chat wallet-chat-id {:name "Wallet"
:dapp-url "http://127.0.0.1:3450"}])))) :dapp-url "http://127.0.0.1:3450"}]))))

View File

@ -26,6 +26,7 @@
[status-im.chat.views.bottom-info :refer [bottom-info-view]] [status-im.chat.views.bottom-info :refer [bottom-info-view]]
[status-im.i18n :refer [label label-pluralize]] [status-im.i18n :refer [label label-pluralize]]
[status-im.components.animation :as anim] [status-im.components.animation :as anim]
[status-im.constants :refer [console-chat-id]]
[reagent.core :as r] [reagent.core :as r]
[clojure.string :as str] [clojure.string :as str]
[cljs-time.core :as t])) [cljs-time.core :as t]))
@ -82,7 +83,7 @@
(<= last-online-date now-date)) (<= last-online-date now-date))
(time/time-ago last-online-date) (time/time-ago last-online-date)
(label :t/active-unknown))) (label :t/active-unknown)))
(if (= chat-id "console") (if (= chat-id console-chat-id)
(label :t/active-online) (label :t/active-online)
(label :t/active-unknown)))) (label :t/active-unknown))))

View File

@ -6,7 +6,8 @@
[status-im.utils.sms-listener :refer [add-sms-listener [status-im.utils.sms-listener :refer [add-sms-listener
remove-sms-listener]] remove-sms-listener]]
[status-im.utils.phone-number :refer [format-phone-number]] [status-im.utils.phone-number :refer [format-phone-number]]
[status-im.constants :refer [text-content-type [status-im.constants :refer [console-chat-id
text-content-type
content-type-command content-type-command
content-type-command-request content-type-command-request
content-type-status]] content-type-status]]
@ -15,7 +16,7 @@
(defn send-console-message [text] (defn send-console-message [text]
{:message-id (random/id) {:message-id (random/id)
:from "me" :from "me"
:to "console" :to console-chat-id
:content text :content text
:content-type text-content-type :content-type text-content-type
:outgoing true}) :outgoing true})
@ -36,7 +37,7 @@
(or message (label :t/confirmation-code))) (or message (label :t/confirmation-code)))
:content-type content-type-command-request :content-type content-type-command-request
:outgoing false :outgoing false
:from "console" :from console-chat-id
:to "me"}]))) :to "me"}])))
(defn handle-sms [{body :body}] (defn handle-sms [{body :body}]
@ -60,7 +61,7 @@
:content (label :t/contacts-syncronized) :content (label :t/contacts-syncronized)
:content-type text-content-type :content-type text-content-type
:outgoing false :outgoing false
:from "console" :from console-chat-id
:to "me"}]) :to "me"}])
(dispatch [:set-signed-up true])) (dispatch [:set-signed-up true]))
@ -74,7 +75,7 @@
:content (:message body) :content (:message body)
:content-type text-content-type :content-type text-content-type
:outgoing false :outgoing false
:from "console" :from console-chat-id
:to "me"}]) :to "me"}])
(let [status (keyword (:status body))] (let [status (keyword (:status body))]
(when (= :confirmed status) (when (= :confirmed status)
@ -95,7 +96,7 @@
(label :t/phone-number-required)) (label :t/phone-number-required))
:content-type content-type-command-request :content-type content-type-command-request
:outgoing false :outgoing false
:from "console" :from console-chat-id
:to "me"}]))) :to "me"}])))
;; -- Saving password ---------------------------------------- ;; -- Saving password ----------------------------------------
@ -106,7 +107,7 @@
:content (label :t/password-saved) :content (label :t/password-saved)
:content-type text-content-type :content-type text-content-type
:outgoing false :outgoing false
:from "console" :from console-chat-id
:to "me" :to "me"
:new? false}]) :new? false}])
(dispatch [:received-message (dispatch [:received-message
@ -114,7 +115,7 @@
:content (label :t/generate-passphrase) :content (label :t/generate-passphrase)
:content-type text-content-type :content-type text-content-type
:outgoing false :outgoing false
:from "console" :from console-chat-id
:to "me" :to "me"
:new? false}]) :new? false}])
(dispatch [:received-message (dispatch [:received-message
@ -122,7 +123,7 @@
:content (label :t/here-is-your-passphrase) :content (label :t/here-is-your-passphrase)
:content-type text-content-type :content-type text-content-type
:outgoing false :outgoing false
:from "console" :from console-chat-id
:to "me" :to "me"
:new? false}]) :new? false}])
(dispatch [:received-message (dispatch [:received-message
@ -130,7 +131,7 @@
:content mnemonic :content mnemonic
:content-type text-content-type :content-type text-content-type
:outgoing false :outgoing false
:from "console" :from console-chat-id
:to "me" :to "me"
:new? false}]) :new? false}])
(dispatch [:received-message (dispatch [:received-message
@ -138,7 +139,7 @@
:content (label :t/written-down) :content (label :t/written-down)
:content-type text-content-type :content-type text-content-type
:outgoing false :outgoing false
:from "console" :from console-chat-id
:to "me" :to "me"
:new? false}]) :new? false}])
;; TODO highlight '!phone' ;; TODO highlight '!phone'
@ -149,8 +150,8 @@
(def intro-status (def intro-status
{:message-id "intro-status" {:message-id "intro-status"
:content (label :t/intro-status) :content (label :t/intro-status)
:from "console" :from console-chat-id
:chat-id "console" :chat-id console-chat-id
:content-type content-type-status :content-type content-type-status
:outgoing false :outgoing false
:to "me"}) :to "me"})
@ -162,7 +163,7 @@
:content (label :t/intro-message1) :content (label :t/intro-message1)
:content-type text-content-type :content-type text-content-type
:outgoing false :outgoing false
:from "console" :from console-chat-id
:to "me"}]) :to "me"}])
(when-not logged-in? (when-not logged-in?
(dispatch [:received-message (dispatch [:received-message
@ -170,7 +171,7 @@
:content (label :t/intro-message2) :content (label :t/intro-message2)
:content-type text-content-type :content-type text-content-type
:outgoing false :outgoing false
:from "console" :from console-chat-id
:to "me"}]) :to "me"}])
(dispatch [:received-message (dispatch [:received-message
@ -180,12 +181,12 @@
(label :t/keypair-generated)) (label :t/keypair-generated))
:content-type content-type-command-request :content-type content-type-command-request
:outgoing false :outgoing false
:from "console" :from console-chat-id
:to "me"}]))) :to "me"}])))
(def console-chat (def console-chat
{:chat-id "console" {:chat-id console-chat-id
:name "console" :name console-chat-id
; todo remove/change dapp config fot console ; todo remove/change dapp config fot console
:dapp-url "http://localhost:8185/resources" :dapp-url "http://localhost:8185/resources"
:dapp-hash 858845357 :dapp-hash 858845357
@ -193,6 +194,6 @@
:group-chat false :group-chat false
:is-active true :is-active true
:timestamp (.getTime (js/Date.)) :timestamp (.getTime (js/Date.))
:contacts [{:identity "console" :contacts [{:identity console-chat-id
:text-color "#FFFFFF" :text-color "#FFFFFF"
:background-color "#AB7967"}]}) :background-color "#AB7967"}]})

View File

@ -1,7 +1,8 @@
(ns status-im.chat.utils) (ns status-im.chat.utils
(:require [status-im.constants :refer [console-chat-id]]))
(defn console? [s] (defn console? [s]
(= "console" s)) (= console-chat-id s))
(def not-console? (def not-console?
(complement console?)) (complement console?))

View File

@ -6,7 +6,8 @@
[status-im.utils.types :refer [json->clj]] [status-im.utils.types :refer [json->clj]]
[status-im.commands.utils :refer [generate-hiccup reg-handler]] [status-im.commands.utils :refer [generate-hiccup reg-handler]]
[clojure.string :as s] [clojure.string :as s]
[status-im.components.react :as r])) [status-im.components.react :as r]
[status-im.constants :refer [console-chat-id]]))
(defn init-render-command! (defn init-render-command!
[_ [chat-id command message-id data]] [_ [chat-id command message-id data]]
@ -37,7 +38,7 @@
parameters' (assoc parameters :command command')] parameters' (assoc parameters :command command')]
(if transaction-hash (if transaction-hash
(dispatch [:wait-for-transaction transaction-hash parameters']) (dispatch [:wait-for-transaction transaction-hash parameters'])
(let [events (if (= "console" chat-id) (let [events (if (= console-chat-id chat-id)
(merge regular-events console-events) (merge regular-events console-events)
regular-events) regular-events)
parameters'' (if-let [handler (events (keyword event))] parameters'' (if-let [handler (events (keyword event))]

View File

@ -7,7 +7,8 @@
[status-im.persistence.realm.core :as realm] [status-im.persistence.realm.core :as realm]
[status-im.components.status :as status] [status-im.components.status :as status]
[status-im.utils.types :refer [json->clj]] [status-im.utils.types :refer [json->clj]]
[status-im.commands.utils :refer [reg-handler]])) [status-im.commands.utils :refer [reg-handler]]
[status-im.constants :refer [console-chat-id wallet-chat-id]]))
(def commands-js "commands.js") (def commands-js "commands.js")
@ -25,10 +26,10 @@
(when true (when true
;-let [url (get-in db [:chats identity :dapp-url])] ;-let [url (get-in db [:chats identity :dapp-url])]
(cond (cond
(= "console" identity) (= console-chat-id identity)
(dispatch [::validate-hash identity (slurp "resources/console.js")]) (dispatch [::validate-hash identity (slurp "resources/console.js")])
(= "wallet" identity) (= wallet-chat-id identity)
(dispatch [::validate-hash identity (slurp "resources/wallet.js")]) (dispatch [::validate-hash identity (slurp "resources/wallet.js")])
:else :else

View File

@ -8,6 +8,7 @@
[status-im.components.icons.custom-icons :refer [oct-icon]] [status-im.components.icons.custom-icons :refer [oct-icon]]
[status-im.components.chat-icon.styles :as st] [status-im.components.chat-icon.styles :as st]
[status-im.components.styles :refer [default-chat-color]] [status-im.components.styles :refer [default-chat-color]]
[status-im.constants :refer [console-chat-id]]
[clojure.string :as s])) [clojure.string :as s]))
(defn default-chat-icon [name styles] (defn default-chat-icon [name styles]
@ -33,7 +34,7 @@
(defview chat-icon-view [chat-id group-chat name online styles] (defview chat-icon-view [chat-id group-chat name online styles]
[photo-path [:chat-photo chat-id]] [photo-path [:chat-photo chat-id]]
[view (:container styles) [view (:container styles)
(if-not (or (s/blank? photo-path) (= chat-id "console")) (if-not (or (s/blank? photo-path) (= chat-id console-chat-id))
[chat-icon photo-path styles] [chat-icon photo-path styles]
[default-chat-icon name styles]) [default-chat-icon name styles])
(when-not group-chat (when-not group-chat

View File

@ -15,6 +15,7 @@
(def color-light-gray "#EEF2F5") (def color-light-gray "#EEF2F5")
(def text1-color color-black) (def text1-color color-black)
(def text1-disabled-color "#555555")
(def text2-color color-gray) (def text2-color color-gray)
(def text3-color color-blue) (def text3-color color-blue)
(def text4-color color-white) (def text4-color color-white)

View File

@ -1,4 +1,5 @@
(ns status-im.components.text-field.styles) (ns status-im.components.text-field.styles
(:require [status-im.utils.platform :refer [platform-specific]]))
(def text-field-container (def text-field-container
@ -15,12 +16,13 @@
:text-align-vertical :top}) :text-align-vertical :top})
(defn label [top font-size color] (defn label [top font-size color]
{:position :absolute (let [input-label-style (get-in platform-specific [:component-styles :input-label])]
:top top (merge input-label-style
:left 0 {:position :absolute
:color color :top top
:font-size font-size :color color
:background-color :transparent}) :font-size font-size
:background-color :transparent})))
(def label-float (def label-float
{}) {})
@ -36,6 +38,8 @@
:width width}) :width width})
(defn error-text [color] (defn error-text [color]
{:color color (let [input-error-text-style (get-in platform-specific [:component-styles :input-error-text])]
:background-color :transparent (merge input-error-text-style
:font-size 12}) {:color color
:background-color :transparent
:font-size 12})))

View File

@ -126,32 +126,32 @@
(when onFocus (onFocus)))) (when onFocus (onFocus))))
(defn on-input-blur [{:keys [component value animation onBlur]}] (defn on-input-blur [{:keys [component value animation onBlur]}]
(do (log/debug "Input blurred")
(log/debug "Input blurred") (r/set-state component {:has-focus false
(r/set-state component {:has-focus false :float-label? (if (s/blank? value) false true)})
:float-label? (if (s/blank? value) false true)}) (when (s/blank? value)
(when (s/blank? value) (field-animation animation))
(field-animation animation)) (when onBlur (onBlur)))
(when onBlur (onBlur))))
(defn get-width [event] (defn get-width [event]
(.-width (.-layout (.-nativeEvent event)))) (.-width (.-layout (.-nativeEvent event))))
(defn reagent-render [data children] (defn reagent-render [data children]
(let [component (r/current-component) (let [component (r/current-component)
{:keys [has-focus {:keys [has-focus
float-label? float-label?
label-top label-top
label-font-size label-font-size
line-width line-width
current-value
max-line-width] :as state} (r/state component) max-line-width] :as state} (r/state component)
{:keys [wrapper-style input-style line-color focus-line-color secure-text-entry {:keys [wrapper-style input-style line-color focus-line-color secure-text-entry
label-color error-color error label value on-focus on-blur label-color error-color error label value on-focus on-blur
on-change-text on-change editable] :as props} (merge default-props (r/props component)) on-change-text on-change editable] :as props} (merge default-props (r/props component))
line-color (if error error-color line-color) line-color (if error error-color line-color)
focus-line-color (if error error-color focus-line-color) focus-line-color (if error error-color focus-line-color)
label-color (if (and error (not float-label?)) error-color label-color) label-color (if (and error (not float-label?)) error-color label-color)
label (if error (str label " *") label)] label (if error (str label " *") label)]
[view (merge st/text-field-container wrapper-style) [view (merge st/text-field-container wrapper-style)
[animated-text {:style (st/label label-top label-font-size label-color)} label] [animated-text {:style (st/label label-top label-font-size label-color)} label]
[text-input {:style (merge st/text-input input-style) [text-input {:style (merge st/text-input input-style)
@ -167,7 +167,7 @@
:to-line-width max-line-width} :to-line-width max-line-width}
:onFocus on-focus}) :onFocus on-focus})
:on-blur #(on-input-blur {:component component :on-blur #(on-input-blur {:component component
:value value :value (or current-value value)
:animation {:top label-top :animation {:top label-top
:to-top (:label-bottom config) :to-top (:label-bottom config)
:font-size label-font-size :font-size label-font-size
@ -175,7 +175,9 @@
:line-width line-width :line-width line-width
:to-line-width 0} :to-line-width 0}
:onBlur on-blur}) :onBlur on-blur})
:on-change-text #(on-change-text %) :on-change-text (fn [text]
(r/set-state component {:current-value text})
(on-change-text text))
:on-change #(on-change %) :on-change #(on-change %)
:default-value value}] :default-value value}]
[view {:style (st/underline-container line-color) [view {:style (st/underline-container line-color)

View File

@ -18,4 +18,7 @@
(def default-number-of-messages 20) (def default-number-of-messages 20)
(def default-number-of-discovery-search-results 20) (def default-number-of-discovery-search-results 20)
(def console-chat-id "console")
(def wallet-chat-id "wallet")

View File

@ -159,8 +159,8 @@
:left 0}) :left 0})
(def form-container (def form-container
{:marginLeft 16 {:margin-left 16
:margin-top 16}) :margin-top 16})
(def address-explication-container (def address-explication-container
{:flex 1 {:flex 1

View File

@ -1,7 +1,8 @@
(ns status-im.db (ns status-im.db
(:require [schema.core :as s :include-macros true] (:require [schema.core :as s :include-macros true]
[status-im.components.react :refer [animated]] [status-im.components.react :refer [animated]]
[status-im.components.animation :as anim])) [status-im.components.animation :as anim]
[status-im.constants :refer [console-chat-id]]))
;; schema of app-db ;; schema of app-db
(def schema {:greeting s/Str}) (def schema {:greeting s/Str})
@ -31,7 +32,7 @@
:chats {} :chats {}
:chat {:command nil :chat {:command nil
:last-message nil} :last-message nil}
:current-chat-id "console" :current-chat-id console-chat-id
:contacts-ids #{} :contacts-ids #{}
:selected-contacts #{} :selected-contacts #{}

View File

@ -22,7 +22,8 @@
status-im.accounts.handlers status-im.accounts.handlers
status-im.protocol.handlers status-im.protocol.handlers
status-im.transactions.handlers status-im.transactions.handlers
[status-im.utils.types :as t])) [status-im.utils.types :as t]
[status-im.constants :refer [console-chat-id]]))
;; -- Common -------------------------------------------------------------- ;; -- Common --------------------------------------------------------------
@ -49,7 +50,7 @@
(fn [db _] (fn [db _]
(assoc db (assoc db
:chats {} :chats {}
:current-chat-id "console"))) :current-chat-id console-chat-id)))
(register-handler :initialize-account (register-handler :initialize-account
(u/side-effect! (u/side-effect!
@ -69,7 +70,7 @@
(dispatch [:initialize-db]) (dispatch [:initialize-db])
(dispatch [:load-accounts]) (dispatch [:load-accounts])
(dispatch [:init-console-chat]) (dispatch [:init-console-chat])
(dispatch [:load-commands! "console"])))) (dispatch [:load-commands! console-chat-id]))))
(register-handler :initialize-crypt (register-handler :initialize-crypt
(u/side-effect! (u/side-effect!

View File

@ -18,7 +18,9 @@
:border-bottom-width 0.5} :border-bottom-width 0.5}
:chat {:new-message {:border-top-color styles/color-gray3 :chat {:new-message {:border-top-color styles/color-gray3
:border-top-width 0.5}} :border-top-width 0.5}}
:bottom-gradient {:height 1}}) :bottom-gradient {:height 1}
:input-label {:left 0}
:input-error-text {:margin-left 0}})
(def fonts (def fonts
{:default {:font-family "SFUIDisplay-Regular"} {:default {:font-family "SFUIDisplay-Regular"}

View File

@ -1,7 +1,8 @@
(ns status-im.profile.screen (ns status-im.profile.screen
(:require-macros [status-im.utils.views :refer [defview]]) (:require-macros [status-im.utils.views :refer [defview]])
(:require [reagent.core :as r] (:require [re-frame.core :refer [subscribe dispatch]]
[re-frame.core :refer [subscribe dispatch]] [clojure.string :as str]
[cljs.spec :as s]
[status-im.components.react :refer [view [status-im.components.react :refer [view
text text
text-input text-input
@ -12,51 +13,51 @@
touchable-opacity touchable-opacity
show-image-picker]] show-image-picker]]
[status-im.components.icons.custom-icons :refer [oct-icon]] [status-im.components.icons.custom-icons :refer [oct-icon]]
[status-im.components.chat-icon.screen :refer [profile-icon [status-im.components.chat-icon.screen :refer [my-profile-icon]]
my-profile-icon]]
[status-im.components.status-bar :refer [status-bar]] [status-im.components.status-bar :refer [status-bar]]
[status-im.profile.styles :as st] [status-im.components.text-field.view :refer [text-field]]
[status-im.utils.handlers :refer [get-hashtags]]
[status-im.profile.handlers :refer [message-user
update-profile]]
[status-im.components.qr-code :refer [qr-code]] [status-im.components.qr-code :refer [qr-code]]
[status-im.utils.phone-number :refer [format-phone-number [status-im.utils.handlers :refer [get-hashtags]]
valid-mobile-number?]] [status-im.utils.phone-number :refer [format-phone-number]]
[status-im.utils.fs :refer [read-file]]
[status-im.utils.types :refer [clj->json]]
[status-im.utils.image-processing :refer [img->base64]] [status-im.utils.image-processing :refer [img->base64]]
[status-im.utils.platform :refer [platform-specific]] [status-im.utils.platform :refer [platform-specific]]
[status-im.i18n :refer [label]] [status-im.profile.handlers :refer [message-user
[clojure.string :as str])) update-profile]]
[status-im.profile.validations :as v]
[status-im.profile.styles :as st]
[status-im.i18n :refer [label]]))
(defview toolbar [{:keys [account profile-edit-data edit?]}] (defn toolbar [{:keys [account profile-edit-data edit?]}]
[view (let [profile-edit-data-valid? (s/valid? ::v/profile profile-edit-data)]
[touchable-highlight {:style st/back-btn-touchable [view
:on-press (fn [] [touchable-highlight {:style st/back-btn-touchable
(dispatch [:set :profile-edit {:edit? false :on-press (fn []
:name nil (dispatch [:set :profile-edit {:edit? false
:email nil :name nil
:status nil :email nil
:photo-path nil}]) :status nil
(dispatch [:navigate-back]))} :photo-path nil}])
[view st/back-btn-container (dispatch [:navigate-back]))}
[icon :back st/back-btn-icon]]] [view st/back-btn-container
[touchable-highlight {:style st/actions-btn-touchable [icon :back st/back-btn-icon]]]
:on-press (fn [] [touchable-highlight {:style st/actions-btn-touchable
(when edit? :on-press (fn []
(update-profile account profile-edit-data)) (if edit?
(dispatch [:set-in [:profile-edit :edit?] (not edit?)]))} (when profile-edit-data-valid?
[view st/actions-btn-container (update-profile account profile-edit-data)
(if edit? (dispatch [:set-in [:profile-edit :edit?] false]))
[oct-icon {:name :check (dispatch [:set-in [:profile-edit :edit?] true])))}
:style st/ok-btn-icon}] [view st/actions-btn-container
[icon :dots st/edit-btn-icon])]]]) (if edit?
[oct-icon {:name :check
:style (st/ok-btn-icon profile-edit-data-valid?)}]
[icon :dots st/edit-btn-icon])]]]))
(defview status-image-view [{{address :address (defn status-image-view [{{address :address
username :name} :account username :name} :account
photo-path :photo-path photo-path :photo-path
status :status status :status
edit? :edit?}] edit? :edit?}]
[view st/status-block [view st/status-block
[view st/user-photo-container [view st/user-photo-container
(if edit? (if edit?
@ -78,24 +79,8 @@
[text-input {:style st/status-input [text-input {:style st/status-input
:editable edit? :editable edit?
:placeholder (label :t/profile-no-status) :placeholder (label :t/profile-no-status)
:on-change-text #(dispatch [:set-in [:profile-edit :status] %])} :on-change-text #(dispatch [:set-in [:profile-edit :status] %])
status]]) :value status}]])
(defview profile-property-view [{name :name
value :value
empty-value :empty-value
on-change-text :on-change-text
{edit-mode? :edit?} :profile-data}]
[view st/profile-property-view-container
[view st/profile-property-view-sub-container
[text {:style st/profile-property-view-label
:font :medium}
name]
[text-input {:style st/profile-property-view-value
:editable (and on-change-text edit-mode?)
:on-change-text on-change-text}
(or value (when-not edit-mode? empty-value))]]])
(defview profile [] (defview profile []
[{whisper-identity :whisper-identity [{whisper-identity :whisper-identity
@ -136,18 +121,35 @@
[icon :more_vertical_blue st/more-btn-image]]]]] [icon :more_vertical_blue st/more-btn-image]]]]]
[scroll-view st/profile-properties-container [scroll-view st/profile-properties-container
[profile-property-view {:name (label :t/username) [text-field
:value (if (not= username address) {:editable false
username) :input-style st/profile-input-text
:empty-value (label :t/not-specified)}] :wrapper-style st/profile-input-wrapper
[profile-property-view {:name (label :t/phone-number) :value (if (and (not= username address)
:value (if-not (or (not phone) (str/blank? phone)) username
(format-phone-number phone)) (not (str/blank? username)))
:empty-value (label :t/not-specified)}] username
[profile-property-view {:name (label :t/email) (label :t/not-specified))
:value (if-not (or (not email) (str/blank? email)) :label (label :t/username)}]
email)
:empty-value (label :t/not-specified)}] [text-field
{:editable false
:input-style st/profile-input-text
:wrapper-style st/profile-input-wrapper
:value (if (and phone (not (str/blank? phone)))
(format-phone-number phone)
(label :t/not-specified))
:label (label :t/phone-number)}]
[text-field
{:editable false
:input-style st/profile-input-text
:wrapper-style st/profile-input-wrapper
:value (if (and email (not (str/blank? email)))
email
(label :t/not-specified))
:label (label :t/email)}]
[view st/report-user-container [view st/report-user-container
[touchable-highlight {:on-press (fn [] [touchable-highlight {:on-press (fn []
;; TODO not implemented ;; TODO not implemented
@ -164,6 +166,8 @@
status :status status :status
:as account} [:get-current-account] :as account} [:get-current-account]
{edit? :edit? {edit? :edit?
new-name :name
new-email :email
new-status :status new-status :status
new-photo-path :photo-path new-photo-path :photo-path
:as profile-edit-data} [:get :profile-edit]] :as profile-edit-data} [:get :profile-edit]]
@ -179,23 +183,42 @@
:edit? edit?}] :edit? edit?}]
[scroll-view st/profile-properties-container [scroll-view st/profile-properties-container
[profile-property-view {:name (label :t/username) [text-field
:value (if (not= username address) {:error (if-not (s/valid? ::v/name new-name)
username) (label :t/error-incorrect-name))
:empty-value (label :t/not-specified) :error-color "#7099e6"
:on-change-text #(dispatch [:set-in [:profile-edit :name] %]) :editable edit?
:profile-data profile-edit-data}] :input-style (if edit?
[profile-property-view {:name (label :t/phone-number) st/profile-input-text
:value (if-not (or (not phone) (str/blank? phone)) st/profile-input-text-non-editable)
(format-phone-number phone)) :wrapper-style st/profile-input-wrapper
:empty-value (label :t/not-specified) :value (if (not= username address)
:profile-data profile-edit-data}] username)
[profile-property-view {:name (label :t/email) :label (label :t/username)
:value (if-not (or (not email) (str/blank? email)) :on-change-text #(dispatch [:set-in [:profile-edit :name] %])}]
email)
:empty-value (label :t/not-specified) [text-field
:on-change-text #(dispatch [:set-in [:profile-edit :email] %]) {:editable false
:profile-data profile-edit-data}] :input-style st/profile-input-text-non-editable
:wrapper-style st/profile-input-wrapper
:value (if (and phone (not (str/blank? phone)))
(format-phone-number phone))
:label (label :t/phone-number)}]
[text-field
{:error (if-not (s/valid? ::v/email new-email)
(label :t/error-incorrect-email))
:error-color "#7099e6"
:editable edit?
:input-style (if edit?
st/profile-input-text
st/profile-input-text-non-editable)
:wrapper-style st/profile-input-wrapper
:value (if (and email (not (str/blank? email)))
email)
:label (label :t/email)
:on-change-text #(dispatch [:set-in [:profile-edit :email] %])}]
[view st/qr-code-container [view st/qr-code-container
;; TODO: this public key should be replaced by address ;; TODO: this public key should be replaced by address
[qr-code {:value (str "ethereum:" public-key) [qr-code {:value (str "ethereum:" public-key)

View File

@ -1,6 +1,7 @@
(ns status-im.profile.styles (ns status-im.profile.styles
(:require [status-im.components.styles :refer [color-light-blue-transparent (:require [status-im.components.styles :refer [color-light-blue-transparent
color-white color-white
color-gray
color-black color-black
color-blue color-blue
color-blue-transparent color-blue-transparent
@ -8,6 +9,7 @@
online-color online-color
separator-color separator-color
text1-color text1-color
text1-disabled-color
text2-color]])) text2-color]]))
(def profile (def profile
@ -42,9 +44,9 @@
{:width 4 {:width 4
:height 16}) :height 16})
(def ok-btn-icon (defn ok-btn-icon [enabled?]
{:font-size 22 {:font-size 22
:color :black}) :color (if enabled? color-black color-gray)})
(def user-photo-container (def user-photo-container
{:margin-top 22}) {:margin-top 22})
@ -113,32 +115,21 @@
(def profile-properties-container (def profile-properties-container
{:margin-top 20 {:margin-top 20
:margin-left 16
:align-items :stretch :align-items :stretch
:flex-firection :column}) :flex-firection :column})
(def profile-property-view-container (def profile-input-wrapper
{:padding-left 16}) {:margin-bottom 16})
(def profile-property-view-sub-container (def profile-input-text
{:border-bottom-width 1 {:color text1-color})
:border-bottom-color separator-color
:padding-right 16})
(def profile-property-view-label (def profile-input-text-non-editable
{:margin-top 18 {:color text1-disabled-color})
:font-size 14
:color text2-color})
(def profile-property-view-value
{:margin-top 8
:margin-bottom 8
:padding 0
:height 40
:font-size 16
:color text1-color})
(def report-user-container (def report-user-container
{:margin-top 50 {:margin-top 32
:margin-bottom 43 :margin-bottom 43
:align-items :center}) :align-items :center})

View File

@ -0,0 +1,22 @@
(ns status-im.profile.validations
(:require [cljs.spec :as s]
[status-im.utils.phone-number :refer [valid-mobile-number?]]
[status-im.constants :refer [console-chat-id wallet-chat-id]]
[clojure.string :as str]))
(def homoglyph-finder (js/require "homoglyph-finder"))
(defn correct-name? [username]
(let [username (some-> username (str/trim))]
(and (not (.isMatches homoglyph-finder username console-chat-id))
(not (.isMatches homoglyph-finder username wallet-chat-id)))))
(defn correct-email? [email]
(let [pattern #"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?"]
(or (str/blank? email)
(and (string? email) (re-matches pattern email)))))
(s/def ::name correct-name?)
(s/def ::email correct-email?)
(s/def ::profile (s/keys :req-un [::name ::email]))

View File

@ -56,6 +56,8 @@
:email "Email" :email "Email"
:profile-no-status "No status" :profile-no-status "No status"
:add-to-contacts "Add to contacts" :add-to-contacts "Add to contacts"
:error-incorrect-name "Please, select another name"
:error-incorrect-email "Incorrect e-mail"
;;make_photo ;;make_photo
:image-source-title "Profile image" :image-source-title "Profile image"