Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a9ad0ccea | ||
|
|
a8a08c82b0 | ||
|
|
aa28678188 | ||
|
|
67aa733736 |
@@ -4,6 +4,7 @@
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.platform :as utils.platform]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[status-im.common.new-device-sheet.view :as new-device-sheet]
|
||||
[status-im.config :as config]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
@@ -220,6 +221,12 @@
|
||||
:name (:name metadata)
|
||||
:device-type (:deviceType metadata))})
|
||||
|
||||
|
||||
(defn should-show-syncing-pop-up?
|
||||
[db installations]
|
||||
(and (:syncing/pairing-process-initiated? db)
|
||||
(first (filter #(not (get-in db [:pairing/installations (:id %)])) installations))))
|
||||
|
||||
(rf/defn handle-installations
|
||||
[{:keys [db]} installations]
|
||||
{:db (update db
|
||||
@@ -228,7 +235,10 @@
|
||||
(fn [acc {:keys [id] :as i}]
|
||||
(update acc id merge (installation<-rpc i)))
|
||||
%
|
||||
installations))})
|
||||
installations))
|
||||
:fx [(when-let [new-installation (should-show-syncing-pop-up? db installations)]
|
||||
[:dispatch
|
||||
[:show-bottom-sheet {:content (fn [] [new-device-sheet/view (:id new-installation)])}]])]})
|
||||
|
||||
(rf/defn load-installations
|
||||
{:events [:pairing.callback/get-our-installations-success]}
|
||||
@@ -243,6 +253,24 @@
|
||||
{}
|
||||
installations))})
|
||||
|
||||
(rf/defn finish-seed-phrase-fallback-syncing
|
||||
{:events [:pairing/finish-seed-phrase-fallback-syncing]}
|
||||
[{:keys [db]}]
|
||||
{:fx [[:dispatch [:show-bottom-sheet {:content (fn [] [new-device-sheet/view-2])}]]
|
||||
[:json-rpc/call
|
||||
[{:method "wakuext_finishPairingThroughSeedPhraseProcess"
|
||||
:params [{:installationId (:syncing/installation-id db)}]
|
||||
:js-response true
|
||||
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])}]]]})
|
||||
|
||||
(rf/defn pair-and-sync
|
||||
{:events [:pairing/pair-and-sync]}
|
||||
[cofx installation-id]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_enableAndSyncInstallation"
|
||||
:params [{:installationId installation-id}]
|
||||
:on-success #(log/debug "successfully synced devices")}]]]})
|
||||
|
||||
(rf/defn enable-installation-success
|
||||
{:events [:pairing.callback/enable-installation-success]}
|
||||
[cofx installation-id]
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
(ns status-im.common.new-device-sheet.style
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(def heading
|
||||
{:padding-left 20
|
||||
:padding-bottom 8})
|
||||
|
||||
(def message
|
||||
{:padding-horizontal 20
|
||||
:padding-top 4})
|
||||
|
||||
(def warning
|
||||
{:margin-horizontal 20
|
||||
:margin-top 10})
|
||||
|
||||
(def drawer-container
|
||||
{:padding-horizontal 13
|
||||
:padding-top 16})
|
||||
|
||||
(def settings-subtext
|
||||
{:color colors/white-opa-70
|
||||
:align-self :center
|
||||
:margin-bottom 12})
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
(ns status-im.common.new-device-sheet.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[status-im.common.new-device-sheet.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- dismiss-keyboard
|
||||
[]
|
||||
(rf/dispatch [:dismiss-keyboard]))
|
||||
|
||||
(defn- hide-bottom-sheet
|
||||
[]
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
|
||||
(defn- pair-and-sync
|
||||
[installation-id]
|
||||
(rf/dispatch [:pairing/pair-and-sync installation-id])
|
||||
(hide-bottom-sheet))
|
||||
|
||||
(defn view
|
||||
[installation-id]
|
||||
(dismiss-keyboard)
|
||||
[:<>
|
||||
[quo/text
|
||||
{:weight :semi-bold
|
||||
:size :heading-2
|
||||
:accessibility-label :new-device-sheet-heading
|
||||
:style style/heading}
|
||||
(i18n/label :t/pair-new-device-and-sync)]
|
||||
[quo/text
|
||||
{:weight :regular
|
||||
:size :paragraph-1
|
||||
:accessibility-label :new-device-sheet-message
|
||||
:style style/message}
|
||||
(i18n/label :t/new-device-detected)]
|
||||
[quo/text
|
||||
{:weight :semi-bold
|
||||
:size :heading-2
|
||||
:accessibility-label :new-device-installation-id
|
||||
:style style/heading}
|
||||
installation-id]
|
||||
[quo/bottom-actions
|
||||
{:actions :two-actions
|
||||
:blur? true
|
||||
:container-style {:margin-top 12}
|
||||
:button-two-label (i18n/label :t/cancel)
|
||||
:button-two-props {:type :grey
|
||||
:on-press hide-bottom-sheet}
|
||||
:button-one-label (i18n/label :t/pair-and-sync)
|
||||
:button-one-props {:on-press #(pair-and-sync installation-id)}}]])
|
||||
|
||||
(defn view-2
|
||||
[]
|
||||
(let [installation-id (rf/sub [:profile/installation-id])]
|
||||
(dismiss-keyboard)
|
||||
[:<>
|
||||
[quo/text
|
||||
{:weight :semi-bold
|
||||
:size :heading-2
|
||||
:accessibility-label :new-device-sheet-heading
|
||||
:style style/heading}
|
||||
(i18n/label :t/pair-new-device-and-sync)]
|
||||
[quo/text
|
||||
{:weight :regular
|
||||
:size :paragraph-1
|
||||
:accessibility-label :new-device-sheet-message
|
||||
:style style/message}
|
||||
(i18n/label :t/check-new-device)]
|
||||
[quo/text
|
||||
{:weight :semi-bold
|
||||
:size :heading-2
|
||||
:accessibility-label :new-device-installation-id
|
||||
:style style/heading}
|
||||
installation-id]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:blur? true
|
||||
:container-style {:margin-top 12}
|
||||
:button-one-label (i18n/label :t/close)
|
||||
:button-one-props {:type :grey
|
||||
:on-press hide-bottom-sheet}}]]))
|
||||
@@ -17,3 +17,17 @@
|
||||
{:events [:onboarding/overlay-dismiss]}
|
||||
[_]
|
||||
{:onboarding/overlay-dismiss-fx nil})
|
||||
|
||||
(re-frame/reg-fx
|
||||
:onboarding/overlay-show-fx
|
||||
(fn []
|
||||
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
||||
(blur-show-fn))
|
||||
(when-let [push-animation-fn @profiles/push-animation-fn-atom]
|
||||
(push-animation-fn))))
|
||||
|
||||
(rf/defn overlay-show
|
||||
{:events [:onboarding/overlay-show]}
|
||||
[_]
|
||||
{:onboarding/overlay-show-fx nil})
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
(rf/dispatch [:push-notifications/switch true])
|
||||
(rf/dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.welcome
|
||||
:screen/onboarding.generating-keys]]))
|
||||
:screen/onboarding.enable-notifications]]))
|
||||
:type :primary
|
||||
:icon-left :i/notifications
|
||||
:accessibility-label :enable-notifications-button
|
||||
@@ -52,7 +52,7 @@
|
||||
nil)
|
||||
(rf/dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.welcome
|
||||
:screen/onboarding.generating-keys]]))
|
||||
:screen/onboarding.enable-notifications]]))
|
||||
:accessibility-label :enable-notifications-later-button
|
||||
:type :grey
|
||||
:background :blur
|
||||
|
||||
@@ -125,25 +125,31 @@
|
||||
mnemonic key-uid]))
|
||||
on-error]})
|
||||
|
||||
;; TODO: clear syncing data if key-uid does not match
|
||||
(rf/defn seed-phrase-validated
|
||||
{:events [:onboarding/seed-phrase-validated]}
|
||||
[{:keys [db]} seed-phrase key-uid]
|
||||
(if (contains? (:profile/profiles-overview db) key-uid)
|
||||
{:effects.utils/show-confirmation
|
||||
{:title (i18n/label :t/multiaccount-exists-title)
|
||||
:content (i18n/label :t/multiaccount-exists-content)
|
||||
:confirm-button-text (i18n/label :t/unlock)
|
||||
:on-accept (fn []
|
||||
(re-frame/dispatch [:pop-to-root :screen/profile.profiles])
|
||||
(re-frame/dispatch
|
||||
[:profile/profile-selected key-uid]))
|
||||
:on-cancel #(re-frame/dispatch [:pop-to-root :multiaccounts])}}
|
||||
{:db (assoc-in db [:onboarding/profile :seed-phrase] seed-phrase)
|
||||
:dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.create-profile
|
||||
(get db
|
||||
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
||||
:screen/onboarding.new-to-status)]]}))
|
||||
(let [next-screen (if (and (seq (:syncing/key-uid db))
|
||||
(= (:syncing/key-uid db) key-uid))
|
||||
:screen/onboarding.create-profile-password
|
||||
:screen/onboarding.create-profile)]
|
||||
|
||||
(if (contains? (:profile/profiles-overview db) key-uid)
|
||||
{:effects.utils/show-confirmation
|
||||
{:title (i18n/label :t/multiaccount-exists-title)
|
||||
:content (i18n/label :t/multiaccount-exists-content)
|
||||
:confirm-button-text (i18n/label :t/unlock)
|
||||
:on-accept (fn []
|
||||
(re-frame/dispatch [:pop-to-root :screen/profile.profiles])
|
||||
(re-frame/dispatch
|
||||
[:profile/profile-selected key-uid]))
|
||||
:on-cancel #(re-frame/dispatch [:pop-to-root :multiaccounts])}}
|
||||
{:db (assoc-in db [:onboarding/profile :seed-phrase] seed-phrase)
|
||||
:dispatch [:navigate-to-within-stack
|
||||
[next-screen
|
||||
(get db
|
||||
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
||||
:screen/onboarding.new-to-status)]]})))
|
||||
|
||||
(rf/defn navigate-to-create-profile
|
||||
{:events [:onboarding/navigate-to-create-profile]}
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(def absolute-fill
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0})
|
||||
|
||||
(defn page-container
|
||||
[in-onboarding?]
|
||||
{:flex 1
|
||||
|
||||
@@ -26,33 +26,62 @@
|
||||
:title-accessibility-label :progress-screen-title
|
||||
:description-accessibility-label :progress-screen-sub-title}])
|
||||
|
||||
(defn navigate-to-enter-seed-phrase
|
||||
[view-id]
|
||||
(if (= view-id :screen/onboarding.syncing-progress-intro)
|
||||
(do
|
||||
(rf/dispatch [:navigate-back-to :screen/onboarding.sync-or-recover-profile])
|
||||
(debounce/debounce-and-dispatch
|
||||
[:onboarding/navigate-to-sign-in-by-seed-phrase :screen/onboarding.sync-or-recover-profile]
|
||||
300))
|
||||
(do
|
||||
(rf/dispatch [:navigate-back])
|
||||
(debounce/debounce-and-dispatch [:onboarding/overlay-show] 100)
|
||||
(debounce/debounce-and-dispatch [:open-modal :screen/onboarding.new-to-status] 200)
|
||||
(debounce/debounce-and-dispatch
|
||||
[:onboarding/navigate-to-sign-in-by-seed-phrase :screen/onboarding.new-to-status]
|
||||
300))))
|
||||
|
||||
(defn try-again-button
|
||||
[profile-color in-onboarding? logged-in?]
|
||||
[quo/button
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:syncing/clear-states])
|
||||
(cond
|
||||
logged-in? (rf/dispatch [:navigate-back])
|
||||
in-onboarding? (rf/dispatch [:navigate-back-to
|
||||
:screen/onboarding.sign-in-intro])
|
||||
:else (do
|
||||
(rf/dispatch [:navigate-back])
|
||||
(debounce/throttle-and-dispatch
|
||||
[:open-modal
|
||||
:screen/onboarding.sign-in]
|
||||
1000))))
|
||||
:accessibility-label :try-again-later-button
|
||||
:customization-color profile-color
|
||||
:container-style style/try-again-button}
|
||||
(i18n/label :t/try-again)])
|
||||
[profile-color in-onboarding? logged-in? view-id]
|
||||
[rn/view
|
||||
(when-not logged-in?
|
||||
[quo/button
|
||||
{:on-press #(navigate-to-enter-seed-phrase view-id)
|
||||
:accessibility-label :try-seed-phrase-button
|
||||
:customization-color profile-color
|
||||
:container-style style/try-again-button}
|
||||
(i18n/label :t/enter-seed-phrase)])
|
||||
|
||||
|
||||
[quo/button
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:syncing/clear-states])
|
||||
(cond
|
||||
logged-in? (rf/dispatch [:navigate-back])
|
||||
in-onboarding? (rf/dispatch [:navigate-back-to
|
||||
:screen/onboarding.sign-in-intro])
|
||||
:else (do
|
||||
(rf/dispatch [:navigate-back])
|
||||
(debounce/throttle-and-dispatch
|
||||
[:open-modal
|
||||
:screen/onboarding.sign-in]
|
||||
1000))))
|
||||
:accessibility-label :try-again-later-button
|
||||
:customization-color profile-color
|
||||
:container-style style/try-again-button}
|
||||
(i18n/label :t/try-again)]])
|
||||
|
||||
(defn view
|
||||
[in-onboarding?]
|
||||
(let [pairing-status (rf/sub [:pairing/pairing-status])
|
||||
profile-color (:color (rf/sub [:onboarding/profile]))
|
||||
logged-in? (rf/sub [:multiaccount/logged-in?])]
|
||||
logged-in? (rf/sub [:multiaccount/logged-in?])
|
||||
view-id (rf/sub [:view-id])]
|
||||
[rn/view {:style (style/page-container in-onboarding?)}
|
||||
(when-not in-onboarding? [background/view true])
|
||||
(when-not in-onboarding?
|
||||
[rn/view {:style style/absolute-fill}
|
||||
[background/view true]])
|
||||
[quo/page-nav {:type :no-title :background :blur}]
|
||||
[page-title (pairing-progress pairing-status)]
|
||||
(if config/show-not-implemented-features?
|
||||
@@ -63,7 +92,7 @@
|
||||
[quo/text "[Error here]"]])
|
||||
[rn/view {:flex 1}])
|
||||
(when-not (pairing-progress pairing-status)
|
||||
[try-again-button profile-color in-onboarding? logged-in?])]))
|
||||
[try-again-button profile-color in-onboarding? logged-in? view-id])]))
|
||||
|
||||
(defn view-onboarding
|
||||
[]
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
|
||||
(def absolute-fill
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0})
|
||||
|
||||
(defn page-container
|
||||
[top]
|
||||
{:flex 1
|
||||
|
||||
@@ -66,7 +66,8 @@
|
||||
translate-x (reanimated/use-shared-value 0)
|
||||
window-width (:width (rn/get-window))]
|
||||
[rn/view {:style (style/page-container top)}
|
||||
[background/view true]
|
||||
[rn/view {:style style/absolute-fill}
|
||||
[background/view true]]
|
||||
[reanimated/view
|
||||
{:style (style/content translate-x)}
|
||||
[page-title]
|
||||
|
||||
@@ -124,6 +124,8 @@
|
||||
:on-success [:profile.login/node-info-fetched]
|
||||
:on-error #(log/error "node-info: failed error" %)}]]
|
||||
[:pairing/get-our-installations]
|
||||
(when (:syncing/installation-id db)
|
||||
[:dispatch [:pairing/finish-seed-phrase-fallback-syncing]])
|
||||
(when-not new-account?
|
||||
[:dispatch [:universal-links/process-stored-event]])]})))
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
(:require
|
||||
[native-module.core :as native-module]
|
||||
[status-im.common.emoji-picker.utils :as emoji-picker.utils]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.profile.config :as profile.config]
|
||||
status-im.contexts.profile.recover.effects
|
||||
[utils.re-frame :as rf]
|
||||
@@ -17,11 +18,11 @@
|
||||
(assoc-in [:syncing :login-sha3-password] login-sha3-password))
|
||||
|
||||
:effects.profile/restore-and-login
|
||||
(merge (profile.config/create)
|
||||
{:displayName display-name
|
||||
:mnemonic (security/safe-unmask-data seed-phrase)
|
||||
:password login-sha3-password
|
||||
:imagePath (profile.config/strip-file-prefix image-path)
|
||||
:customizationColor color
|
||||
:emoji (emoji-picker.utils/random-emoji)
|
||||
:fetchBackup true})}))
|
||||
(assoc (profile.config/create)
|
||||
:displayName display-name
|
||||
:mnemonic (security/safe-unmask-data seed-phrase)
|
||||
:password login-sha3-password
|
||||
:imagePath (profile.config/strip-file-prefix image-path)
|
||||
:customizationColor (or color constants/profile-default-color)
|
||||
:emoji (emoji-picker.utils/random-emoji)
|
||||
:fetchBackup true)}))
|
||||
|
||||
@@ -46,13 +46,29 @@
|
||||
(log/info "[local-pairing] input-connection-string-for-bootstrapping callback"
|
||||
{:response res
|
||||
:event :syncing/input-connection-string-for-bootstrapping})
|
||||
(let [error (when (sync-utils/extract-error res)
|
||||
(str "generic-error: " res))]
|
||||
(when (some? error)
|
||||
(let [response (transforms/json->clj res)
|
||||
installation-id (:installationId response)
|
||||
key-uid (:keyUID response)
|
||||
error (:error response)]
|
||||
(when (seq installation-id)
|
||||
(rf/dispatch [:syncing/set-syncing-installation-id installation-id key-uid]))
|
||||
(when (seq error)
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:type :negative
|
||||
:text error}]))))
|
||||
|
||||
(rf/defn initiate-pairing-process
|
||||
{:events [:syncing/initiate-pairing-process]}
|
||||
[{:keys [db]}]
|
||||
{:db (assoc db :syncing/pairing-process-initiated? true)})
|
||||
|
||||
(rf/defn set-syncing-installation-id
|
||||
{:events [:syncing/set-syncing-installation-id]}
|
||||
[{:keys [db]} installation-id key-uid]
|
||||
{:db (assoc db
|
||||
:syncing/key-uid key-uid
|
||||
:syncing/installation-id installation-id)})
|
||||
|
||||
(rf/defn preflight-outbound-check-for-local-pairing
|
||||
{:events [:syncing/preflight-outbound-check]}
|
||||
[_ set-checks-passed]
|
||||
@@ -96,6 +112,7 @@
|
||||
(when (sync-utils/valid-connection-string? response)
|
||||
(on-valid-connection-string response)
|
||||
(rf/dispatch [:syncing/update-role constants/local-pairing-role-sender])
|
||||
(rf/dispatch [:syncing/initiate-pairing-process])
|
||||
(rf/dispatch [:hide-bottom-sheet])))]
|
||||
(when-not (and error (string/blank? error))
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])
|
||||
|
||||
@@ -251,6 +251,11 @@
|
||||
(fn [{:keys [preview-privacy?]}]
|
||||
(boolean preview-privacy?)))
|
||||
|
||||
(re-frame/reg-sub :profile/installation-id
|
||||
:<- [:profile/profile]
|
||||
(fn [{:keys [installation-id]}]
|
||||
installation-id))
|
||||
|
||||
(defn- replace-multiaccount-image-uri
|
||||
[profile ens-names port font-file avatar-opts theme]
|
||||
(let [{:keys [key-uid ens-name? images
|
||||
|
||||
@@ -6,15 +6,14 @@
|
||||
prefer to use it for more general purpose concepts, such as the re-frame event
|
||||
layer."
|
||||
(:require-macros test-helpers.unit)
|
||||
(:require
|
||||
(:require ;; We must require this namespace to register the custom cljs.test
|
||||
;; directive `match-strict?`.
|
||||
[re-frame.core :as rf]
|
||||
[re-frame.db :as rf-db]
|
||||
[re-frame.events :as rf-events]
|
||||
[re-frame.registrar :as rf-registrar]
|
||||
[re-frame.subs :as rf-subs]
|
||||
[taoensso.timbre :as log]
|
||||
|
||||
;; We must require this namespace to register the custom cljs.test directive `match-strict?`.
|
||||
[taoensso.timbre :as log] ;; We must require this namespace to register the custom cljs.test
|
||||
test-helpers.matchers))
|
||||
|
||||
(defn db
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
||||
"owner": "status-im",
|
||||
"repo": "status-go",
|
||||
"version": "v0.182.37",
|
||||
"commit-sha1": "4a43b2b2bebe45df2100d1a5c5034105d93e50b8",
|
||||
"src-sha256": "0f5mm7lx6s2qcy9xpa9v7piqb60yazi6p677fy105yz7hg731cw6"
|
||||
"version": "feat/enable_sync_fallback",
|
||||
"commit-sha1": "880152abcac69bb7cf29088ce413d2c4e01be412",
|
||||
"src-sha256": "067pj4xx0bph9573sdk57hdhq0xkaaz1zmgkk09d27a5fz2rdm4n"
|
||||
}
|
||||
|
||||
@@ -357,6 +357,7 @@
|
||||
"check-before-syncing-doc-checkbox-2": "Make sure you are logged in on the other device",
|
||||
"check-before-syncing-doc-checkbox-3": "Disable the firewall and VPN on your devices",
|
||||
"check-before-syncing-doc-description": "To sync your devices successfully, make sure to check and complete these steps:",
|
||||
"check-new-device": "A new device has been detected. You can see device ID below and on your other device. Only confirm the request if device ID matches.",
|
||||
"check-on-block-explorer": "Check on block explorer",
|
||||
"check-on-opensea": "Check on opensea",
|
||||
"check-your-account-balance-and-activity": "Check your account balance and activity",
|
||||
@@ -1626,6 +1627,7 @@
|
||||
"new-community-title": "New community",
|
||||
"new-contact": "New contact",
|
||||
"new-contract": "New Contract",
|
||||
"new-device-detected": "A new device has been detected. You can see device ID below and on your other device. Only confirm the request if device ID matches.",
|
||||
"new-favourite": "New favourite",
|
||||
"new-group": "New group",
|
||||
"new-group-chat": "New group chat",
|
||||
@@ -1790,12 +1792,14 @@
|
||||
"page-camera-request-blocked": "camera requests blocked. To enable camera requests go to Settings",
|
||||
"page-would-like-to-use-camera": "would like to use your camera",
|
||||
"pair": "Pair",
|
||||
"pair-and-sync": "Pair and Sync",
|
||||
"pair-card": "Pair to this device",
|
||||
"pair-code": "Pair code",
|
||||
"pair-code-explanation": "Pairs card to a different device (up to 5) to unlock keys and sign transactions with the same Keycard",
|
||||
"pair-code-placeholder": "Pair code...",
|
||||
"pair-device-toast": "Device successfully paired",
|
||||
"pair-devices": "Pair devices",
|
||||
"pair-new-device-and-sync": "Pair new device and sync profile",
|
||||
"pair-this-card": "Pair this card",
|
||||
"pair-this-device": "Advertise device",
|
||||
"pair-this-device-description": "Pair your devices to sync contacts and chats between them",
|
||||
|
||||
Reference in New Issue
Block a user