Compare commits

..
Author SHA1 Message Date
Omar Basem 3ff2510720 draft 2023-03-21 16:55:48 +04:00
Omar Basem 30f3ed5b3d draft 2023-03-21 16:38:00 +04:00
Omar Basem 3da2118e15 draft 2023-03-21 16:20:19 +04:00
Omar Basem e046feb124 draft 2023-03-21 15:55:37 +04:00
Omar Basem 1e6c4e1932 lint 2023-03-21 13:56:53 +04:00
Omar Basem 2ade8fc7ee lint 2023-03-21 13:56:53 +04:00
Omar Basem ee0df8633e remove image delay 2023-03-21 13:56:53 +04:00
Jamie Caprani ada7a02c21 chore: add skeleton for sign in with syncing flow 2023-03-21 09:42:31 +00:00
Siddarth Kumar 3f3cbe98a4 set signing to auto for debug builds (#15420) 2023-03-21 13:10:55 +05:30
12 changed files with 291 additions and 157 deletions
+6 -12
View File
@@ -417,9 +417,7 @@
TestTargetID = 13B07F861A680F5B00A75B9A;
};
13B07F861A680F5B00A75B9A = {
DevelopmentTeam = 8B5X2M6H2Y;
LastSwiftMigration = 1140;
ProvisioningStyle = Manual;
SystemCapabilities = {
com.apple.BackgroundModes = {
enabled = 1;
@@ -843,9 +841,8 @@
BUNDLE_ID_SUFFIX = .debug;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = StatusIm/StatusIm.entitlements;
CODE_SIGN_IDENTITY = "iPhone Distribution";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CUSTOM_PRODUCT_NAME = "Status Debug";
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 8B5X2M6H2Y;
@@ -898,8 +895,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = im.status.ethereum;
PRODUCT_NAME = StatusIm;
PROVISIONING_PROFILE = "9da75626-9594-43d9-a827-0f6d43c28f54";
PROVISIONING_PROFILE_SPECIFIER = "match Development im.status.ethereum";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "StatusIm-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
@@ -917,9 +913,8 @@
BUNDLE_ID_SUFFIX = "";
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = StatusIm/StatusIm.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CUSTOM_PRODUCT_NAME = Status;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 8B5X2M6H2Y;
@@ -964,8 +959,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = im.status.ethereum;
PRODUCT_NAME = StatusIm;
PROVISIONING_PROFILE = "e2202b12-7a66-4ff7-af3c-a52e35f32dc1";
PROVISIONING_PROFILE_SPECIFIER = "match AdHoc im.status.ethereum";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "StatusIm-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
+2 -3
View File
@@ -342,9 +342,8 @@
(rf/defn navigate-to-lightbox
{:events [:chat.ui/navigate-to-lightbox]}
[{:keys [db]} shared-element-id screen-params]
(let [updated-db (assoc db :shared-element-id shared-element-id)]
(reagent/next-tick #(rf/dispatch [:navigate-to :lightbox screen-params]))
{:db updated-db}))
(reagent/next-tick #(rf/dispatch [:navigate-to :lightbox screen-params]))
{:db (assoc db :shared-element-id shared-element-id)})
(rf/defn exit-lightbox-signal
{:events [:chat.ui/exit-lightbox-signal]}
+106 -86
View File
@@ -3,7 +3,6 @@
[clojure.string :as string]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.fast-image :as fast-image]
[react-native.navigation :as navigation]
[react-native.orientation :as orientation]
[react-native.platform :as platform]
@@ -26,7 +25,7 @@
(defn toggle-opacity
[index {:keys [opacity-value border-value transparent? atoms]} portrait?]
(let [{:keys [small-list-ref]} atoms
opacity (reanimated/get-shared-value opacity-value)]
opacity (reanimated/get-shared-value opacity-value)]
(if (= opacity 1)
(do
(when platform/ios?
@@ -64,8 +63,8 @@
(orientation/lock-to-portrait "lightbox"))
(js/setTimeout #(when @flat-list-ref
(.scrollToOffset
^js @flat-list-ref
#js {:animated false :offset (* (+ item-width seperator-width) @index)}))
^js @flat-list-ref
#js {:animated false :offset (* (+ item-width seperator-width) @index)}))
timeout)
(when platform/ios?
(top-view/animate-rotation result screen-width screen-height insets animations))))
@@ -125,57 +124,58 @@
;; we get `insets` from `screen-params` because trying to consume it from
;; lightbox screen causes lots of problems
(let [{:keys [messages index insets]} (rf/sub [:get-screen-params])
atoms {:flat-list-ref (atom nil)
:small-list-ref (atom nil)
:scroll-index-lock? (atom true)}
render-list (reagent/atom false)
atoms {:flat-list-ref (atom nil)
:small-list-ref (atom nil)
:scroll-index-lock? (atom true)}
;; The initial value of data is the image that was pressed (and not the whole album) in order
;; for the transition animation to execute properly, otherwise it would animate towards
;; outside the screen (even if we have `initialScrollIndex` set).
data (reagent/atom [(nth messages index)])
scroll-index (reagent/atom index)
transparent? (reagent/atom false)
set-full-height? (reagent/atom false)
window (rf/sub [:dimensions/window])
window-width (:width window)
window-height (:height window)
window-height (if platform/android?
(+ window-height (:top insets))
window-height)
animations {:background-color (anim/use-val "rgba(0,0,0,0)")
:border (anim/use-val (if platform/ios? 0 12))
:opacity (anim/use-val 0)
:rotate (anim/use-val "0deg")
:layout (anim/use-val -10)
:top-view-y (anim/use-val 0)
:top-view-x (anim/use-val 0)
:top-view-width (anim/use-val window-width)
:top-view-bg (anim/use-val colors/neutral-100-opa-0)
:pan-y (anim/use-val 0)
:pan-x (anim/use-val 0)}
derived {:top-layout (worklet/info-layout (:layout animations)
true)
:bottom-layout (worklet/info-layout (:layout animations)
false)}
callback (fn [e]
(on-viewable-items-changed e scroll-index atoms))]
data (reagent/atom [(nth messages index)])
scroll-index (reagent/atom index)
transparent? (reagent/atom false)
set-full-height? (reagent/atom false)
window (rf/sub [:dimensions/window])
window-width (:width window)
window-height (:height window)
window-height (if platform/android?
(+ window-height (:top insets))
window-height)
animations {:background-color (anim/use-val "rgba(0,0,0,0)")
:border (anim/use-val (if platform/ios? 0 12))
:opacity (anim/use-val 0)
:rotate (anim/use-val "0deg")
:layout (anim/use-val -10)
:top-view-y (anim/use-val 0)
:top-view-x (anim/use-val 0)
:top-view-width (anim/use-val window-width)
:top-view-bg (anim/use-val colors/neutral-100-opa-0)
:pan-y (anim/use-val 0)
:pan-x (anim/use-val 0)}
derived {:top-layout (worklet/info-layout (:layout animations)
true)
:bottom-layout (worklet/info-layout (:layout animations)
false)}
callback (fn [e]
(on-viewable-items-changed e scroll-index atoms))]
(anim/animate (:background-color animations) "rgba(0,0,0,1)")
(reset! data messages)
(orientation/use-device-orientation-change
(fn [result]
(if platform/ios?
(handle-orientation result scroll-index window-width window-height animations insets atoms)
;; `use-device-orientation-change` will always be called on Android, so need to check
(orientation/get-auto-rotate-state
(fn [enabled?]
;; RNN does not support landscape-right
(when (and enabled? (not= result orientation/landscape-right))
(handle-orientation result
scroll-index
window-width
window-height
animations
insets
atoms)))))))
(fn [result]
(if platform/ios?
(handle-orientation result scroll-index window-width window-height animations insets atoms)
;; `use-device-orientation-change` will always be called on Android, so need to check
(orientation/get-auto-rotate-state
(fn [enabled?]
;; RNN does not support landscape-right
(when (and enabled? (not= result orientation/landscape-right))
(handle-orientation result
scroll-index
window-width
window-height
animations
insets
atoms)))))))
(rn/use-effect (fn []
(when @(:flat-list-ref atoms)
(.scrollToIndex ^js @(:flat-list-ref atoms)
@@ -186,11 +186,11 @@
(anim/animate (:border animations) 12))
(if platform/ios? 250 100))
(js/setTimeout #(reset! (:scroll-index-lock? atoms) false) 300)
(js/setTimeout #(reset! render-list true) 500)
(fn []
(rf/dispatch [:chat.ui/zoom-out-signal nil])
(when platform/android?
(rf/dispatch [:chat.ui/lightbox-scale 1])))))
[:f>
(fn []
(let [curr-orientation (or (rf/sub [:lightbox/orientation]) orientation/portrait)
@@ -204,14 +204,18 @@
window-height
window-width)
item-width (if (and landscape? platform/ios?) screen-height screen-width)]
;[gesture/flat-list
; {:data [1]
; :horizontal true
; :render-fn (fn [] [rn/view {:style {:width 300 :height 300 :background-color :red}
; :native-ID :shared-element}])}]
;[rn/view {:style (merge (style/image (+ screen-width seperator-width) screen-height) {:background-color :black})}
;[reanimated/fast-image
; {:source {:uri (:image (:content (nth messages index)))}
; :native-ID :shared-element
; :style {:width window-width
; :height (* (:image-height (nth messages index)) (/ window-width (:image-width (nth messages index))))}
; ;:style (style/image dimensions animations (:border-value args))
; }]]
[reanimated/view
{:style (reanimated/apply-animations-to-style {:background-color (:background-color
animations)}
animations)}
{:height screen-height})}
;(when-not @transparent?
; [top-view/top-view (first messages) insets scroll-index animations derived landscape?
@@ -220,37 +224,53 @@
{:gesture (drag-gesture animations (and landscape? platform/ios?) set-full-height?)}
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:transform [{:translateY (:pan-y animations)}
{:translateX (:pan-x animations)}]}
{})}
[gesture/flat-list
{:ref #(reset! (:flat-list-ref atoms) %)
:key-fn :message-id
:style {:width (+ screen-width seperator-width)}
:data @data
:render-fn (fn [] [rn/view {:style {:width 300 :height 300 :background-color :red}
:native-ID :shared-element}])
:render-data {:opacity-value (:opacity animations)
:border-value (:border animations)
:transparent? transparent?
:set-full-height? set-full-height?
:screen-height screen-height
:screen-width screen-width
:window-height window-height
:window-width window-width
:atoms atoms}
:horizontal horizontal?
:inverted inverted?
:paging-enabled true
:get-item-layout (fn [_ index] (get-item-layout _ index item-width))
:viewability-config {:view-area-coverage-percent-threshold 50
:wait-for-interaction true}
:shows-vertical-scroll-indicator false
:shows-horizontal-scroll-indicator false
:on-viewable-items-changed callback}]]]
{:transform [{:translateY (:pan-y animations)}
{:translateX (:pan-x animations)}]}
{})}
(if @render-list
[gesture/flat-list
{:ref #(reset! (:flat-list-ref atoms) %)
:key-fn :message-id
:style {:width (+ screen-width seperator-width)}
:data @data
:render-fn image
:render-data {:opacity-value (:opacity animations)
:border-value (:border animations)
:transparent? transparent?
:set-full-height? set-full-height?
:screen-height screen-height
:screen-width screen-width
:window-height window-height
:window-width window-width
:atoms atoms}
:initial-scroll-index index
:horizontal horizontal?
:inverted inverted?
:paging-enabled true
:get-item-layout (fn [_ index] (get-item-layout _ index item-width))
:viewability-config {:view-area-coverage-percent-threshold 50
:wait-for-interaction true}
:shows-vertical-scroll-indicator false
:shows-horizontal-scroll-indicator false
:on-viewable-items-changed callback}]
[rn/view
{:style (style/image (+ screen-width seperator-width) screen-height)}
[rn/view {:style {:width window-width
:height (* (:image-height (nth messages index)) (/ window-width (:image-width (nth messages index))))}}
[reanimated/fast-image
{:source {:uri (:image (:content (nth messages index)))}
:native-ID :shared-element
:style {:border-radius 12
:width window-width
:height (* (:image-height (nth messages index)) (/ window-width (:image-width (nth messages index))))}
;:style (style/image dimensions animations (:border-value args))
}]
]
[rn/view {:style {:width seperator-width}}]]
)
]]
;(when (and (not @transparent?) (not landscape?))
; [bottom-view/bottom-view messages index scroll-index insets animations derived
; item-width atoms])
]
))]
))])
))]))])
@@ -272,12 +272,7 @@
animations
@set-full-height?
(= curr-orientation orientation/portrait))}
[rn/view {:style {:width 300 :height 300 :background-color :red}
:native-ID :shared-element}]
;[reanimated/fast-image
; {:source {:uri (:image content)}
; ;:native-ID (when focused? :shared-element)
; :native-ID :shared-element
; :style (style/image dimensions animations (:border-value args))}]
]]
))]))])
[reanimated/fast-image
{:source {:uri (:image content)}
:native-ID (when focused? :shared-element)
:style (style/image dimensions animations (:border-value args))}]]]))]))])
@@ -60,11 +60,9 @@
[fast-image/fast-image
{:style (style/image dimensions index portrait? images-count)
:source {:uri (:image (:content item))}
:native-ID :source-image
;:native-ID (when (and (= shared-element-id (:message-id item))
; (< index constants/max-album-photos))
; :shared-element)
}]
:native-ID (when (and (= shared-element-id (:message-id item))
(< index constants/max-album-photos))
:shared-element)}]
(when (and (> images-count constants/max-album-photos)
(= index (- constants/max-album-photos 1)))
[rn/view
@@ -2,7 +2,6 @@
(:require
[react-native.core :as rn]
[react-native.fast-image :as fast-image]
[react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area]
[status-im2.constants :as constants]
[utils.re-frame :as rf]
@@ -25,7 +24,6 @@
(let [shared-element-id (rf/sub [:shared-element-id])]
[rn/touchable-opacity
{:active-opacity 1
;:native-ID :source-image
:key message-id
:style {:margin-top (when (pos? index) 10)}
:on-long-press on-long-press
@@ -36,12 +34,7 @@
:insets insets}])}
(when (and (not= text "placeholder") (= index 0))
[rn/view {:style {:margin-bottom 10}} [text/text-content message context]])
[rn/view {:style {:width 300 :height 300 :background-color :red}
:native-ID :shared-element}]
;[fast-image/fast-image
; {:source {:uri (:image content)}
; :style (merge dimensions {:border-radius 12})
; :native-ID :shared-element
; ;:native-ID (when (= shared-element-id message-id) :shared-element)
; }]
]))))])
[fast-image/fast-image
{:source {:uri (:image content)}
:style (merge dimensions {:border-radius 12})
:native-ID (when (= shared-element-id message-id) :shared-element)}]]))))])
@@ -61,7 +61,7 @@
:source (get-in carousels [@carousel-index :image])}]
[quo/drawer-buttons
{:top-card {:on-press (fn []
(rf/dispatch [:navigate-to :new-to-status])
(rf/dispatch [:navigate-to :sign-in])
(rf/dispatch [:hide-terms-of-services-opt-in-screen]))
:heading (i18n/label :t/sign-in)
:accessibility-label :already-use-status-button}
@@ -0,0 +1,14 @@
(ns status-im2.contexts.onboarding.sign-in.style
(:require [quo2.foundations.colors :as colors]
[react-native.platform :as platform]))
(def navigation-bar {:height 56})
(def page-container
{:padding-top (if platform/ios? 44 0)
:position :absolute
:top 0
:bottom 0
:left 0
:right 0
:background-color colors/neutral-80-opa-80-blur})
@@ -0,0 +1,42 @@
(ns status-im2.contexts.onboarding.sign-in.view
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[status-im2.contexts.onboarding.sign-in.style :as style]
[utils.i18n :as i18n]
[status-im2.contexts.onboarding.common.background.view :as background]
[utils.re-frame :as rf]))
(defn navigation-bar
[]
[rn/view {:style style/navigation-bar}
[quo/page-nav
{:align-mid? true
:mid-section {:type :text-only :main-text ""}
:left-section {:type :blur-bg
:icon :i/arrow-left
:icon-override-theme :dark
:on-press #(rf/dispatch [:navigate-back])}
:right-section-buttons [{:type :blur-bg
:icon :i/info
:icon-override-theme :dark
:on-press #(js/alert "Pending")}]}]])
(defn page
[]
[rn/view {:style style/page-container}
[navigation-bar]
[rn/view {:style {:padding-horizontal 20}}
[quo/text
{:size :heading-1
:weight :semi-bold
:style {:color colors/white}} "Sign in by syncing"]
[quo/button
{:on-press #(rf/dispatch [:navigate-to :syncing-devices])
:style {}} (i18n/label :t/continue)]]])
(defn sign-in
[]
[rn/view {:style {:flex 1}}
[background/view true]
[page]])
@@ -0,0 +1,14 @@
(ns status-im2.contexts.onboarding.syncing.syncing-devices.style
(:require [quo2.foundations.colors :as colors]
[react-native.platform :as platform]))
(def navigation-bar {:height 56})
(def page-container
{:padding-top (if platform/ios? 44 0)
:position :absolute
:top 0
:bottom 0
:left 0
:right 0
:background-color colors/neutral-80-opa-80-blur})
@@ -0,0 +1,51 @@
(ns status-im2.contexts.onboarding.syncing.syncing-devices.view
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[status-im2.contexts.onboarding.syncing.syncing-devices.style :as style]
[utils.i18n :as i18n]
[status-im2.contexts.onboarding.common.background.view :as background]
[utils.re-frame :as rf]))
(defn navigation-bar
[]
[rn/view {:style style/navigation-bar}
[quo/page-nav
{:align-mid? true
:mid-section {:type :text-only :main-text ""}
:left-section {:type :blur-bg
:icon :i/arrow-left
:icon-override-theme :dark
:on-press #(rf/dispatch [:navigate-back])}
:right-section-buttons [{:type :blur-bg
:icon :i/info
:icon-override-theme :dark
:on-press #(js/alert "Pending")}]}]])
(defn page
[]
[rn/view {:style style/page-container}
[navigation-bar]
[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"]
[quo/button
{:on-press #(rf/dispatch [:navigate-to :enable-notifications])
:style {}} (i18n/label :t/continue)]]])
(defn syncing-devices
[]
[rn/view {:style {:flex 1}}
[background/view true]
[page]])
+44 -30
View File
@@ -1,27 +1,30 @@
(ns status-im2.navigation.screens
(:require [utils.i18n :as i18n] ;; TODO remove when not used anymore
[quo2.foundations.colors :as colors]
[react-native.platform :as platform]
[status-im.ui.screens.screens :as old-screens]
[status-im2.config :as config]
[status-im2.contexts.activity-center.view :as activity-center]
[status-im2.contexts.add-new-contact.views :as add-new-contact]
[status-im2.contexts.chat.lightbox.view :as lightbox]
[status-im2.contexts.chat.messages.view :as chat]
[status-im2.contexts.chat.photo-selector.album-selector.view :as album-selector]
[status-im2.contexts.chat.photo-selector.view :as photo-selector]
[status-im2.contexts.communities.discover.view :as communities.discover]
[status-im2.contexts.communities.overview.view :as communities.overview]
[status-im2.contexts.onboarding.common.intro.view :as intro]
[status-im2.contexts.onboarding.create-password.view :as create-password]
[status-im2.contexts.onboarding.create-profile.view :as create-profile]
[status-im2.contexts.onboarding.enable-biometrics.view :as enable-biometrics]
[status-im2.contexts.onboarding.enable-notifications.view :as enable-notifications]
[status-im2.contexts.onboarding.new-to-status.view :as new-to-status]
[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.view :as settings-syncing]))
(:require
[utils.i18n :as i18n] ;; TODO remove when not used anymore
[quo2.foundations.colors :as colors]
[react-native.platform :as platform]
[status-im.ui.screens.screens :as old-screens]
[status-im2.config :as config]
[status-im2.contexts.activity-center.view :as activity-center]
[status-im2.contexts.add-new-contact.views :as add-new-contact]
[status-im2.contexts.chat.lightbox.view :as lightbox]
[status-im2.contexts.chat.messages.view :as chat]
[status-im2.contexts.chat.photo-selector.album-selector.view :as album-selector]
[status-im2.contexts.chat.photo-selector.view :as photo-selector]
[status-im2.contexts.communities.discover.view :as communities.discover]
[status-im2.contexts.communities.overview.view :as communities.overview]
[status-im2.contexts.onboarding.common.intro.view :as intro]
[status-im2.contexts.onboarding.create-password.view :as create-password]
[status-im2.contexts.onboarding.create-profile.view :as create-profile]
[status-im2.contexts.onboarding.enable-biometrics.view :as enable-biometrics]
[status-im2.contexts.onboarding.enable-notifications.view :as enable-notifications]
[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.profiles.view :as profiles]
[status-im2.contexts.quo-preview.main :as quo.preview]
[status-im2.contexts.shell.view :as shell]
[status-im2.contexts.syncing.view :as settings-syncing]))
(def components
[])
@@ -64,8 +67,7 @@
{:name :lightbox
:insets {:top false :bottom false}
:options {
:topBar {:visible false}
:options {:topBar {:visible false}
:statusBar {:backgroundColor :transparent
:style :light
:animate true
@@ -76,15 +78,13 @@
:backgroundColor :transparent}
:animations {:push {:sharedElementTransitions [{:fromId :shared-element
:toId :shared-element
:interpolation {:type
:decelerate
:interpolation {:type :decelerate
:factor 1.5}}]}
:pop {:sharedElementTransitions [{:fromId :shared-element
:toId :shared-element
:interpolation {:type
:decelerate
:factor 1.5}}]}
}}
:factor 1.5}}]}}}
:component lightbox/lightbox}
{:name :photo-selector
:options {:topBar {:visible false}}
@@ -151,7 +151,21 @@
:topBar {:visible false}
:navigationBar {:backgroundColor colors/black}}
:insets {:top false}
:component enable-notifications/enable-notifications}]
:component enable-notifications/enable-notifications}
{:name :sign-in
:options {:statusBar {:style :light}
:topBar {:visible false}
:navigationBar {:backgroundColor colors/black}}
:insets {:top false}
:component sign-in/sign-in}
{:name :syncing-devices
:options {:statusBar {:style :light}
:topBar {:visible false}
:navigationBar {:backgroundColor colors/black}}
:insets {:top false}
:component syncing-devices/syncing-devices}]
(when config/quo-preview-enabled?
quo.preview/screens)