sync devices after sign in

* onboarding sync devices after scan to sign in

* using subscription to get the status of pairing progress

* update following reviews

* polished code following reviews

* fixed showing unknown devices
This commit is contained in:
John Ngei 2023-05-19 19:17:38 +03:00 committed by GitHub
parent 694591ad5c
commit d3b4f60848
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 299 additions and 112 deletions

View File

@ -11,7 +11,6 @@
[status-im2.contexts.chat.messages.link-preview.events :as link-preview]
[taoensso.timbre :as log]
[status-im2.constants :as constants]
[quo2.foundations.colors :as colors]
[status-im.multiaccounts.model :as multiaccounts.model]))
(rf/defn status-node-started
@ -33,7 +32,7 @@
;; in case of an unknown error we show the
;; error
(if (= error "file is not a database")
(i18n/label :t/oops-wrong-password)
(i18n/label :t/wrong-password)
error)))}
(= (:view-id db) :progress)
(assoc :dispatch [:navigate-to :login]))
@ -73,25 +72,18 @@
;; since `connection-success` event is received on both sender and receiver devices
;; we check the `logged-in?` status to identify the receiver and take the user to next screen
navigate-to-syncing-devices? (and connection-success? (not logged-in?))
user-in-syncing-devices-screen? (= (:view-id db) :syncing-devices)]
user-in-syncing-devices-screen? (= (:view-id db) :syncing-progress)]
(merge {:db (cond-> db
connection-success?
(assoc-in [:syncing :pairing-in-progress?] true)
(assoc-in [:syncing :pairing-in-progress?] :connected)
error-on-pairing?
(update-in [:syncing :pairing-in-progress?] dissoc)
(assoc-in [:syncing :pairing-in-progress?] :error)
completed-pairing?
(assoc-in [:syncing :pairing-in-progress?] false))}
(when navigate-to-syncing-devices?
{:dispatch [:navigate-to :syncing-devices]})
(when (and error-on-pairing? user-in-syncing-devices-screen?)
{:dispatch-n [[:toasts/upsert
{:icon :i/info
:icon-color colors/danger-50
:override-theme :light
:text (i18n/label :t/error-syncing-connection-failed)}]
[:navigate-back]]})
(assoc-in [:syncing :pairing-in-progress?] :completed))}
(when (and navigate-to-syncing-devices? (not user-in-syncing-devices-screen?))
{:dispatch [:navigate-to :syncing-progress]})
(when completed-pairing?
{:dispatch [:syncing/pairing-completed]}))))

View File

@ -0,0 +1,29 @@
(ns status-im2.common.syncing.style
(:require [quo2.foundations.colors :as colors]))
(def device-container
{:padding-top 12
:padding-horizontal 12
:padding-bottom 16
:border-color colors/white-opa-5
:border-radius 16
:border-width 1
:margin-bottom 24})
(def device-container-orientation
{:flex-direction :row})
(def icon-container
{:height 20
:margin-right 12})
(def tag-container
{:margin-top 8})
(def render-device-status
{:background-color colors/success-60
:align-self :center
:width 8
:height 8
:border-radius 4
:margin-right 6})

View File

@ -0,0 +1,51 @@
(ns status-im2.common.syncing.view
[:require
[quo2.core :as quo]
[utils.i18n :as i18n]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[status-im2.common.not-implemented :as not-implemented]
[status-im2.common.syncing.style :as style]])
;; TODO replace with section list component
;; https://github.com/status-im/status-mobile/issues/15665
(defn view
[{:keys [name
this-device?
device-type]}]
[rn/view {:style style/device-container}
[rn/view {:style style/device-container-orientation}
[rn/view {:style style/icon-container}
[quo/icon
(if (= device-type :mobile) :i/mobile :i/desktop)
{:color colors/white}]]
[rn/view
[quo/text
{:accessibility-label :device-name
:weight :medium
:size :paragraph-1
:style {:color colors/white}}
name]
(when this-device?
[not-implemented/not-implemented
[quo/text
{:accessibility-label :next-back-up
:size :paragraph-2
:style {:color colors/white-opa-40}}
"Next backup in 04:36:12"]])
(when this-device?
[rn/view {:style style/tag-container}
[quo/status-tag
{:size :small
:status {:type :positive}
:no-icon? true
:label (i18n/label :t/this-device)
:override-theme :dark}]])
(when-not this-device?
[rn/view {:style {:flex-direction :row}}
[rn/view style/render-device-status]
[quo/text
{:accessibility-label :next-back-up
:size :paragraph-2
:style {:color colors/white-opa-40}}
(i18n/label :t/online-now)]])]]])

View File

@ -0,0 +1,25 @@
(ns status-im2.contexts.onboarding.syncing.progress.style
(:require [quo2.foundations.colors :as colors]))
(def page-container
{:flex 1
:position :absolute
:top 0
:bottom 0
:left 0
:right 0
:padding-bottom 20
:background-color colors/neutral-80-opa-80-blur})
(def page-illustration
{:flex 1
:background-color colors/danger-50
:align-items :center
:margin-horizontal 20
:border-radius 20
:margin-top 20
:justify-content :center})
(def try-again-button
{:margin-top 20
:padding-horizontal 20})

View File

@ -0,0 +1,54 @@
(ns status-im2.contexts.onboarding.syncing.progress.view
(:require [quo2.core :as quo]
[utils.i18n :as i18n]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[utils.re-frame :as rf]
[status-im2.contexts.onboarding.syncing.progress.style :as style]
[status-im2.contexts.onboarding.common.background.view :as background]))
(defn pairing-progress
[status]
(cond
(= status :error)
false
:else
true))
(defn page-title
[pairing-progress?]
[quo/title
{:title (i18n/label (if pairing-progress?
:t/sync-devices-title
:t/sync-devices-error-title))
:subtitle (i18n/label (if pairing-progress?
:t/sync-devices-sub-title
:t/sync-devices-error-sub-title))
:title-accessibility-label :progress-screen-title
:subtitle-accessibility-label :progress-screen-sub-title}])
(defn try-again-button
[profile-color]
[quo/button
{:on-press #(rf/dispatch [:navigate-back])
:accessibility-label :try-again-later-button
:override-background-color (colors/custom-color profile-color 60)
:style style/try-again-button}
(i18n/label :t/try-again)])
(defn view
[]
(let [pairing-status (rf/sub [:pairing/pairing-in-progress])
profile-color (:color (rf/sub [:onboarding-2/profile]))]
[rn/view {:style style/page-container}
[background/view true]
[quo/page-nav]
[page-title (pairing-progress pairing-status)]
(if (pairing-progress pairing-status)
[rn/view {:style style/page-illustration}
[quo/text "[Success here]"]]
[rn/view {:style style/page-illustration}
[quo/text "[Error here]"]])
(when-not (pairing-progress pairing-status)
[try-again-button profile-color])]))

View File

@ -0,0 +1,24 @@
(ns status-im2.contexts.onboarding.syncing.results.style
(:require [quo2.foundations.colors :as colors]))
(def page-container
{:flex 1
:position :absolute
:top 0
:bottom 0
:left 0
:right 0
:padding-bottom 20
:background-color colors/neutral-80-opa-80-blur})
(def current-device
{:flex 1})
(def device-list
{:flex 1
:margin-top 24
:padding-horizontal 20})
(def continue-button
{:margin-top 20
:padding-horizontal 20})

View File

@ -0,0 +1,60 @@
(ns status-im2.contexts.onboarding.syncing.results.view
(:require [quo2.core :as quo]
[utils.i18n :as i18n]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[utils.re-frame :as rf]
[status-im2.contexts.onboarding.syncing.results.style :as style]
[status-im2.common.syncing.view :as device]
[status-im2.contexts.onboarding.common.background.view :as background]))
(defn page-title
[]
[quo/title
{:title (i18n/label :t/sync-devices-complete-title)
:title-accessibility-label :sync-devices-title
:subtitle (i18n/label :t/sync-devices-complete-sub-title)
:subtitle-accessibility-label :sync-devices-complete-sub-title}])
(defn current-device
[installation]
[rn/view {:style style/current-device}
[device/view
(merge installation
{:this-device? true})]
[quo/text
{:accessibility-label :sync-with-sub-title
:weight :regular
:size :paragraph-1
:style {:color colors/white}}
(i18n/label :t/sync-with)]])
(defn devices-list
[]
(let [installations (rf/sub [:pairing/enabled-installations])]
[rn/view {:style style/device-list}
[rn/flat-list
{:data (rest installations)
:shows-vertical-scroll-indicator false
:key-fn :installation-id
:header [current-device (first installations)]
:render-fn device/view}]]))
(defn continue-button
[]
(let [profile-color (:color (rf/sub [:onboarding-2/profile]))]
[quo/button
{:on-press #(rf/dispatch [:init-root :enable-notifications])
:accessibility-label :continue-button
:override-background-color (colors/custom-color profile-color 60)
:style style/continue-button}
(i18n/label :t/continue)]))
(defn view
[]
[rn/view {:style style/page-container}
[background/view true]
[quo/page-nav]
[page-title]
[devices-list]
[continue-button]])

View File

@ -1,10 +0,0 @@
(ns status-im2.contexts.onboarding.syncing.syncing-devices.style
(:require [quo2.foundations.colors :as colors]))
(def page-container
{:position :absolute
:top 0
:bottom 0
:left 0
:right 0
:background-color colors/neutral-80-opa-80-blur})

View File

@ -1,37 +0,0 @@
(ns status-im2.contexts.onboarding.syncing.syncing-devices.view
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[status-im2.contexts.onboarding.syncing.syncing-devices.style :as style]
[status-im2.contexts.onboarding.common.background.view :as background]
[status-im2.contexts.onboarding.common.navigation-bar.view :as navigation-bar]))
(defn page
[{:keys [navigation-bar-top]}]
[rn/view {:style style/page-container}
[navigation-bar/navigation-bar
{:top navigation-bar-top
:right-section-buttons [{:type :blur-bg
:icon :i/info
:icon-override-theme :dark
:on-press #(js/alert "Pending")}]}]
[rn/view {:style {:padding-horizontal 20}}
[quo/text
{:size :heading-1
:weight :semi-bold
:style {:color colors/white}} "Syncing devices..."]
[quo/text
{:size :heading-2
:weight :semi-bold
:style {:color colors/white}} "will show sync complete if successful"]
[quo/text
{:size :heading-2
:weight :semi-bold
:style {:color colors/white}} "will show sync failed if unsuccessful"]]])
(defn syncing-devices
[]
[rn/view {:style {:flex 1}}
[background/view true]
[page {:navigation-bar-top (safe-area/get-top)}]])

View File

@ -17,7 +17,7 @@
(merge
{:db (dissoc db :syncing)}
(when receiver?
{:dispatch [:init-root :enable-notifications]}))))
{:dispatch [:init-root :syncing-results]}))))
(rf/defn local-pairing-update-role
{:events [:syncing/update-role]}

View File

@ -181,8 +181,7 @@
:blur-amount 10
:blur-type :transparent
:overlay-color colors/neutral-80-opa-80
:background-color colors/neutral-80-opa-80}]
]]))
:background-color colors/neutral-80-opa-80}]]]))
(defn f-view
[{:keys [title show-bottom-view? background]}]
@ -231,8 +230,7 @@
2 [enter-sync-code-tab]
nil)
[rn/view {:style style/flex-spacer}]
(when show-bottom-view? [bottom-view insets])
]]))))
(when show-bottom-view? [bottom-view insets])]]))))
(defn view
[props]

View File

@ -3,15 +3,17 @@
(def container-main
{:background-color colors/neutral-95
:padding-top 44
:flex 1})
(def page-container {:margin-horizontal 20})
(def page-container
{:flex 1
:margin-horizontal 20})
(def title-container
{:flex-direction :row
:align-items :center
:justify-content :space-between})
:justify-content :space-between
:margin-bottom 24})
(def devices-container
{:flex 1})

View File

@ -4,7 +4,7 @@
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[status-im2.contexts.syncing.syncing-devices-list.style :as style]
[status-im2.common.not-implemented :as not-implemented]
[status-im2.common.syncing.view :as device]
[utils.re-frame :as rf]))
;;TODO remove mock data (#https://github.com/status-im/status-mobile/issues/15142)
@ -19,37 +19,6 @@
:icon-override-theme :dark
:on-press #(rf/dispatch [:navigate-back])}}]])
(defn render-device
[{:keys [device
this-device?
type]}]
[rn/view {:style style/device-container}
[rn/view {:style style/icon-container}
[quo/icon
(if (= type :mobile) :i/mobile :i/desktop)
{:color colors/white}]]
[rn/view {:style style/device-details}
[quo/text
{:accessibility-label :device-name
:weight :medium
:size :paragraph-1
:style {:color colors/white}}
device]
[not-implemented/not-implemented
[quo/text
{:accessibility-label :next-back-up
:size :paragraph-2
:style {:color colors/white-opa-40}}
"Next backup in 04:36:12"]]
(when this-device?
[rn/view {:style style/tag-container}
[quo/status-tag
{:size :small
:status {:type :positive}
:no-icon? true
:label (i18n/label :t/this-device)
:override-theme :dark}]])]])
(defn view
[]
[rn/view {:style style/container-main}
@ -66,7 +35,7 @@
:on-press #(rf/dispatch [:navigate-to :settings-setup-syncing])}
:i/add]]
[rn/view {:style style/devices-container}
[render-device
{:device "iPhone 11"
[device/view
{:name "iPhone 11"
:this-device? true
:type :mobile}]]]])
:device-type :mobile}]]]])

View File

@ -119,4 +119,8 @@
:welcome
{:root {:stack {:children [{:component {:name :welcome
:id :welcome
:options (options/default-root)}}]}}}
:syncing-results
{:root {:stack {:children [{:component {:name :syncing-results
:id :syncing-results
:options (options/default-root)}}]}}}}))

View File

@ -18,7 +18,6 @@
[status-im2.contexts.onboarding.welcome.view :as welcome]
[status-im2.contexts.onboarding.new-to-status.view :as new-to-status]
[status-im2.contexts.onboarding.sign-in.view :as sign-in]
[status-im2.contexts.onboarding.syncing.syncing-devices.view :as syncing-devices]
[status-im2.contexts.onboarding.generating-keys.view :as generating-keys]
[status-im2.contexts.onboarding.enter-seed-phrase.view :as enter-seed-phrase]
[status-im2.contexts.onboarding.profiles.view :as profiles]
@ -32,7 +31,9 @@
[status-im.ui.screens.screens :as old-screens]
[status-im2.contexts.communities.actions.request-to-join.view :as join-menu]
[status-im2.contexts.syncing.setup-syncing.view :as settings-setup-syncing]
[status-im2.contexts.share.view :as share]))
[status-im2.contexts.share.view :as share]
[status-im2.contexts.onboarding.syncing.results.view :as syncing-results]
[status-im2.contexts.onboarding.syncing.progress.view :as syncing-devices]))
(defn screens
[]
@ -153,9 +154,12 @@
:options {:layout options/onboarding-layout}
:component sign-in/view}
{:name :syncing-devices
{:name :syncing-progress
:options {:layout options/onboarding-layout}
:component syncing-devices/syncing-devices}
:component syncing-devices/view}
{:name :syncing-results
:component syncing-results/view}
{:name :welcome
:options {:layout options/onboarding-layout}

View File

@ -11,6 +11,12 @@
vals
(pairing/sort-installations installation-id))))
(re-frame/reg-sub
:pairing/enabled-installations
:<- [:pairing/installations]
(fn [installations]
(filter :enabled? installations)))
(re-frame/reg-sub
:pairing/installation-id
:<- [:multiaccount]
@ -20,3 +26,9 @@
:pairing/installation-name
:<- [:multiaccount]
(fn [multiaccount] (:installation-name multiaccount)))
(re-frame/reg-sub
:pairing/pairing-in-progress
:<- [:syncing]
(fn [syncing]
(:pairing-in-progress? syncing)))

View File

@ -44,6 +44,7 @@
(reg-root-key-sub :bottom-sheet :bottom-sheet)
;;general
(reg-root-key-sub :syncing :syncing)
(reg-root-key-sub :sync-state :sync-state)
(reg-root-key-sub :network-status :network-status)
(reg-root-key-sub :peers-count :peers-count)

View File

@ -1851,6 +1851,7 @@
"account-is-used": "The account is being used with Dapps in the browser.",
"normal": "Normal",
"never": "Never",
"online-now": "Online now",
"fee-options": "Suggested fee options",
"fee-cap": "Fee cap",
"tip-cap": "Tip cap",
@ -2159,5 +2160,13 @@
"link-to-profile": "Link to profile",
"emoji-hash": "Emoji Hash",
"emoji-hash-copied":"Emojihash copied to clipboard",
"link-to-profile-copied":"Link to Profile copied to clipboard"
"link-to-profile-copied":"Link to Profile copied to clipboard",
"sync-devices-result-sub-title": "Your devices are now in sync",
"sync-devices-title": "Syncing devices...",
"sync-devices-sub-title": "Please keep both devices switched on and connected to the internet until sync is complete",
"sync-devices-error-title": "Oops, somethings wrong",
"sync-devices-error-sub-title":"Make sure both devices are powered on and connected to the internet.",
"sync-devices-complete-title": "Device sync complete!",
"sync-devices-complete-sub-title": "Your devices are now in sync",
"sync-with": "Synced with"
}