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
|
(defn view
|
||||||
[{:keys [header footer customization-color footer-container-padding header-container-style
|
[{:keys [header footer customization-color footer-container-padding header-container-style
|
||||||
content-container-style gradient-cover? keyboard-should-persist-taps shell-overlay?
|
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)}}
|
:or {footer-container-padding (safe-area/get-top)}}
|
||||||
& children]
|
& children]
|
||||||
(reagent/with-let [scroll-view-ref (atom nil)
|
(reagent/with-let [scroll-view-ref (atom nil)
|
||||||
set-scroll-ref #(reset! scroll-view-ref %)
|
set-scroll-ref #(reset! scroll-view-ref %)
|
||||||
window-height (:height (rn/get-window))
|
window-height (:height (rn/get-window))
|
||||||
footer-container-height (reagent/atom 0)
|
footer-container-height (reagent/atom 0)
|
||||||
header-height (reagent/atom 0)
|
header-height (reagent/atom nil)
|
||||||
content-container-height (reagent/atom 0)
|
content-container-height (reagent/atom 0)
|
||||||
content-scroll-y (reagent/atom 0)
|
content-scroll-y (reagent/atom 0)
|
||||||
keyboard-height (reagent/atom 0)
|
keyboard-height (reagent/atom 0)
|
||||||
|
@ -112,7 +115,7 @@
|
||||||
{:style
|
{:style
|
||||||
(if content-avoid-keyboard?
|
(if content-avoid-keyboard?
|
||||||
(style/content-keyboard-avoiding-view
|
(style/content-keyboard-avoiding-view
|
||||||
{:top @header-height
|
{:top (or @header-height initial-header-height)
|
||||||
:bottom (if keyboard-shown?
|
:bottom (if keyboard-shown?
|
||||||
@footer-container-height
|
@footer-container-height
|
||||||
(+ bottom-safe-area @footer-container-height))})
|
(+ bottom-safe-area @footer-container-height))})
|
||||||
|
|
|
@ -28,9 +28,10 @@
|
||||||
:long-enough?
|
:long-enough?
|
||||||
:short-enough?)))))
|
:short-enough?)))))
|
||||||
|
|
||||||
|
(def password-tip? (set constants/password-tips))
|
||||||
|
|
||||||
(defn strength
|
(defn strength
|
||||||
[validations]
|
[validations]
|
||||||
(->> (select-keys validations constants/password-tips)
|
(->> validations
|
||||||
(vals)
|
(filter #(and (password-tip? (key %)) (val %)))
|
||||||
(filter true?)
|
(count)))
|
||||||
count))
|
|
||||||
|
|
|
@ -52,8 +52,8 @@
|
||||||
{:eventName "navigation"
|
{:eventName "navigation"
|
||||||
:platform platform-os
|
:platform platform-os
|
||||||
:appVersion app-version
|
:appVersion app-version
|
||||||
:eventValue {:viewId "onboarding.create-profile-info"}}}]
|
:eventValue {:viewId "onboarding.create-profile-password"}}}]
|
||||||
(tracking/track-view-id-event :screen/onboarding.create-profile)))
|
(tracking/track-view-id-event :screen/onboarding.create-profile-password)))
|
||||||
(is (= [] (tracking/track-view-id-event :unknown-stack)))))
|
(is (= [] (tracking/track-view-id-event :unknown-stack)))))
|
||||||
|
|
||||||
(deftest tracked-event-test
|
(deftest tracked-event-test
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns status-im.contexts.onboarding.create-password.style
|
(ns status-im.contexts.onboarding.create-password.style
|
||||||
(:require
|
(:require
|
||||||
[quo.foundations.colors :as colors]))
|
[quo.foundations.colors :as colors]
|
||||||
|
[react-native.platform :as platform]))
|
||||||
|
|
||||||
(def heading {:margin-bottom 20})
|
(def heading {:margin-bottom 20})
|
||||||
(def heading-subtitle {:color colors/white})
|
(def heading-subtitle {:color colors/white})
|
||||||
|
@ -21,6 +22,18 @@
|
||||||
:padding-top 12
|
:padding-top 12
|
||||||
:padding-horizontal 20})
|
:padding-horizontal 20})
|
||||||
|
|
||||||
(def disclaimer-container {:padding-horizontal 20})
|
|
||||||
(def footer-container {:padding-bottom 12})
|
(def footer-container {:padding-bottom 12})
|
||||||
(def footer-button-container {:margin-top 20 :padding-horizontal 20})
|
(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
|
(ns status-im.contexts.onboarding.create-password.view
|
||||||
(:require
|
(:require
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[quo.foundations.colors :as colors]
|
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.platform :as platform]
|
|
||||||
[react-native.safe-area :as safe-area]
|
[react-native.safe-area :as safe-area]
|
||||||
[status-im.common.floating-button-page.view :as floating-button]
|
[status-im.common.floating-button-page.view :as floating-button]
|
||||||
[status-im.common.password-with-hint.view :as password-with-hint]
|
[status-im.common.password-with-hint.view :as password-with-hint]
|
||||||
|
@ -29,22 +27,37 @@
|
||||||
(i18n/label :t/password-creation-subtitle)]])
|
(i18n/label :t/password-creation-subtitle)]])
|
||||||
|
|
||||||
(defn password-inputs
|
(defn password-inputs
|
||||||
[{:keys [passwords-match? on-change-password on-change-repeat-password on-input-focus
|
[{:keys [set-password set-repeat-password same-password-length? same-passwords?
|
||||||
password-long-enough? password-short-enough? empty-password? show-password-validation?
|
password-long-enough? password-short-enough? non-empty-password?]}]
|
||||||
on-blur-repeat-password]}]
|
(let [[show-validation?
|
||||||
(let [hint-1-status (if password-long-enough? :success :default)
|
set-show-validation?] (rn/use-state false)
|
||||||
hint-2-status (if passwords-match? :success :error)
|
on-change-password (rn/use-callback
|
||||||
hint-2-text (if passwords-match?
|
(fn [new-value]
|
||||||
(i18n/label :t/password-creation-match)
|
(set-password new-value)
|
||||||
(i18n/label :t/password-creation-dont-match))
|
(when same-password-length?
|
||||||
error? (and show-password-validation?
|
(set-show-validation? true)))
|
||||||
(not passwords-match?)
|
[same-password-length?])
|
||||||
(not empty-password?))]
|
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
|
[password-with-hint/view
|
||||||
{:hint (if (not password-short-enough?)
|
{:hint (if (not password-short-enough?)
|
||||||
{:text (i18n/label
|
{:text (i18n/label :t/password-creation-max-length-hint)
|
||||||
:t/password-creation-max-length-hint)
|
|
||||||
:status :error
|
:status :error
|
||||||
:shown? true}
|
:shown? true}
|
||||||
{:text (i18n/label :t/password-creation-hint)
|
{:text (i18n/label :t/password-creation-hint)
|
||||||
|
@ -52,55 +65,50 @@
|
||||||
:shown? true})
|
:shown? true})
|
||||||
:placeholder (i18n/label :t/password-creation-placeholder-1)
|
:placeholder (i18n/label :t/password-creation-placeholder-1)
|
||||||
:on-change-text on-change-password
|
:on-change-text on-change-password
|
||||||
:on-focus on-input-focus
|
|
||||||
:auto-focus true}]
|
:auto-focus true}]
|
||||||
[rn/view {:style style/space-between-inputs}]
|
[rn/view {:style style/space-between-inputs}]
|
||||||
[password-with-hint/view
|
[password-with-hint/view
|
||||||
{:hint {:text hint-2-text
|
{:hint {:text hint-2-text
|
||||||
:status hint-2-status
|
:status hint-2-status
|
||||||
:shown? (and (not empty-password?)
|
:shown? (and non-empty-password? show-validation?)}
|
||||||
show-password-validation?)}
|
|
||||||
:error? error?
|
:error? error?
|
||||||
:placeholder (i18n/label :t/password-creation-placeholder-2)
|
:placeholder (i18n/label :t/password-creation-placeholder-2)
|
||||||
:on-change-text on-change-repeat-password
|
:on-change-text on-change-repeat-password
|
||||||
:on-focus on-input-focus
|
|
||||||
:on-blur on-blur-repeat-password}]]))
|
:on-blur on-blur-repeat-password}]]))
|
||||||
|
|
||||||
(defn help
|
(defn help
|
||||||
[{{:keys [lower-case? upper-case? numbers? symbols?]} :validations
|
[{:keys [lower-case? upper-case? numbers? symbols?] :as validations}]
|
||||||
password-strength :password-strength}]
|
(let [password-strength (constants/strength-status (password/strength validations) :info)]
|
||||||
[rn/view
|
[rn/view
|
||||||
[quo/strength-divider {:type (constants/strength-status password-strength :info)}
|
[quo/strength-divider {:type password-strength}
|
||||||
(i18n/label :t/password-creation-tips-title)]
|
(i18n/label :t/password-creation-tips-title)]
|
||||||
[rn/view {:style style/password-tips}
|
[rn/view {:style style/password-tips}
|
||||||
[quo/tips {:completed? lower-case?}
|
[quo/tips {:completed? lower-case?}
|
||||||
(i18n/label :t/password-creation-tips-1)]
|
(i18n/label :t/password-creation-tips-1)]
|
||||||
[quo/tips {:completed? upper-case?}
|
[quo/tips {:completed? upper-case?}
|
||||||
(i18n/label :t/password-creation-tips-2)]
|
(i18n/label :t/password-creation-tips-2)]
|
||||||
[quo/tips {:completed? numbers?}
|
[quo/tips {:completed? numbers?}
|
||||||
(i18n/label :t/password-creation-tips-3)]
|
(i18n/label :t/password-creation-tips-3)]
|
||||||
[quo/tips {:completed? symbols?}
|
[quo/tips {:completed? symbols?}
|
||||||
(i18n/label :t/password-creation-tips-4)]]])
|
(i18n/label :t/password-creation-tips-4)]]]))
|
||||||
|
|
||||||
(defn- use-password-checks
|
(defn- use-password-checks
|
||||||
[password]
|
[password]
|
||||||
(rn/use-memo
|
(rn/use-memo
|
||||||
(fn []
|
(fn []
|
||||||
(let [{:keys [long-enough? short-enough?]
|
(-> password
|
||||||
:as validations} (password/validate password)]
|
(password/validate)
|
||||||
{:password-long-enough? long-enough?
|
(assoc :non-empty? (seq password))))
|
||||||
:password-short-enough? short-enough?
|
|
||||||
:password-validations validations
|
|
||||||
:password-strength (password/strength validations)
|
|
||||||
:empty-password? (empty? password)}))
|
|
||||||
[password]))
|
[password]))
|
||||||
|
|
||||||
(defn- use-repeat-password-checks
|
(defn- use-repeat-password-checks
|
||||||
[password repeat-password]
|
[password repeat-password]
|
||||||
(rn/use-memo
|
(rn/use-memo
|
||||||
(fn []
|
(fn []
|
||||||
{:same-password-length? (and (seq password) (= (count password) (count repeat-password)))
|
{:same-password-length? (and (seq password)
|
||||||
:same-passwords? (and (seq password) (= password repeat-password))})
|
(= (count password) (count repeat-password)))
|
||||||
|
:same-passwords? (and (seq password)
|
||||||
|
(= password repeat-password))})
|
||||||
[password repeat-password]))
|
[password repeat-password]))
|
||||||
|
|
||||||
(defn create-password-doc
|
(defn create-password-doc
|
||||||
|
@ -119,102 +127,70 @@
|
||||||
{:content create-password-doc
|
{:content create-password-doc
|
||||||
:shell? true}]))
|
:shell? true}]))
|
||||||
|
|
||||||
(defn- navigate-back
|
(defn- navigate-back [] (rf/dispatch [:navigate-back]))
|
||||||
[]
|
|
||||||
(rf/dispatch [:navigate-back]))
|
|
||||||
|
|
||||||
(defn- page-nav
|
(defn- page-nav
|
||||||
[]
|
[top]
|
||||||
(let [{:keys [top]} (safe-area/get-insets)]
|
[quo/page-nav
|
||||||
[quo/page-nav
|
{:margin-top top
|
||||||
{:margin-top top
|
:background :blur
|
||||||
:background :blur
|
:icon-name :i/arrow-left
|
||||||
:icon-name :i/arrow-left
|
:on-press navigate-back
|
||||||
:on-press navigate-back
|
:right-side [{:icon-name :i/info
|
||||||
:right-side [{:icon-name :i/info
|
:on-press on-press-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
|
(defn create-password
|
||||||
[]
|
[]
|
||||||
(let [[password set-password] (rn/use-state "")
|
(let [[password set-password] (rn/use-state "")
|
||||||
[repeat-password set-repeat-password] (rn/use-state "")
|
[repeat-password
|
||||||
[accepts-disclaimer? set-accepts-disclaimer?] (rn/use-state false)
|
set-repeat-password] (rn/use-state "")
|
||||||
[focused-input set-focused-input] (rn/use-state nil)
|
{:keys [long-enough? short-enough? non-empty?]
|
||||||
[show-password-validation?
|
:as password-validations} (use-password-checks password)
|
||||||
set-show-password-validation?] (rn/use-state false)
|
{:keys [same-password-length?
|
||||||
{user-color :color} (rf/sub [:onboarding/profile])
|
same-passwords?]} (use-repeat-password-checks password repeat-password)
|
||||||
|
on-submit (rn/use-callback
|
||||||
|
#(on-confirm-password password)
|
||||||
{:keys [password-long-enough?
|
[password])
|
||||||
password-short-enough?
|
top (safe-area/get-top)]
|
||||||
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?)]
|
|
||||||
|
|
||||||
[floating-button/view
|
[floating-button/view
|
||||||
{:header [page-nav]
|
{:header [page-nav top]
|
||||||
:keyboard-should-persist-taps :handled
|
:initial-header-height (+ style/page-nav-height top)
|
||||||
:content-avoid-keyboard? true
|
:keyboard-should-persist-taps :handled
|
||||||
|
:content-avoid-keyboard? true
|
||||||
:automatically-adjust-keyboard-insets true
|
:automatically-adjust-keyboard-insets true
|
||||||
:blur-options
|
:blur-options style/blur-options
|
||||||
{:blur-amount 34
|
:footer-container-padding 0
|
||||||
:blur-radius 20
|
:footer [help-and-confirm-button
|
||||||
:blur-type :transparent
|
{:password-validations password-validations
|
||||||
:overlay-color :transparent
|
:same-passwords? same-passwords?
|
||||||
:background-color (if platform/android? colors/neutral-100 colors/neutral-80-opa-1-blur)
|
:on-submit on-submit}]}
|
||||||
: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)]]}
|
|
||||||
|
|
||||||
[rn/view {:style style/form-container}
|
[rn/view {:style style/form-container}
|
||||||
[header]
|
[header]
|
||||||
[password-inputs
|
[password-inputs
|
||||||
{:password-long-enough? password-long-enough?
|
{:password-long-enough? long-enough?
|
||||||
:password-short-enough? password-short-enough?
|
:password-short-enough? short-enough?
|
||||||
:passwords-match? same-passwords?
|
:non-empty-password? non-empty?
|
||||||
:empty-password? empty-password?
|
:same-passwords? same-passwords?
|
||||||
:show-password-validation? show-password-validation?
|
:same-password-length? same-password-length?
|
||||||
:on-input-focus #(set-focused-input :password)
|
:set-password set-password
|
||||||
:on-change-password (fn [new-value]
|
:set-repeat-password set-repeat-password}]]]))
|
||||||
(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))}]]]))
|
|
||||||
|
|
|
@ -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
|
(ns status-im.contexts.onboarding.events
|
||||||
(:require
|
(:require
|
||||||
|
[quo.foundations.colors :as colors]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
status-im.common.biometric.events
|
status-im.common.biometric.events
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
|
@ -111,63 +112,57 @@
|
||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
:onboarding/password-set
|
:onboarding/password-set
|
||||||
(fn [{:keys [db]} [masked-password]]
|
(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
|
{:db (-> db
|
||||||
(assoc-in [:onboarding/profile :password] masked-password)
|
(assoc-in [:onboarding/profile :password] masked-password)
|
||||||
(assoc-in [:onboarding/profile :auth-method] constants/auth-method-password))
|
(assoc-in [:onboarding/profile :auth-method] constants/auth-method-password))
|
||||||
:fx [[:dispatch
|
:fx [[:dispatch
|
||||||
(if biometric-supported-type
|
(if biometric-supported-type
|
||||||
[:navigate-to-within-stack
|
[:navigate-to-within-stack [:screen/onboarding.enable-biometrics from-screen]]
|
||||||
[:screen/onboarding.enable-biometrics
|
|
||||||
(get db
|
|
||||||
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
|
||||||
:screen/onboarding.new-to-status)]]
|
|
||||||
[:onboarding/create-account-and-login])]]})))
|
[:onboarding/create-account-and-login])]]})))
|
||||||
|
|
||||||
(rf/defn navigate-to-enable-biometrics
|
(rf/reg-event-fx
|
||||||
{:events [:onboarding/navigate-to-enable-biometrics]}
|
:onboarding/navigate-to-enable-biometrics
|
||||||
[{:keys [db]}]
|
(fn [{:keys [db]}]
|
||||||
(let [supported-type (get-in db [:biometrics :supported-type])]
|
(let [supported-type (get-in db [:biometrics :supported-type])]
|
||||||
{:dispatch (if supported-type
|
{:dispatch (if supported-type
|
||||||
[:open-modal :screen/onboarding.enable-biometrics]
|
[:open-modal :screen/onboarding.enable-biometrics]
|
||||||
[:open-modal :screen/onboarding.enable-notifications])}))
|
[:open-modal :screen/onboarding.enable-notifications])})))
|
||||||
|
|
||||||
(rf/defn seed-phrase-validated
|
(rf/reg-event-fx
|
||||||
{:events [:onboarding/seed-phrase-validated]}
|
:onboarding/seed-phrase-validated
|
||||||
[{:keys [db]} seed-phrase key-uid]
|
(fn [{:keys [db]} [seed-phrase key-uid]]
|
||||||
(let [syncing-account-recovered? (and (seq (:syncing/key-uid db))
|
(let [next-screen :screen/onboarding.create-profile-password
|
||||||
(= (:syncing/key-uid db) key-uid))
|
from-screen (get db
|
||||||
next-screen (if syncing-account-recovered?
|
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
||||||
:screen/onboarding.create-profile-password
|
:screen/onboarding.new-to-status)]
|
||||||
:screen/onboarding.create-profile)]
|
(if (contains? (:profile/profiles-overview db) key-uid)
|
||||||
(if (contains? (:profile/profiles-overview db) key-uid)
|
{:fx [[:effects.utils/show-confirmation
|
||||||
{:effects.utils/show-confirmation
|
{:title (i18n/label :t/multiaccount-exists-title)
|
||||||
{:title (i18n/label :t/multiaccount-exists-title)
|
:content (i18n/label :t/multiaccount-exists-content)
|
||||||
:content (i18n/label :t/multiaccount-exists-content)
|
:confirm-button-text (i18n/label :t/unlock)
|
||||||
:confirm-button-text (i18n/label :t/unlock)
|
:on-accept (fn []
|
||||||
:on-accept (fn []
|
(re-frame/dispatch [:pop-to-root :screen/profile.profiles])
|
||||||
(re-frame/dispatch [:pop-to-root :screen/profile.profiles])
|
(re-frame/dispatch [:profile/profile-selected key-uid]))
|
||||||
(re-frame/dispatch
|
:on-cancel #(re-frame/dispatch [:pop-to-root :multiaccounts])}]]}
|
||||||
[:profile/profile-selected key-uid]))
|
{:db (-> db
|
||||||
:on-cancel #(re-frame/dispatch [:pop-to-root :multiaccounts])}}
|
(assoc-in [:onboarding/profile :seed-phrase] seed-phrase)
|
||||||
{:db (-> db
|
(assoc-in [:onboarding/profile :key-uid] key-uid)
|
||||||
(assoc-in [:onboarding/profile :seed-phrase] seed-phrase)
|
(assoc-in [:onboarding/profile :color] constants/profile-default-color))
|
||||||
(assoc-in [:onboarding/profile :key-uid] key-uid)
|
:fx [[:dispatch [:navigate-to-within-stack [next-screen from-screen]]]]}))))
|
||||||
(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/defn navigate-to-create-profile
|
(rf/reg-event-fx
|
||||||
{:events [:onboarding/navigate-to-create-profile]}
|
:onboarding/navigate-to-create-profile
|
||||||
[{:keys [db]}]
|
(fn [{:keys [db]}]
|
||||||
;; Restart the flow
|
{:db (-> db
|
||||||
{:db (dissoc db :onboarding/profile)
|
(assoc-in [:onboarding/profile :color] (rand-nth colors/account-colors))
|
||||||
:dispatch [:navigate-to-within-stack
|
(update :onboarding/profile dissoc :image-path))
|
||||||
[:screen/onboarding.create-profile :screen/onboarding.new-to-status]]})
|
: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
|
(rf/reg-event-fx :onboarding/navigate-to-sign-in-by-syncing
|
||||||
(fn [{:keys [db]}]
|
(fn [{:keys [db]}]
|
||||||
|
@ -180,26 +175,43 @@
|
||||||
(fn [{:keys [db]} [auth-method]]
|
(fn [{:keys [db]} [auth-method]]
|
||||||
{:db (assoc db :auth-method auth-method)}))
|
{:db (assoc db :auth-method auth-method)}))
|
||||||
|
|
||||||
(rf/defn onboarding-new-account-finalize-setup
|
(def ^:const temp-display-name
|
||||||
{:events [:onboarding/finalize-setup]}
|
"While creating a profile, we cannot use an empty string; this value works as a
|
||||||
[{:keys [db]}]
|
placeholder that will be updated later once the compressed key exists. See
|
||||||
(let [masked-password (get-in db [:onboarding/profile :password])
|
`status-im.contexts.profile.edit.name.events/get-default-display-name` for more details."
|
||||||
key-uid (get-in db [:profile/profile :key-uid])
|
"temporal username")
|
||||||
syncing? (get-in db [:onboarding/profile :syncing?])
|
|
||||||
auth-method (get-in db [:onboarding/profile :auth-method])
|
(rf/reg-event-fx
|
||||||
biometric-enabled? (= auth-method constants/auth-method-biometric)]
|
:onboarding/use-temporary-display-name
|
||||||
(cond-> {:db (assoc db :onboarding/generated-keys? true)}
|
(fn [{:keys [db]} [temporary-display-name?]]
|
||||||
biometric-enabled?
|
{:db (assoc db
|
||||||
(assoc :keychain/save-password-and-auth-method
|
:onboarding/profile
|
||||||
{:key-uid key-uid
|
{:temporary-display-name? temporary-display-name?
|
||||||
:masked-password (if syncing?
|
:display-name (if temporary-display-name?
|
||||||
masked-password
|
temp-display-name
|
||||||
(security/hash-masked-password masked-password))
|
"")})}))
|
||||||
:on-success (fn []
|
|
||||||
(rf/dispatch [:onboarding/set-auth-method auth-method])
|
(rf/reg-event-fx
|
||||||
(when syncing?
|
:onboarding/finalize-setup
|
||||||
(rf/dispatch
|
(fn [{db :db}]
|
||||||
[:onboarding/navigate-to-enable-notifications-from-syncing])))
|
(let [{:keys [password syncing? auth-method
|
||||||
:on-error #(log/error "failed to save biometrics"
|
temporary-display-name?]} (:onboarding/profile db)
|
||||||
{:key-uid key-uid
|
{:keys [key-uid] :as profile} (:profile/profile db)
|
||||||
:error %})}))))
|
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]
|
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
||||||
(blur-show-fn))
|
(blur-show-fn))
|
||||||
|
(rf/dispatch [:onboarding/use-temporary-display-name false])
|
||||||
(rf/dispatch [:open-modal
|
(rf/dispatch [:open-modal
|
||||||
:screen/onboarding.share-usage
|
:screen/onboarding.share-usage
|
||||||
{:next-screen :screen/onboarding.sync-or-recover-profile}]))
|
{:next-screen :screen/onboarding.sync-or-recover-profile}]))
|
||||||
|
@ -60,6 +61,7 @@
|
||||||
[]
|
[]
|
||||||
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
||||||
(blur-show-fn))
|
(blur-show-fn))
|
||||||
|
(rf/dispatch [:onboarding/use-temporary-display-name true])
|
||||||
(rf/dispatch [:open-modal :screen/onboarding.share-usage
|
(rf/dispatch [:open-modal :screen/onboarding.share-usage
|
||||||
{:next-screen :screen/onboarding.new-to-status}]))
|
{:next-screen :screen/onboarding.new-to-status}]))
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
(ns status-im.contexts.profile.edit.name.events
|
(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]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(rf/reg-event-fx :profile/edit-profile-name-success
|
(rf/reg-event-fx :profile/edit-profile-name-success
|
||||||
|
@ -20,3 +22,16 @@
|
||||||
:on-success [:profile/edit-profile-name-success]}]]]})
|
:on-success [:profile/edit-profile-name-success]}]]]})
|
||||||
|
|
||||||
(rf/reg-event-fx :profile/edit-name edit-profile-name)
|
(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
|
(rf/reg-event-fx
|
||||||
:profile.login/login-node-signal
|
:profile.login/login-node-signal
|
||||||
(fn [{{:onboarding/keys [recovered-account? new-account?] :as db} :db}
|
(fn [{db :db} [{:keys [settings account ensUsernames error]}]]
|
||||||
[{:keys [settings account ensUsernames error]}]]
|
|
||||||
(log/debug "[signals] node.login" "error" error)
|
(log/debug "[signals] node.login" "error" error)
|
||||||
(if error
|
(if error
|
||||||
{:db (update db :profile/login #(-> % (dissoc :processing) (assoc :error error)))}
|
{:db (update db :profile/login #(-> % (dissoc :processing) (assoc :error error)))}
|
||||||
{:db (dissoc db :profile/login)
|
{:db (dissoc db :profile/login)
|
||||||
:fx [(when (and new-account? (not recovered-account?))
|
:fx [[:dispatch-later [{:ms 2000 :dispatch [:ens/update-usernames ensUsernames]}]]
|
||||||
[:dispatch-later [{:ms 1000 :dispatch [:wallet-legacy/set-initial-blocks-range]}]])
|
|
||||||
[:dispatch-later [{:ms 2000 :dispatch [:ens/update-usernames ensUsernames]}]]
|
|
||||||
[:dispatch [:profile.login/login-existing-profile settings account]]]})))
|
[:dispatch [:profile.login/login-existing-profile settings account]]]})))
|
||||||
|
|
||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
[]
|
[]
|
||||||
(when @push-animation-fn-atom
|
(when @push-animation-fn-atom
|
||||||
(@push-animation-fn-atom))
|
(@push-animation-fn-atom))
|
||||||
|
(rf/dispatch [:onboarding/use-temporary-display-name true])
|
||||||
(debounce/throttle-and-dispatch
|
(debounce/throttle-and-dispatch
|
||||||
[:open-modal :screen/onboarding.new-to-status]
|
[:open-modal :screen/onboarding.new-to-status]
|
||||||
1000))
|
1000))
|
||||||
|
@ -55,6 +56,7 @@
|
||||||
[]
|
[]
|
||||||
(when @push-animation-fn-atom
|
(when @push-animation-fn-atom
|
||||||
(@push-animation-fn-atom))
|
(@push-animation-fn-atom))
|
||||||
|
(rf/dispatch [:onboarding/use-temporary-display-name false])
|
||||||
(debounce/throttle-and-dispatch
|
(debounce/throttle-and-dispatch
|
||||||
[:open-modal :screen/onboarding.sync-or-recover-profile]
|
[:open-modal :screen/onboarding.sync-or-recover-profile]
|
||||||
1000))
|
1000))
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
[status-im.contexts.keycard.pin.enter.view :as keycard.pin.enter]
|
[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-or-sync-profile.view :as create-or-sync-profile]
|
||||||
[status-im.contexts.onboarding.create-password.view :as create-password]
|
[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-biometrics.view :as enable-biometrics]
|
||||||
[status-im.contexts.onboarding.enable-notifications.view :as enable-notifications]
|
[status-im.contexts.onboarding.enable-notifications.view :as enable-notifications]
|
||||||
[status-im.contexts.onboarding.identifiers.view :as identifiers]
|
[status-im.contexts.onboarding.identifiers.view :as identifiers]
|
||||||
|
@ -728,16 +727,6 @@
|
||||||
:modalPresentationStyle :overCurrentContext}
|
:modalPresentationStyle :overCurrentContext}
|
||||||
:component create-or-sync-profile/sync-or-recover-profile})
|
: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
|
(def onboarding-create-profile-password
|
||||||
{:name :screen/onboarding.create-profile-password
|
{:name :screen/onboarding.create-profile-password
|
||||||
:metrics {:track? true
|
:metrics {:track? true
|
||||||
|
@ -872,7 +861,6 @@
|
||||||
[onboarding-intro
|
[onboarding-intro
|
||||||
onboarding-new-to-status
|
onboarding-new-to-status
|
||||||
onboarding-sync-or-recover-profile
|
onboarding-sync-or-recover-profile
|
||||||
onboarding-create-profile
|
|
||||||
onboarding-create-profile-password
|
onboarding-create-profile-password
|
||||||
onboarding-enable-biometrics
|
onboarding-enable-biometrics
|
||||||
onboarding-preparing-status
|
onboarding-preparing-status
|
||||||
|
|
|
@ -17,11 +17,10 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
|
||||||
def prepare_devices(self):
|
def prepare_devices(self):
|
||||||
self.drivers, self.loop = create_shared_drivers(2)
|
self.drivers, self.loop = create_shared_drivers(2)
|
||||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
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}),
|
||||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True,
|
(self.device_2.create_user,))))
|
||||||
'username': self.username_1}),
|
|
||||||
(self.device_2.create_user, {'username': self.username_2}))))
|
|
||||||
self.homes = 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.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.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.public_key_1 = self.home_1.get_public_key()
|
||||||
self.profile_link_2 = self.home_2.get_link_to_profile()
|
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):
|
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.device_2.just_fyi('Creating a new user on Device2')
|
||||||
self.home_2.reopen_app(sign_in=False)
|
self.home_2.reopen_app(sign_in=False)
|
||||||
new_username = "new user"
|
self.device_2.create_user(first_user=False)
|
||||||
self.device_2.create_user(username=new_username, 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.device_2.just_fyi('Device2 sends a contact request to Device1 via Paste button and check user details')
|
||||||
self.home_2.chats_tab.click()
|
self.home_2.chats_tab.click()
|
||||||
|
@ -159,20 +158,19 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
|
||||||
self.username_2, self.profile_link_2, decoded_username))
|
self.username_2, self.profile_link_2, decoded_username))
|
||||||
public_key_2 = self.profile_link_2.split("#")[-1]
|
public_key_2 = self.profile_link_2.split("#")[-1]
|
||||||
|
|
||||||
new_username_1 = "test user 123"
|
|
||||||
|
|
||||||
def _device_1_creates_user():
|
def _device_1_creates_user():
|
||||||
self.home_1.just_fyi("Device 1 creates a new user")
|
self.home_1.just_fyi("Device 1 creates a new user")
|
||||||
self.home_1.reopen_app(sign_in=False)
|
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():
|
def _device_2_sign_in():
|
||||||
self.home_2.just_fyi("Device 2 sign in, user name is " + self.username_2)
|
self.home_2.just_fyi("Device 2 sign in, user name is " + self.username_2)
|
||||||
self.home_2.reopen_app(sign_in=False)
|
self.home_2.reopen_app(sign_in=False)
|
||||||
self.device_2.sign_in(user_name=self.username_2)
|
self.device_2.sign_in(user_name=self.username_2)
|
||||||
|
|
||||||
self.loop.run_until_complete(run_in_parallel(((_device_1_creates_user, {}),
|
new_username_1, _ = self.loop.run_until_complete(run_in_parallel(((_device_1_creates_user, {}),
|
||||||
(_device_2_sign_in, {}))))
|
(_device_2_sign_in, {}))))
|
||||||
|
|
||||||
self.device_1.just_fyi('Device1 sends a contact request to Device2 using his profile link')
|
self.device_1.just_fyi('Device1 sends a contact request to Device2 using his profile link')
|
||||||
self.home_1.chats_tab.click()
|
self.home_1.chats_tab.click()
|
||||||
|
@ -242,11 +240,11 @@ class TestActivityMultipleDevicePR(MultipleSharedDeviceTestCase):
|
||||||
def prepare_devices(self):
|
def prepare_devices(self):
|
||||||
self.drivers, self.loop = create_shared_drivers(2)
|
self.drivers, self.loop = create_shared_drivers(2)
|
||||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
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(
|
self.loop.run_until_complete(
|
||||||
run_in_parallel(((self.device_1.create_user, {'username': self.username_1}),
|
run_in_parallel(((self.device_1.create_user,),
|
||||||
(self.device_2.create_user, {'username': self.username_2}))))
|
(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.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.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.public_key_2 = self.home_2.get_public_key()
|
||||||
self.home_2.navigate_back_to_home_view()
|
self.home_2.navigate_back_to_home_view()
|
||||||
|
@ -382,11 +380,11 @@ class TestActivityMultipleDevicePRTwo(MultipleSharedDeviceTestCase):
|
||||||
def prepare_devices(self):
|
def prepare_devices(self):
|
||||||
self.drivers, self.loop = create_shared_drivers(2)
|
self.drivers, self.loop = create_shared_drivers(2)
|
||||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
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(
|
self.loop.run_until_complete(
|
||||||
run_in_parallel(((self.device_1.create_user, {'username': self.username_1}),
|
run_in_parallel(((self.device_1.create_user,),
|
||||||
(self.device_2.create_user, {'username': self.username_2}))))
|
(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.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.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.public_key_2 = self.home_2.get_public_key()
|
||||||
self.home_2.navigate_back_to_home_view()
|
self.home_2.navigate_back_to_home_view()
|
||||||
|
|
|
@ -20,13 +20,11 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
|
||||||
self.drivers, self.loop = create_shared_drivers(2)
|
self.drivers, self.loop = create_shared_drivers(2)
|
||||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
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}),
|
||||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True,
|
(self.device_2.create_user, {'enable_notifications': True}))))
|
||||||
'username': self.username_1}),
|
|
||||||
(self.device_2.create_user, {'enable_notifications': True,
|
|
||||||
'username': self.username_2}))))
|
|
||||||
self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
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.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.profile_1, self.profile_2 = (home.get_profile_view() for home in self.homes)
|
||||||
self.public_key_2 = self.home_2.get_public_key()
|
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.drivers, self.loop = create_shared_drivers(2)
|
||||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
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}),
|
||||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True,
|
(self.device_2.create_user, {'enable_notifications': True}))))
|
||||||
'username': self.username_1}),
|
|
||||||
(self.device_2.create_user, {'enable_notifications': True,
|
|
||||||
'username': self.username_2}))))
|
|
||||||
self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
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.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.profile_1, self.profile_2 = (home.get_profile_view() for home in self.homes)
|
||||||
self.public_key_2 = self.home_2.get_public_key()
|
self.public_key_2 = self.home_2.get_public_key()
|
||||||
|
|
||||||
|
|
|
@ -21,17 +21,25 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
|
||||||
self.message_to_admin = 'Hey, admin!'
|
self.message_to_admin = 'Hey, admin!'
|
||||||
self.public_keys, self.usernames, self.chats = {}, {}, {}
|
self.public_keys, self.usernames, self.chats = {}, {}, {}
|
||||||
self.sign_in_views = [SignInView(self.drivers[key]) for key in self.drivers]
|
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(
|
self.loop.run_until_complete(
|
||||||
run_in_parallel(
|
run_in_parallel(
|
||||||
(
|
(
|
||||||
(self.sign_in_views[0].create_user, {'enable_notifications': True, 'username': self.usernames[0]}),
|
(self.sign_in_views[0].create_user, {'enable_notifications': True}),
|
||||||
(self.sign_in_views[1].create_user, {'enable_notifications': True, 'username': self.usernames[1]}),
|
(self.sign_in_views[1].create_user, {'enable_notifications': True}),
|
||||||
(self.sign_in_views[2].create_user, {'enable_notifications': True, 'username': self.usernames[2]})
|
(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.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(
|
self.public_keys = self.loop.run_until_complete(
|
||||||
run_in_parallel(
|
run_in_parallel(
|
||||||
(
|
(
|
||||||
|
|
|
@ -21,9 +21,9 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
|
||||||
def prepare_devices(self):
|
def prepare_devices(self):
|
||||||
self.drivers, self.loop = create_shared_drivers(1)
|
self.drivers, self.loop = create_shared_drivers(1)
|
||||||
self.sign_in = SignInView(self.drivers[0])
|
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.home.communities_tab.click_until_presence_of_element(self.home.plus_community_button)
|
||||||
self.community_name = "closed community"
|
self.community_name = "closed community"
|
||||||
self.channel_name = "cats"
|
self.channel_name = "cats"
|
||||||
|
@ -158,8 +158,8 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
|
||||||
def test_restore_multiaccount_with_waku_backup_remove_profile_switch(self):
|
def test_restore_multiaccount_with_waku_backup_remove_profile_switch(self):
|
||||||
self.home.reopen_app(sign_in=False)
|
self.home.reopen_app(sign_in=False)
|
||||||
self.home.just_fyi("Restore user with predefined communities and contacts")
|
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)
|
||||||
self.sign_in.recover_access(passphrase=waku_user.seed, second_user=True, username=recover_user_name)
|
recover_user_name = self.home.get_username()
|
||||||
|
|
||||||
self.home.just_fyi("Check contacts/blocked users")
|
self.home.just_fyi("Check contacts/blocked users")
|
||||||
self.home.chats_tab.click()
|
self.home.chats_tab.click()
|
||||||
|
@ -306,11 +306,10 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
|
||||||
def prepare_devices(self):
|
def prepare_devices(self):
|
||||||
self.drivers, self.loop = create_shared_drivers(2)
|
self.drivers, self.loop = create_shared_drivers(2)
|
||||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
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}),
|
||||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True,
|
(self.device_2.create_user,))))
|
||||||
'username': self.username_1}),
|
|
||||||
(self.device_2.create_user, {'username': self.username_2}))))
|
|
||||||
self.homes = 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.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.public_key_2 = self.home_2.get_public_key()
|
||||||
self.profile_1 = self.home_1.get_profile_view()
|
self.profile_1 = self.home_1.get_profile_view()
|
||||||
[home.navigate_back_to_home_view() for home in self.homes]
|
[home.navigate_back_to_home_view() for home in self.homes]
|
||||||
|
@ -836,12 +835,10 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
|
||||||
def prepare_devices(self):
|
def prepare_devices(self):
|
||||||
self.drivers, self.loop = create_shared_drivers(2)
|
self.drivers, self.loop = create_shared_drivers(2)
|
||||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
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}),
|
||||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True,
|
(self.device_2.create_user, {'enable_notifications': True}))))
|
||||||
'username': self.username_1}),
|
|
||||||
(self.device_2.create_user, {'enable_notifications': True,
|
|
||||||
'username': self.username_2}))))
|
|
||||||
self.homes = 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.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.public_key_2 = self.home_2.get_public_key()
|
||||||
self.profile_1 = self.home_1.get_profile_view()
|
self.profile_1 = self.home_1.get_profile_view()
|
||||||
[home.navigate_back_to_home_view() for home in self.homes]
|
[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.drivers, self.loop = create_shared_drivers(1)
|
||||||
self.driver = self.drivers[0]
|
self.driver = self.drivers[0]
|
||||||
self.sign_in = SignInView(self.driver)
|
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.home.communities_tab.click_until_presence_of_element(self.home.plus_community_button)
|
||||||
self.open_community_name = "open community"
|
self.open_community_name = "open community"
|
||||||
self.channel_name = "general"
|
self.channel_name = "general"
|
||||||
|
|
|
@ -20,10 +20,10 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
|
||||||
self.sign_in_3.get_home_view()
|
self.sign_in_3.get_home_view()
|
||||||
self.sign_in_1.just_fyi("Device 1: create a new user")
|
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.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(
|
self.loop.run_until_complete(
|
||||||
run_in_parallel(((self.sign_in_1.create_user, {'username': self.user_name_1}),
|
run_in_parallel(((self.sign_in_1.create_user,),
|
||||||
(self.sign_in_3.create_user, {'username': self.user_name_3}))))
|
(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_1 = self.home_1.profile_button.click()
|
||||||
self.profile_2 = self.home_2.get_profile_view()
|
self.profile_2 = self.home_2.get_profile_view()
|
||||||
self.sign_in_3.just_fyi("Device 3: get public key")
|
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, self.receiver = transaction_senders['ETH_1'], transaction_senders['ETH_2']
|
||||||
self.sender['wallet_address'] = '0x' + self.sender['address']
|
self.sender['wallet_address'] = '0x' + self.sender['address']
|
||||||
self.receiver['wallet_address'] = '0x' + self.receiver['address']
|
self.receiver['wallet_address'] = '0x' + self.receiver['address']
|
||||||
self.sender_username, self.receiver_username = 'sender', 'receiver'
|
|
||||||
self.loop.run_until_complete(
|
self.loop.run_until_complete(
|
||||||
run_in_parallel(((self.sign_in_1.recover_access, {'passphrase': self.sender['passphrase'],
|
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']}))))
|
||||||
(self.sign_in_2.recover_access, {'passphrase': self.receiver['passphrase'],
|
|
||||||
'username': self.receiver_username}))))
|
|
||||||
self.home_1, self.home_2 = self.sign_in_1.get_home_view(), self.sign_in_2.get_home_view()
|
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, 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_1.wallet_tab.click()
|
||||||
self.wallet_2.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.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.sender['wallet_address'] = '0x' + self.sender['address']
|
||||||
self.receiver['wallet_address'] = '0x' + self.receiver['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'])
|
||||||
self.sign_in_view.recover_access(passphrase=self.sender['passphrase'], username=self.sender_username)
|
|
||||||
|
|
||||||
self.home_view = self.sign_in_view.get_home_view()
|
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()
|
self.wallet_view = self.home_view.wallet_tab.click()
|
||||||
|
|
||||||
@marks.testrail_id(740490)
|
@marks.testrail_id(740490)
|
||||||
|
|
|
@ -624,3 +624,11 @@ class HomeView(BaseView):
|
||||||
element = Text(self.driver, accessibility_id='new-device-installation-id')
|
element = Text(self.driver, accessibility_id='new-device-installation-id')
|
||||||
element.wait_for_visibility_of_element()
|
element.wait_for_visibility_of_element()
|
||||||
return element.text
|
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
|
# Header
|
||||||
self.public_key_text = Text(self.driver, accessibility_id="chat-key")
|
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.contact_name_text = Text(self.driver, accessibility_id="contact-name")
|
||||||
self.share_my_profile_button = Button(self.driver, accessibility_id="share-header-button")
|
self.share_my_profile_button = Button(self.driver, accessibility_id="share-header-button")
|
||||||
self.profile_picture = ProfilePictureElement(self.driver)
|
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_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_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_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.enable_biometric_maybe_later_button = Button(self.driver, translation_id="maybe-later")
|
||||||
self.identifiers_button = Button(self.driver, accessibility_id="skip-identifiers")
|
self.identifiers_button = Button(self.driver, accessibility_id="skip-identifiers")
|
||||||
self.start_button = Button(self.driver, accessibility_id="welcome-button")
|
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[0].send_keys(password)
|
||||||
input_elements[1].click()
|
input_elements[1].click()
|
||||||
input_elements[1].send_keys(password)
|
input_elements[1].send_keys(password)
|
||||||
self.checkbox_button.scroll_to_element()
|
|
||||||
self.checkbox_button.click()
|
|
||||||
self.profile_confirm_password_button.click()
|
self.profile_confirm_password_button.click()
|
||||||
|
|
||||||
def set_profile(self, username: str, set_image=False):
|
def set_profile(self, username: str, set_image=False):
|
||||||
|
@ -238,7 +236,7 @@ class SignInView(BaseView):
|
||||||
if set_image:
|
if set_image:
|
||||||
pass
|
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)
|
self.driver.info("## Creating new multiaccount with password:'%s'" % password, device=False)
|
||||||
if first_user:
|
if first_user:
|
||||||
self.create_profile_button.click_until_presence_of_element(self.start_fresh_lets_go_button)
|
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.plus_profiles_button.click()
|
||||||
self.create_new_profile_button.click()
|
self.create_new_profile_button.click()
|
||||||
self.start_fresh_lets_go_button.click_until_presence_of_element(self.profile_title_input)
|
self.start_fresh_lets_go_button.click_until_presence_of_element(self.profile_title_input)
|
||||||
self.set_profile(username)
|
|
||||||
self.set_password(password)
|
self.set_password(password)
|
||||||
self.chats_tab.wait_for_visibility_of_element(30)
|
self.chats_tab.wait_for_visibility_of_element(30)
|
||||||
self.driver.info("## New multiaccount is created successfully!", device=False)
|
self.driver.info("## New multiaccount is created successfully!", device=False)
|
||||||
|
@ -261,7 +258,7 @@ class SignInView(BaseView):
|
||||||
return home_view
|
return home_view
|
||||||
|
|
||||||
def recover_access(self, passphrase: str, password: str = common_password, enable_notifications=False,
|
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)
|
self.driver.info("## Recover access (password:%s)" % password, device=False)
|
||||||
|
|
||||||
if not after_sync_code:
|
if not after_sync_code:
|
||||||
|
@ -274,8 +271,6 @@ class SignInView(BaseView):
|
||||||
self.use_recovery_phrase_button.click()
|
self.use_recovery_phrase_button.click()
|
||||||
self.passphrase_edit_box.send_keys(passphrase)
|
self.passphrase_edit_box.send_keys(passphrase)
|
||||||
self.continue_button.click_until_presence_of_element(self.profile_title_input)
|
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.set_password(password)
|
||||||
self.chats_tab.wait_for_visibility_of_element(30)
|
self.chats_tab.wait_for_visibility_of_element(30)
|
||||||
self.driver.info("## Multiaccount is recovered successfully!", device=False)
|
self.driver.info("## Multiaccount is recovered successfully!", device=False)
|
||||||
|
|
|
@ -1930,7 +1930,7 @@
|
||||||
"password-creation-max-length-hint": "Maximum 100 characters",
|
"password-creation-max-length-hint": "Maximum 100 characters",
|
||||||
"password-creation-placeholder-1": "Type password",
|
"password-creation-placeholder-1": "Type password",
|
||||||
"password-creation-placeholder-2": "Repeat 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-1": "Lower case",
|
||||||
"password-creation-tips-2": "Upper case",
|
"password-creation-tips-2": "Upper case",
|
||||||
"password-creation-tips-3": "Numbers",
|
"password-creation-tips-3": "Numbers",
|
||||||
|
|
Loading…
Reference in New Issue