feat(onboarding): Remove color and username steps (#21715)
* Remove password disclaimer, update copy and simplify implementation * Remove non-existing wallet event * Skip profile configuration for the "create profile" onboarding flow * Include flow for new profiles when another profile already exists * Add explanation about temp username * Point 20 to a constant * Simplify create profile password screen * Fix password creation screen jump on mount * e2e: updated tests * Completely remove the "create profile" onboarding screen * e2e: updated tests with recovering user --------- Co-authored-by: Yevheniia Berdnyk <ie.berdnyk@gmail.com>
This commit is contained in:
parent
c26d298573
commit
e85bc539d3
|
@ -61,14 +61,17 @@
|
|||
(defn view
|
||||
[{:keys [header footer customization-color footer-container-padding header-container-style
|
||||
content-container-style gradient-cover? keyboard-should-persist-taps shell-overlay?
|
||||
blur-options content-avoid-keyboard? automatically-adjust-keyboard-insets]
|
||||
blur-options content-avoid-keyboard? automatically-adjust-keyboard-insets
|
||||
;; Note: Provide `initial-header-height` to avoid a jump due to the on-layout 1-frame
|
||||
;; delay. Revisit this on RN 0.76 since the on-layout delay has been fixed.
|
||||
initial-header-height]
|
||||
: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)
|
||||
header-height (reagent/atom nil)
|
||||
content-container-height (reagent/atom 0)
|
||||
content-scroll-y (reagent/atom 0)
|
||||
keyboard-height (reagent/atom 0)
|
||||
|
@ -112,7 +115,7 @@
|
|||
{:style
|
||||
(if content-avoid-keyboard?
|
||||
(style/content-keyboard-avoiding-view
|
||||
{:top @header-height
|
||||
{:top (or @header-height initial-header-height)
|
||||
:bottom (if keyboard-shown?
|
||||
@footer-container-height
|
||||
(+ bottom-safe-area @footer-container-height))})
|
||||
|
|
|
@ -28,9 +28,10 @@
|
|||
:long-enough?
|
||||
:short-enough?)))))
|
||||
|
||||
(def password-tip? (set constants/password-tips))
|
||||
|
||||
(defn strength
|
||||
[validations]
|
||||
(->> (select-keys validations constants/password-tips)
|
||||
(vals)
|
||||
(filter true?)
|
||||
count))
|
||||
(->> validations
|
||||
(filter #(and (password-tip? (key %)) (val %)))
|
||||
(count)))
|
||||
|
|
|
@ -52,8 +52,8 @@
|
|||
{:eventName "navigation"
|
||||
:platform platform-os
|
||||
:appVersion app-version
|
||||
:eventValue {:viewId "onboarding.create-profile-info"}}}]
|
||||
(tracking/track-view-id-event :screen/onboarding.create-profile)))
|
||||
:eventValue {:viewId "onboarding.create-profile-password"}}}]
|
||||
(tracking/track-view-id-event :screen/onboarding.create-profile-password)))
|
||||
(is (= [] (tracking/track-view-id-event :unknown-stack)))))
|
||||
|
||||
(deftest tracked-event-test
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(ns status-im.contexts.onboarding.create-password.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]))
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.platform :as platform]))
|
||||
|
||||
(def heading {:margin-bottom 20})
|
||||
(def heading-subtitle {:color colors/white})
|
||||
|
@ -21,6 +22,18 @@
|
|||
:padding-top 12
|
||||
:padding-horizontal 20})
|
||||
|
||||
(def disclaimer-container {:padding-horizontal 20})
|
||||
(def footer-container {:padding-bottom 12})
|
||||
(def footer-button-container {:margin-top 20 :padding-horizontal 20})
|
||||
|
||||
(def blur-options
|
||||
{:blur-amount 34
|
||||
:blur-radius 20
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent
|
||||
:background-color (if platform/android?
|
||||
colors/neutral-100
|
||||
colors/neutral-80-opa-1-blur)
|
||||
:padding-vertical 0
|
||||
:padding-horizontal 0})
|
||||
|
||||
(def page-nav-height 56)
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
(ns status-im.contexts.onboarding.create-password.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.floating-button-page.view :as floating-button]
|
||||
[status-im.common.password-with-hint.view :as password-with-hint]
|
||||
|
@ -29,22 +27,37 @@
|
|||
(i18n/label :t/password-creation-subtitle)]])
|
||||
|
||||
(defn password-inputs
|
||||
[{:keys [passwords-match? on-change-password on-change-repeat-password on-input-focus
|
||||
password-long-enough? password-short-enough? empty-password? show-password-validation?
|
||||
on-blur-repeat-password]}]
|
||||
(let [hint-1-status (if password-long-enough? :success :default)
|
||||
hint-2-status (if passwords-match? :success :error)
|
||||
hint-2-text (if passwords-match?
|
||||
(i18n/label :t/password-creation-match)
|
||||
(i18n/label :t/password-creation-dont-match))
|
||||
error? (and show-password-validation?
|
||||
(not passwords-match?)
|
||||
(not empty-password?))]
|
||||
[{:keys [set-password set-repeat-password same-password-length? same-passwords?
|
||||
password-long-enough? password-short-enough? non-empty-password?]}]
|
||||
(let [[show-validation?
|
||||
set-show-validation?] (rn/use-state false)
|
||||
on-change-password (rn/use-callback
|
||||
(fn [new-value]
|
||||
(set-password new-value)
|
||||
(when same-password-length?
|
||||
(set-show-validation? true)))
|
||||
[same-password-length?])
|
||||
on-change-repeat-password (rn/use-callback
|
||||
(fn [new-value]
|
||||
(set-repeat-password new-value)
|
||||
(when same-password-length?
|
||||
(set-show-validation? true)))
|
||||
[same-password-length?])
|
||||
on-blur-repeat-password (rn/use-callback
|
||||
#(set-show-validation? non-empty-password?)
|
||||
[non-empty-password?])
|
||||
hint-1-status (if password-long-enough? :success :default)
|
||||
hint-2-status (if same-passwords? :success :error)
|
||||
hint-2-text (if same-passwords?
|
||||
(i18n/label :t/password-creation-match)
|
||||
(i18n/label :t/password-creation-dont-match))
|
||||
error? (and show-validation?
|
||||
(not same-passwords?)
|
||||
non-empty-password?)]
|
||||
[:<>
|
||||
[password-with-hint/view
|
||||
{:hint (if (not password-short-enough?)
|
||||
{:text (i18n/label
|
||||
:t/password-creation-max-length-hint)
|
||||
{:text (i18n/label :t/password-creation-max-length-hint)
|
||||
:status :error
|
||||
:shown? true}
|
||||
{:text (i18n/label :t/password-creation-hint)
|
||||
|
@ -52,55 +65,50 @@
|
|||
:shown? true})
|
||||
:placeholder (i18n/label :t/password-creation-placeholder-1)
|
||||
:on-change-text on-change-password
|
||||
:on-focus on-input-focus
|
||||
:auto-focus true}]
|
||||
[rn/view {:style style/space-between-inputs}]
|
||||
[password-with-hint/view
|
||||
{:hint {:text hint-2-text
|
||||
:status hint-2-status
|
||||
:shown? (and (not empty-password?)
|
||||
show-password-validation?)}
|
||||
:shown? (and non-empty-password? show-validation?)}
|
||||
:error? error?
|
||||
:placeholder (i18n/label :t/password-creation-placeholder-2)
|
||||
:on-change-text on-change-repeat-password
|
||||
:on-focus on-input-focus
|
||||
:on-blur on-blur-repeat-password}]]))
|
||||
|
||||
(defn help
|
||||
[{{:keys [lower-case? upper-case? numbers? symbols?]} :validations
|
||||
password-strength :password-strength}]
|
||||
[rn/view
|
||||
[quo/strength-divider {:type (constants/strength-status password-strength :info)}
|
||||
(i18n/label :t/password-creation-tips-title)]
|
||||
[rn/view {:style style/password-tips}
|
||||
[quo/tips {:completed? lower-case?}
|
||||
(i18n/label :t/password-creation-tips-1)]
|
||||
[quo/tips {:completed? upper-case?}
|
||||
(i18n/label :t/password-creation-tips-2)]
|
||||
[quo/tips {:completed? numbers?}
|
||||
(i18n/label :t/password-creation-tips-3)]
|
||||
[quo/tips {:completed? symbols?}
|
||||
(i18n/label :t/password-creation-tips-4)]]])
|
||||
[{:keys [lower-case? upper-case? numbers? symbols?] :as validations}]
|
||||
(let [password-strength (constants/strength-status (password/strength validations) :info)]
|
||||
[rn/view
|
||||
[quo/strength-divider {:type password-strength}
|
||||
(i18n/label :t/password-creation-tips-title)]
|
||||
[rn/view {:style style/password-tips}
|
||||
[quo/tips {:completed? lower-case?}
|
||||
(i18n/label :t/password-creation-tips-1)]
|
||||
[quo/tips {:completed? upper-case?}
|
||||
(i18n/label :t/password-creation-tips-2)]
|
||||
[quo/tips {:completed? numbers?}
|
||||
(i18n/label :t/password-creation-tips-3)]
|
||||
[quo/tips {:completed? symbols?}
|
||||
(i18n/label :t/password-creation-tips-4)]]]))
|
||||
|
||||
(defn- use-password-checks
|
||||
[password]
|
||||
(rn/use-memo
|
||||
(fn []
|
||||
(let [{:keys [long-enough? short-enough?]
|
||||
:as validations} (password/validate password)]
|
||||
{:password-long-enough? long-enough?
|
||||
:password-short-enough? short-enough?
|
||||
:password-validations validations
|
||||
:password-strength (password/strength validations)
|
||||
:empty-password? (empty? password)}))
|
||||
(-> password
|
||||
(password/validate)
|
||||
(assoc :non-empty? (seq password))))
|
||||
[password]))
|
||||
|
||||
(defn- use-repeat-password-checks
|
||||
[password repeat-password]
|
||||
(rn/use-memo
|
||||
(fn []
|
||||
{:same-password-length? (and (seq password) (= (count password) (count repeat-password)))
|
||||
:same-passwords? (and (seq password) (= password repeat-password))})
|
||||
{:same-password-length? (and (seq password)
|
||||
(= (count password) (count repeat-password)))
|
||||
:same-passwords? (and (seq password)
|
||||
(= password repeat-password))})
|
||||
[password repeat-password]))
|
||||
|
||||
(defn create-password-doc
|
||||
|
@ -119,102 +127,70 @@
|
|||
{:content create-password-doc
|
||||
:shell? true}]))
|
||||
|
||||
(defn- navigate-back
|
||||
[]
|
||||
(rf/dispatch [:navigate-back]))
|
||||
(defn- navigate-back [] (rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn- page-nav
|
||||
[]
|
||||
(let [{:keys [top]} (safe-area/get-insets)]
|
||||
[quo/page-nav
|
||||
{:margin-top top
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press navigate-back
|
||||
:right-side [{:icon-name :i/info
|
||||
:on-press on-press-info}]}]))
|
||||
[top]
|
||||
[quo/page-nav
|
||||
{:margin-top top
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press navigate-back
|
||||
:right-side [{:icon-name :i/info
|
||||
:on-press on-press-info}]}])
|
||||
|
||||
(defn- help-and-confirm-button
|
||||
[{:keys [password-validations same-passwords? on-submit]}]
|
||||
(let [{customization-color :color} (rf/sub [:onboarding/profile])
|
||||
all-requirements-met? (and (:non-empty? password-validations)
|
||||
(:long-enough? password-validations)
|
||||
(:short-enough? password-validations)
|
||||
same-passwords?)]
|
||||
[rn/view {:style style/footer-container}
|
||||
[help password-validations]
|
||||
[quo/button
|
||||
{:container-style style/footer-button-container
|
||||
:disabled? (not all-requirements-met?)
|
||||
:customization-color customization-color
|
||||
:on-press on-submit}
|
||||
(i18n/label :t/password-creation-confirm)]]))
|
||||
|
||||
(defn- on-confirm-password
|
||||
[password]
|
||||
(rf/dispatch [:onboarding/password-set (security/mask-data password)]))
|
||||
|
||||
(defn create-password
|
||||
[]
|
||||
(let [[password set-password] (rn/use-state "")
|
||||
[repeat-password set-repeat-password] (rn/use-state "")
|
||||
[accepts-disclaimer? set-accepts-disclaimer?] (rn/use-state false)
|
||||
[focused-input set-focused-input] (rn/use-state nil)
|
||||
[show-password-validation?
|
||||
set-show-password-validation?] (rn/use-state false)
|
||||
{user-color :color} (rf/sub [:onboarding/profile])
|
||||
|
||||
|
||||
{:keys [password-long-enough?
|
||||
password-short-enough?
|
||||
password-validations password-strength
|
||||
empty-password?]} (use-password-checks password)
|
||||
|
||||
{:keys [same-password-length? same-passwords?]} (use-repeat-password-checks password
|
||||
repeat-password)
|
||||
|
||||
meet-requirements? (and (not empty-password?)
|
||||
password-long-enough?
|
||||
password-short-enough?
|
||||
same-passwords?
|
||||
accepts-disclaimer?)]
|
||||
|
||||
(let [[password set-password] (rn/use-state "")
|
||||
[repeat-password
|
||||
set-repeat-password] (rn/use-state "")
|
||||
{:keys [long-enough? short-enough? non-empty?]
|
||||
:as password-validations} (use-password-checks password)
|
||||
{:keys [same-password-length?
|
||||
same-passwords?]} (use-repeat-password-checks password repeat-password)
|
||||
on-submit (rn/use-callback
|
||||
#(on-confirm-password password)
|
||||
[password])
|
||||
top (safe-area/get-top)]
|
||||
[floating-button/view
|
||||
{:header [page-nav]
|
||||
:keyboard-should-persist-taps :handled
|
||||
:content-avoid-keyboard? true
|
||||
{:header [page-nav top]
|
||||
:initial-header-height (+ style/page-nav-height top)
|
||||
:keyboard-should-persist-taps :handled
|
||||
:content-avoid-keyboard? true
|
||||
:automatically-adjust-keyboard-insets true
|
||||
:blur-options
|
||||
{:blur-amount 34
|
||||
:blur-radius 20
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent
|
||||
:background-color (if platform/android? colors/neutral-100 colors/neutral-80-opa-1-blur)
|
||||
:padding-vertical 0
|
||||
:padding-horizontal 0}
|
||||
:footer-container-padding 0
|
||||
:footer
|
||||
[rn/view
|
||||
{:style style/footer-container}
|
||||
(when same-passwords?
|
||||
[rn/view {:style style/disclaimer-container}
|
||||
[quo/disclaimer
|
||||
{:blur? true
|
||||
:on-change (partial set-accepts-disclaimer? not)
|
||||
:checked? accepts-disclaimer?
|
||||
:customization-color user-color}
|
||||
(i18n/label :t/password-creation-disclaimer)]])
|
||||
(when (and (= focused-input :password) (not same-passwords?))
|
||||
[help
|
||||
{:validations password-validations
|
||||
:password-strength password-strength}])
|
||||
[quo/button
|
||||
{:container-style style/footer-button-container
|
||||
:disabled? (not meet-requirements?)
|
||||
:customization-color user-color
|
||||
:on-press #(rf/dispatch
|
||||
[:onboarding/password-set
|
||||
(security/mask-data password)])}
|
||||
(i18n/label :t/password-creation-confirm)]]}
|
||||
|
||||
:blur-options style/blur-options
|
||||
:footer-container-padding 0
|
||||
:footer [help-and-confirm-button
|
||||
{:password-validations password-validations
|
||||
:same-passwords? same-passwords?
|
||||
:on-submit on-submit}]}
|
||||
[rn/view {:style style/form-container}
|
||||
[header]
|
||||
[password-inputs
|
||||
{:password-long-enough? password-long-enough?
|
||||
:password-short-enough? password-short-enough?
|
||||
:passwords-match? same-passwords?
|
||||
:empty-password? empty-password?
|
||||
:show-password-validation? show-password-validation?
|
||||
:on-input-focus #(set-focused-input :password)
|
||||
:on-change-password (fn [new-value]
|
||||
(set-password new-value)
|
||||
(when same-password-length?
|
||||
(set-show-password-validation? true)))
|
||||
|
||||
:on-change-repeat-password (fn [new-value]
|
||||
(set-repeat-password new-value)
|
||||
(when same-password-length?
|
||||
(set-show-password-validation? true)))
|
||||
:on-blur-repeat-password #(if empty-password?
|
||||
(set-show-password-validation? false)
|
||||
(set-show-password-validation? true))}]]]))
|
||||
{:password-long-enough? long-enough?
|
||||
:password-short-enough? short-enough?
|
||||
:non-empty-password? non-empty?
|
||||
:same-passwords? same-passwords?
|
||||
:same-password-length? same-password-length?
|
||||
:set-password set-password
|
||||
:set-repeat-password set-repeat-password}]]]))
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
(ns status-im.contexts.onboarding.create-profile.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.platform :as platform]))
|
||||
|
||||
(def continue-button
|
||||
{:width "100%"
|
||||
:margin-left :auto
|
||||
:margin-top (if platform/android? :auto 0)
|
||||
:margin-right :auto})
|
||||
|
||||
(def button-container
|
||||
{:width "100%"
|
||||
:padding-left 20
|
||||
:padding-right 20
|
||||
:padding-top 12
|
||||
:align-self :flex-end
|
||||
:height 64})
|
||||
|
||||
(defn view-button-container
|
||||
[keyboard-shown?]
|
||||
(merge button-container
|
||||
(if platform/ios?
|
||||
{:margin-bottom (if keyboard-shown? 0 34)}
|
||||
{:margin-bottom (if keyboard-shown? 12 34)})))
|
||||
|
||||
(def blur-button-container
|
||||
(merge button-container
|
||||
(when platform/android? {:padding-bottom 12})))
|
||||
|
||||
(def page-container
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0
|
||||
:z-index 100})
|
||||
|
||||
(def info-message
|
||||
{:margin-top 8})
|
||||
|
||||
(def title
|
||||
{:color colors/white
|
||||
:margin-top 12
|
||||
:margin-bottom 18})
|
||||
|
||||
(def color-title
|
||||
{:color colors/white-70-blur
|
||||
:margin-top 20
|
||||
:margin-bottom 16})
|
||||
|
||||
(def content-container
|
||||
{:padding-horizontal 20})
|
||||
|
||||
(def input-container
|
||||
{:align-items :flex-start})
|
||||
|
||||
(def profile-input-container
|
||||
{:flex-direction :row
|
||||
:justify-content :center})
|
|
@ -1,210 +0,0 @@
|
|||
(ns status-im.contexts.onboarding.create-profile.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[oops.core :as oops]
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.hooks :as hooks]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.common.avatar-picture-picker.view :as profile-picture-picker]
|
||||
[status-im.common.validation.profile :as profile-validator]
|
||||
[status-im.constants :as c]
|
||||
[status-im.contexts.onboarding.create-profile.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.responsiveness :as responsiveness]))
|
||||
|
||||
(def scroll-view-height (reagent/atom 0))
|
||||
(def content-container-height (reagent/atom 0))
|
||||
|
||||
(defn show-button-background
|
||||
[keyboard-height keyboard-shown content-scroll-y]
|
||||
(let [button-container-height 64
|
||||
keyboard-view-height (+ keyboard-height button-container-height)]
|
||||
(when keyboard-shown
|
||||
(cond
|
||||
platform/android?
|
||||
(< (- @scroll-view-height button-container-height) @content-container-height)
|
||||
|
||||
platform/ios?
|
||||
(< (- @scroll-view-height keyboard-view-height) (- @content-container-height content-scroll-y))
|
||||
|
||||
:else
|
||||
false))))
|
||||
|
||||
(defn button-container
|
||||
[show-keyboard? keyboard-shown show-background? keyboard-height children]
|
||||
(let [height (reagent/atom 0)]
|
||||
(reset! height (if show-keyboard? (if keyboard-shown keyboard-height 0) 0))
|
||||
[rn/view {:style {:margin-top :auto}}
|
||||
(cond
|
||||
(and (> @height 0) show-background?)
|
||||
[quo/blur
|
||||
(when keyboard-shown
|
||||
{: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]
|
||||
|
||||
(and (> @height 0) (not show-background?))
|
||||
[rn/view {:style (style/view-button-container true)}
|
||||
children]
|
||||
|
||||
(not show-keyboard?)
|
||||
[rn/view {:style (style/view-button-container false)}
|
||||
children])]))
|
||||
|
||||
(defn- page
|
||||
[{:keys [onboarding-profile-data navigation-bar-top]}]
|
||||
(reagent/with-let [show-keyboard? (reagent/atom false)
|
||||
content-scroll-y (reagent/atom 0)
|
||||
show-listener (oops/ocall rn/keyboard
|
||||
"addListener"
|
||||
(if platform/android?
|
||||
"keyboardDidShow"
|
||||
"keyboardWillShow")
|
||||
#(reset! show-keyboard? true))
|
||||
hide-listener (oops/ocall rn/keyboard
|
||||
"addListener"
|
||||
(if platform/android?
|
||||
"keyboardDidHide"
|
||||
"keyboardWillHide")
|
||||
#(reset! show-keyboard? false))
|
||||
{:keys [image-path display-name color]} onboarding-profile-data
|
||||
full-name (reagent/atom display-name)
|
||||
validation-msg (reagent/atom
|
||||
(profile-validator/validation-name
|
||||
@full-name))
|
||||
on-change-text (fn [s]
|
||||
(reset! validation-msg
|
||||
(profile-validator/validation-name
|
||||
s))
|
||||
(reset! full-name (string/trim s)))
|
||||
custom-color (reagent/atom (or color
|
||||
c/profile-default-color))
|
||||
profile-pic (reagent/atom image-path)
|
||||
on-change-profile-pic #(reset! profile-pic %)
|
||||
on-change #(reset! custom-color %)]
|
||||
(let [name-too-short? (profile-validator/name-too-short? @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
|
||||
profile-validator/min-length}))
|
||||
info-type (cond @validation-msg :error
|
||||
name-too-short? :default
|
||||
:else :success)
|
||||
{:keys [keyboard-shown keyboard-height]} (hooks/use-keyboard)
|
||||
show-background? (show-button-background keyboard-height
|
||||
keyboard-shown
|
||||
@content-scroll-y)
|
||||
{window-width :width} (rn/get-window)]
|
||||
[rn/view {:style style/page-container}
|
||||
[quo/page-nav
|
||||
{:margin-top navigation-bar-top
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press #(rf/dispatch [:navigate-back])}]
|
||||
[rn/scroll-view
|
||||
{:on-layout (fn [event]
|
||||
(let [height (oops/oget event "nativeEvent.layout.height")]
|
||||
(reset! scroll-view-height height)
|
||||
(reset! content-scroll-y 0)))
|
||||
:on-scroll (fn [event]
|
||||
(let [y (oops/oget event "nativeEvent.contentOffset.y")]
|
||||
(reset! content-scroll-y y)))
|
||||
:scroll-event-throttle 64
|
||||
:content-container-style {:flexGrow 1}}
|
||||
[rn/view
|
||||
{:on-layout (fn [event]
|
||||
(let [height (oops/oget event "nativeEvent.layout.height")]
|
||||
(reset! content-container-height height)))}
|
||||
[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}
|
||||
[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
|
||||
{:content (fn []
|
||||
[profile-picture-picker/view
|
||||
{:on-result on-change-profile-pic
|
||||
:has-picture? false}])
|
||||
:shell? true}]))
|
||||
:image-picker-props {:profile-picture @profile-pic
|
||||
:full-name (if (seq @full-name)
|
||||
@full-name
|
||||
(i18n/label :t/your-name))
|
||||
:customization-color @custom-color}
|
||||
:title-input-props {:default-value display-name
|
||||
:auto-focus true
|
||||
:max-length c/profile-name-max-length
|
||||
:on-change-text on-change-text}}]]
|
||||
|
||||
[quo/info-message
|
||||
{:status info-type
|
||||
:size :default
|
||||
:icon (if valid-name? :i/positive-state :i/info)
|
||||
:color (when (= :default info-type) colors/white-70-blur)
|
||||
:container-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
|
||||
:on-change on-change
|
||||
:window-width window-width
|
||||
:container-style {:padding-left (responsiveness/iphone-11-Pro-20-pixel-from-width
|
||||
window-width)}}]]]
|
||||
|
||||
[rn/keyboard-avoiding-view
|
||||
{:style {:position :absolute
|
||||
:top 0
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0}
|
||||
:pointer-events :box-none}
|
||||
[button-container @show-keyboard? keyboard-shown show-background? keyboard-height
|
||||
[quo/button
|
||||
{:accessibility-label :submit-create-profile-button
|
||||
:type :primary
|
||||
:customization-color @custom-color
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:onboarding/profile-data-set
|
||||
{:image-path @profile-pic
|
||||
:display-name @full-name
|
||||
:color @custom-color}]))
|
||||
:container-style style/continue-button
|
||||
:disabled? (or (not valid-name?) (not (seq @full-name)))}
|
||||
(i18n/label :t/continue)]]]])
|
||||
(finally
|
||||
(oops/ocall show-listener "remove")
|
||||
(oops/ocall hide-listener "remove"))))
|
||||
|
||||
(defn create-profile
|
||||
[]
|
||||
(let [{:keys [top]} (safe-area/get-insets)
|
||||
onboarding-profile-data (rf/sub [:onboarding/profile])]
|
||||
[page
|
||||
{:navigation-bar-top top
|
||||
:onboarding-profile-data onboarding-profile-data}]))
|
|
@ -1,5 +1,6 @@
|
|||
(ns status-im.contexts.onboarding.events
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]
|
||||
[re-frame.core :as re-frame]
|
||||
status-im.common.biometric.events
|
||||
[status-im.constants :as constants]
|
||||
|
@ -111,63 +112,57 @@
|
|||
(rf/reg-event-fx
|
||||
:onboarding/password-set
|
||||
(fn [{:keys [db]} [masked-password]]
|
||||
(let [biometric-supported-type (get-in db [:biometrics :supported-type])]
|
||||
(let [biometric-supported-type (get-in db [:biometrics :supported-type])
|
||||
from-screen (get db
|
||||
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
||||
:screen/onboarding.new-to-status)]
|
||||
{:db (-> db
|
||||
(assoc-in [:onboarding/profile :password] masked-password)
|
||||
(assoc-in [:onboarding/profile :auth-method] constants/auth-method-password))
|
||||
:fx [[:dispatch
|
||||
(if biometric-supported-type
|
||||
[:navigate-to-within-stack
|
||||
[:screen/onboarding.enable-biometrics
|
||||
(get db
|
||||
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
||||
:screen/onboarding.new-to-status)]]
|
||||
[:navigate-to-within-stack [:screen/onboarding.enable-biometrics from-screen]]
|
||||
[:onboarding/create-account-and-login])]]})))
|
||||
|
||||
(rf/defn navigate-to-enable-biometrics
|
||||
{:events [:onboarding/navigate-to-enable-biometrics]}
|
||||
[{:keys [db]}]
|
||||
(let [supported-type (get-in db [:biometrics :supported-type])]
|
||||
{:dispatch (if supported-type
|
||||
[:open-modal :screen/onboarding.enable-biometrics]
|
||||
[:open-modal :screen/onboarding.enable-notifications])}))
|
||||
(rf/reg-event-fx
|
||||
:onboarding/navigate-to-enable-biometrics
|
||||
(fn [{:keys [db]}]
|
||||
(let [supported-type (get-in db [:biometrics :supported-type])]
|
||||
{:dispatch (if supported-type
|
||||
[:open-modal :screen/onboarding.enable-biometrics]
|
||||
[:open-modal :screen/onboarding.enable-notifications])})))
|
||||
|
||||
(rf/defn seed-phrase-validated
|
||||
{:events [:onboarding/seed-phrase-validated]}
|
||||
[{:keys [db]} seed-phrase key-uid]
|
||||
(let [syncing-account-recovered? (and (seq (:syncing/key-uid db))
|
||||
(= (:syncing/key-uid db) key-uid))
|
||||
next-screen (if syncing-account-recovered?
|
||||
:screen/onboarding.create-profile-password
|
||||
:screen/onboarding.create-profile)]
|
||||
(if (contains? (:profile/profiles-overview db) key-uid)
|
||||
{:effects.utils/show-confirmation
|
||||
{:title (i18n/label :t/multiaccount-exists-title)
|
||||
:content (i18n/label :t/multiaccount-exists-content)
|
||||
:confirm-button-text (i18n/label :t/unlock)
|
||||
:on-accept (fn []
|
||||
(re-frame/dispatch [:pop-to-root :screen/profile.profiles])
|
||||
(re-frame/dispatch
|
||||
[:profile/profile-selected key-uid]))
|
||||
:on-cancel #(re-frame/dispatch [:pop-to-root :multiaccounts])}}
|
||||
{:db (-> db
|
||||
(assoc-in [:onboarding/profile :seed-phrase] seed-phrase)
|
||||
(assoc-in [:onboarding/profile :key-uid] key-uid)
|
||||
(assoc-in [:onboarding/profile :color] constants/profile-default-color))
|
||||
:fx [[:dispatch
|
||||
[:navigate-to-within-stack
|
||||
[next-screen
|
||||
(get db
|
||||
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
||||
:screen/onboarding.new-to-status)]]]]})))
|
||||
(rf/reg-event-fx
|
||||
:onboarding/seed-phrase-validated
|
||||
(fn [{:keys [db]} [seed-phrase key-uid]]
|
||||
(let [next-screen :screen/onboarding.create-profile-password
|
||||
from-screen (get db
|
||||
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
||||
:screen/onboarding.new-to-status)]
|
||||
(if (contains? (:profile/profiles-overview db) key-uid)
|
||||
{:fx [[:effects.utils/show-confirmation
|
||||
{:title (i18n/label :t/multiaccount-exists-title)
|
||||
:content (i18n/label :t/multiaccount-exists-content)
|
||||
:confirm-button-text (i18n/label :t/unlock)
|
||||
:on-accept (fn []
|
||||
(re-frame/dispatch [:pop-to-root :screen/profile.profiles])
|
||||
(re-frame/dispatch [:profile/profile-selected key-uid]))
|
||||
:on-cancel #(re-frame/dispatch [:pop-to-root :multiaccounts])}]]}
|
||||
{:db (-> db
|
||||
(assoc-in [:onboarding/profile :seed-phrase] seed-phrase)
|
||||
(assoc-in [:onboarding/profile :key-uid] key-uid)
|
||||
(assoc-in [:onboarding/profile :color] constants/profile-default-color))
|
||||
:fx [[:dispatch [:navigate-to-within-stack [next-screen from-screen]]]]}))))
|
||||
|
||||
(rf/defn navigate-to-create-profile
|
||||
{:events [:onboarding/navigate-to-create-profile]}
|
||||
[{:keys [db]}]
|
||||
;; Restart the flow
|
||||
{:db (dissoc db :onboarding/profile)
|
||||
:dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.create-profile :screen/onboarding.new-to-status]]})
|
||||
(rf/reg-event-fx
|
||||
:onboarding/navigate-to-create-profile
|
||||
(fn [{:keys [db]}]
|
||||
{:db (-> db
|
||||
(assoc-in [:onboarding/profile :color] (rand-nth colors/account-colors))
|
||||
(update :onboarding/profile dissoc :image-path))
|
||||
:fx [[:dispatch
|
||||
[:navigate-to-within-stack
|
||||
[:screen/onboarding.create-profile-password :screen/onboarding.new-to-status]]]]}))
|
||||
|
||||
(rf/reg-event-fx :onboarding/navigate-to-sign-in-by-syncing
|
||||
(fn [{:keys [db]}]
|
||||
|
@ -180,26 +175,43 @@
|
|||
(fn [{:keys [db]} [auth-method]]
|
||||
{:db (assoc db :auth-method auth-method)}))
|
||||
|
||||
(rf/defn onboarding-new-account-finalize-setup
|
||||
{:events [:onboarding/finalize-setup]}
|
||||
[{:keys [db]}]
|
||||
(let [masked-password (get-in db [:onboarding/profile :password])
|
||||
key-uid (get-in db [:profile/profile :key-uid])
|
||||
syncing? (get-in db [:onboarding/profile :syncing?])
|
||||
auth-method (get-in db [:onboarding/profile :auth-method])
|
||||
biometric-enabled? (= auth-method constants/auth-method-biometric)]
|
||||
(cond-> {:db (assoc db :onboarding/generated-keys? true)}
|
||||
biometric-enabled?
|
||||
(assoc :keychain/save-password-and-auth-method
|
||||
{:key-uid key-uid
|
||||
:masked-password (if syncing?
|
||||
masked-password
|
||||
(security/hash-masked-password masked-password))
|
||||
:on-success (fn []
|
||||
(rf/dispatch [:onboarding/set-auth-method auth-method])
|
||||
(when syncing?
|
||||
(rf/dispatch
|
||||
[:onboarding/navigate-to-enable-notifications-from-syncing])))
|
||||
:on-error #(log/error "failed to save biometrics"
|
||||
{:key-uid key-uid
|
||||
:error %})}))))
|
||||
(def ^:const temp-display-name
|
||||
"While creating a profile, we cannot use an empty string; this value works as a
|
||||
placeholder that will be updated later once the compressed key exists. See
|
||||
`status-im.contexts.profile.edit.name.events/get-default-display-name` for more details."
|
||||
"temporal username")
|
||||
|
||||
(rf/reg-event-fx
|
||||
:onboarding/use-temporary-display-name
|
||||
(fn [{:keys [db]} [temporary-display-name?]]
|
||||
{:db (assoc db
|
||||
:onboarding/profile
|
||||
{:temporary-display-name? temporary-display-name?
|
||||
:display-name (if temporary-display-name?
|
||||
temp-display-name
|
||||
"")})}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:onboarding/finalize-setup
|
||||
(fn [{db :db}]
|
||||
(let [{:keys [password syncing? auth-method
|
||||
temporary-display-name?]} (:onboarding/profile db)
|
||||
{:keys [key-uid] :as profile} (:profile/profile db)
|
||||
biometric-enabled? (= auth-method constants/auth-method-biometric)]
|
||||
{:db (assoc db :onboarding/generated-keys? true)
|
||||
:fx [(when temporary-display-name?
|
||||
[:dispatch [:profile/set-default-profile-name profile]])
|
||||
(when biometric-enabled?
|
||||
[:keychain/save-password-and-auth-method
|
||||
{:key-uid key-uid
|
||||
:masked-password (if syncing?
|
||||
password
|
||||
(security/hash-masked-password password))
|
||||
:on-success (fn []
|
||||
(rf/dispatch [:onboarding/set-auth-method auth-method])
|
||||
(when syncing?
|
||||
(rf/dispatch
|
||||
[:onboarding/navigate-to-enable-notifications-from-syncing])))
|
||||
:on-error #(log/error "failed to save biometrics"
|
||||
{:key-uid key-uid
|
||||
:error %})}])]})))
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
[]
|
||||
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
||||
(blur-show-fn))
|
||||
(rf/dispatch [:onboarding/use-temporary-display-name false])
|
||||
(rf/dispatch [:open-modal
|
||||
:screen/onboarding.share-usage
|
||||
{:next-screen :screen/onboarding.sync-or-recover-profile}]))
|
||||
|
@ -60,6 +61,7 @@
|
|||
[]
|
||||
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
||||
(blur-show-fn))
|
||||
(rf/dispatch [:onboarding/use-temporary-display-name true])
|
||||
(rf/dispatch [:open-modal :screen/onboarding.share-usage
|
||||
{:next-screen :screen/onboarding.new-to-status}]))
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
(ns status-im.contexts.profile.edit.name.events
|
||||
(:require [utils.i18n :as i18n]
|
||||
(:require [clojure.string :as string]
|
||||
[status-im.constants :as constants]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/reg-event-fx :profile/edit-profile-name-success
|
||||
|
@ -20,3 +22,16 @@
|
|||
:on-success [:profile/edit-profile-name-success]}]]]})
|
||||
|
||||
(rf/reg-event-fx :profile/edit-name edit-profile-name)
|
||||
|
||||
(defn display-name-from-compressed-key
|
||||
[profile]
|
||||
(-> profile :compressed-key (string/split #"zQ3") second (subs 0 constants/profile-name-max-length)))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:profile/set-default-profile-name
|
||||
(fn [{db :db} [profile]]
|
||||
(let [default-display-name (display-name-from-compressed-key profile)]
|
||||
{:db (assoc-in db [:profile/profile :display-name] default-display-name)
|
||||
:fx [[:json-rpc/call
|
||||
[{:method "wakuext_setDisplayName"
|
||||
:params [default-display-name]}]]]})))
|
||||
|
|
|
@ -152,15 +152,12 @@
|
|||
|
||||
(rf/reg-event-fx
|
||||
:profile.login/login-node-signal
|
||||
(fn [{{:onboarding/keys [recovered-account? new-account?] :as db} :db}
|
||||
[{:keys [settings account ensUsernames error]}]]
|
||||
(fn [{db :db} [{:keys [settings account ensUsernames error]}]]
|
||||
(log/debug "[signals] node.login" "error" error)
|
||||
(if error
|
||||
{:db (update db :profile/login #(-> % (dissoc :processing) (assoc :error error)))}
|
||||
{:db (dissoc db :profile/login)
|
||||
:fx [(when (and new-account? (not recovered-account?))
|
||||
[:dispatch-later [{:ms 1000 :dispatch [:wallet-legacy/set-initial-blocks-range]}]])
|
||||
[:dispatch-later [{:ms 2000 :dispatch [:ens/update-usernames ensUsernames]}]]
|
||||
:fx [[:dispatch-later [{:ms 2000 :dispatch [:ens/update-usernames ensUsernames]}]]
|
||||
[:dispatch [:profile.login/login-existing-profile settings account]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
[]
|
||||
(when @push-animation-fn-atom
|
||||
(@push-animation-fn-atom))
|
||||
(rf/dispatch [:onboarding/use-temporary-display-name true])
|
||||
(debounce/throttle-and-dispatch
|
||||
[:open-modal :screen/onboarding.new-to-status]
|
||||
1000))
|
||||
|
@ -55,6 +56,7 @@
|
|||
[]
|
||||
(when @push-animation-fn-atom
|
||||
(@push-animation-fn-atom))
|
||||
(rf/dispatch [:onboarding/use-temporary-display-name false])
|
||||
(debounce/throttle-and-dispatch
|
||||
[:open-modal :screen/onboarding.sync-or-recover-profile]
|
||||
1000))
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
[status-im.contexts.keycard.pin.enter.view :as keycard.pin.enter]
|
||||
[status-im.contexts.onboarding.create-or-sync-profile.view :as create-or-sync-profile]
|
||||
[status-im.contexts.onboarding.create-password.view :as create-password]
|
||||
[status-im.contexts.onboarding.create-profile.view :as create-profile]
|
||||
[status-im.contexts.onboarding.enable-biometrics.view :as enable-biometrics]
|
||||
[status-im.contexts.onboarding.enable-notifications.view :as enable-notifications]
|
||||
[status-im.contexts.onboarding.identifiers.view :as identifiers]
|
||||
|
@ -728,16 +727,6 @@
|
|||
:modalPresentationStyle :overCurrentContext}
|
||||
:component create-or-sync-profile/sync-or-recover-profile})
|
||||
|
||||
(def onboarding-create-profile
|
||||
{:name :screen/onboarding.create-profile
|
||||
:metrics {:track? true
|
||||
:alias-id :onboarding.create-profile-info}
|
||||
:options {:theme :dark
|
||||
:layout options/onboarding-transparent-layout
|
||||
:animations transitions/push-animations-for-transparent-background
|
||||
:popGesture false}
|
||||
:component create-profile/create-profile})
|
||||
|
||||
(def onboarding-create-profile-password
|
||||
{:name :screen/onboarding.create-profile-password
|
||||
:metrics {:track? true
|
||||
|
@ -872,7 +861,6 @@
|
|||
[onboarding-intro
|
||||
onboarding-new-to-status
|
||||
onboarding-sync-or-recover-profile
|
||||
onboarding-create-profile
|
||||
onboarding-create-profile-password
|
||||
onboarding-enable-biometrics
|
||||
onboarding-preparing-status
|
||||
|
|
|
@ -17,11 +17,10 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
|
|||
def prepare_devices(self):
|
||||
self.drivers, self.loop = create_shared_drivers(2)
|
||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||
self.username_1, self.username_2 = 'sender', 'receiver'
|
||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True,
|
||||
'username': self.username_1}),
|
||||
(self.device_2.create_user, {'username': self.username_2}))))
|
||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True}),
|
||||
(self.device_2.create_user,))))
|
||||
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
||||
self.username_1, self.username_2 = self.home_1.get_username(), self.home_2.get_username()
|
||||
self.profile_1, self.profile_2 = self.home_1.get_profile_view(), self.home_2.get_profile_view()
|
||||
self.public_key_1 = self.home_1.get_public_key()
|
||||
self.profile_link_2 = self.home_2.get_link_to_profile()
|
||||
|
@ -98,8 +97,8 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
|
|||
def test_activity_center_contact_request_accept_swipe_mark_all_as_read(self):
|
||||
self.device_2.just_fyi('Creating a new user on Device2')
|
||||
self.home_2.reopen_app(sign_in=False)
|
||||
new_username = "new user"
|
||||
self.device_2.create_user(username=new_username, first_user=False)
|
||||
self.device_2.create_user(first_user=False)
|
||||
new_username = self.home_2.get_username()
|
||||
|
||||
self.device_2.just_fyi('Device2 sends a contact request to Device1 via Paste button and check user details')
|
||||
self.home_2.chats_tab.click()
|
||||
|
@ -159,20 +158,19 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
|
|||
self.username_2, self.profile_link_2, decoded_username))
|
||||
public_key_2 = self.profile_link_2.split("#")[-1]
|
||||
|
||||
new_username_1 = "test user 123"
|
||||
|
||||
def _device_1_creates_user():
|
||||
self.home_1.just_fyi("Device 1 creates a new user")
|
||||
self.home_1.reopen_app(sign_in=False)
|
||||
self.device_1.create_user(username=new_username_1, first_user=False)
|
||||
self.device_1.create_user(first_user=False)
|
||||
return self.home_1.get_username()
|
||||
|
||||
def _device_2_sign_in():
|
||||
self.home_2.just_fyi("Device 2 sign in, user name is " + self.username_2)
|
||||
self.home_2.reopen_app(sign_in=False)
|
||||
self.device_2.sign_in(user_name=self.username_2)
|
||||
|
||||
self.loop.run_until_complete(run_in_parallel(((_device_1_creates_user, {}),
|
||||
(_device_2_sign_in, {}))))
|
||||
new_username_1, _ = self.loop.run_until_complete(run_in_parallel(((_device_1_creates_user, {}),
|
||||
(_device_2_sign_in, {}))))
|
||||
|
||||
self.device_1.just_fyi('Device1 sends a contact request to Device2 using his profile link')
|
||||
self.home_1.chats_tab.click()
|
||||
|
@ -242,11 +240,11 @@ class TestActivityMultipleDevicePR(MultipleSharedDeviceTestCase):
|
|||
def prepare_devices(self):
|
||||
self.drivers, self.loop = create_shared_drivers(2)
|
||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||
self.username_1, self.username_2 = 'user1', 'user2'
|
||||
self.loop.run_until_complete(
|
||||
run_in_parallel(((self.device_1.create_user, {'username': self.username_1}),
|
||||
(self.device_2.create_user, {'username': self.username_2}))))
|
||||
run_in_parallel(((self.device_1.create_user,),
|
||||
(self.device_2.create_user,))))
|
||||
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
||||
self.username_1, self.username_2 = self.home_1.get_username(), self.home_2.get_username()
|
||||
self.profile_1, self.profile_2 = self.home_1.get_profile_view(), self.home_2.get_profile_view()
|
||||
self.public_key_2 = self.home_2.get_public_key()
|
||||
self.home_2.navigate_back_to_home_view()
|
||||
|
@ -382,11 +380,11 @@ class TestActivityMultipleDevicePRTwo(MultipleSharedDeviceTestCase):
|
|||
def prepare_devices(self):
|
||||
self.drivers, self.loop = create_shared_drivers(2)
|
||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||
self.username_1, self.username_2 = 'user1', 'user2'
|
||||
self.loop.run_until_complete(
|
||||
run_in_parallel(((self.device_1.create_user, {'username': self.username_1}),
|
||||
(self.device_2.create_user, {'username': self.username_2}))))
|
||||
run_in_parallel(((self.device_1.create_user,),
|
||||
(self.device_2.create_user,))))
|
||||
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
||||
self.username_1, self.username_2 = self.home_1.get_username(), self.home_2.get_username()
|
||||
self.profile_1, self.profile_2 = self.home_1.get_profile_view(), self.home_2.get_profile_view()
|
||||
self.public_key_2 = self.home_2.get_public_key()
|
||||
self.home_2.navigate_back_to_home_view()
|
||||
|
|
|
@ -20,13 +20,11 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
|
|||
self.drivers, self.loop = create_shared_drivers(2)
|
||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||
|
||||
self.username_1, self.username_2 = 'sender', 'receiver'
|
||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True,
|
||||
'username': self.username_1}),
|
||||
(self.device_2.create_user, {'enable_notifications': True,
|
||||
'username': self.username_2}))))
|
||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True}),
|
||||
(self.device_2.create_user, {'enable_notifications': True}))))
|
||||
self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
||||
self.homes = (self.home_1, self.home_2)
|
||||
self.username_1, self.username_2 = self.home_1.get_username(), self.home_2.get_username()
|
||||
self.profile_1, self.profile_2 = (home.get_profile_view() for home in self.homes)
|
||||
self.public_key_2 = self.home_2.get_public_key()
|
||||
|
||||
|
@ -543,13 +541,11 @@ class TestOneToOneChatMultipleSharedDevicesNewUiTwo(MultipleSharedDeviceTestCase
|
|||
self.drivers, self.loop = create_shared_drivers(2)
|
||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||
|
||||
self.username_1, self.username_2 = 'sender', 'receiver'
|
||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True,
|
||||
'username': self.username_1}),
|
||||
(self.device_2.create_user, {'enable_notifications': True,
|
||||
'username': self.username_2}))))
|
||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True}),
|
||||
(self.device_2.create_user, {'enable_notifications': True}))))
|
||||
self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
||||
self.homes = (self.home_1, self.home_2)
|
||||
self.username_1, self.username_2 = self.home_1.get_username(), self.home_2.get_username()
|
||||
self.profile_1, self.profile_2 = (home.get_profile_view() for home in self.homes)
|
||||
self.public_key_2 = self.home_2.get_public_key()
|
||||
|
||||
|
|
|
@ -21,17 +21,25 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
|
|||
self.message_to_admin = 'Hey, admin!'
|
||||
self.public_keys, self.usernames, self.chats = {}, {}, {}
|
||||
self.sign_in_views = [SignInView(self.drivers[key]) for key in self.drivers]
|
||||
self.usernames = ('user admin', 'member_1', 'member_2')
|
||||
self.loop.run_until_complete(
|
||||
run_in_parallel(
|
||||
(
|
||||
(self.sign_in_views[0].create_user, {'enable_notifications': True, 'username': self.usernames[0]}),
|
||||
(self.sign_in_views[1].create_user, {'enable_notifications': True, 'username': self.usernames[1]}),
|
||||
(self.sign_in_views[2].create_user, {'enable_notifications': True, 'username': self.usernames[2]})
|
||||
(self.sign_in_views[0].create_user, {'enable_notifications': True}),
|
||||
(self.sign_in_views[1].create_user, {'enable_notifications': True}),
|
||||
(self.sign_in_views[2].create_user, {'enable_notifications': True})
|
||||
)
|
||||
)
|
||||
)
|
||||
self.homes = [sign_in.get_home_view() for sign_in in self.sign_in_views]
|
||||
self.usernames = self.loop.run_until_complete(
|
||||
run_in_parallel(
|
||||
(
|
||||
(self.homes[0].get_username,),
|
||||
(self.homes[1].get_username,),
|
||||
(self.homes[2].get_username,)
|
||||
)
|
||||
)
|
||||
)
|
||||
self.public_keys = self.loop.run_until_complete(
|
||||
run_in_parallel(
|
||||
(
|
||||
|
|
|
@ -21,9 +21,9 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
|
|||
def prepare_devices(self):
|
||||
self.drivers, self.loop = create_shared_drivers(1)
|
||||
self.sign_in = SignInView(self.drivers[0])
|
||||
self.username = 'first user'
|
||||
|
||||
self.home = self.sign_in.create_user(username=self.username)
|
||||
self.home = self.sign_in.create_user()
|
||||
self.username = self.home.get_username()
|
||||
self.home.communities_tab.click_until_presence_of_element(self.home.plus_community_button)
|
||||
self.community_name = "closed community"
|
||||
self.channel_name = "cats"
|
||||
|
@ -158,8 +158,8 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
|
|||
def test_restore_multiaccount_with_waku_backup_remove_profile_switch(self):
|
||||
self.home.reopen_app(sign_in=False)
|
||||
self.home.just_fyi("Restore user with predefined communities and contacts")
|
||||
recover_user_name = 'Recover user'
|
||||
self.sign_in.recover_access(passphrase=waku_user.seed, second_user=True, username=recover_user_name)
|
||||
self.sign_in.recover_access(passphrase=waku_user.seed, second_user=True)
|
||||
recover_user_name = self.home.get_username()
|
||||
|
||||
self.home.just_fyi("Check contacts/blocked users")
|
||||
self.home.chats_tab.click()
|
||||
|
@ -306,11 +306,10 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
|
|||
def prepare_devices(self):
|
||||
self.drivers, self.loop = create_shared_drivers(2)
|
||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||
self.username_1, self.username_2 = "user_1", "user_2"
|
||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True,
|
||||
'username': self.username_1}),
|
||||
(self.device_2.create_user, {'username': self.username_2}))))
|
||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True}),
|
||||
(self.device_2.create_user,))))
|
||||
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
||||
self.username_1, self.username_2 = self.home_1.get_username(), self.home_2.get_username()
|
||||
self.public_key_2 = self.home_2.get_public_key()
|
||||
self.profile_1 = self.home_1.get_profile_view()
|
||||
[home.navigate_back_to_home_view() for home in self.homes]
|
||||
|
@ -836,12 +835,10 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
|
|||
def prepare_devices(self):
|
||||
self.drivers, self.loop = create_shared_drivers(2)
|
||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||
self.username_1, self.username_2 = "user_1", "user_2"
|
||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True,
|
||||
'username': self.username_1}),
|
||||
(self.device_2.create_user, {'enable_notifications': True,
|
||||
'username': self.username_2}))))
|
||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True}),
|
||||
(self.device_2.create_user, {'enable_notifications': True}))))
|
||||
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
||||
self.username_1, self.username_2 = self.home_1.get_username(), self.home_2.get_username()
|
||||
self.public_key_2 = self.home_2.get_public_key()
|
||||
self.profile_1 = self.home_1.get_profile_view()
|
||||
[home.navigate_back_to_home_view() for home in self.homes]
|
||||
|
|
|
@ -13,9 +13,9 @@ class TestDeepLinksOneDevice(MultipleSharedDeviceTestCase):
|
|||
self.drivers, self.loop = create_shared_drivers(1)
|
||||
self.driver = self.drivers[0]
|
||||
self.sign_in = SignInView(self.driver)
|
||||
self.username = 'test user'
|
||||
|
||||
self.home = self.sign_in.create_user(username=self.username)
|
||||
self.home = self.sign_in.create_user()
|
||||
self.username = self.home.get_username()
|
||||
self.home.communities_tab.click_until_presence_of_element(self.home.plus_community_button)
|
||||
self.open_community_name = "open community"
|
||||
self.channel_name = "general"
|
||||
|
|
|
@ -20,10 +20,10 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
|
|||
self.sign_in_3.get_home_view()
|
||||
self.sign_in_1.just_fyi("Device 1: create a new user")
|
||||
self.sign_in_3.just_fyi("Device 3: create a new user")
|
||||
self.user_name_1, self.user_name_3 = 'first user', 'third user'
|
||||
self.loop.run_until_complete(
|
||||
run_in_parallel(((self.sign_in_1.create_user, {'username': self.user_name_1}),
|
||||
(self.sign_in_3.create_user, {'username': self.user_name_3}))))
|
||||
run_in_parallel(((self.sign_in_1.create_user,),
|
||||
(self.sign_in_3.create_user,))))
|
||||
self.user_name_1, self.user_name_3 = self.home_1.get_username(), self.home_3.get_username()
|
||||
self.profile_1 = self.home_1.profile_button.click()
|
||||
self.profile_2 = self.home_2.get_profile_view()
|
||||
self.sign_in_3.just_fyi("Device 3: get public key")
|
||||
|
|
|
@ -24,13 +24,11 @@ class TestWalletMultipleDevice(MultipleSharedDeviceTestCase):
|
|||
self.sender, self.receiver = transaction_senders['ETH_1'], transaction_senders['ETH_2']
|
||||
self.sender['wallet_address'] = '0x' + self.sender['address']
|
||||
self.receiver['wallet_address'] = '0x' + self.receiver['address']
|
||||
self.sender_username, self.receiver_username = 'sender', 'receiver'
|
||||
self.loop.run_until_complete(
|
||||
run_in_parallel(((self.sign_in_1.recover_access, {'passphrase': self.sender['passphrase'],
|
||||
'username': self.sender_username}),
|
||||
(self.sign_in_2.recover_access, {'passphrase': self.receiver['passphrase'],
|
||||
'username': self.receiver_username}))))
|
||||
run_in_parallel(((self.sign_in_1.recover_access, {'passphrase': self.sender['passphrase']}),
|
||||
(self.sign_in_2.recover_access, {'passphrase': self.receiver['passphrase']}))))
|
||||
self.home_1, self.home_2 = self.sign_in_1.get_home_view(), self.sign_in_2.get_home_view()
|
||||
self.sender_username, self.receiver_username = self.home_1.get_username(), self.home_2.get_username()
|
||||
self.wallet_1, self.wallet_2 = self.sign_in_1.get_wallet_view(), self.sign_in_2.get_wallet_view()
|
||||
self.wallet_1.wallet_tab.click()
|
||||
self.wallet_2.wallet_tab.click()
|
||||
|
@ -206,10 +204,10 @@ class TestWalletOneDevice(MultipleSharedDeviceTestCase):
|
|||
self.arb_balance = {'Ether': 0.0001, 'USDCoin': 0.0, 'Status': 0.0, 'Uniswap': 0.5, 'Dai Stablecoin': 0.0}
|
||||
self.sender['wallet_address'] = '0x' + self.sender['address']
|
||||
self.receiver['wallet_address'] = '0x' + self.receiver['address']
|
||||
self.sender_username, self.receiver_username = 'sender', 'receiver'
|
||||
self.sign_in_view.recover_access(passphrase=self.sender['passphrase'], username=self.sender_username)
|
||||
self.sign_in_view.recover_access(passphrase=self.sender['passphrase'])
|
||||
|
||||
self.home_view = self.sign_in_view.get_home_view()
|
||||
self.sender_username = self.home_view.get_username()
|
||||
self.wallet_view = self.home_view.wallet_tab.click()
|
||||
|
||||
@marks.testrail_id(740490)
|
||||
|
|
|
@ -624,3 +624,11 @@ class HomeView(BaseView):
|
|||
element = Text(self.driver, accessibility_id='new-device-installation-id')
|
||||
element.wait_for_visibility_of_element()
|
||||
return element.text
|
||||
|
||||
def get_username(self):
|
||||
profile_view = self.get_profile_view()
|
||||
profile_view = self.profile_button.click_until_presence_of_element(profile_view.default_username_text)
|
||||
profile_view.default_username_text.wait_for_element(3)
|
||||
username = profile_view.default_username_text.text
|
||||
profile_view.click_system_back_button()
|
||||
return username
|
||||
|
|
|
@ -179,7 +179,7 @@ class ProfileView(BaseView):
|
|||
|
||||
# Header
|
||||
self.public_key_text = Text(self.driver, accessibility_id="chat-key")
|
||||
self.default_username_text = Text(self.driver, accessibility_id="default-username")
|
||||
self.default_username_text = Text(self.driver, accessibility_id="username")
|
||||
self.contact_name_text = Text(self.driver, accessibility_id="contact-name")
|
||||
self.share_my_profile_button = Button(self.driver, accessibility_id="share-header-button")
|
||||
self.profile_picture = ProfilePictureElement(self.driver)
|
||||
|
|
|
@ -211,7 +211,7 @@ class SignInView(BaseView):
|
|||
self.profile_continue_button = Button(self.driver, accessibility_id="submit-create-profile-button")
|
||||
self.profile_password_edit_box = EditBox(self.driver, translation_id="password-creation-placeholder-1")
|
||||
self.profile_repeat_password_edit_box = EditBox(self.driver, translation_id="password-creation-placeholder-2")
|
||||
self.profile_confirm_password_button = Button(self.driver, translation_id="password-creation-confirm")
|
||||
self.profile_confirm_password_button = Button(self.driver, accessibility_id="Confirm password")
|
||||
self.enable_biometric_maybe_later_button = Button(self.driver, translation_id="maybe-later")
|
||||
self.identifiers_button = Button(self.driver, accessibility_id="skip-identifiers")
|
||||
self.start_button = Button(self.driver, accessibility_id="welcome-button")
|
||||
|
@ -228,8 +228,6 @@ class SignInView(BaseView):
|
|||
input_elements[0].send_keys(password)
|
||||
input_elements[1].click()
|
||||
input_elements[1].send_keys(password)
|
||||
self.checkbox_button.scroll_to_element()
|
||||
self.checkbox_button.click()
|
||||
self.profile_confirm_password_button.click()
|
||||
|
||||
def set_profile(self, username: str, set_image=False):
|
||||
|
@ -238,7 +236,7 @@ class SignInView(BaseView):
|
|||
if set_image:
|
||||
pass
|
||||
|
||||
def create_user(self, password=common_password, username="test user", first_user=True, enable_notifications=False):
|
||||
def create_user(self, password=common_password, first_user=True, enable_notifications=False):
|
||||
self.driver.info("## Creating new multiaccount with password:'%s'" % password, device=False)
|
||||
if first_user:
|
||||
self.create_profile_button.click_until_presence_of_element(self.start_fresh_lets_go_button)
|
||||
|
@ -249,7 +247,6 @@ class SignInView(BaseView):
|
|||
self.plus_profiles_button.click()
|
||||
self.create_new_profile_button.click()
|
||||
self.start_fresh_lets_go_button.click_until_presence_of_element(self.profile_title_input)
|
||||
self.set_profile(username)
|
||||
self.set_password(password)
|
||||
self.chats_tab.wait_for_visibility_of_element(30)
|
||||
self.driver.info("## New multiaccount is created successfully!", device=False)
|
||||
|
@ -261,7 +258,7 @@ class SignInView(BaseView):
|
|||
return home_view
|
||||
|
||||
def recover_access(self, passphrase: str, password: str = common_password, enable_notifications=False,
|
||||
second_user=False, username='Restore user', set_image=False, after_sync_code=False):
|
||||
second_user=False, after_sync_code=False):
|
||||
self.driver.info("## Recover access (password:%s)" % password, device=False)
|
||||
|
||||
if not after_sync_code:
|
||||
|
@ -274,8 +271,6 @@ class SignInView(BaseView):
|
|||
self.use_recovery_phrase_button.click()
|
||||
self.passphrase_edit_box.send_keys(passphrase)
|
||||
self.continue_button.click_until_presence_of_element(self.profile_title_input)
|
||||
if not after_sync_code:
|
||||
self.set_profile(username, set_image)
|
||||
self.set_password(password)
|
||||
self.chats_tab.wait_for_visibility_of_element(30)
|
||||
self.driver.info("## Multiaccount is recovered successfully!", device=False)
|
||||
|
|
|
@ -1930,7 +1930,7 @@
|
|||
"password-creation-max-length-hint": "Maximum 100 characters",
|
||||
"password-creation-placeholder-1": "Type password",
|
||||
"password-creation-placeholder-2": "Repeat password",
|
||||
"password-creation-subtitle": "To log in to Status and sign transactions",
|
||||
"password-creation-subtitle": "This password can't be recovered",
|
||||
"password-creation-tips-1": "Lower case",
|
||||
"password-creation-tips-2": "Upper case",
|
||||
"password-creation-tips-3": "Numbers",
|
||||
|
|
Loading…
Reference in New Issue