chore: add generate code to new sync ui (#15584)
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 539 KiB After Width: | Height: | Size: 539 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 153 KiB |
Before Width: | Height: | Size: 377 KiB |
Before Width: | Height: | Size: 738 KiB |
|
@ -132,8 +132,9 @@
|
|||
:text text}])]]))))
|
||||
|
||||
(defn- password-input
|
||||
[_]
|
||||
(let [password-shown? (reagent/atom false)]
|
||||
[{:keys [default-shown?]
|
||||
:or {default-shown? false}}]
|
||||
(let [password-shown? (reagent/atom default-shown?)]
|
||||
(fn [props]
|
||||
[base-input
|
||||
(assoc props
|
||||
|
@ -161,6 +162,7 @@
|
|||
- :label - A string to set as label for this input.
|
||||
- :char-limit - A number to set a maximum char limit for this input.
|
||||
- :on-char-limit-reach - Function executed each time char limit is reached or exceeded.
|
||||
- :default-shown? - boolean to show password input initially
|
||||
and supports the usual React Native's TextInput properties to control its behaviour:
|
||||
- :value
|
||||
- :default-value
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
{:no-color true})))
|
||||
|
||||
(defn left-section-view
|
||||
[{:keys [on-press icon accessibility-label type icon-background-color] :or {type :grey}}
|
||||
[{:keys [on-press icon accessibility-label type icon-background-color icon-override-theme]
|
||||
:or {type :grey}}
|
||||
put-middle-section-on-left?]
|
||||
[rn/view {:style (when put-middle-section-on-left? {:margin-right 5})}
|
||||
[button/button
|
||||
|
@ -39,6 +40,7 @@
|
|||
:type type
|
||||
:size 32
|
||||
:accessibility-label accessibility-label
|
||||
:override-theme icon-override-theme
|
||||
:override-background-color icon-background-color}
|
||||
icon]])
|
||||
|
||||
|
@ -150,7 +152,7 @@
|
|||
:justify-content :flex-end)}
|
||||
(let [last-icon-index (-> right-section-buttons count dec)]
|
||||
(map-indexed (fn [index
|
||||
{:keys [icon on-press type style icon-override-theme accessibility-label]
|
||||
{:keys [icon on-press type style icon-override-theme accessibility-label label]
|
||||
:or {type :grey}}]
|
||||
^{:key index}
|
||||
[rn/view
|
||||
|
@ -161,11 +163,12 @@
|
|||
:accessible true))
|
||||
[button/button
|
||||
{:on-press on-press
|
||||
:icon true
|
||||
:icon (not label)
|
||||
:type type
|
||||
:before (when label icon)
|
||||
:size 32
|
||||
:override-theme icon-override-theme}
|
||||
icon]])
|
||||
(if label label icon)]])
|
||||
right-section-buttons))])
|
||||
|
||||
(defn page-nav
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
(ns quo2.components.share.qr-code.style)
|
||||
(ns quo2.components.share.qr-code.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(def container
|
||||
{:flex-direction :row
|
||||
|
@ -6,7 +7,8 @@
|
|||
|
||||
(defn image
|
||||
[width height]
|
||||
{:width width
|
||||
:height height
|
||||
:border-radius 12
|
||||
:aspect-ratio 1})
|
||||
{:width width
|
||||
:height height
|
||||
:background-color colors/white-opa-70
|
||||
:border-radius 12
|
||||
:aspect-ratio 1})
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
(ns react-native.hooks
|
||||
(:require ["@react-native-community/hooks" :as hooks]))
|
||||
(:require ["@react-native-community/hooks" :as hooks]
|
||||
[react-native.core :as rn]
|
||||
[oops.core :as oops]))
|
||||
|
||||
(defn use-keyboard
|
||||
[]
|
||||
|
@ -10,3 +12,21 @@
|
|||
(defn use-back-handler
|
||||
[handler]
|
||||
(.useBackHandler hooks handler))
|
||||
|
||||
(defn use-interval
|
||||
[cb cleanup-cb delay]
|
||||
(let [saved-callback (rn/use-ref)]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(oops/oset! saved-callback "current" cb))
|
||||
[cb])
|
||||
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(let [tick (oops/oget saved-callback "current")]
|
||||
(when delay
|
||||
(let [id (js/setInterval tick delay)]
|
||||
(fn []
|
||||
(cleanup-cb)
|
||||
(js/clearInterval id))))))
|
||||
[delay])))
|
||||
|
|
|
@ -8,4 +8,4 @@
|
|||
(def clippath (reagent/adapt-react-class Svg/ClipPath))
|
||||
(def defs (reagent/adapt-react-class Svg/Defs))
|
||||
(def circle (reagent/adapt-react-class Svg/Circle))
|
||||
|
||||
(def svgxml (reagent/adapt-react-class Svg/SvgXml))
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
(ns status-im.ui.components.qr-code-viewer.views
|
||||
(:require ["qrcode" :as qr-code-js]
|
||||
["react-native-svg" :refer (SvgXml)]
|
||||
[cljs-bean.core :as bean]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.ui.components.qr-code-viewer.styles :as styles]
|
||||
[status-im.ui.components.react :as react]))
|
||||
|
||||
(def svgxml (reagent/adapt-react-class SvgXml))
|
||||
|
||||
(defn qr-code
|
||||
[{:keys [size value]}]
|
||||
(let [uri (reagent/atom nil)]
|
||||
(.toString
|
||||
qr-code-js
|
||||
value
|
||||
(bean/->js {:margin 0 :width size})
|
||||
#(reset! uri %2))
|
||||
(fn []
|
||||
(when @uri
|
||||
[svgxml {:xml @uri :width size :height size}]))))
|
||||
|
||||
(defn qr-code-view
|
||||
"Qr Code view including the frame.
|
||||
Note: `size` includes frame with `styles/qr-code-padding.`"
|
||||
[size value]
|
||||
(when (and size value)
|
||||
[react/view
|
||||
{:style (styles/qr-code-container size)
|
||||
:accessibility-label :qr-code-image}
|
||||
[qr-code
|
||||
{:value value
|
||||
:size (- size (* styles/qr-code-padding 2))}]]))
|
|
@ -11,7 +11,7 @@
|
|||
[status-im.ui.components.copyable-text :as copyable-text]
|
||||
[status-im.ui.components.list-selection :as list-selection]
|
||||
[status-im.ui.components.profile-header.view :as profile-header]
|
||||
[status-im.ui.components.qr-code-viewer.views :as qr-code-viewer]
|
||||
[status-im2.common.qr-code-viewer.view :as qr-code-viewer]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.screens.profile.user.edit-picture :as edit]
|
||||
[status-im.ui.screens.profile.user.styles :as styles]
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
[status-im.ethereum.eip681 :as eip681]
|
||||
[utils.i18n :as i18n]
|
||||
[status-im.ui.components.copyable-text :as copyable-text]
|
||||
[status-im.ui.components.qr-code-viewer.views :as qr-code-viewer]
|
||||
[status-im2.common.qr-code-viewer.view :as qr-code-viewer]
|
||||
[status-im.ui.components.react :as react])
|
||||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
(ns status-im.ui.components.qr-code-viewer.styles
|
||||
(ns status-im2.common.qr-code-viewer.style
|
||||
(:require [quo.design-system.colors :as colors]))
|
||||
|
||||
(def qr-code-padding 16)
|
||||
|
@ -14,4 +14,4 @@
|
|||
:align-items :center
|
||||
:justify-content :center
|
||||
:border-width 1
|
||||
:border-radius 8})
|
||||
:border-radius 8})
|
|
@ -0,0 +1,31 @@
|
|||
(ns status-im2.common.qr-code-viewer.view
|
||||
(:require ["qrcode" :as qr-code-js]
|
||||
[cljs-bean.core :as bean]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.qr-code-viewer.style :as style]
|
||||
[react-native.core :as rn]
|
||||
[react-native.svg :as svg]))
|
||||
|
||||
(defn qr-code
|
||||
[{:keys [size value]}]
|
||||
(let [uri (reagent/atom nil)]
|
||||
(.toString
|
||||
qr-code-js
|
||||
value
|
||||
(bean/->js {:margin 0 :width size})
|
||||
#(reset! uri %2))
|
||||
(fn []
|
||||
(when @uri
|
||||
[svg/svgxml {:xml @uri :width size :height size}]))))
|
||||
|
||||
(defn qr-code-view
|
||||
"Qr Code view including the frame.
|
||||
Note: `size` includes frame with `style/qr-code-padding.`"
|
||||
[size value]
|
||||
(when (and size value)
|
||||
[rn/view
|
||||
{:style (style/qr-code-container size)
|
||||
:accessibility-label :qr-code-image}
|
||||
[qr-code
|
||||
{:value value
|
||||
:size (- size (* style/qr-code-padding 2))}]]))
|
|
@ -5,11 +5,12 @@
|
|||
:lifestyle (js/require "../resources/images/ui2/lifestyle.png")
|
||||
:music (js/require "../resources/images/ui2/music.png")
|
||||
:podcasts (js/require "../resources/images/ui2/podcasts.png")
|
||||
:sync-device (js/require "../resources/images/ui2/sync-new-device-cover-background.png")
|
||||
:generate-keys (js/require "../resources/images/ui2/generate_keys.png")
|
||||
:ethereum-address (js/require "../resources/images/ui2/ethereum_address.png")
|
||||
:generate-keys (js/require "../resources/images/ui2/generate-keys.png")
|
||||
:ethereum-address (js/require "../resources/images/ui2/ethereum-address.png")
|
||||
:use-keycard (js/require "../resources/images/ui2/keycard.png")
|
||||
:onboarding-illustration (js/require "../resources/images/ui2/onboarding_illustration.png")})
|
||||
:onboarding-illustration (js/require "../resources/images/ui2/onboarding_illustration.png")
|
||||
:qr-code (js/require "../resources/images/ui2/qr-code.png")
|
||||
})
|
||||
|
||||
(def mock-images
|
||||
{:coinbase (js/require "../resources/images/mock2/coinbase.png")
|
||||
|
|
|
@ -158,4 +158,4 @@
|
|||
[background/view true]
|
||||
[page
|
||||
{:navigation-bar-top top
|
||||
:onboarding-profile-data onboarding-profile-data}]]))])
|
||||
:onboarding-profile-data onboarding-profile-data}]]))])
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
(ns status-im2.contexts.syncing.events
|
||||
(:require [status-im.native-module.core :as status]
|
||||
[status-im2.contexts.syncing.sheets.enter-password.view :as sheet]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]
|
||||
|
@ -62,15 +61,12 @@
|
|||
|
||||
(rf/defn preparations-for-connection-string
|
||||
{:events [:syncing/get-connection-string-for-bootstrapping-another-device]}
|
||||
[{:keys [db]} entered-password]
|
||||
[{:keys [db]} entered-password set-code]
|
||||
(let [valid-password? (>= (count entered-password) constants/min-password-length)
|
||||
show-sheet (fn [connection-string]
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn []
|
||||
[sheet/qr-code-view-with-connection-string
|
||||
connection-string])}])
|
||||
(rf/dispatch [:syncing/update-role constants/local-pairing-role-sender]))]
|
||||
(set-code connection-string)
|
||||
(rf/dispatch [:syncing/update-role constants/local-pairing-role-sender])
|
||||
(rf/dispatch [:bottom-sheet/hide]))]
|
||||
(if valid-password?
|
||||
(let [sha3-pwd (status/sha3 (str (security/safe-unmask-data entered-password)))
|
||||
key-uid (get-in db [:multiaccount :key-uid])
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
(ns status-im2.contexts.syncing.setup-syncing.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn container-main
|
||||
[top]
|
||||
{:background-color colors/neutral-95
|
||||
:flex 1
|
||||
:padding-top top})
|
||||
|
||||
(def page-container
|
||||
{:margin-horizontal 20})
|
||||
|
||||
(def title-container
|
||||
{:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content :space-between})
|
||||
|
||||
(def navigation-bar
|
||||
{:height 56})
|
||||
|
||||
(def sync-code
|
||||
{:margin-top 36})
|
||||
|
||||
(defn qr-container
|
||||
[valid-code?]
|
||||
(merge {:margin-top 12
|
||||
:background-color colors/white-opa-5
|
||||
:border-radius 20
|
||||
:padding 12}
|
||||
(if valid-code?
|
||||
{:flex 1}
|
||||
{:aspect-ratio 1})))
|
||||
|
||||
(def sub-text-container
|
||||
{:margin-bottom 8
|
||||
:justify-content :space-between
|
||||
:align-items :center
|
||||
:flex-direction :row})
|
||||
|
||||
(def valid-cs-container
|
||||
{:flex 1
|
||||
:margin 12})
|
||||
|
||||
(def generate-button
|
||||
{:position :absolute
|
||||
:top "50%"
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0
|
||||
:margin-horizontal 60})
|
|
@ -0,0 +1,148 @@
|
|||
(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]))
|
||||
|
||||
(def code-valid-for-ms 120000)
|
||||
(def one-min-ms 60000)
|
||||
|
||||
(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 :grey
|
||||
:icon :i/close
|
||||
:icon-override-theme :dark
|
||||
:on-press #(rf/dispatch [:navigate-back])}
|
||||
:right-section-buttons [{:type :grey
|
||||
:label (i18n/label :t/how-to-scan)
|
||||
:icon :i/info
|
||||
:icon-override-theme :dark
|
||||
:on-press #(js/alert "to be implemented")}]}]])
|
||||
|
||||
(defn valid-cs?
|
||||
[connection-string]
|
||||
(when connection-string
|
||||
(string/starts-with?
|
||||
connection-string
|
||||
constants/local-pairing-connection-string-identifier)))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [valid-for-ms (reagent/atom code-valid-for-ms)
|
||||
code (reagent/atom nil)
|
||||
delay (reagent/atom nil)
|
||||
timestamp (reagent/atom nil)
|
||||
set-code (fn [connection-string]
|
||||
(when (valid-cs? connection-string)
|
||||
(reset! timestamp (* 1000 (js/Math.ceil (/ (datetime/timestamp) 1000))))
|
||||
(reset! delay 1000)
|
||||
(reset! code connection-string)))
|
||||
clock (fn []
|
||||
(if (pos? (- code-valid-for-ms
|
||||
(- (* 1000 (js/Math.ceil (/ (datetime/timestamp) 1000)))
|
||||
@timestamp)))
|
||||
(swap! valid-for-ms (fn [_]
|
||||
(- code-valid-for-ms
|
||||
(- (* 1000
|
||||
(js/Math.ceil (/ (datetime/timestamp) 1000)))
|
||||
@timestamp))))
|
||||
(reset! delay nil)))
|
||||
cleanup-clock (fn []
|
||||
(reset! code nil)
|
||||
(reset! timestamp nil)
|
||||
(reset! valid-for-ms code-valid-for-ms))]
|
||||
[:f>
|
||||
(fn []
|
||||
(hooks/use-interval clock
|
||||
cleanup-clock
|
||||
@delay)
|
||||
[safe-area/consumer
|
||||
(fn [{:keys [top]}]
|
||||
[rn/view {:style (style/container-main top)}
|
||||
[rn/scroll-view {}
|
||||
[navigation-bar]
|
||||
[rn/view {:style style/page-container}
|
||||
[rn/view {:style style/title-container}
|
||||
[quo/text
|
||||
{:size :heading-1
|
||||
: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)
|
||||
[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)
|
||||
[quo/button
|
||||
{:on-press (fn []
|
||||
;TODO https://github.com/status-im/status-mobile/issues/15570
|
||||
;remove old bottom sheet when Authentication process design is created.
|
||||
(rf/dispatch [:bottom-sheet/hide-old])
|
||||
(rf/dispatch [:bottom-sheet/show-sheet-old
|
||||
{:content (fn []
|
||||
[enter-password/sheet set-code])}]))
|
||||
:size 40
|
||||
:style style/generate-button
|
||||
:before :i/reveal} (i18n/label :t/reveal-sync-code)])
|
||||
(when (valid-cs? @code)
|
||||
[rn/view
|
||||
{:style style/valid-cs-container}
|
||||
[rn/view
|
||||
{:style style/sub-text-container}
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style {:color colors/white-opa-40}}
|
||||
(i18n/label :t/sync-code)]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style {:color (if (< @valid-for-ms one-min-ms)
|
||||
colors/danger-60
|
||||
colors/white-opa-40)}}
|
||||
(i18n/label :t/valid-for-time {:valid-for (datetime/ms-to-duration @valid-for-ms)})]]
|
||||
[quo/input
|
||||
{:default-value @code
|
||||
:type :password
|
||||
:override-theme :dark
|
||||
:default-shown? true
|
||||
:editable false}]
|
||||
[quo/button
|
||||
{:on-press (fn []
|
||||
(clipboard/set-string @code)
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:icon :correct
|
||||
:icon-color colors/success-50
|
||||
:text (i18n/label
|
||||
:t/sharing-copied-to-clipboard)}]))
|
||||
:override-theme :dark
|
||||
:type :grey
|
||||
:style {:margin-top 12}
|
||||
:before :i/copy}
|
||||
(i18n/label :t/copy-qr)]])]]
|
||||
[rn/view {:style style/sync-code}
|
||||
[quo/divider-label
|
||||
{:label (i18n/label :t/have-a-sync-code?)
|
||||
:increase-padding-top? true}]
|
||||
[quo/action-drawer
|
||||
[[{:icon :i/scan
|
||||
:override-theme :dark
|
||||
:on-press #(js/alert "to be implemented")
|
||||
:label (i18n/label :t/Scan-or-enter-sync-code)}]]]]]])])]))
|
|
@ -1,45 +1,14 @@
|
|||
(ns status-im2.contexts.syncing.sheets.enter-password.view
|
||||
(:require [clojure.string :as string]
|
||||
[utils.i18n :as i18n]
|
||||
(:require [utils.i18n :as i18n]
|
||||
[quo.core :as quo-old]
|
||||
[quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im.ui.components.qr-code-viewer.views :as qr-code-viewer]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn qr-code-view-with-connection-string
|
||||
[connection-string]
|
||||
(let [window-width (rf/sub [:dimensions/window-width])
|
||||
eighty-percent-screen-width (* window-width 0.8)
|
||||
valid-cs? (string/starts-with?
|
||||
connection-string
|
||||
constants/local-pairing-connection-string-identifier)]
|
||||
[:<>
|
||||
(if valid-cs?
|
||||
[rn/view {:margin 20}
|
||||
[quo/text
|
||||
{:accessibility-label :sync-code-generated
|
||||
:weight :bold
|
||||
:size :heading-1
|
||||
:style {:color colors/neutral-100
|
||||
:margin 20}}
|
||||
(i18n/label :t/sync-code-generated)]
|
||||
[qr-code-viewer/qr-code-view eighty-percent-screen-width connection-string]
|
||||
[quo/information-box
|
||||
{:type :informative
|
||||
:closable? false
|
||||
:icon :i/placeholder
|
||||
:style {:margin-top 20}} (i18n/label :t/instruction-after-qr-generated)]]
|
||||
[rn/view {:margin 20}
|
||||
[rn/view {:padding-horizontal 8}
|
||||
[quo/button
|
||||
{:on-press #(rf/dispatch [:preparations-for-connection-string])}
|
||||
(i18n/label :t/try-your-luck-again)]]])]))
|
||||
|
||||
;;TODO : this file is temporary and will be removed for new design auth method
|
||||
(defn sheet
|
||||
[]
|
||||
[set-code]
|
||||
(let [entered-password (atom "")]
|
||||
[:<>
|
||||
[rn/view {:margin 20}
|
||||
|
@ -53,7 +22,7 @@
|
|||
(i18n/label :t/enter-your-password)]
|
||||
[rn/view {:flex-direction :row :align-items :center}
|
||||
[rn/view {:flex 1}
|
||||
[quo-old/text-input ;;TODO : migrate text-input from quo to quo2 namespace
|
||||
[quo-old/text-input
|
||||
{:placeholder (i18n/label :t/enter-your-password)
|
||||
:auto-focus true
|
||||
:accessibility-label :password-input
|
||||
|
@ -64,6 +33,10 @@
|
|||
{:padding-horizontal 18
|
||||
:margin-top 20}
|
||||
[quo/button
|
||||
{:on-press #(rf/dispatch [:syncing/get-connection-string-for-bootstrapping-another-device
|
||||
@entered-password])}
|
||||
{:on-press (fn []
|
||||
;TODO https://github.com/status-im/status-mobile/issues/15570
|
||||
;remove old bottom sheet when Authentication process design is created.
|
||||
(rf/dispatch [:bottom-sheet/hide-old])
|
||||
(rf/dispatch [:syncing/get-connection-string-for-bootstrapping-another-device
|
||||
@entered-password set-code]))}
|
||||
(i18n/label :t/generate-scan-sync-code)]]]]]))
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
(ns status-im2.contexts.syncing.sheets.sync-device-notice.styles
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(def sync-devices-header
|
||||
{:width "100%"})
|
||||
|
||||
(def sync-devices-header-image
|
||||
{:width "100%"
|
||||
:height 192})
|
||||
|
||||
(def sync-devices-body-container
|
||||
{:margin-bottom 20
|
||||
:border-radius 20
|
||||
:z-index 2
|
||||
:margin-top -16
|
||||
:background-color colors/white
|
||||
:padding 20})
|
||||
|
||||
(def header-text
|
||||
{:color colors/neutral-100})
|
||||
|
||||
(def instructions-text
|
||||
{:color colors/neutral-100
|
||||
:margin-top 8})
|
||||
|
||||
(def list-item-text
|
||||
{:color colors/neutral-100
|
||||
:margin-top 18})
|
||||
|
||||
(def setup-syncing-button
|
||||
{:margin-top 21})
|
||||
|
||||
(def secondary-body-container
|
||||
{:margin-top 21})
|
|
@ -1,62 +0,0 @@
|
|||
(ns status-im2.contexts.syncing.sheets.sync-device-notice.view
|
||||
(:require [quo2.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.contexts.syncing.sheets.enter-password.view :as enter-password]
|
||||
[status-im2.contexts.syncing.sheets.sync-device-notice.styles :as styles]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.common.resources :as resources]))
|
||||
|
||||
(defn sheet
|
||||
[]
|
||||
[:<>
|
||||
[rn/view {:style styles/sync-devices-header}
|
||||
[rn/image
|
||||
{:source (resources/get-image :sync-device)
|
||||
:style styles/sync-devices-header-image}]]
|
||||
[rn/view {:style styles/sync-devices-body-container}
|
||||
[quo/text
|
||||
{:accessibility-label :privacy-policy
|
||||
:weight :bold
|
||||
:size :heading-1
|
||||
:style styles/header-text}
|
||||
(i18n/label :t/sync-new-device)]
|
||||
|
||||
[quo/text
|
||||
{:accessibility-label :privacy-policy
|
||||
:weight :regular
|
||||
:size :paragraph-1
|
||||
:style styles/instructions-text}
|
||||
(i18n/label :t/sync-instructions-text)]
|
||||
|
||||
[quo/text
|
||||
{:accessibility-label :privacy-policy
|
||||
:weight :regular
|
||||
:size :paragraph-2
|
||||
:style styles/list-item-text}
|
||||
(i18n/label :t/sync-instruction-step-1)]
|
||||
|
||||
[quo/text
|
||||
{:accessibility-label :privacy-policy
|
||||
:weight :regular
|
||||
:size :paragraph-2
|
||||
:style styles/list-item-text}
|
||||
(i18n/label :t/sync-instruction-step-2)]
|
||||
|
||||
[quo/text
|
||||
{:accessibility-label :privacy-policy
|
||||
:weight :regular
|
||||
:size :paragraph-2
|
||||
:style styles/list-item-text}
|
||||
(i18n/label :t/sync-instruction-step-3)]
|
||||
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:size 40
|
||||
:style styles/setup-syncing-button
|
||||
:before :i/face-id20
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
;; this should be a modal screen
|
||||
{:content (fn []
|
||||
[enter-password/sheet])}])}
|
||||
(i18n/label :t/setup-syncing)]]])
|
|
@ -1,4 +1,4 @@
|
|||
(ns status-im2.contexts.syncing.style
|
||||
(ns status-im2.contexts.syncing.syncing-devices-list.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(def container-main
|
|
@ -1,10 +1,9 @@
|
|||
(ns status-im2.contexts.syncing.view
|
||||
(ns status-im2.contexts.syncing.syncing-devices-list.view
|
||||
(:require [utils.i18n :as i18n]
|
||||
[quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.contexts.syncing.sheets.sync-device-notice.view :as sync-device-notice]
|
||||
[status-im2.contexts.syncing.style :as style]
|
||||
[status-im2.contexts.syncing.syncing-devices-list.style :as style]
|
||||
[status-im2.common.not-implemented :as not-implemented]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
|
@ -15,7 +14,7 @@
|
|||
[quo/page-nav
|
||||
{:align-mid? true
|
||||
:mid-section {:type :text-only :main-text ""}
|
||||
:left-section {:type :blur-bg
|
||||
:left-section {:type :grey
|
||||
:icon :i/arrow-left
|
||||
:icon-override-theme :dark
|
||||
:on-press #(rf/dispatch [:navigate-back])}}]])
|
||||
|
@ -64,10 +63,7 @@
|
|||
[quo/button
|
||||
{:size 32
|
||||
:icon true
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:show-handle? false
|
||||
:content (fn []
|
||||
[sync-device-notice/sheet])}])}
|
||||
:on-press #(rf/dispatch [:navigate-to :settings-setup-syncing])}
|
||||
:i/add]]
|
||||
[rn/view {:style style/devices-container}
|
||||
[render-device
|
|
@ -30,22 +30,26 @@
|
|||
:backgroundColor (colors/theme-colors colors/white colors/neutral-100)}}))
|
||||
|
||||
(defn navbar
|
||||
[]
|
||||
{:navigationBar {:backgroundColor (colors/theme-colors colors/white colors/neutral-100)}})
|
||||
([dark?]
|
||||
{:navigationBar {:backgroundColor (if (or dark? colors/dark?) colors/neutral-100 colors/white)}})
|
||||
([] (navbar nil)))
|
||||
|
||||
(defn statusbar
|
||||
[]
|
||||
(if platform/android?
|
||||
{:statusBar {:translucent true
|
||||
:backgroundColor :transparent
|
||||
:drawBehind true
|
||||
:style (if (colors/dark?) :light :dark)}}
|
||||
{:statusBar {:style (if (colors/dark?) :light :dark)}}))
|
||||
([dark?]
|
||||
(let [style (if (or dark? colors/dark?) :light :dark)]
|
||||
(if platform/android?
|
||||
{:statusBar {:translucent true
|
||||
:backgroundColor :transparent
|
||||
:drawBehind true
|
||||
:style style}}
|
||||
{:statusBar {:style style}})))
|
||||
([] (statusbar nil)))
|
||||
|
||||
|
||||
(defn statusbar-and-navbar
|
||||
[]
|
||||
(merge (navbar) (statusbar)))
|
||||
([dark?]
|
||||
(merge (navbar dark?) (statusbar dark?)))
|
||||
([] (statusbar-and-navbar nil)))
|
||||
|
||||
(defn topbar-options
|
||||
[]
|
||||
|
|
|
@ -24,12 +24,12 @@
|
|||
[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]
|
||||
[status-im2.contexts.syncing.syncing-devices-list.view :as settings-syncing]
|
||||
[status-im2.navigation.options :as options]
|
||||
[status-im2.contexts.chat.group-details.view :as group-details]
|
||||
|
||||
[status-im.ui.screens.screens :as old-screens]
|
||||
[status-im2.contexts.communities.menus.request-to-join.view :as join-menu]))
|
||||
[status-im2.contexts.communities.menus.request-to-join.view :as join-menu]
|
||||
[status-im2.contexts.syncing.setup-syncing.view :as settings-setup-syncing]))
|
||||
|
||||
(defn screens
|
||||
[]
|
||||
|
@ -81,10 +81,15 @@
|
|||
:component communities.overview/overview}
|
||||
|
||||
{:name :settings-syncing
|
||||
:options {:statusBar {:style :light}
|
||||
:insets {:top false}}
|
||||
:options (options/statusbar true)
|
||||
:component settings-syncing/view}
|
||||
|
||||
{:name :settings-setup-syncing
|
||||
:options (options/statusbar true)
|
||||
|
||||
:component settings-setup-syncing/view}
|
||||
|
||||
;; Onboarding
|
||||
{:name :profiles
|
||||
:component profiles/views}
|
||||
|
||||
|
|
|
@ -255,7 +255,7 @@
|
|||
(* 1000 sec))
|
||||
|
||||
(defn ms-to-duration
|
||||
"milisecods to mm:ss format"
|
||||
"miliseconds to mm:ss format"
|
||||
[ms]
|
||||
(let [sec (quot ms 1000)]
|
||||
(gstring/format "%02d:%02d" (quot sec 60) (mod sec 60))))
|
||||
|
|
|
@ -659,6 +659,7 @@
|
|||
"group-info": "Group info",
|
||||
"gwei": "Gwei",
|
||||
"hash": "Hash",
|
||||
"have-a-sync-code?": "Have a sync code?",
|
||||
"help": "help",
|
||||
"help-capitalized": "Help",
|
||||
"help-center": "Help Center",
|
||||
|
@ -669,6 +670,7 @@
|
|||
"hold-card": "Hold card to the back\n of your phone",
|
||||
"home": "Home",
|
||||
"hooks": "Hooks",
|
||||
"how-to-scan": "How to scan",
|
||||
"identifier": "Identifier",
|
||||
"if-you-cancel": "If you cancel, you can request to join this community at any point.",
|
||||
"image-remove-current": "Remove current photo",
|
||||
|
@ -1196,12 +1198,14 @@
|
|||
"reset-card": "Reset card",
|
||||
"reset-card-description": "This operation will reset card to initial state. It will erase all card data including private keys. Operation is not reversible.",
|
||||
"retry": "Retry",
|
||||
"reveal-sync-code": "Reveal sync code",
|
||||
"revoke-access": "Revoke access",
|
||||
"rpc-url": "RPC URL",
|
||||
"save": "Save",
|
||||
"save-password": "Save password",
|
||||
"save-password-unavailable": "Set device passcode to save password",
|
||||
"save-password-unavailable-android": "Save password is unavailable: your device may be rooted or lacks necessary security features.",
|
||||
"Scan-or-enter-sync-code": "Scan or enter sync code",
|
||||
"scan-qr": "Scan QR code",
|
||||
"scan-qr-code": "Scan a QR code with a wallet address",
|
||||
"search": "Search",
|
||||
|
@ -1411,6 +1415,7 @@
|
|||
"usd-currency": "USD",
|
||||
"use-the-multichain-wallet": "Use the leading multi-chain self-custodial wallet",
|
||||
"use-valid-contact-code": "Please enter or scan a valid chat key or username",
|
||||
"valid-for-time": "Valid for {{valid-for}}",
|
||||
"validation-amount-invalid-number": "Amount is not a valid number",
|
||||
"validation-amount-is-too-precise": "Amount is too precise. Max number of decimals is {{decimals}}.",
|
||||
"version": "App version",
|
||||
|
@ -1993,12 +1998,8 @@
|
|||
"local-pairing-experimental-mode": "Local Pairing Mode (alpha)",
|
||||
"syncing": "Syncing",
|
||||
"synced-devices": "Synced Devices",
|
||||
"sync-new-device": "Sync a new device",
|
||||
"sync-instructions-text": "You own your data. Synchronize it among all your devices.",
|
||||
"sync-instruction-step-1": "1. Verify login with password",
|
||||
"sync-instruction-step-2": "2. Reveal a temporary QR and Sync Code",
|
||||
"sync-instruction-step-3": "3. Share that info with your new device",
|
||||
"setup-syncing": "Setup Syncing",
|
||||
"sync-code": "Sync Code",
|
||||
"sync-code-generated": "Sync code generated",
|
||||
"generate-scan-sync-code": "Generate Scan Sync Code",
|
||||
"try-your-luck-again": "Try your luck again!",
|
||||
|
|