Merge pull request #320 from status-im/feature/#294
Status & Name, quick profile change in drawer (#294), length limit (#324)
Former-commit-id: 2cbad4dc76
This commit is contained in:
commit
6530f9c4e4
|
@ -9,7 +9,8 @@
|
||||||
separator-color
|
separator-color
|
||||||
text1-color
|
text1-color
|
||||||
text2-color
|
text2-color
|
||||||
text3-color]]))
|
text3-color
|
||||||
|
color-red]]))
|
||||||
|
|
||||||
(def drawer-menu
|
(def drawer-menu
|
||||||
{:flex 1
|
{:flex 1
|
||||||
|
@ -27,14 +28,38 @@
|
||||||
:height 64})
|
:height 64})
|
||||||
|
|
||||||
(def name-container
|
(def name-container
|
||||||
{:margin-top 20
|
{:margin-top -16
|
||||||
|
:margin-bottom -16
|
||||||
:margin-left 16
|
:margin-left 16
|
||||||
|
:margin-right 16})
|
||||||
|
|
||||||
|
(def name-input-wrapper
|
||||||
|
{})
|
||||||
|
|
||||||
|
(defn name-input-text [valid?]
|
||||||
|
{:color (if valid? text1-color
|
||||||
|
color-red)
|
||||||
|
:text-align :center})
|
||||||
|
|
||||||
|
(def status-container
|
||||||
|
{:margin-left 16
|
||||||
:margin-right 16
|
:margin-right 16
|
||||||
|
:margin-top 4
|
||||||
:align-items :center})
|
:align-items :center})
|
||||||
|
|
||||||
|
(def status-input
|
||||||
|
{:align-self "stretch"
|
||||||
|
:height 56
|
||||||
|
:font-size 14
|
||||||
|
:padding-left 4
|
||||||
|
:line-height 20
|
||||||
|
:text-align :center
|
||||||
|
:text-align-vertical :top
|
||||||
|
:color text2-color})
|
||||||
|
|
||||||
(def menu-items-container
|
(def menu-items-container
|
||||||
{:flex 1
|
{:flex 1
|
||||||
:margin-top 50
|
:margin-top 20
|
||||||
:align-items :stretch
|
:align-items :stretch
|
||||||
:flex-direction :column})
|
:flex-direction :column})
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,23 @@
|
||||||
(ns status-im.components.drawer.view
|
(ns status-im.components.drawer.view
|
||||||
(:require-macros [status-im.utils.views :refer [defview]])
|
(:require-macros [status-im.utils.views :refer [defview]])
|
||||||
(:require [clojure.string :as s]
|
(:require [reagent.core :as r]
|
||||||
[re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
[re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
||||||
[reagent.core :as r]
|
[clojure.string :as str]
|
||||||
[status-im.components.react :refer [react-native
|
[cljs.spec :as s]
|
||||||
view
|
[status-im.components.react :refer [view
|
||||||
text
|
text
|
||||||
|
text-input
|
||||||
image
|
image
|
||||||
drawer-layout
|
drawer-layout
|
||||||
|
touchable-without-feedback
|
||||||
touchable-opacity]]
|
touchable-opacity]]
|
||||||
[status-im.resources :as res]
|
[status-im.components.text-field.view :refer [text-field]]
|
||||||
[status-im.components.drawer.styles :as st]
|
[status-im.components.drawer.styles :as st]
|
||||||
[status-im.i18n :refer [label]]))
|
[status-im.profile.validations :as v]
|
||||||
|
[status-im.profile.handlers :refer [update-profile]]
|
||||||
|
[status-im.resources :as res]
|
||||||
|
[status-im.i18n :refer [label]]
|
||||||
|
[status-im.components.react :refer [dismiss-keyboard!]]))
|
||||||
|
|
||||||
(defonce drawer-atom (atom))
|
(defonce drawer-atom (atom))
|
||||||
|
|
||||||
|
@ -22,7 +28,7 @@
|
||||||
(.closeDrawer @drawer-atom))
|
(.closeDrawer @drawer-atom))
|
||||||
|
|
||||||
(defn user-photo [{:keys [photo-path]}]
|
(defn user-photo [{:keys [photo-path]}]
|
||||||
[image {:source (if (s/blank? photo-path)
|
[image {:source (if (str/blank? photo-path)
|
||||||
res/user-no-photo
|
res/user-no-photo
|
||||||
{:uri photo-path})
|
{:uri photo-path})
|
||||||
:style st/user-photo}])
|
:style st/user-photo}])
|
||||||
|
@ -37,47 +43,70 @@
|
||||||
name]])
|
name]])
|
||||||
|
|
||||||
(defview drawer-menu []
|
(defview drawer-menu []
|
||||||
[{:keys [name address photo-path]} [:get-current-account]]
|
[{:keys [name address photo-path status] :as account} [:get-current-account]
|
||||||
|
{new-name :name :as profile-edit-data} [:get :profile-edit]
|
||||||
|
keyboard-height [:get :keyboard-height]]
|
||||||
[view st/drawer-menu
|
[view st/drawer-menu
|
||||||
[view st/user-photo-container
|
[touchable-without-feedback {:on-press #(dismiss-keyboard!)}
|
||||||
[user-photo {:photo-path photo-path}]]
|
[view st/drawer-menu
|
||||||
[view st/name-container
|
[touchable-opacity {:on-press #(dispatch [:navigate-to :my-profile])}
|
||||||
[text {:style st/name-text
|
[view st/user-photo-container
|
||||||
:number-of-lines 1
|
[user-photo {:photo-path photo-path}]]]
|
||||||
:font :default}
|
[view st/name-container
|
||||||
(if (= name address)
|
[text-field
|
||||||
(label :t/user-anonymous)
|
{:line-color :white
|
||||||
name)]]
|
:focus-line-color :white
|
||||||
[view st/menu-items-container
|
:placeholder (label :t/user-anonymous)
|
||||||
[menu-item {:name (label :t/profile)
|
:editable true
|
||||||
:handler #(dispatch [:navigate-to :my-profile])}]
|
:input-style (st/name-input-text (s/valid? ::v/name (or new-name name)))
|
||||||
[menu-item {:name (label :t/settings)
|
:wrapper-style st/name-input-wrapper
|
||||||
:handler (fn []
|
:value (if (not= name address)
|
||||||
;; TODO not implemented
|
name)
|
||||||
)}]
|
:on-change-text #(dispatch [:set-in [:profile-edit :name] %])
|
||||||
[menu-item {:name (label :t/discovery)
|
:on-end-editing #(update-profile account profile-edit-data)}]]
|
||||||
:handler #(dispatch [:navigate-to :discovery])}]
|
[view st/status-container
|
||||||
[menu-item {:name (label :t/contacts)
|
[text-input {:style st/status-input
|
||||||
:handler #(dispatch [:navigate-to :contact-list])}]
|
:editable true
|
||||||
[menu-item {:name (label :t/invite-friends)
|
:multiline true
|
||||||
:handler (fn []
|
:blur-on-submit true
|
||||||
;; TODO not implemented
|
:maxLength 140
|
||||||
)}]
|
:accessibility-label :input
|
||||||
[menu-item {:name (label :t/faq)
|
:placeholder (label :t/profile-no-status)
|
||||||
:handler (fn [])}]]
|
:on-change-text #(dispatch [:set-in [:profile-edit :status] %])
|
||||||
[view st/switch-users-container
|
:on-blur #(update-profile account profile-edit-data)
|
||||||
[touchable-opacity {:onPress (fn []
|
:default-value status}]]
|
||||||
(close-drawer)
|
[view st/menu-items-container
|
||||||
(dispatch [:navigate-to :accounts])
|
[menu-item {:name (label :t/profile)
|
||||||
;; TODO not implemented
|
:handler #(dispatch [:navigate-to :my-profile])}]
|
||||||
)}
|
[menu-item {:name (label :t/settings)
|
||||||
[text {:style st/switch-users-text
|
:handler (fn []
|
||||||
:font :default}
|
;; TODO not implemented
|
||||||
(label :t/switch-users)]]]])
|
)}]
|
||||||
|
[menu-item {:name (label :t/discovery)
|
||||||
|
:handler #(dispatch [:navigate-to :discovery])}]
|
||||||
|
[menu-item {:name (label :t/contacts)
|
||||||
|
:handler #(dispatch [:navigate-to :contact-list])}]
|
||||||
|
[menu-item {:name (label :t/invite-friends)
|
||||||
|
:handler (fn []
|
||||||
|
;; TODO not implemented
|
||||||
|
)}]
|
||||||
|
[menu-item {:name (label :t/faq)
|
||||||
|
:handler (fn [])}]]
|
||||||
|
(when (= keyboard-height 0)
|
||||||
|
[view st/switch-users-container
|
||||||
|
[touchable-opacity {:onPress (fn []
|
||||||
|
(close-drawer)
|
||||||
|
(dispatch [:navigate-to :accounts])
|
||||||
|
;; TODO not implemented
|
||||||
|
)}
|
||||||
|
[text {:style st/switch-users-text
|
||||||
|
:font :default}
|
||||||
|
(label :t/switch-users)]]])]]])
|
||||||
|
|
||||||
(defn drawer-view [items]
|
(defn drawer-view [items]
|
||||||
[drawer-layout {:drawerWidth 260
|
[drawer-layout {:drawerWidth 260
|
||||||
:render-navigation-view #(r/as-element [drawer-menu])
|
:renderNavigationView #(r/as-element [drawer-menu])
|
||||||
:ref (fn [drawer]
|
:onDrawerSlide dismiss-keyboard!
|
||||||
(reset! drawer-atom drawer))}
|
:ref (fn [drawer]
|
||||||
|
(reset! drawer-atom drawer))}
|
||||||
items])
|
items])
|
||||||
|
|
|
@ -8,11 +8,10 @@
|
||||||
(def color-gray "#838c93de")
|
(def color-gray "#838c93de")
|
||||||
(def color-gray2 "#8f838c93")
|
(def color-gray2 "#8f838c93")
|
||||||
(def color-gray3 "#00000040")
|
(def color-gray3 "#00000040")
|
||||||
(def color-white :white)
|
(def color-white "white")
|
||||||
(def color-light-blue "#bbc4cb")
|
|
||||||
(def color-light-blue-transparent "#bbc4cb32")
|
(def color-light-blue-transparent "#bbc4cb32")
|
||||||
(def color-dark-mint "#5fc48d")
|
|
||||||
(def color-light-gray "#EEF2F5")
|
(def color-light-gray "#EEF2F5")
|
||||||
|
(def color-red "red")
|
||||||
|
|
||||||
(def text1-color color-black)
|
(def text1-color color-black)
|
||||||
(def text1-disabled-color "#555555")
|
(def text1-disabled-color "#555555")
|
||||||
|
|
|
@ -144,10 +144,10 @@
|
||||||
label-font-size
|
label-font-size
|
||||||
line-width
|
line-width
|
||||||
current-value
|
current-value
|
||||||
max-line-width] :as state} (r/state component)
|
max-line-width]} (r/state component)
|
||||||
{:keys [wrapper-style input-style label-hidden? line-color focus-line-color secure-text-entry
|
{:keys [wrapper-style input-style label-hidden? 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 on-end-editing editable placeholder]} (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)
|
||||||
|
@ -157,7 +157,7 @@
|
||||||
(when-not label-hidden?
|
(when-not label-hidden?
|
||||||
[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)
|
||||||
:placeholder ""
|
:placeholder (or placeholder "")
|
||||||
:editable editable
|
:editable editable
|
||||||
:secure-text-entry secure-text-entry
|
:secure-text-entry secure-text-entry
|
||||||
:on-focus #(on-input-focus {:component component
|
:on-focus #(on-input-focus {:component component
|
||||||
|
@ -181,7 +181,9 @@
|
||||||
(r/set-state component {:current-value text})
|
(r/set-state component {:current-value text})
|
||||||
(on-change-text text))
|
(on-change-text text))
|
||||||
:on-change #(on-change %)
|
:on-change #(on-change %)
|
||||||
:default-value value}]
|
:default-value value
|
||||||
|
:on-end-editing (when on-end-editing
|
||||||
|
on-end-editing)}]
|
||||||
[view {:style (st/underline-container line-color)
|
[view {:style (st/underline-container line-color)
|
||||||
:onLayout #(r/set-state component {:max-line-width (get-width %)})}
|
:onLayout #(r/set-state component {:max-line-width (get-width %)})}
|
||||||
[animated-view {:style (st/underline focus-line-color line-width)}]]
|
[animated-view {:style (st/underline focus-line-color line-width)}]]
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
[status-im.i18n :refer [label]]
|
[status-im.i18n :refer [label]]
|
||||||
[status-im.utils.handlers :as u :refer [get-hashtags]]
|
[status-im.utils.handlers :as u :refer [get-hashtags]]
|
||||||
[status-im.utils.platform :refer [ios?]]
|
[status-im.utils.platform :refer [ios?]]
|
||||||
[clojure.string :as str]))
|
[clojure.string :as str]
|
||||||
|
[status-im.profile.validations :as v]
|
||||||
|
[cljs.spec :as s]))
|
||||||
|
|
||||||
(defn message-user [identity]
|
(defn message-user [identity]
|
||||||
(when identity
|
(when identity
|
||||||
|
@ -20,7 +22,11 @@
|
||||||
new-email :email
|
new-email :email
|
||||||
new-status :status
|
new-status :status
|
||||||
new-photo-path :photo-path}]
|
new-photo-path :photo-path}]
|
||||||
(let [new-name (if (or (not new-name) (str/blank? new-name)) name new-name)
|
(let [new-name (if (or (not new-name)
|
||||||
|
(str/blank? new-name)
|
||||||
|
(not (s/valid? ::v/name new-name)))
|
||||||
|
name
|
||||||
|
new-name)
|
||||||
status-updated? (and (not= new-status nil)
|
status-updated? (and (not= new-status nil)
|
||||||
(not= status new-status))]
|
(not= status new-status))]
|
||||||
(when status-updated?
|
(when status-updated?
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
(:require [re-frame.core :refer [subscribe dispatch]]
|
(:require [re-frame.core :refer [subscribe dispatch]]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[cljs.spec :as s]
|
[cljs.spec :as s]
|
||||||
|
[reagent.core :as r]
|
||||||
[status-im.components.react :refer [view
|
[status-im.components.react :refer [view
|
||||||
text
|
text
|
||||||
text-input
|
text-input
|
||||||
|
@ -32,11 +33,7 @@
|
||||||
[view
|
[view
|
||||||
[touchable-highlight {:style st/back-btn-touchable
|
[touchable-highlight {:style st/back-btn-touchable
|
||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
(dispatch [:set :profile-edit {:edit? false
|
(dispatch [:set-in [:profile-edit :edit?] false])
|
||||||
:name nil
|
|
||||||
:email nil
|
|
||||||
:status nil
|
|
||||||
:photo-path nil}])
|
|
||||||
(dispatch [:navigate-back]))}
|
(dispatch [:navigate-back]))}
|
||||||
[view st/back-btn-container
|
[view st/back-btn-container
|
||||||
[icon :back st/back-btn-icon]]]
|
[icon :back st/back-btn-icon]]]
|
||||||
|
@ -77,10 +74,11 @@
|
||||||
(label :t/user-anonymous)
|
(label :t/user-anonymous)
|
||||||
username)]
|
username)]
|
||||||
[text-input {:style st/status-input
|
[text-input {:style st/status-input
|
||||||
|
:maxLength 140
|
||||||
: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] %])
|
||||||
:value status}]])
|
:default-value status}]])
|
||||||
|
|
||||||
(defview profile []
|
(defview profile []
|
||||||
[{whisper-identity :whisper-identity
|
[{whisper-identity :whisper-identity
|
||||||
|
@ -156,70 +154,82 @@
|
||||||
)}
|
)}
|
||||||
[view [text {:style st/report-user-text} (label :t/report-user)]]]]]])
|
[view [text {:style st/report-user-text} (label :t/report-user)]]]]]])
|
||||||
|
|
||||||
(defview my-profile []
|
(defview my-profile-render []
|
||||||
[{public-key :public-key
|
[{public-key :public-key
|
||||||
address :address
|
address :address
|
||||||
username :name
|
username :name
|
||||||
email :email
|
email :email
|
||||||
photo-path :photo-path
|
photo-path :photo-path
|
||||||
phone :phone
|
phone :phone
|
||||||
status :status
|
status :status
|
||||||
:as account} [:get-current-account]
|
:as account} [:get-current-account]
|
||||||
{edit? :edit?
|
{edit? :edit?
|
||||||
new-name :name
|
new-name :name
|
||||||
new-email :email
|
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]]
|
||||||
[scroll-view {:style st/profile}
|
[scroll-view {:style st/profile}
|
||||||
[status-bar]
|
[status-bar]
|
||||||
[toolbar {:account account
|
[toolbar {:account account
|
||||||
:profile-edit-data profile-edit-data
|
:profile-edit-data profile-edit-data
|
||||||
:edit? edit?}]
|
:edit? edit?}]
|
||||||
|
|
||||||
[status-image-view {:account account
|
[status-image-view {:account account
|
||||||
:photo-path (or new-photo-path photo-path)
|
:photo-path (or new-photo-path photo-path)
|
||||||
:status (or new-status status)
|
:status (or new-status status)
|
||||||
:edit? edit?}]
|
:edit? edit?}]
|
||||||
|
|
||||||
[scroll-view st/profile-properties-container
|
[scroll-view st/profile-properties-container
|
||||||
[text-field
|
[text-field
|
||||||
{:error (if-not (s/valid? ::v/name new-name)
|
{:error (if-not (s/valid? ::v/name new-name)
|
||||||
(label :t/error-incorrect-name))
|
(label :t/error-incorrect-name))
|
||||||
:error-color "#7099e6"
|
:error-color "#7099e6"
|
||||||
:editable edit?
|
:editable edit?
|
||||||
:input-style (if edit?
|
:input-style (if edit?
|
||||||
st/profile-input-text
|
st/profile-input-text
|
||||||
st/profile-input-text-non-editable)
|
st/profile-input-text-non-editable)
|
||||||
:wrapper-style st/profile-input-wrapper
|
:wrapper-style st/profile-input-wrapper
|
||||||
:value (if (not= username address)
|
:value (if (not= username address)
|
||||||
username)
|
username)
|
||||||
:label (label :t/username)
|
:label (label :t/username)
|
||||||
:on-change-text #(dispatch [:set-in [:profile-edit :name] %])}]
|
:on-change-text #(dispatch [:set-in [:profile-edit :name] %])}]
|
||||||
|
|
||||||
[text-field
|
[text-field
|
||||||
{:editable false
|
{:editable false
|
||||||
:input-style st/profile-input-text-non-editable
|
:input-style st/profile-input-text-non-editable
|
||||||
:wrapper-style st/profile-input-wrapper
|
:wrapper-style st/profile-input-wrapper
|
||||||
:value (if (and phone (not (str/blank? phone)))
|
:value (if (and phone (not (str/blank? phone)))
|
||||||
(format-phone-number phone))
|
(format-phone-number phone))
|
||||||
:label (label :t/phone-number)}]
|
:label (label :t/phone-number)}]
|
||||||
|
|
||||||
[text-field
|
[text-field
|
||||||
{:error (if-not (s/valid? ::v/email new-email)
|
{:error (if-not (s/valid? ::v/email new-email)
|
||||||
(label :t/error-incorrect-email))
|
(label :t/error-incorrect-email))
|
||||||
:error-color "#7099e6"
|
:error-color "#7099e6"
|
||||||
:editable edit?
|
:editable edit?
|
||||||
:input-style (if edit?
|
:input-style (if edit?
|
||||||
st/profile-input-text
|
st/profile-input-text
|
||||||
st/profile-input-text-non-editable)
|
st/profile-input-text-non-editable)
|
||||||
:wrapper-style st/profile-input-wrapper
|
:wrapper-style st/profile-input-wrapper
|
||||||
:value (if (and email (not (str/blank? email)))
|
:value (if (and email (not (str/blank? email)))
|
||||||
email)
|
email)
|
||||||
:label (label :t/email)
|
:label (label :t/email)
|
||||||
:on-change-text #(dispatch [:set-in [:profile-edit :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)
|
||||||
:size 220}]]]])
|
:size 220}]]]])
|
||||||
|
|
||||||
|
(defview my-profile []
|
||||||
|
[{username :name
|
||||||
|
email :email} [:get-current-account]]
|
||||||
|
(r/create-class
|
||||||
|
{:component-will-mount
|
||||||
|
(fn []
|
||||||
|
(dispatch [:set :profile-edit {:edit? false
|
||||||
|
:name username
|
||||||
|
:email email}]))
|
||||||
|
:reagent-render
|
||||||
|
my-profile-render}))
|
||||||
|
|
Loading…
Reference in New Issue