From 4b2d62ee1f309906582c03d0f1d58c14945d7cd6 Mon Sep 17 00:00:00 2001 From: Jamie Caprani Date: Mon, 15 May 2023 18:07:13 +0100 Subject: [PATCH] chore: update ui for syncing page for onboarding and in profile (#15623) --- .../contexts/onboarding/sign_in/view.cljs | 242 +----------------- .../syncing/scan_sync_code/style.cljs | 113 ++++++++ .../contexts/syncing/scan_sync_code/view.cljs | 239 +++++++++++++++++ .../syncing/scan_sync_code_page/style.cljs | 10 + .../syncing/scan_sync_code_page/view.cljs | 12 + .../contexts/syncing/setup_syncing/view.cljs | 24 +- src/status_im2/contexts/syncing/utils.cljs | 10 + src/status_im2/navigation/screens.cljs | 3 + 8 files changed, 401 insertions(+), 252 deletions(-) create mode 100644 src/status_im2/contexts/syncing/scan_sync_code/style.cljs create mode 100644 src/status_im2/contexts/syncing/scan_sync_code/view.cljs create mode 100644 src/status_im2/contexts/syncing/scan_sync_code_page/style.cljs create mode 100644 src/status_im2/contexts/syncing/scan_sync_code_page/view.cljs create mode 100644 src/status_im2/contexts/syncing/utils.cljs diff --git a/src/status_im2/contexts/onboarding/sign_in/view.cljs b/src/status_im2/contexts/onboarding/sign_in/view.cljs index b956426ec8..54c6e66584 100644 --- a/src/status_im2/contexts/onboarding/sign_in/view.cljs +++ b/src/status_im2/contexts/onboarding/sign_in/view.cljs @@ -1,241 +1,11 @@ (ns status-im2.contexts.onboarding.sign-in.view - (:require [clojure.string :as string] - [oops.core :as oops] - [quo2.core :as quo] - [quo2.foundations.colors :as colors] - [react-native.blur :as blur] - [react-native.camera-kit :as camera-kit] - [react-native.core :as rn] - [react-native.hole-view :as hole-view] - [react-native.permissions :as permissions] - [react-native.platform :as platform] - [react-native.safe-area :as safe-area] - [reagent.core :as reagent] - [status-im2.constants :as constants] + (:require [utils.i18n :as i18n] [status-im2.contexts.onboarding.common.background.view :as background] - [status-im2.contexts.onboarding.sign-in.style :as style] - [utils.i18n :as i18n] - [utils.re-frame :as rf] - [utils.transforms :as transforms])) - -(defonce camera-permission-granted? (reagent/atom false)) - -(defn- header - [active-tab read-qr-once?] - [:<> - [rn/view {:style style/header-container} - [quo/button - {:icon true - :type :blur-bg - :size 32 - :accessibility-label :close-sign-in-by-syncing - :override-theme :dark - :on-press #(rf/dispatch [:navigate-back])} - :i/close] - [quo/button - {:before :i/info - :type :blur-bg - :size 32 - :accessibility-label :find-sync-code - :override-theme :dark - :on-press #(js/alert "Yet to be implemented")} - (i18n/label :t/find-sync-code)]] - [quo/text - {:size :heading-1 - :weight :semi-bold - :style style/header-text} - (i18n/label :t/sign-in-by-syncing)] - [quo/text - {:size :paragraph-1 - :weight :regular - :style style/header-sub-text} - (i18n/label :t/synchronise-your-data-across-your-devices)] - [rn/view {:style style/tabs-container} - [quo/segmented-control - {:size 32 - :override-theme :dark - :blur? true - :default-active @active-tab - :data [{:id 1 :label (i18n/label :t/scan-sync-qr-code)} - {:id 2 :label (i18n/label :t/enter-sync-code)}] - :on-change (fn [id] - (reset! active-tab id) - (reset! read-qr-once? false))}]]]) - -(defn- camera-permission-view - [request-camera-permission] - [rn/view {:style style/camera-permission-container} - [quo/text - {:size :paragraph-1 - :weight :medium - :style style/enable-camera-access-header} - (i18n/label :t/enable-access-to-camera)] - [quo/text - {:size :paragraph-2 - :weight :regular - :style style/enable-camera-access-sub-text} - (i18n/label :t/to-scan-a-qr-enable-your-camera)] - [quo/button - {:before :i/camera - :type :primary - :size 32 - :accessibility-label :request-camera-permission - :override-theme :dark - :on-press request-camera-permission} - (i18n/label :t/enable-camera)]]) - -(defn- qr-scan-hole-area - [qr-view-finder] - [rn/view - {:style style/qr-view-finder - :on-layout (fn [event] - (let [layout (transforms/js->clj (oops/oget event "nativeEvent.layout")) - width (:width layout) - y (if platform/android? - (+ (safe-area/get-top) (:y layout)) - (:y layout)) - view-finder (-> layout - (assoc :height width) - (assoc :y y))] - (reset! qr-view-finder view-finder)))}]) - - -(defn- border - [border1 border2 corner] - [rn/view - (assoc {:border-color colors/white :width 80 :height 80} border1 2 border2 2 corner 16)]) - -(defn- viewfinder - [qr-view-finder] - (let [size (:width qr-view-finder)] - [rn/view {:style (style/viewfinder-container qr-view-finder)} - [rn/view {:width size :height size :justify-content :space-between} - [rn/view {:flex-direction :row :justify-content :space-between} - [border :border-top-width :border-left-width :border-top-left-radius] - [border :border-top-width :border-right-width :border-top-right-radius]] - [rn/view {:flex-direction :row :justify-content :space-between} - [border :border-bottom-width :border-left-width :border-bottom-left-radius] - [border :border-bottom-width :border-right-width :border-bottom-right-radius]]] - [quo/text - {:size :paragraph-2 - :weight :regular - :style style/viewfinder-text} - (i18n/label :t/ensure-qr-code-is-in-focus-to-scan)]])) - -(defn- scan-qr-code-tab - [qr-view-finder request-camera-permission] - [:<> - [rn/view {:style style/scan-qr-code-container}] - (when (empty? @qr-view-finder) - [qr-scan-hole-area qr-view-finder]) - (if (and @camera-permission-granted? (boolean (not-empty @qr-view-finder))) - [viewfinder @qr-view-finder] - [camera-permission-view request-camera-permission])]) - -(defn- enter-sync-code-tab - [] - [rn/view {:style style/enter-sync-code-container} - [quo/text - {:size :paragraph-1 - :weight :medium - :style {:color colors/white}} - "Yet to be implemented"]]) - -(defn- bottom-view - [insets] - [rn/touchable-without-feedback - {:on-press #(js/alert "Yet to be implemented")} - [rn/view - {:style (style/bottom-container (:bottom insets))} - [quo/text - {:size :paragraph-2 - :weight :regular - :style style/bottom-text} - (i18n/label :t/i-dont-have-status-on-another-device)]]]) - -(defn- check-qr-code-data - [event] - (let [connection-string (string/trim (oops/oget event "nativeEvent.codeStringValue")) - valid-connection-string? (string/starts-with? - connection-string - constants/local-pairing-connection-string-identifier)] - (if valid-connection-string? - (rf/dispatch [:syncing/input-connection-string-for-bootstrapping connection-string]) - (rf/dispatch [:toasts/upsert - {:icon :i/info - :icon-color colors/danger-50 - :override-theme :light - :text (i18n/label :t/error-this-is-not-a-sync-qr-code)}])))) - -(defn f-view - [] - (let [camera-ref (atom nil) - read-qr-once? (atom false) - insets (safe-area/get-insets) - active-tab (reagent/atom 1) - qr-view-finder (reagent/atom {}) - {:keys [height width]} (rf/sub [:dimensions/window]) - request-camera-permission (fn [] - (rf/dispatch - [:request-permissions - {:permissions [:camera] - :on-allowed #(reset! camera-permission-granted? true) - :on-denied #(rf/dispatch - [:toasts/upsert - {:icon :i/info - :icon-color colors/danger-50 - :override-theme :light - :text (i18n/label - :t/camera-permission-denied)}])}]))] - (fn [] - (let [holes (merge @qr-view-finder {:borderRadius 16}) - scan-qr-code-tab? (= @active-tab 1) - show-camera? (and scan-qr-code-tab? @camera-permission-granted?) - show-holes? (and show-camera? - (boolean (not-empty @qr-view-finder))) - on-read-code (fn [data] - (when-not @read-qr-once? - (reset! read-qr-once? true) - (js/setTimeout (fn [] - (reset! read-qr-once? false)) - 3000) - (check-qr-code-data data))) - hole-view-wrapper (if show-camera? - [hole-view/hole-view - {:style style/absolute-fill - :holes (if show-holes? - [holes] - [])}] - [:<>])] - (rn/use-effect - (fn [] - (when-not @camera-permission-granted? - (permissions/permission-granted? :camera - #(reset! camera-permission-granted? %) - #(reset! camera-permission-granted? false))))) - [rn/view {:style (style/root-container (:top insets))} - (if show-camera? - [camera-kit/camera - {:ref #(reset! camera-ref %) - :style (merge style/absolute-fill {:height height :width width}) - :camera-options {:zoomMode :off} - :scan-barcode true - :on-read-code on-read-code}] - [background/view true]) - (conj hole-view-wrapper - [blur/view - {:style style/absolute-fill - :overlay-color colors/neutral-80-opa-80 - :blur-type :dark - :blur-amount (if platform/ios? 15 5)}]) - [header active-tab read-qr-once?] - (case @active-tab - 1 [scan-qr-code-tab qr-view-finder request-camera-permission] - 2 [enter-sync-code-tab] - nil) - [rn/view {:style style/flex-spacer}] - [bottom-view insets]])))) + [status-im2.contexts.syncing.scan-sync-code.view :as scan-sync-code])) (defn view [] - [:f> f-view]) + [scan-sync-code/view + {:title (i18n/label :t/sign-in-by-syncing) + :show-bottom-view? true + :background [background/view true]}]) diff --git a/src/status_im2/contexts/syncing/scan_sync_code/style.cljs b/src/status_im2/contexts/syncing/scan_sync_code/style.cljs new file mode 100644 index 0000000000..1ad2c4d8a8 --- /dev/null +++ b/src/status_im2/contexts/syncing/scan_sync_code/style.cljs @@ -0,0 +1,113 @@ +(ns status-im2.contexts.syncing.scan-sync-code.style + (:require [quo2.foundations.colors :as colors] + [status-im.utils.platform :as platform])) + +(def screen-padding 20) + +(def flex-spacer {:flex 1}) + +(def absolute-fill + {:position :absolute + :top 0 + :bottom 0 + :left 0 + :right 0}) + +(def hole + (merge absolute-fill + {:z-index 2 :opacity 0.95})) + +(defn root-container + [padding-top] + {:z-index 5 + :flex 1 + :padding-top padding-top}) + +(def header-container + {:flex-direction :row + :justify-content :space-between + :padding-horizontal screen-padding + :margin-vertical 12}) + +(def header-text + {:padding-horizontal screen-padding + :padding-top 12 + :padding-bottom 8 + :color colors/white}) + +(def header-sub-text + {:padding-horizontal screen-padding + :color colors/white}) + +(def tabs-container + {:padding-horizontal screen-padding + :margin-top 20}) + +(def scan-qr-code-container + {:margin-top 19}) + +(def qr-view-finder + {:margin-horizontal screen-padding + :height 1 + :display :flex}) + +(defn viewfinder-container + [viewfinder] + {:position :absolute + :left (:x viewfinder) + :top (:y viewfinder) + :overflow :hidden}) + +(def viewfinder-text + {:color colors/white-opa-70 + :text-align :center + :padding-top 16}) + +(def camera-permission-container + {:height 335 + :margin-horizontal screen-padding + :background-color colors/white-opa-5 + :border-color colors/white-opa-10 + :border-radius 12 + :align-items :center + :justify-content :center}) + +(def enable-camera-access-header + {:color colors/white}) + +(def enable-camera-access-sub-text + {:color colors/white-opa-70 + :margin-bottom 16}) + +(def enter-sync-code-container + {:margin-top 20 + :justify-content :center + :align-items :center}) + +(defn bottom-container + [padding-bottom] + {:z-index 6 + :padding-top 12 + :padding-bottom padding-bottom + :background-color colors/white-opa-5 + :border-top-left-radius 20 + :border-top-right-radius 20 + :align-items :center + :justify-content :center}) + +(def bottom-text + {:color colors/white + :padding-bottom 12}) + +(def camera-style + {:height "100%" + :borderRadius 16 + :background-color :transparent}) + +(def camera-container + {:position :absolute + :top (if platform/android? 40 0) + :left 0 + :right 0 + :bottom 0 + :border-radius 16}) diff --git a/src/status_im2/contexts/syncing/scan_sync_code/view.cljs b/src/status_im2/contexts/syncing/scan_sync_code/view.cljs new file mode 100644 index 0000000000..c5c6b5685e --- /dev/null +++ b/src/status_im2/contexts/syncing/scan_sync_code/view.cljs @@ -0,0 +1,239 @@ +(ns status-im2.contexts.syncing.scan-sync-code.view + (:require [clojure.string :as string] + [oops.core :as oops] + [quo2.core :as quo] + [quo2.foundations.colors :as colors] + [react-native.camera-kit :as camera-kit] + [react-native.core :as rn] + [react-native.blur :as blur] + [react-native.hole-view :as hole-view] + [react-native.permissions :as permissions] + [react-native.safe-area :as safe-area] + [reagent.core :as reagent] + [status-im2.contexts.syncing.scan-sync-code.style :as style] + [utils.i18n :as i18n] + [utils.re-frame :as rf] + [status-im2.contexts.syncing.utils :as sync-utils])) + +(defonce camera-permission-granted? (reagent/atom false)) + +(defn- header + [active-tab read-qr-once? title] + [:<> + [rn/view {:style style/header-container} + [quo/button + {:icon true + :type :blur-bg + :size 32 + :accessibility-label :close-sign-in-by-syncing + :override-theme :dark + :on-press #(rf/dispatch [:navigate-back])} + :i/close] + [quo/button + {:before :i/info + :type :blur-bg + :size 32 + :accessibility-label :find-sync-code + :override-theme :dark + :on-press #(js/alert "Yet to be implemented")} + (i18n/label :t/find-sync-code)]] + [quo/text + {:size :heading-1 + :weight :semi-bold + :style style/header-text} + title] + [quo/text + {:size :paragraph-1 + :weight :regular + :style style/header-sub-text} + (i18n/label :t/synchronise-your-data-across-your-devices)] + [rn/view {:style style/tabs-container} + [quo/segmented-control + {:size 32 + :override-theme :dark + :blur? true + :default-active @active-tab + :data [{:id 1 :label (i18n/label :t/scan-sync-qr-code)} + {:id 2 :label (i18n/label :t/enter-sync-code)}] + :on-change (fn [id] + (reset! active-tab id) + (reset! read-qr-once? false))}]]]) + +(defn- camera-permission-view + [request-camera-permission] + [rn/view {:style style/camera-permission-container} + [quo/text + {:size :paragraph-1 + :weight :medium + :style style/enable-camera-access-header} + (i18n/label :t/enable-access-to-camera)] + [quo/text + {:size :paragraph-2 + :weight :regular + :style style/enable-camera-access-sub-text} + (i18n/label :t/to-scan-a-qr-enable-your-camera)] + [quo/button + {:before :i/camera + :type :primary + :size 32 + :accessibility-label :request-camera-permission + :override-theme :dark + :on-press request-camera-permission} + (i18n/label :t/enable-camera)]]) + +(defn- qr-scan-hole-area + [qr-view-finder] + [rn/view + {:style style/qr-view-finder + :on-layout (fn [event] + (let [layout (js->clj (oops/oget event "nativeEvent.layout") + :keywordize-keys + true) + view-finder (assoc layout :height (:width layout))] + (reset! qr-view-finder view-finder)))}]) + +(defn- border + [border1 border2 corner] + [rn/view + (assoc {:border-color colors/white :width 80 :height 80} border1 2 border2 2 corner 16)]) + +(defn- viewfinder + [qr-view-finder] + (let [size (:width qr-view-finder)] + [:<> + [rn/view {:style (style/viewfinder-container qr-view-finder)} + + [rn/view {:width size :height size :justify-content :space-between} + [rn/view {:flex-direction :row :justify-content :space-between} + [border :border-top-width :border-left-width :border-top-left-radius] + [border :border-top-width :border-right-width :border-top-right-radius]] + [rn/view {:flex-direction :row :justify-content :space-between} + [border :border-bottom-width :border-left-width :border-bottom-left-radius] + [border :border-bottom-width :border-right-width :border-bottom-right-radius]]] + [quo/text + {:size :paragraph-2 + :weight :regular + :style style/viewfinder-text} + (i18n/label :t/ensure-qr-code-is-in-focus-to-scan)]]])) + +(defn- scan-qr-code-tab + [qr-view-finder request-camera-permission] + [:<> + [rn/view {:style style/scan-qr-code-container}] + (when (empty? @qr-view-finder) + [qr-scan-hole-area qr-view-finder]) + (if (and @camera-permission-granted? (boolean (not-empty @qr-view-finder))) + [viewfinder @qr-view-finder] + [camera-permission-view request-camera-permission])]) + +(defn- enter-sync-code-tab + [] + [rn/view {:style style/enter-sync-code-container} + [quo/text + {:size :paragraph-1 + :weight :medium + :style {:color colors/white}} + "Yet to be implemented"]]) + +(defn- bottom-view + [insets] + [rn/touchable-without-feedback + {:on-press #(js/alert "Yet to be implemented")} + [rn/view + {:style (style/bottom-container (:bottom insets))} + [quo/text + {:size :paragraph-2 + :weight :regular + :style style/bottom-text} + (i18n/label :t/i-dont-have-status-on-another-device)]]]) + +(defn- check-qr-code-data + [event] + (let [connection-string (string/trim (oops/oget event "nativeEvent.codeStringValue")) + valid-connection-string? (sync-utils/valid-connection-string? connection-string)] + (if valid-connection-string? + (rf/dispatch [:syncing/input-connection-string-for-bootstrapping connection-string]) + (rf/dispatch [:toasts/upsert + {:icon :i/info + :icon-color colors/danger-50 + :override-theme :light + :text (i18n/label :t/error-this-is-not-a-sync-qr-code)}])))) + +(defn render-camera + [show-camera? qr-view-finder camera-ref on-read-code show-holes?] + (when (and show-camera? (:x qr-view-finder)) + [:<> + [rn/view {:style style/camera-container} + [camera-kit/camera + {:ref #(reset! camera-ref %) + :style style/camera-style + :camera-options {:zoomMode :off} + :scan-barcode true + :on-read-code on-read-code}]] + [hole-view/hole-view + {:style style/hole + :holes (if show-holes? + [(merge qr-view-finder + {:borderRadius 16})] + [])} + [blur/view + {:style style/absolute-fill + :blur-amount 10 + :blur-type :transparent + :overlay-color colors/neutral-80-opa-80 + :background-color colors/neutral-80-opa-80}] + ]])) + +(defn f-view + [{:keys [title show-bottom-view? background]}] + (let [insets (safe-area/get-insets) + active-tab (reagent/atom 1) + qr-view-finder (reagent/atom {}) + request-camera-permission (fn [] + (rf/dispatch + [:request-permissions + {:permissions [:camera] + :on-allowed #(reset! camera-permission-granted? true) + :on-denied #(rf/dispatch + [:toasts/upsert + {:icon :i/info + :icon-color colors/danger-50 + :override-theme :light + :text (i18n/label + :t/camera-permission-denied)}])}]))] + (fn [] + (let [camera-ref (atom nil) + read-qr-once? (atom false) + on-read-code (fn [data] + (when-not @read-qr-once? + (reset! read-qr-once? true) + (js/setTimeout (fn [] + (reset! read-qr-once? false)) + 3000) + (check-qr-code-data data))) + scan-qr-code-tab? (= @active-tab 1) + show-camera? (and scan-qr-code-tab? @camera-permission-granted?) + show-holes? (and show-camera? + (boolean (not-empty @qr-view-finder)))] + (rn/use-effect + (fn [] + (when-not @camera-permission-granted? + (permissions/permission-granted? :camera + #(reset! camera-permission-granted? %) + #(reset! camera-permission-granted? false))))) + [:<> + background + [render-camera show-camera? @qr-view-finder camera-ref on-read-code show-holes?] + [rn/view {:style (style/root-container (:top insets))} + [header active-tab read-qr-once? title] + (case @active-tab + 1 [scan-qr-code-tab qr-view-finder request-camera-permission] + 2 [enter-sync-code-tab] + nil) + [rn/view {:style style/flex-spacer}] + (when show-bottom-view? [bottom-view insets]) + ]])))) + +(defn view + [props] + [:f> f-view props]) diff --git a/src/status_im2/contexts/syncing/scan_sync_code_page/style.cljs b/src/status_im2/contexts/syncing/scan_sync_code_page/style.cljs new file mode 100644 index 0000000000..4ba590f327 --- /dev/null +++ b/src/status_im2/contexts/syncing/scan_sync_code_page/style.cljs @@ -0,0 +1,10 @@ +(ns status-im2.contexts.syncing.scan-sync-code-page.style + (:require [quo2.foundations.colors :as colors])) + +(def background + {:position :absolute + :top 0 + :bottom 0 + :left 0 + :right 0 + :background-color colors/neutral-95}) diff --git a/src/status_im2/contexts/syncing/scan_sync_code_page/view.cljs b/src/status_im2/contexts/syncing/scan_sync_code_page/view.cljs new file mode 100644 index 0000000000..56921c7b44 --- /dev/null +++ b/src/status_im2/contexts/syncing/scan_sync_code_page/view.cljs @@ -0,0 +1,12 @@ +(ns status-im2.contexts.syncing.scan-sync-code-page.view + (:require [react-native.core :as rn] + [status-im2.contexts.syncing.scan-sync-code-page.style :as style] + [status-im2.contexts.syncing.scan-sync-code.view :as scan-sync-code] + [utils.i18n :as i18n])) + +(defn view + [] + [scan-sync-code/view + {:title (i18n/label :t/scan-sync-code) + :background [rn/view + {:style style/background} true]}]) diff --git a/src/status_im2/contexts/syncing/setup_syncing/view.cljs b/src/status_im2/contexts/syncing/setup_syncing/view.cljs index 2b3f6844fc..f426d7aa48 100644 --- a/src/status_im2/contexts/syncing/setup_syncing/view.cljs +++ b/src/status_im2/contexts/syncing/setup_syncing/view.cljs @@ -1,20 +1,19 @@ (ns status-im2.contexts.syncing.setup-syncing.view (:require [utils.i18n :as i18n] - [clojure.string :as string] [quo2.core :as quo] [quo2.foundations.colors :as colors] [react-native.core :as rn] [utils.datetime :as datetime] [status-im2.contexts.syncing.setup-syncing.style :as style] [utils.re-frame :as rf] - [status-im2.constants :as constants] [react-native.clipboard :as clipboard] [status-im2.contexts.syncing.sheets.enter-password.view :as enter-password] [status-im2.common.qr-code-viewer.view :as qr-code-viewer] [reagent.core :as reagent] [status-im2.common.resources :as resources] [react-native.hooks :as hooks] - [react-native.safe-area :as safe-area])) + [react-native.safe-area :as safe-area] + [status-im2.contexts.syncing.utils :as sync-utils])) (def code-valid-for-ms 120000) (def one-min-ms 60000) @@ -35,13 +34,6 @@ :icon-override-theme :dark :on-press #(rf/dispatch [:open-modal :how-to-pair])}]}]]) -(defn valid-cs? - [connection-string] - (when connection-string - (string/starts-with? - connection-string - constants/local-pairing-connection-string-identifier))) - (defn f-use-interval [clock cleanup-clock delay] (hooks/use-interval clock cleanup-clock delay)) @@ -53,7 +45,7 @@ delay (reagent/atom nil) timestamp (reagent/atom nil) set-code (fn [connection-string] - (when (valid-cs? connection-string) + (when (sync-utils/valid-connection-string? connection-string) (reset! timestamp (* 1000 (js/Math.ceil (/ (datetime/timestamp) 1000)))) (reset! delay 1000) (reset! code connection-string))) @@ -84,14 +76,14 @@ :weight :semi-bold :style {:color colors/white}} (i18n/label :t/setup-syncing)]] - [rn/view {:style (style/qr-container (valid-cs? @code))} - (if (valid-cs? @code) + [rn/view {:style (style/qr-container (sync-utils/valid-connection-string? @code))} + (if (sync-utils/valid-connection-string? @code) [qr-code-viewer/qr-code-view 331 @code] [quo/qr-code {:source (resources/get-image :qr-code) :height 220 :width "100%"}]) - (when-not (valid-cs? @code) + (when-not (sync-utils/valid-connection-string? @code) [quo/button {:on-press (fn [] ;TODO https://github.com/status-im/status-mobile/issues/15570 @@ -103,7 +95,7 @@ :size 40 :style style/generate-button :before :i/reveal} (i18n/label :t/reveal-sync-code)]) - (when (valid-cs? @code) + (when (sync-utils/valid-connection-string? @code) [rn/view {:style style/valid-cs-container} [rn/view @@ -144,5 +136,5 @@ [quo/action-drawer [[{:icon :i/scan :override-theme :dark - :on-press #(js/alert "to be implemented") + :on-press #(rf/dispatch [:navigate-to :scan-sync-code-page]) :label (i18n/label :t/scan-or-enter-sync-code)}]]]]]]))) diff --git a/src/status_im2/contexts/syncing/utils.cljs b/src/status_im2/contexts/syncing/utils.cljs new file mode 100644 index 0000000000..ff15a2f46b --- /dev/null +++ b/src/status_im2/contexts/syncing/utils.cljs @@ -0,0 +1,10 @@ +(ns status-im2.contexts.syncing.utils + (:require [clojure.string :as string] + [status-im2.constants :as constants])) + +(defn valid-connection-string? + [connection-string] + (when connection-string + (string/starts-with? + connection-string + constants/local-pairing-connection-string-identifier))) diff --git a/src/status_im2/navigation/screens.cljs b/src/status_im2/navigation/screens.cljs index 0ef6966f96..b21a73a58f 100644 --- a/src/status_im2/navigation/screens.cljs +++ b/src/status_im2/navigation/screens.cljs @@ -24,6 +24,7 @@ [status-im2.contexts.onboarding.profiles.view :as profiles] [status-im2.contexts.quo-preview.main :as quo.preview] [status-im2.contexts.shell.view :as shell] + [status-im2.contexts.syncing.scan-sync-code-page.view :as scan-sync-code-page] [status-im2.contexts.syncing.syncing-devices-list.view :as settings-syncing] [status-im2.contexts.syncing.how-to-pair.view :as how-to-pair] [status-im2.navigation.options :as options] @@ -140,6 +141,8 @@ :popGesture false :hardwareBackButton {:dismissModalOnPress false :popStackOnPress false}}} + {:name :scan-sync-code-page + :component scan-sync-code-page/view} {:name :sign-in :options {:layout options/onboarding-layout}