Add pairing/unpairing of devices (#19692)
* feat: added pairing/unpairing of synced devices * feat: remove flatlists & add confirmation/toast
This commit is contained in:
parent
8aa586fe6e
commit
cd54aa9b92
|
@ -1,17 +1,47 @@
|
||||||
(ns status-im.contexts.syncing.device.view
|
(ns status-im.contexts.syncing.device.view
|
||||||
(:require
|
(:require
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
|
[react-native.core :as rn]
|
||||||
[status-im.contexts.syncing.device.style :as style]
|
[status-im.contexts.syncing.device.style :as style]
|
||||||
[utils.i18n :as i18n]))
|
[utils.i18n :as i18n]
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(defn- hide-sheet
|
||||||
|
[]
|
||||||
|
(rf/dispatch [:hide-bottom-sheet]))
|
||||||
|
|
||||||
|
(defn- unpair-confirmation
|
||||||
|
[installation-id name]
|
||||||
|
(fn []
|
||||||
|
(let [unpair-device #(rf/dispatch [:syncing/disable-installation installation-id])]
|
||||||
|
[rn/view
|
||||||
|
[quo/drawer-top
|
||||||
|
{:title (i18n/label :t/unpair-device)
|
||||||
|
:description (i18n/label :t/unpair-device-description {:name name})}]
|
||||||
|
[quo/bottom-actions
|
||||||
|
{:actions :two-actions
|
||||||
|
:button-one-label (i18n/label :t/unpair)
|
||||||
|
:button-one-props {:type :danger
|
||||||
|
:on-press unpair-device}
|
||||||
|
:button-two-label (i18n/label :t/cancel)
|
||||||
|
:button-two-props {:type :grey
|
||||||
|
:on-press hide-sheet}}]])))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[{:keys [name
|
[{:keys [name
|
||||||
|
installation-id
|
||||||
this-device?
|
this-device?
|
||||||
device-type
|
device-type
|
||||||
enabled?
|
enabled?
|
||||||
show-button?]}]
|
show-button?]}]
|
||||||
(let [paired? (and (not this-device?) enabled?)
|
(let [paired? (and (not this-device?) enabled?)
|
||||||
unpaired? (not enabled?)]
|
unpaired? (not enabled?)
|
||||||
|
show-unpair-confirmation (fn []
|
||||||
|
(rf/dispatch [:show-bottom-sheet
|
||||||
|
{:theme :dark
|
||||||
|
:content (unpair-confirmation installation-id name)}]))
|
||||||
|
pair-device (fn []
|
||||||
|
(rf/dispatch [:syncing/enable-installation installation-id]))]
|
||||||
[quo/settings-item
|
[quo/settings-item
|
||||||
(cond->
|
(cond->
|
||||||
{:container-style style/device-container
|
{:container-style style/device-container
|
||||||
|
@ -24,13 +54,13 @@
|
||||||
(and show-button? unpaired?) (assoc
|
(and show-button? unpaired?) (assoc
|
||||||
:action :button
|
:action :button
|
||||||
:action-props
|
:action-props
|
||||||
{:title (i18n/label :t/pair)
|
{:button-text (i18n/label :t/pair)
|
||||||
:on-press #(js/alert "feature not added yet")})
|
:on-press pair-device})
|
||||||
(and show-button? paired?) (assoc
|
(and show-button? paired?) (assoc
|
||||||
:action :button
|
:action :button
|
||||||
:action-props
|
:action-props
|
||||||
{:button-text (i18n/label :t/unpair)
|
{:button-text (i18n/label :t/unpair)
|
||||||
:on-press #(js/alert "feature not added yet")})
|
:on-press show-unpair-confirmation})
|
||||||
this-device? (assoc
|
this-device? (assoc
|
||||||
:tag :positive
|
:tag :positive
|
||||||
:tag-props {:label (i18n/label :t/this-device)}))]))
|
:tag-props {:label (i18n/label :t/this-device)}))]))
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[status-im.contexts.syncing.utils :as sync-utils]
|
[status-im.contexts.syncing.utils :as sync-utils]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[utils.security.core :as security]
|
[utils.security.core :as security]
|
||||||
[utils.transforms :as transforms]))
|
[utils.transforms :as transforms]))
|
||||||
|
@ -111,3 +112,53 @@
|
||||||
(native-module/get-connection-string-for-bootstrapping-another-device
|
(native-module/get-connection-string-for-bootstrapping-another-device
|
||||||
config-map
|
config-map
|
||||||
handle-connection)))))
|
handle-connection)))))
|
||||||
|
|
||||||
|
(rf/reg-event-fx
|
||||||
|
:syncing/enable-installation
|
||||||
|
(fn [_ [installation-id]]
|
||||||
|
{:fx [[:json-rpc/call
|
||||||
|
[{:method "wakuext_enableInstallation"
|
||||||
|
:params [installation-id]
|
||||||
|
:on-success #(rf/dispatch [:syncing/on-enable-installation-success installation-id])
|
||||||
|
:on-error #(rf/dispatch [:syncing/on-toggle-installation-failed % installation-id])}]]]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx
|
||||||
|
:syncing/disable-installation
|
||||||
|
(fn [_ [installation-id]]
|
||||||
|
{:fx [[:json-rpc/call
|
||||||
|
[{:method "wakuext_disableInstallation"
|
||||||
|
:params [installation-id]
|
||||||
|
:on-success #(rf/dispatch [:syncing/on-disable-installation-success installation-id])
|
||||||
|
:on-error #(rf/dispatch [:syncing/on-toggle-installation-failed % installation-id])}]]]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx
|
||||||
|
:syncing/on-enable-installation-success
|
||||||
|
(fn [{:keys [db]} [installation-id]]
|
||||||
|
{:db (assoc-in db
|
||||||
|
[:pairing/installations installation-id :enabled?]
|
||||||
|
true)
|
||||||
|
:fx [[:dispatch
|
||||||
|
[:toasts/upsert
|
||||||
|
{:type :positive
|
||||||
|
:theme :dark
|
||||||
|
:text (i18n/label :t/pair-device-toast)}]]]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx
|
||||||
|
:syncing/on-disable-installation-success
|
||||||
|
(fn [{:keys [db]} [installation-id]]
|
||||||
|
{:db (assoc-in db
|
||||||
|
[:pairing/installations installation-id :enabled?]
|
||||||
|
false)
|
||||||
|
:fx [[:dispatch [:hide-bottom-sheet]]
|
||||||
|
[:dispatch
|
||||||
|
[:toasts/upsert
|
||||||
|
{:type :positive
|
||||||
|
:theme :dark
|
||||||
|
:text (i18n/label :t/unpair-device-toast)}]]]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx
|
||||||
|
:syncing/on-toggle-installation-failed
|
||||||
|
(fn [_ [error installation-id]]
|
||||||
|
(log/error "Failed to toggle installation"
|
||||||
|
{:error error
|
||||||
|
:installation-id installation-id})))
|
||||||
|
|
|
@ -9,9 +9,8 @@
|
||||||
:flex 1})
|
:flex 1})
|
||||||
|
|
||||||
(def page-container
|
(def page-container
|
||||||
{:flex 1
|
{:flex 1
|
||||||
:justify-content :flex-start
|
:padding-horizontal 20})
|
||||||
:margin-horizontal 20})
|
|
||||||
|
|
||||||
(def title-container
|
(def title-container
|
||||||
{:flex-direction :row
|
{:flex-direction :row
|
||||||
|
@ -20,9 +19,6 @@
|
||||||
:margin-top 12
|
:margin-top 12
|
||||||
:margin-bottom 12})
|
:margin-bottom 12})
|
||||||
|
|
||||||
(def navigation-bar
|
|
||||||
{:height 56})
|
|
||||||
|
|
||||||
(def subtitle
|
(def subtitle
|
||||||
{:margin-top 20
|
{:margin-top 20
|
||||||
:color colors/white-opa-40})
|
:color colors/white-opa-40})
|
||||||
|
|
|
@ -9,6 +9,14 @@
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(defn go-back
|
||||||
|
[]
|
||||||
|
(rf/dispatch [:navigate-back]))
|
||||||
|
|
||||||
|
(defn open-setup-syncing
|
||||||
|
[]
|
||||||
|
(rf/dispatch [:open-modal :settings-setup-syncing]))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
(let [devices (rf/sub [:pairing/installations])
|
(let [devices (rf/sub [:pairing/installations])
|
||||||
|
@ -25,8 +33,11 @@
|
||||||
{:type :no-title
|
{:type :no-title
|
||||||
:background :blur
|
:background :blur
|
||||||
:icon-name :i/arrow-left
|
:icon-name :i/arrow-left
|
||||||
:on-press #(rf/dispatch [:navigate-back])}]
|
:on-press go-back}]
|
||||||
[rn/view {:style style/page-container}
|
[rn/scroll-view
|
||||||
|
{:content-container-style style/page-container
|
||||||
|
:style {:flex 1}
|
||||||
|
:shows-vertical-scroll-indicator false}
|
||||||
[rn/view {:style style/title-container}
|
[rn/view {:style style/title-container}
|
||||||
[quo/text
|
[quo/text
|
||||||
{:size :heading-1
|
{:size :heading-1
|
||||||
|
@ -38,7 +49,7 @@
|
||||||
:type :primary
|
:type :primary
|
||||||
:customization-color profile-color
|
:customization-color profile-color
|
||||||
:icon-only? true
|
:icon-only? true
|
||||||
:on-press #(rf/dispatch [:open-modal :settings-setup-syncing])}
|
:on-press open-setup-syncing}
|
||||||
:i/add]]
|
:i/add]]
|
||||||
[device/view (merge user-device {:this-device? true})]
|
[device/view (merge user-device {:this-device? true})]
|
||||||
(when (seq paired-devices)
|
(when (seq paired-devices)
|
||||||
|
@ -48,10 +59,9 @@
|
||||||
:weight :medium
|
:weight :medium
|
||||||
:style style/subtitle}
|
:style style/subtitle}
|
||||||
(i18n/label :t/paired-with-this-device)]
|
(i18n/label :t/paired-with-this-device)]
|
||||||
[rn/flat-list
|
(for [device-props paired-devices]
|
||||||
{:key-fn str
|
^{:key (:installation-id device-props)}
|
||||||
:render-fn device/view
|
[device/view device-props])])
|
||||||
:data paired-devices}]])
|
|
||||||
(when (seq unpaired-devices)
|
(when (seq unpaired-devices)
|
||||||
[rn/view
|
[rn/view
|
||||||
[quo/text
|
[quo/text
|
||||||
|
@ -59,7 +69,6 @@
|
||||||
:weight :medium
|
:weight :medium
|
||||||
:style style/subtitle}
|
:style style/subtitle}
|
||||||
(i18n/label :t/not-paired-with-this-device)]
|
(i18n/label :t/not-paired-with-this-device)]
|
||||||
[rn/flat-list
|
(for [device-props unpaired-devices]
|
||||||
{:key-fn str
|
^{:key (:installation-id device-props)}
|
||||||
:render-fn device/view
|
[device/view device-props])])]]))
|
||||||
:data unpaired-devices}]])]]))
|
|
||||||
|
|
|
@ -1118,6 +1118,7 @@
|
||||||
"own-your-crypto": "Own your crypto",
|
"own-your-crypto": "Own your crypto",
|
||||||
"pair": "Pair",
|
"pair": "Pair",
|
||||||
"pair-devices": "Pair devices",
|
"pair-devices": "Pair devices",
|
||||||
|
"pair-device-toast": "Device successfully paired",
|
||||||
"pair-card": "Pair to this device",
|
"pair-card": "Pair to this device",
|
||||||
"pair-code": "Pair code",
|
"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-explanation": "Pairs card to a different device (up to 5) to unlock keys and sign transactions with the same Keycard",
|
||||||
|
@ -1476,6 +1477,9 @@
|
||||||
"unpair": "Unpair",
|
"unpair": "Unpair",
|
||||||
"unpair-card": "Unpair card",
|
"unpair-card": "Unpair card",
|
||||||
"unpair-card-confirmation": "This operation will unpair card from current device. Requires 6-digit passcode authorization. Do you want to proceed?",
|
"unpair-card-confirmation": "This operation will unpair card from current device. Requires 6-digit passcode authorization. Do you want to proceed?",
|
||||||
|
"unpair-device": "Unpair device?",
|
||||||
|
"unpair-device-description": "This device will no longer synchronize with {{name}} until you pair them again.",
|
||||||
|
"unpair-device-toast": "Device successfully unpaired",
|
||||||
"unpaired-keycard-text": "The Keycard you tapped is not associated with this phone",
|
"unpaired-keycard-text": "The Keycard you tapped is not associated with this phone",
|
||||||
"unpaired-keycard-title": "Looks like your card has been unpaired",
|
"unpaired-keycard-title": "Looks like your card has been unpaired",
|
||||||
"unpair-keycard": "Unpair Keycard from this phone",
|
"unpair-keycard": "Unpair Keycard from this phone",
|
||||||
|
|
Loading…
Reference in New Issue