Onboarding screens (#17165)
* Broken back navigation on "Create profile" screen #17155 Onboarding screens layout is broken #17152 Onboarding Flow - Layout issues in enable biometrics screen #17151 Onboarding navigation issues #17129
This commit is contained in:
parent
7ca17e537e
commit
a1babada69
|
@ -2,14 +2,10 @@
|
|||
|
||||
(defn container
|
||||
[container-style]
|
||||
(merge
|
||||
{:flex 1
|
||||
:margin-horizontal 20}
|
||||
container-style))
|
||||
(assoc container-style :margin-horizontal 20))
|
||||
|
||||
(def title-container
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
{:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(def avatar-container
|
||||
|
|
|
@ -34,8 +34,7 @@
|
|||
|
||||
(defn f-video
|
||||
[{:keys [layers disable-parallax? offset stretch container-style enable-looping?]
|
||||
:or {offset 50
|
||||
stretch 0}}]
|
||||
:or {offset 50 stretch 0}}]
|
||||
[rn/view
|
||||
{:style (style/outer-container container-style)}
|
||||
(map-indexed (fn [idx layer]
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
(ns status-im2.contexts.onboarding.common.overlay.events
|
||||
(:require [utils.re-frame :as rf]
|
||||
[status-im2.contexts.onboarding.common.overlay.view :as overlay]
|
||||
[status-im2.contexts.profile.profiles.view :as profiles]
|
||||
[re-frame.core :as re-frame]))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:onboarding/overlay-dismiss-fx
|
||||
(fn []
|
||||
(when-let [blur-dismiss-fn @overlay/blur-dismiss-fn-atom]
|
||||
(blur-dismiss-fn))
|
||||
(when-let [pop-animation-fn @profiles/pop-animation-fn-atom]
|
||||
(pop-animation-fn))))
|
||||
|
||||
(rf/defn overlay-dismiss
|
||||
{:events [:onboarding/overlay-dismiss]}
|
||||
[_]
|
||||
{:onboarding/overlay-dismiss-fx nil})
|
|
@ -35,19 +35,23 @@
|
|||
0
|
||||
(/ constants/onboarding-modal-animation-duration 2)
|
||||
(/ constants/onboarding-modal-animation-duration 2))
|
||||
(js/clearInterval @timer-interval)
|
||||
(reset! timer-interval
|
||||
(js/setInterval
|
||||
(fn []
|
||||
(if (> @blur-amount 0)
|
||||
(swap! blur-amount - 1)
|
||||
(swap! blur-amount dec)
|
||||
(js/clearInterval @timer-interval)))
|
||||
(/ constants/onboarding-modal-animation-duration
|
||||
max-blur-amount
|
||||
2))))
|
||||
|
||||
;; we had to register it here, because of hotreload, overwise on hotreload it will be reseted
|
||||
(defonce blur-amount (reagent/atom 0))
|
||||
|
||||
(defn f-view
|
||||
[blur-amount]
|
||||
(let [opacity (reanimated/use-shared-value 0)
|
||||
[]
|
||||
(let [opacity (reanimated/use-shared-value (if (zero? @blur-amount) 0 1))
|
||||
blur-show-fn #(blur-show opacity blur-amount)
|
||||
blur-dismiss-fn #(blur-dismiss opacity blur-amount)]
|
||||
(rn/use-effect
|
||||
|
@ -69,5 +73,4 @@
|
|||
|
||||
(defn view
|
||||
[]
|
||||
(let [blur-amount (reagent/atom 0)]
|
||||
[:f> f-view blur-amount]))
|
||||
[:f> f-view])
|
||||
|
|
|
@ -136,7 +136,7 @@
|
|||
{:margin-top navigation-bar-top
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press #(rf/dispatch [:navigate-back])}]
|
||||
:on-press #(rf/dispatch [:navigate-back-within-stack :new-to-status])}]
|
||||
[rn/scroll-view
|
||||
{:on-layout (fn [event]
|
||||
(let [height (oops/oget event "nativeEvent.layout.height")]
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
[insets]
|
||||
{:flex 1
|
||||
:justify-content :space-between
|
||||
:padding-top (:top insets)})
|
||||
:padding-top (+ (:top insets) 56)})
|
||||
|
||||
(defn page-illustration
|
||||
[width]
|
||||
|
|
|
@ -43,31 +43,23 @@
|
|||
(defn enable-biometrics-parallax
|
||||
[]
|
||||
(let [stretch (if rn/small-screen? 25 40)]
|
||||
[:<>
|
||||
[parallax/video
|
||||
{:layers (:biometrics resources/parallax-video)
|
||||
:stretch stretch}]
|
||||
[rn/view
|
||||
[quo/page-nav {:background :blur}]
|
||||
[page-title]]]))
|
||||
[parallax/video
|
||||
{:layers (:biometrics resources/parallax-video)
|
||||
:stretch stretch}]))
|
||||
|
||||
(defn enable-biometrics-simple
|
||||
[]
|
||||
(let [width (:width (rn/get-window))]
|
||||
[:<>
|
||||
[rn/view {:flex 1}
|
||||
[quo/page-nav {:background :blur}]
|
||||
[page-title]
|
||||
[rn/view {:style {:flex 1}}
|
||||
[rn/image
|
||||
{:resize-mode :contain
|
||||
:style (style/page-illustration width)
|
||||
:source (resources/get-image :biometrics)}]]]]))
|
||||
[rn/image
|
||||
{:resize-mode :contain
|
||||
:style (style/page-illustration width)
|
||||
:source (resources/get-image :biometrics)}]))
|
||||
|
||||
(defn enable-biometrics
|
||||
[]
|
||||
(let [insets (safe-area/get-insets)]
|
||||
[rn/view {:style (style/page-container insets)}
|
||||
[page-title]
|
||||
(if whitelist/whitelisted?
|
||||
[enable-biometrics-parallax]
|
||||
[enable-biometrics-simple])
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
[quo/page-nav
|
||||
{:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press #(rf/dispatch [:navigate-back-within-stack :identifiers])}]
|
||||
:on-press #(rf/dispatch [:navigate-back-within-stack :new-to-status])}]
|
||||
[page-title]
|
||||
[rn/view {:style style/page-illustration}
|
||||
[quo/text
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
:animated-heading (i18n/label :t/sign-in-by-syncing)
|
||||
:accessibility-label :already-use-status-button}
|
||||
:bottom-card {:on-press (fn []
|
||||
(when @overlay/blur-show-fn-atom
|
||||
(@overlay/blur-show-fn-atom))
|
||||
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
||||
(blur-show-fn))
|
||||
(rf/dispatch [:open-modal :new-to-status]))
|
||||
:heading (i18n/label :t/new-to-status)
|
||||
:accessibility-label :new-to-status-button}}
|
||||
|
|
|
@ -8,17 +8,8 @@
|
|||
[status-im2.contexts.onboarding.new-to-status.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.contexts.onboarding.common.overlay.view :as overlay]
|
||||
[status-im2.contexts.profile.profiles.view :as profiles]
|
||||
[status-im2.config :as config]))
|
||||
|
||||
(defn navigate-back
|
||||
[]
|
||||
(when @overlay/blur-dismiss-fn-atom
|
||||
(@overlay/blur-dismiss-fn-atom))
|
||||
(when @profiles/pop-animation-fn-atom
|
||||
(@profiles/pop-animation-fn-atom))
|
||||
(rf/dispatch [:dismiss-modal :new-to-status]))
|
||||
[status-im2.config :as config]
|
||||
re-frame.db))
|
||||
|
||||
(defn sign-in-options
|
||||
[]
|
||||
|
@ -107,7 +98,9 @@
|
|||
:type :no-title
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press navigate-back
|
||||
:on-press #(do
|
||||
(rf/dispatch [:onboarding/overlay-dismiss])
|
||||
(rf/dispatch [:navigate-back]))
|
||||
:right-side [{:icon-name :i/info
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content getting-started-doc
|
||||
|
|
|
@ -3,11 +3,6 @@
|
|||
[status-im2.contexts.onboarding.common.background.view :as background]
|
||||
[status-im2.contexts.syncing.scan-sync-code.view :as scan-sync-code]))
|
||||
|
||||
(defn navigate-back
|
||||
[]
|
||||
(when @scan-sync-code/navigate-back-fn
|
||||
(@scan-sync-code/navigate-back-fn)))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
[scan-sync-code/view
|
||||
|
|
|
@ -20,10 +20,13 @@
|
|||
|
||||
(defonce push-animation-fn-atom (atom nil))
|
||||
(defonce pop-animation-fn-atom (atom nil))
|
||||
;; we need this for hotreload, overwise on hotreload translate-x will be reseted
|
||||
(defonce translate-x-atom (atom 0))
|
||||
|
||||
(defn push-animation
|
||||
[translate-x]
|
||||
(let [window-width (:width (rn/get-window))]
|
||||
(reset! translate-x-atom (- window-width))
|
||||
(reanimated/animate-shared-value-with-delay translate-x
|
||||
(- window-width)
|
||||
constants/onboarding-modal-animation-duration
|
||||
|
@ -32,6 +35,7 @@
|
|||
|
||||
(defn pop-animation
|
||||
[translate-x]
|
||||
(reset! translate-x-atom 0)
|
||||
(reanimated/animate-shared-value-with-delay translate-x
|
||||
0
|
||||
constants/onboarding-modal-animation-duration
|
||||
|
@ -126,7 +130,7 @@
|
|||
(defn- f-profiles-section
|
||||
[{:keys [set-hide-profiles]}]
|
||||
(let [profiles (vals (rf/sub [:profile/profiles-overview]))
|
||||
translate-x (reanimated/use-shared-value 0)]
|
||||
translate-x (reanimated/use-shared-value @translate-x-atom)]
|
||||
(rn/use-effect (fn []
|
||||
(reset! push-animation-fn-atom #(push-animation translate-x))
|
||||
(reset! pop-animation-fn-atom #(pop-animation translate-x))
|
||||
|
@ -305,10 +309,12 @@
|
|||
:container-style {:margin-bottom (+ (safe-area/get-bottom) 12)}}
|
||||
(i18n/label :t/log-in)]]))
|
||||
|
||||
;; we had to register it here, because of hotreload, overwise on hotreload it will be reseted
|
||||
(defonce show-profiles? (reagent/atom false))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [show-profiles? (reagent/atom false)
|
||||
set-show-profiles #(reset! show-profiles? true)
|
||||
(let [set-show-profiles #(reset! show-profiles? true)
|
||||
set-hide-profiles #(reset! show-profiles? false)]
|
||||
(fn []
|
||||
[:<>
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
[status-im2.contexts.syncing.scan-sync-code.animation :as animation]
|
||||
[status-im2.contexts.syncing.scan-sync-code.style :as style]
|
||||
[status-im2.contexts.syncing.utils :as sync-utils]
|
||||
[status-im2.navigation.util :as navigation.util]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
|
@ -28,7 +27,6 @@
|
|||
|
||||
(defonce camera-permission-granted? (reagent/atom false))
|
||||
(defonce dismiss-animations (atom nil))
|
||||
(defonce navigate-back-fn (atom nil))
|
||||
|
||||
(defn perform-preflight-check
|
||||
"Performing the check for the first time
|
||||
|
@ -290,6 +288,7 @@
|
|||
(defn f-view
|
||||
[_]
|
||||
(let [insets (safe-area/get-insets)
|
||||
qr-code-succeed? (reagent/atom false)
|
||||
active-tab (reagent/atom 1)
|
||||
qr-view-finder (reagent/atom {})
|
||||
render-camera? (reagent/atom false)
|
||||
|
@ -298,8 +297,7 @@
|
|||
set-rescan-timeout (fn []
|
||||
(reset! scan-code? false)
|
||||
(js/setTimeout #(reset! scan-code? true) 3000))]
|
||||
(fn [{:keys [title show-bottom-view? background animated? qr-code-succeed?
|
||||
set-qr-code-succeeded]}]
|
||||
(fn [{:keys [title show-bottom-view? background animated?]}]
|
||||
(let [torch-mode (if @torch? :on :off)
|
||||
flashlight-icon (if @torch? :i/flashlight-on :i/flashlight-off)
|
||||
scan-qr-code-tab? (= @active-tab 1)
|
||||
|
@ -309,7 +307,7 @@
|
|||
(boolean (not-empty @qr-view-finder)))
|
||||
camera-ready-to-scan? (and (or (not animated?) @render-camera?)
|
||||
show-camera?
|
||||
(not qr-code-succeed?))
|
||||
(not @qr-code-succeed?))
|
||||
title-opacity (reanimated/use-shared-value (if animated? 0 1))
|
||||
subtitle-opacity (reanimated/use-shared-value (if animated? 0 1))
|
||||
content-opacity (reanimated/use-shared-value (if animated? 0 1))
|
||||
|
@ -322,10 +320,16 @@
|
|||
:content-opacity content-opacity
|
||||
:subtitle-opacity subtitle-opacity
|
||||
:title-opacity title-opacity})]
|
||||
|
||||
(rn/use-effect
|
||||
#(set-listener-torch-off-on-app-inactive torch?))
|
||||
|
||||
(when animated?
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(rn/hw-back-add-listener reset-animations-fn)
|
||||
#(rn/hw-back-remove-listener reset-animations-fn))
|
||||
[])
|
||||
(animation/animate-subtitle subtitle-opacity)
|
||||
(animation/animate-title title-opacity)
|
||||
(animation/animate-bottom bottom-view-translate-y))
|
||||
|
@ -337,8 +341,7 @@
|
|||
(js/setTimeout #(reset! render-camera? true)
|
||||
(+ constants/onboarding-modal-animation-duration
|
||||
constants/onboarding-modal-animation-delay
|
||||
300))
|
||||
(reset! navigate-back-fn reset-animations-fn))
|
||||
300)))
|
||||
(when-not @camera-permission-granted?
|
||||
(permissions/permission-granted? :camera
|
||||
#(reset! camera-permission-granted? %)
|
||||
|
@ -350,7 +353,7 @@
|
|||
{:torch-mode torch-mode
|
||||
:qr-view-finder @qr-view-finder
|
||||
:scan-code? @scan-code?
|
||||
:set-qr-code-succeeded set-qr-code-succeeded
|
||||
:set-qr-code-succeeded #(reset! qr-code-succeed? true)
|
||||
:set-rescan-timeout set-rescan-timeout}])
|
||||
[rn/view {:style (style/root-container (:top insets))}
|
||||
[:f> header
|
||||
|
@ -389,14 +392,5 @@
|
|||
flashlight-icon])]]))))
|
||||
|
||||
(defn view
|
||||
[{:keys [screen-name] :as _props}]
|
||||
(let [qr-code-succeed? (reagent/atom false)]
|
||||
(navigation.util/create-class-and-bind
|
||||
screen-name
|
||||
{:component-did-appear (fn set-qr-code-failed [_this]
|
||||
(reset! qr-code-succeed? false))}
|
||||
(fn [props]
|
||||
(let [new-pops (assoc props
|
||||
:qr-code-succeed? @qr-code-succeed?
|
||||
:set-qr-code-succeeded #(reset! qr-code-succeed? true))]
|
||||
[:f> f-view new-pops])))))
|
||||
[props]
|
||||
[:f> f-view props])
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
status-im2.contexts.profile.events
|
||||
status-im2.contexts.shell.share.events
|
||||
status-im2.contexts.syncing.events
|
||||
status-im2.contexts.onboarding.common.overlay.events
|
||||
[status-im2.db :as db]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
|
|
|
@ -48,8 +48,12 @@
|
|||
(navigation/reg-component-did-appear-listener
|
||||
(fn [view-id]
|
||||
(when (get views/screens view-id)
|
||||
(set-view-id view-id)
|
||||
;;NOTE when back from the background on Android, this event happens for all screens, but we need
|
||||
;;only for active one
|
||||
(when (and @state/curr-modal (= @state/curr-modal view-id))
|
||||
(set-view-id view-id))
|
||||
(when-not @state/curr-modal
|
||||
(set-view-id view-id)
|
||||
(reset! state/pushed-screen-id view-id)))))
|
||||
|
||||
(defn dissmissModal
|
||||
|
@ -167,18 +171,11 @@
|
|||
|
||||
(navigation/reg-button-pressed-listener
|
||||
(fn [id]
|
||||
(cond
|
||||
(= "dismiss-modal" id)
|
||||
(if (= "dismiss-modal" id)
|
||||
(do
|
||||
(when-let [event (get-in views/screens [(last @state/modals) :on-dissmiss])]
|
||||
(re-frame/dispatch event))
|
||||
(dissmissModal))
|
||||
(= "RNN.hardwareBackButton" id)
|
||||
(when-let [handler (get-in views/screens
|
||||
[(or (last @state/modals) @state/pushed-screen-id)
|
||||
:hardware-back-button-handler])]
|
||||
(handler))
|
||||
:else
|
||||
(when-let [handler (get-in views/screens [(keyword id) :right-handler])]
|
||||
(handler)))))
|
||||
|
||||
|
|
|
@ -118,25 +118,24 @@
|
|||
;; Onboarding
|
||||
{:name :intro
|
||||
:options {:theme :dark}
|
||||
:on-focus [:onboarding/overlay-dismiss]
|
||||
:component intro/view}
|
||||
|
||||
{:name :profiles
|
||||
:options {:theme :dark
|
||||
:layout options/onboarding-layout}
|
||||
:on-focus [:onboarding/overlay-dismiss]
|
||||
:component profiles/view}
|
||||
|
||||
{:name :new-to-status
|
||||
:options {:theme :dark
|
||||
:layout options/onboarding-transparent-layout
|
||||
:animations (merge
|
||||
transitions/new-to-status-modal-animations
|
||||
transitions/push-animations-for-transparent-background)
|
||||
:popGesture false
|
||||
:modalPresentationStyle :overCurrentContext
|
||||
:hardwareBackButton {:dismissModalOnPress false
|
||||
:popStackOnPress false}}
|
||||
:hardware-back-button-handler new-to-status/navigate-back
|
||||
:component new-to-status/new-to-status}
|
||||
{:name :new-to-status
|
||||
:options {:theme :dark
|
||||
:layout options/onboarding-transparent-layout
|
||||
:animations (merge
|
||||
transitions/new-to-status-modal-animations
|
||||
transitions/push-animations-for-transparent-background)
|
||||
:popGesture false
|
||||
:modalPresentationStyle :overCurrentContext}
|
||||
:component new-to-status/new-to-status}
|
||||
|
||||
{:name :create-profile
|
||||
:options {:theme :dark
|
||||
|
@ -181,10 +180,7 @@
|
|||
:layout options/onboarding-transparent-layout
|
||||
:animations (merge transitions/new-to-status-modal-animations
|
||||
transitions/push-animations-for-transparent-background)
|
||||
:modalPresentationStyle :overCurrentContext
|
||||
:popGesture false
|
||||
:hardwareBackButton {:dismissModalOnPress false
|
||||
:popStackOnPress false}}
|
||||
:modalPresentationStyle :overCurrentContext}
|
||||
:component enable-notifications/enable-notifications}
|
||||
|
||||
{:name :identifiers
|
||||
|
@ -200,16 +196,13 @@
|
|||
:options options/dark-screen
|
||||
:component scan-sync-code-page/view}
|
||||
|
||||
{:name :sign-in-intro
|
||||
:options {:layout options/onboarding-transparent-layout
|
||||
:animations (merge
|
||||
transitions/sign-in-modal-animations
|
||||
transitions/push-animations-for-transparent-background)
|
||||
:modalPresentationStyle :overCurrentContext
|
||||
:hardwareBackButton {:dismissModalOnPress false
|
||||
:popStackOnPress false}}
|
||||
:hardware-back-button-handler sign-in/navigate-back
|
||||
:component sign-in/animated-view}
|
||||
{:name :sign-in-intro
|
||||
:options {:layout options/onboarding-transparent-layout
|
||||
:animations (merge
|
||||
transitions/sign-in-modal-animations
|
||||
transitions/push-animations-for-transparent-background)
|
||||
:modalPresentationStyle :overCurrentContext}
|
||||
:component sign-in/animated-view}
|
||||
|
||||
{:name :sign-in
|
||||
:options {:theme :dark
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
(ns status-im2.navigation.util
|
||||
(:require [react-native.navigation :as navigation]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn create-class-and-bind
|
||||
"Creates a React class that allows the use of life-cycle methods added by
|
||||
react-native-navigation:
|
||||
- componentWillAppear
|
||||
- componentDidAppear
|
||||
- componentDidDisappear
|
||||
Receives:
|
||||
- `component-id` - The component-id to subscribe registered in navigation
|
||||
- `react-methods` - A map of React methods (kebab-case) -> function handler
|
||||
- `reagent-render` - A regular reagent function that returns hiccup.
|
||||
Example:
|
||||
(defn view
|
||||
[props & children]
|
||||
;; Bindings executed when component is created
|
||||
(let [qr-code-succeed? (reagent/atom false)]
|
||||
(create-class-and-bind
|
||||
\"sign-in-intro\" ; navigation component-id of the screen to subscribe
|
||||
{:component-did-appear (fn [this]
|
||||
;; Executed when component appeared to the screen
|
||||
)
|
||||
:component-will-appear (fn [this]
|
||||
;; Executed when component will be shown to the screen
|
||||
)
|
||||
:component-did-disappear (fn [this]
|
||||
;; Executed when component disappeared from the screen
|
||||
)}
|
||||
(fn [props & children] ; Must be the same signature as this `view` function
|
||||
;; Regular component call, e.g.:
|
||||
[rn/view {:style {:padding-top 10}}
|
||||
[:f> my-f-component-call (assoc props :on-press identity)]
|
||||
children]))))
|
||||
"
|
||||
[component-id react-methods reagent-render]
|
||||
(reagent/create-class
|
||||
(assoc react-methods
|
||||
:display-name (str component-id "-view")
|
||||
:component-did-mount #(navigation/bind-component % component-id)
|
||||
:reagent-render reagent-render)))
|
Loading…
Reference in New Issue