chore: onboarding profile adjustments (#16291)
* remove b&w color as an option * change system message for minimum display name length to match designs * update display name validation to match desktop
This commit is contained in:
parent
7260c23e8e
commit
9ec4f91c9e
|
@ -3,11 +3,13 @@
|
|||
[reagent.core :as reagent]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(def color-list [:blue :yellow :turquoise :copper :sky :camel :orange :army :pink :purple :magenta])
|
||||
|
||||
(h/describe "color-picker"
|
||||
(h/test "color picker rendered"
|
||||
(h/render [color-picker/view])
|
||||
(-> (h/expect (h/get-all-by-label-text :color-picker-item))
|
||||
(.toHaveLength 12)))
|
||||
(.toHaveLength 11)))
|
||||
(h/test "clicks on a color item"
|
||||
(let [event (h/mock-fn)]
|
||||
(h/render [color-picker/view {:on-change #(event)}])
|
||||
|
@ -19,5 +21,11 @@
|
|||
(h/render [color-picker/view {:on-change #(reset! selected %)}])
|
||||
(h/fire-event :press (get (h/get-all-by-label-text :color-picker-item) 0))
|
||||
(-> (h/expect @selected)
|
||||
(.toStrictEqual :blue)))))
|
||||
(.toStrictEqual :blue))))
|
||||
(h/test "all of the values of colors-list are rendered"
|
||||
(h/render [color-picker/view])
|
||||
(js/Promise.all (map (fn [color]
|
||||
(h/is-truthy (h/get-all-by-label-text color)))
|
||||
color-list))))
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(def color-picker-container
|
||||
{:max-width 338
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:flex-wrap :wrap
|
||||
:justify-content :space-between})
|
||||
|
@ -11,14 +11,17 @@
|
|||
{:flex-basis "100%"
|
||||
:height 10})
|
||||
|
||||
(def color-button-common
|
||||
{:width 48
|
||||
:height 48
|
||||
:border-width 4
|
||||
:border-radius 24
|
||||
:transform [{:rotate "45deg"}]
|
||||
:border-color :transparent})
|
||||
|
||||
(defn color-button
|
||||
[color selected?]
|
||||
(merge {:width 48
|
||||
:height 48
|
||||
:border-width 4
|
||||
:border-radius 24
|
||||
:transform [{:rotate "45deg"}]
|
||||
:border-color :transparent}
|
||||
(merge color-button-common
|
||||
(when selected?
|
||||
{:border-top-color (colors/alpha color 0.4)
|
||||
:border-end-color (colors/alpha color 0.4)
|
||||
|
|
|
@ -5,25 +5,27 @@
|
|||
[reagent.core :as reagent]
|
||||
[quo2.components.colors.color-picker.style :as style]))
|
||||
|
||||
(def color-list [:blue :yellow :turquoise :copper :sky :camel :orange :army :pink :purple :magenta])
|
||||
;; TODO: using :no-color this to keep alignment of colors correct while b & w is being developed.
|
||||
;; https://github.com/status-im/status-mobile/issues/15442
|
||||
(def color-list
|
||||
[:blue :yellow :turquoise :copper :sky :camel :orange :army :pink :purple :magenta :no-color])
|
||||
|
||||
(defn picker-colors
|
||||
[blur?]
|
||||
(concat (map (fn [color]
|
||||
{:name color
|
||||
:color (colors/custom-color-by-theme color (if blur? 60 50) 60)})
|
||||
color-list)
|
||||
[{:name :yinyang
|
||||
:color (colors/theme-colors (colors/custom-color :yin 50)
|
||||
(colors/custom-color :yang 50))
|
||||
:secondary-color (colors/theme-colors (colors/custom-color :yang 50)
|
||||
(colors/custom-color :yin 50))}]))
|
||||
(map (fn [color]
|
||||
{:name color
|
||||
:color (colors/custom-color-by-theme color (if blur? 60 50) 60)})
|
||||
color-list))
|
||||
|
||||
(defn- on-change-handler
|
||||
[selected color-name on-change]
|
||||
(reset! selected color-name)
|
||||
(when on-change (on-change color-name)))
|
||||
|
||||
(defn empty-color-item
|
||||
[]
|
||||
[rn/view {:style style/color-button-common}])
|
||||
|
||||
(defn- color-item
|
||||
[{:keys [name
|
||||
color
|
||||
|
@ -32,20 +34,24 @@
|
|||
on-press
|
||||
blur?]}]
|
||||
(let [border? (and (not blur?) (and secondary-color (not selected?)))]
|
||||
[rn/touchable-opacity
|
||||
{:style (style/color-button color selected?)
|
||||
:accessibility-label :color-picker-item
|
||||
:on-press #(on-press name)}
|
||||
[rn/view
|
||||
{:style (style/color-circle color border?)}
|
||||
(when (and secondary-color (not selected?))
|
||||
[rn/view
|
||||
{:style (style/secondary-overlay secondary-color border?)}])
|
||||
(when selected?
|
||||
[icon/icon :i/check
|
||||
{:size 20
|
||||
:color (or secondary-color
|
||||
colors/white)}])]]))
|
||||
(if (= :no-color name)
|
||||
[empty-color-item]
|
||||
[rn/touchable-opacity
|
||||
{:style (style/color-button color selected?)
|
||||
:accessibility-label :color-picker-item
|
||||
:on-press #(on-press name)}
|
||||
[rn/view
|
||||
{:accessibile true
|
||||
:accessibility-label name
|
||||
:style (style/color-circle color border?)}
|
||||
(when (and secondary-color (not selected?))
|
||||
[rn/view
|
||||
{:style (style/secondary-overlay secondary-color border?)}])
|
||||
(when selected?
|
||||
[icon/icon :i/check
|
||||
{:size 20
|
||||
:color (or secondary-color
|
||||
colors/white)}])]])))
|
||||
|
||||
(defn view
|
||||
"Options
|
||||
|
|
|
@ -182,51 +182,48 @@
|
|||
(def danger-50-opa-30 (alpha danger-50 0.3))
|
||||
(def danger-50-opa-40 (alpha danger-50 0.4))
|
||||
|
||||
;;;; Customization
|
||||
|
||||
;; Colors for customizing profiles and communities themes
|
||||
;; Colors for customizing users account
|
||||
(def customization
|
||||
{:primary {50 primary-50 ;; User can also use primary color as customisation color
|
||||
60 primary-60}
|
||||
:purple {50 "#7140FD"
|
||||
60 "#5A33CA"}
|
||||
:indigo {50 "#496289"
|
||||
60 "#3D5273"}
|
||||
:turquoise {50 "#2A799B"
|
||||
60 "#22617C"}
|
||||
:blue {50 "#2A4AF5"
|
||||
{:blue {50 "#2A4AF5"
|
||||
60 "#223BC4"}
|
||||
:green {50 "#5BCC95"
|
||||
60 "#4CAB7D"}
|
||||
:yellow {50 "#F6B03C"
|
||||
60 "#C58D30"}
|
||||
:orange {50 "#FF7D46"
|
||||
60 "#CC6438"}
|
||||
:red {50 "#F46666"
|
||||
60 "#CD5656"}
|
||||
:pink {50 "#F66F8F"
|
||||
60 "#C55972"}
|
||||
:brown {50 "#99604D"
|
||||
60 "#805141"}
|
||||
:sky {50 "#1992D7"
|
||||
60 "#1475AC"}
|
||||
:army {50 "#216266"
|
||||
60 "#1A4E52"}
|
||||
:magenta {50 "#EC266C"
|
||||
60 "#BD1E56"}
|
||||
:turquoise {50 "#2A799B"
|
||||
60 "#22617C"}
|
||||
:copper {50 "#CB6256"
|
||||
60 "#A24E45"}
|
||||
:sky {50 "#1992D7"
|
||||
60 "#1475AC"}
|
||||
:camel {50 "#C78F67"
|
||||
60 "#9F7252"}
|
||||
:yin {50 "#09101C"
|
||||
60 "#1D232E"}
|
||||
:yang {50 "#FFFFFF"
|
||||
60 "#EBEBEB"}
|
||||
:beige {50 "#CAAE93"
|
||||
60 "#AA927C"}})
|
||||
:orange {50 "#FF7D46"
|
||||
60 "#CC6438"}
|
||||
:army {50 "#216266"
|
||||
60 "#1A4E52"}
|
||||
:pink {50 "#F66F8F"
|
||||
60 "#C55972"}
|
||||
:purple {50 "#7140FD"
|
||||
60 "#5A33CA"}
|
||||
:magenta {50 "#EC266C"
|
||||
60 "#BD1E56"}})
|
||||
|
||||
(def colors-map
|
||||
(merge {:danger {50 danger-50
|
||||
(merge {:primary {50 primary-50 ;; User can also use primary color as customisation color
|
||||
60 primary-60}
|
||||
:beige {50 "#CAAE93"
|
||||
60 "#AA927C"}
|
||||
:green {50 "#5BCC95"
|
||||
60 "#4CAB7D"}
|
||||
:brown {50 "#99604D"
|
||||
60 "#805141"}
|
||||
:red {50 "#F46666"
|
||||
60 "#CD5656"}
|
||||
:magenta {50 "#EC266C"
|
||||
60 "#BD1E56"}
|
||||
:indigo {50 "#496289"
|
||||
60 "#3D5273"}
|
||||
:danger {50 danger-50
|
||||
60 danger-60}
|
||||
:success {50 success-50
|
||||
60 success-60}}
|
||||
|
@ -244,9 +241,7 @@
|
|||
([color suffix opacity]
|
||||
(let [color-keyword (keyword color)
|
||||
base-color (get-in colors-map
|
||||
[(if (= color-keyword :yinyang)
|
||||
(if (theme/dark?) :yang :yin)
|
||||
(keyword color)) suffix])]
|
||||
[color-keyword suffix])]
|
||||
(if opacity (alpha base-color (/ opacity 100)) base-color))))))
|
||||
|
||||
(defn custom-color-by-theme
|
||||
|
|
|
@ -12,16 +12,15 @@
|
|||
{:width "100%"
|
||||
:padding-left 20
|
||||
:padding-right 20
|
||||
:padding-top (if platform/android? 0 12)
|
||||
:padding-top 12
|
||||
:align-self :flex-end
|
||||
:height 64})
|
||||
|
||||
(def blur-button-container
|
||||
(merge button-container
|
||||
{:background-color colors/neutral-80-opa-1-blur}))
|
||||
|
||||
(def view-button-container
|
||||
(merge button-container {:margin-bottom 24}))
|
||||
(merge button-container {:margin-bottom 34}))
|
||||
|
||||
(def blur-button-container
|
||||
(merge button-container (when platform/android? {:padding-bottom 12})))
|
||||
|
||||
(def page-container
|
||||
{:position :absolute
|
||||
|
@ -37,7 +36,7 @@
|
|||
(def title
|
||||
{:color colors/white
|
||||
:margin-top 12
|
||||
:margin-bottom 20})
|
||||
:margin-bottom 18})
|
||||
|
||||
(def color-title
|
||||
{:color colors/white-70-blur
|
||||
|
|
|
@ -13,8 +13,12 @@
|
|||
[utils.re-frame :as rf]
|
||||
[oops.core :as oops]
|
||||
[react-native.blur :as blur]
|
||||
[status-im2.constants :as c]))
|
||||
[status-im2.constants :as c]
|
||||
[react-native.platform :as platform]))
|
||||
|
||||
;; NOTE - validation should match with Desktop
|
||||
;; https://github.com/status-im/status-desktop/blob/2ba96803168461088346bf5030df750cb226df4c/ui/imports/utils/Constants.qml#L468
|
||||
;;
|
||||
(def emoji-regex
|
||||
(new
|
||||
js/RegExp
|
||||
|
@ -23,12 +27,10 @@
|
|||
(defn has-emojis [s] (re-find emoji-regex s))
|
||||
(def common-names ["Ethereum" "Bitcoin"])
|
||||
(defn has-common-names [s] (pos? (count (filter #(string/includes? s %) common-names))))
|
||||
(def special-characters-regex (new js/RegExp #"[^a-zA-Z\d\s-._]" "i"))
|
||||
(defn has-special-characters [s] (re-find special-characters-regex s))
|
||||
(def status-regex (new js/RegExp #"^[a-zA-Z0-9\-_ ]+$"))
|
||||
(defn has-special-characters [s] (not (re-find status-regex s)))
|
||||
(def min-length 5)
|
||||
(defn length-not-valid [s] (< (count (string/trim s)) min-length))
|
||||
(def valid-regex (new js/RegExp #"^[\w-\s]{5,24}$" "i"))
|
||||
(defn valid-name [s] (re-find valid-regex s))
|
||||
(defn length-not-valid [s] (< (count (string/trim (str s))) min-length))
|
||||
|
||||
(defn validation-message
|
||||
[s]
|
||||
|
@ -39,18 +41,22 @@
|
|||
(string/ends-with? s "-eth") (i18n/label :t/ending-not-allowed {:ending "-eth"})
|
||||
(string/ends-with? s "_eth") (i18n/label :t/ending-not-allowed {:ending "_eth"})
|
||||
(string/ends-with? s ".eth") (i18n/label :t/ending-not-allowed {:ending ".eth"})
|
||||
(string/starts-with? s " ") (i18n/label :t/start-with-space)
|
||||
(string/ends-with? s " ") (i18n/label :t/ends-with-space)
|
||||
(has-common-names s) (i18n/label :t/are-not-allowed {:check (i18n/label :t/common-names)})
|
||||
(has-emojis s) (i18n/label :t/are-not-allowed {:check (i18n/label :t/emojis)})
|
||||
(length-not-valid s) (i18n/label :t/name-must-have-at-least-characters
|
||||
{:min-chars min-length})
|
||||
(not (valid-name s)) (i18n/label :t/name-is-not-valid)
|
||||
:else nil))
|
||||
|
||||
(defn button-container
|
||||
[keyboard-shown? children]
|
||||
[rn/view {:style {:margin-top :auto}}
|
||||
(if keyboard-shown?
|
||||
[blur/ios-view {:style style/blur-button-container}
|
||||
[blur/ios-view
|
||||
{:blur-amount 34
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent
|
||||
:background-color (if platform/android? colors/neutral-100 colors/neutral-80-opa-1-blur)
|
||||
:style style/blur-button-container}
|
||||
children]
|
||||
[rn/view {:style style/view-button-container}
|
||||
children])])
|
||||
|
@ -58,13 +64,17 @@
|
|||
(defn- f-page
|
||||
[{:keys [onboarding-profile-data navigation-bar-top]}]
|
||||
(reagent/with-let [keyboard-shown? (reagent/atom false)
|
||||
will-show-listener (oops/ocall rn/keyboard
|
||||
show-listener (oops/ocall rn/keyboard
|
||||
"addListener"
|
||||
"keyboardWillShow"
|
||||
(if platform/android?
|
||||
"keyboardDidShow"
|
||||
"keyboardWillShow")
|
||||
#(reset! keyboard-shown? true))
|
||||
will-hide-listener (oops/ocall rn/keyboard
|
||||
hide-listener (oops/ocall rn/keyboard
|
||||
"addListener"
|
||||
"keyboardWillHide"
|
||||
(if platform/android?
|
||||
"keyboardDidHide"
|
||||
"keyboardWillHide")
|
||||
#(reset! keyboard-shown? false))
|
||||
{:keys [image-path display-name color]} onboarding-profile-data
|
||||
full-name (reagent/atom display-name)
|
||||
|
@ -79,82 +89,92 @@
|
|||
profile-pic (reagent/atom image-path)
|
||||
on-change-profile-pic #(reset! profile-pic %)
|
||||
on-change #(reset! custom-color %)]
|
||||
[rn/view {:style style/page-container}
|
||||
[navigation-bar/navigation-bar {:top navigation-bar-top}]
|
||||
[rn/scroll-view
|
||||
{:keyboard-should-persist-taps :always
|
||||
:content-container-style {:flex-grow 1}}
|
||||
(let [name-too-short? (length-not-valid @full-name)
|
||||
valid-name? (and (not @validation-msg) (not name-too-short?))
|
||||
info-message (if @validation-msg
|
||||
@validation-msg
|
||||
(i18n/label :t/minimum-characters
|
||||
{:min-chars min-length}))
|
||||
info-type (cond @validation-msg :error
|
||||
name-too-short? :default
|
||||
:else :success)]
|
||||
[rn/view {:style style/page-container}
|
||||
[rn/view
|
||||
{:style style/content-container}
|
||||
[quo/text
|
||||
{:size :heading-1
|
||||
:weight :semi-bold
|
||||
:style style/title} (i18n/label :t/create-profile)]
|
||||
[rn/view
|
||||
{:style style/input-container}
|
||||
[navigation-bar/navigation-bar {:top navigation-bar-top}]
|
||||
[rn/scroll-view
|
||||
{:content-container-style {:flexGrow 1}}
|
||||
[rn/view {:style style/page-container}
|
||||
[rn/view
|
||||
{:style style/profile-input-container}
|
||||
[quo/profile-input
|
||||
{:customization-color @custom-color
|
||||
:placeholder (i18n/label :t/your-name)
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:override-theme :dark
|
||||
:content
|
||||
(fn []
|
||||
[method-menu/view on-change-profile-pic])}]))
|
||||
:image-picker-props {:profile-picture (when @profile-pic {:uri @profile-pic})
|
||||
:full-name (if (seq @full-name)
|
||||
@full-name
|
||||
(i18n/label :t/your-name))
|
||||
:customization-color @custom-color}
|
||||
:title-input-props {:default-value @full-name
|
||||
:auto-focus true
|
||||
:max-length c/profile-name-max-length
|
||||
:on-change-text on-change-text}}]]
|
||||
(when @validation-msg
|
||||
{:style style/content-container}
|
||||
[quo/text
|
||||
{:size :heading-1
|
||||
:weight :semi-bold
|
||||
:style style/title} (i18n/label :t/create-profile)]
|
||||
[rn/view
|
||||
{:style style/input-container}
|
||||
[rn/view
|
||||
{:style style/profile-input-container}
|
||||
[quo/profile-input
|
||||
{:customization-color @custom-color
|
||||
:placeholder (i18n/label :t/your-name)
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:override-theme :dark
|
||||
:content
|
||||
(fn []
|
||||
[method-menu/view on-change-profile-pic])}]))
|
||||
:image-picker-props {:profile-picture (when @profile-pic {:uri @profile-pic})
|
||||
:full-name (if (seq @full-name)
|
||||
@full-name
|
||||
(i18n/label :t/your-name))
|
||||
:customization-color @custom-color}
|
||||
:title-input-props {:default-value @full-name
|
||||
:auto-focus true
|
||||
:max-length c/profile-name-max-length
|
||||
:on-change-text on-change-text}}]]
|
||||
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
:size :default
|
||||
:icon :i/info
|
||||
:style style/info-message}
|
||||
@validation-msg])
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style style/color-title}
|
||||
(i18n/label :t/accent-colour)]
|
||||
[quo/color-picker
|
||||
{:blur? true
|
||||
:default-selected? :blue
|
||||
:selected @custom-color
|
||||
:on-change on-change}]]]]]
|
||||
[rn/keyboard-avoiding-view
|
||||
{:style {:position :absolute
|
||||
:top 0
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0}
|
||||
:pointer-events :box-none}
|
||||
[button-container @keyboard-shown?
|
||||
[quo/button
|
||||
{:accessibility-label :submit-create-profile-button
|
||||
:type :primary
|
||||
:override-background-color (colors/custom-color @custom-color 60)
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:onboarding-2/profile-data-set
|
||||
{:image-path @profile-pic
|
||||
:display-name @full-name
|
||||
:color @custom-color}]))
|
||||
:style style/continue-button
|
||||
:disabled (or (not (seq @full-name)) @validation-msg)}
|
||||
(i18n/label :t/continue)]]]]
|
||||
{:type info-type
|
||||
:size :default
|
||||
:icon (if valid-name? :i/positive-state :i/info)
|
||||
:text-color (when (= :default info-type) colors/white-70-blur)
|
||||
:icon-color (when (= :default info-type) colors/white-70-blur)
|
||||
:style style/info-message}
|
||||
info-message]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style style/color-title}
|
||||
(i18n/label :t/accent-colour)]
|
||||
[quo/color-picker
|
||||
{:blur? true
|
||||
:default-selected? :blue
|
||||
:selected @custom-color
|
||||
:on-change on-change}]]]]]
|
||||
[rn/keyboard-avoiding-view
|
||||
{:style {:position :absolute
|
||||
:top 0
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0}
|
||||
:pointer-events :box-none}
|
||||
[button-container @keyboard-shown?
|
||||
[quo/button
|
||||
{:accessibility-label :submit-create-profile-button
|
||||
:type :primary
|
||||
:override-background-color (colors/custom-color @custom-color 60)
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:onboarding-2/profile-data-set
|
||||
{:image-path @profile-pic
|
||||
:display-name @full-name
|
||||
:color @custom-color}]))
|
||||
:style style/continue-button
|
||||
:disabled (or (not valid-name?) (not (seq @full-name)))}
|
||||
(i18n/label :t/continue)]]]])
|
||||
(finally
|
||||
(oops/ocall will-show-listener "remove")
|
||||
(oops/ocall will-hide-listener "remove"))))
|
||||
(oops/ocall show-listener "remove")
|
||||
(oops/ocall hide-listener "remove"))))
|
||||
|
||||
(defn create-profile
|
||||
[]
|
||||
|
|
|
@ -493,6 +493,7 @@
|
|||
"enable-notifications-sub-title": "Receive notifications when somebody sends you a message or crypto to your wallet",
|
||||
"encrypt-with-password": "Encrypt with password",
|
||||
"ending-not-allowed": "{{ending}} ending is not allowed",
|
||||
"ends-with-space": "Cannot end with space",
|
||||
"ens-10-SNT": "10 SNT",
|
||||
"ens-add-username": "Add username",
|
||||
"ens-agree-to": "Agree to ",
|
||||
|
@ -1296,6 +1297,7 @@
|
|||
"start-group-chat": "Start group chat",
|
||||
"start-new-chat": "Start new chat",
|
||||
"start-using-status": "Start using Status",
|
||||
"start-with-space": "Cannot start with space",
|
||||
"status": "Status",
|
||||
"status-confirmed": "Confirmed",
|
||||
"status-hardwallet": "Status hardwallet",
|
||||
|
@ -2110,8 +2112,7 @@
|
|||
"camera-permission-denied": "Permission denied",
|
||||
"enable-biometrics": "Enable biometrics",
|
||||
"use-biometrics": "Use biometrics to fill in your password",
|
||||
"name-must-have-at-least-characters": "Name must have at least {{min-chars}} characters",
|
||||
"name-is-not-valid": "Name is not valid",
|
||||
"minimum-characters": "Minimum {{min-chars}} characters",
|
||||
"no-communities": "No communities",
|
||||
"no-communities-description-strikethrough": "Never",
|
||||
"no-communities-description": "go full nyan, find your community",
|
||||
|
|
Loading…
Reference in New Issue