Add device name to pairing

Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
Andrea Maria Piana 2019-01-14 15:43:34 +01:00
parent a825175aea
commit 2b2c44c9a5
No known key found for this signature in database
GPG Key ID: AA6CCA6DE0E06424
15 changed files with 174 additions and 43 deletions

View File

@ -358,6 +358,20 @@
dapp-permissions/v9 dapp-permissions/v9
contact-recovery/v1]) contact-recovery/v1])
(def v33 [chat/v13
transport/v7
contact/v3
message/v9
mailserver/v11
mailserver-topic/v1
user-status/v2
membership-update/v1
installation/v3
local-storage/v1
browser/v8
dapp-permissions/v9
contact-recovery/v1])
;; put schemas ordered by version ;; put schemas ordered by version
(def schemas [{:schema v1 (def schemas [{:schema v1
:schemaVersion 1 :schemaVersion 1
@ -454,4 +468,7 @@
:migration (constantly nil)} :migration (constantly nil)}
{:schema v32 {:schema v32
:schemaVersion 32 :schemaVersion 32
:migration (constantly nil)}
{:schema v33
:schemaVersion 33
:migration (constantly nil)}]) :migration (constantly nil)}])

View File

@ -18,3 +18,6 @@
:enabled? {:type :bool :enabled? {:type :bool
:optional true :optional true
:default false}}}) :default false}}})
(def v3 (assoc-in v2 [:properties :name] {:type :string
:optional true}))

View File

@ -222,3 +222,6 @@
{:type :string :optional true} {:type :string :optional true}
:keycard-paired-on :keycard-paired-on
{:type :int :optional true}})) {:type :int :optional true}}))
(def v18 (assoc-in v17
[:properties :installation-name]
{:type :string :optional true}))

View File

@ -81,6 +81,11 @@
extension/v12 extension/v12
account/v17]) account/v17])
(def v22 [network/v1
bootnode/v4
extension/v12
account/v18])
;; put schemas ordered by version ;; put schemas ordered by version
(def schemas [{:schema v1 (def schemas [{:schema v1
:schemaVersion 1 :schemaVersion 1
@ -144,4 +149,7 @@
:migration migrations/v20} :migration migrations/v20}
{:schema v21 {:schema v21
:schemaVersion 21 :schemaVersion 21
:migration migrations/v21}]) :migration migrations/v21}
{:schema v22
:schemaVersion 22
:migration (constantly nil)}])

View File

@ -1507,6 +1507,11 @@
(fn [cofx _] (fn [cofx _]
(pairing/pair-installation cofx))) (pairing/pair-installation cofx)))
(handlers/register-handler-fx
:pairing.ui/set-name-pressed
(fn [cofx [_ installation-name]]
(pairing/set-name cofx installation-name)))
(handlers/register-handler-fx (handlers/register-handler-fx
:pairing.ui/synchronize-installation-pressed :pairing.ui/synchronize-installation-pressed
(fn [cofx _] (fn [cofx _]

View File

@ -25,9 +25,10 @@
(js->clj :keywordize-keys true))) (js->clj :keywordize-keys true)))
(defn pair-installation [cofx] (defn pair-installation [cofx]
(let [installation-id (get-in cofx [:db :account/account :installation-id]) (let [installation-name (get-in cofx [:db :account/account :installation-name])
installation-id (get-in cofx [:db :account/account :installation-id])
device-type utils.platform/os] device-type utils.platform/os]
(protocol/send (transport.pairing/PairInstallation. installation-id device-type) nil cofx))) (protocol/send (transport.pairing/PairInstallation. installation-id device-type installation-name) nil cofx)))
(defn has-paired-installations? [cofx] (defn has-paired-installations? [cofx]
(->> (->>
@ -243,16 +244,22 @@
#(when (:public? chat) #(when (:public? chat)
(models.chat/start-public-chat % (:chat-id chat) {:dont-navigate? true}))))))) (models.chat/start-public-chat % (:chat-id chat) {:dont-navigate? true})))))))
(defn handle-pair-installation [{:keys [db] :as cofx} {:keys [installation-id device-type]} timestamp sender] (defn handle-pair-installation [{:keys [db] :as cofx} {:keys [name installation-id device-type]} timestamp sender]
(let [dev-mode? (get-in db [:account/account :dev-mode?])] (let [dev-mode? (get-in db [:account/account :dev-mode?])]
(when (and (config/pairing-enabled? dev-mode?) (when (and (config/pairing-enabled? dev-mode?)
(= sender (accounts.db/current-public-key cofx)) (= sender (accounts.db/current-public-key cofx))
(not= (get-in db [:account/account :installation-id]) installation-id)) (not= (get-in db [:account/account :installation-id]) installation-id))
(let [installation {:installation-id installation-id (let [installation {:installation-id installation-id
:device-type device-type :name name
:last-paired timestamp}] :device-type device-type
:last-paired timestamp}]
(upsert-installation cofx installation))))) (upsert-installation cofx installation)))))
(fx/defn set-name [{:keys [db] :as cofx} installation-name]
(let [new-account (assoc (get-in cofx [:db :account/account]) :installation-name installation-name)]
{:db (assoc db :account/account new-account)
:data-store/base-tx [(data-store.accounts/save-account-tx new-account)]}))
(fx/defn load-installations [{:keys [db all-installations]}] (fx/defn load-installations [{:keys [db all-installations]}]
{:db (assoc db :pairing/installations (reduce {:db (assoc db :pairing/installations (reduce
(fn [acc {:keys [installation-id] :as i}] (fn [acc {:keys [installation-id] :as i}]

View File

@ -4,7 +4,7 @@
[taoensso.timbre :as log])) [taoensso.timbre :as log]))
(defrecord PairInstallation (defrecord PairInstallation
[installation-id device-type] [installation-id device-type name]
protocol/StatusMessage protocol/StatusMessage
(validate [this] (validate [this]
(if (spec/valid? :message/pair-installation this) (if (spec/valid? :message/pair-installation this)

View File

@ -92,8 +92,8 @@
(deftype PairInstallationHandler [] (deftype PairInstallationHandler []
Object Object
(tag [this v] "p2") (tag [this v] "p2")
(rep [this {:keys [installation-id device-type]}] (rep [this {:keys [name installation-id device-type]}]
#js [installation-id device-type])) #js [installation-id device-type name]))
(def writer (transit/writer :json (def writer (transit/writer :json
{:handlers {:handlers
@ -156,8 +156,8 @@
(group-chat/GroupMembershipUpdate. chat-id membership-updates message)) (group-chat/GroupMembershipUpdate. chat-id membership-updates message))
"p1" (fn [[contacts account chat]] "p1" (fn [[contacts account chat]]
(pairing/SyncInstallation. contacts account chat)) (pairing/SyncInstallation. contacts account chat))
"p2" (fn [[installation-id device-type]] "p2" (fn [[installation-id device-type name]]
(pairing/PairInstallation. installation-id device-type))}})) (pairing/PairInstallation. installation-id device-type name))}}))
(defn serialize (defn serialize
"Serializes a record implementing the StatusMessage protocol using the custom writers" "Serializes a record implementing the StatusMessage protocol using the custom writers"

View File

@ -79,16 +79,21 @@
[react/text {:style styles/qr-code-copy-text} [react/text {:style styles/qr-code-copy-text}
(i18n/label :copy-qr)]]]]])) (i18n/label :copy-qr)]]]]]))
(defn installations-section [your-installation-id installations] (defn installations-section [your-installation-id
your-installation-name
installations]
[react/view [react/view
[pairing.views/pair-this-device] (if (string/blank? your-installation-name)
[pairing.views/sync-devices] [pairing.views/edit-installation-name]
[react/view {:style pairing.styles/installation-list} [react/view
[pairing.views/your-device your-installation-id] [pairing.views/pair-this-device]
(for [installation installations] [pairing.views/sync-devices]
^{:key (:installation-id installation)} [react/view {:style pairing.styles/installation-list}
[react/view {:style {:margin-bottom 10}} [pairing.views/your-device your-installation-id your-installation-name]
(pairing.views/render-row installation)])]]) (for [installation installations]
^{:key (:installation-id installation)}
[react/view {:style {:margin-bottom 10}}
(pairing.views/render-row installation)])]])])
(defn connection-status (defn connection-status
"generates a composite message of the current connection state given peer and mailserver statuses" "generates a composite message of the current connection state given peer and mailserver statuses"
@ -194,11 +199,15 @@
:on-value-change #(re-frame/dispatch [:accounts.ui/toggle-pfs (not pfs?)])}]]]))) :on-value-change #(re-frame/dispatch [:accounts.ui/toggle-pfs (not pfs?)])}]]])))
(views/defview installations [] (views/defview installations []
(views/letsubs [installations [:pairing/installations] (views/letsubs [installations [:pairing/installations]
installation-id [:pairing/installation-id]] installation-id [:pairing/installation-id]
installation-name [:pairing/installation-name]]
[react/scroll-view [react/scroll-view
(when (config/pairing-enabled? true) (when (config/pairing-enabled? true)
(installations-section installation-id installations))])) (installations-section
installation-id
installation-name
installations))]))
(views/defview backup-recovery-phrase [] (views/defview backup-recovery-phrase []
[profile.recovery/backup-seed]) [profile.recovery/backup-seed])

View File

@ -1,5 +1,7 @@
(ns status-im.ui.screens.pairing.styles (ns status-im.ui.screens.pairing.styles
(:require [status-im.ui.components.colors :as colors]) (:require
[status-im.ui.components.styles :as styles]
[status-im.ui.components.colors :as colors])
(:require-macros [status-im.utils.styles :refer [defnstyle defstyle]])) (:require-macros [status-im.utils.styles :refer [defnstyle defstyle]]))
(def wrapper (def wrapper
@ -25,6 +27,10 @@
:padding-horizontal 16 :padding-horizontal 16
:flex 1}) :flex 1})
(def edit-installation
{:padding-top 10
:padding-horizontal 16})
(def footer-content {:justify-content :center (def footer-content {:justify-content :center
:flex 1 :flex 1
:align-items :center}) :align-items :center})
@ -76,3 +82,23 @@
(def paired-devices-title (def paired-devices-title
{:color colors/gray {:color colors/gray
:margin-vertical 10}) :margin-vertical 10})
(def bottom-container
{:flex-direction :row
:margin-horizontal 12
:margin-vertical 15})
(def input-container
{:flex-direction :row
:align-items :center
:justify-content :space-between
:border-radius styles/border-radius
:height 52
:margin-top 15})
(defstyle input
{:flex 1
:font-size 15
:letter-spacing -0.2
:android {:padding 0}})

View File

@ -12,3 +12,7 @@
(re-frame/reg-sub :pairing/installation-id (re-frame/reg-sub :pairing/installation-id
:<- [:get :account/account] :<- [:get :account/account]
:installation-id) :installation-id)
(re-frame/reg-sub :pairing/installation-name
:<- [:get :account/account]
(fn [account] (:installation-name account)))

View File

@ -3,6 +3,7 @@
(:require [re-frame.core :as re-frame] (:require [re-frame.core :as re-frame]
[status-im.i18n :as i18n] [status-im.i18n :as i18n]
[reagent.core :as reagent] [reagent.core :as reagent]
[clojure.string :as string]
[status-im.utils.config :as config] [status-im.utils.config :as config]
[status-im.ui.screens.main-tabs.styles :as main-tabs.styles] [status-im.ui.screens.main-tabs.styles :as main-tabs.styles]
[status-im.ui.components.colors :as colors] [status-im.ui.components.colors :as colors]
@ -11,16 +12,20 @@
[status-im.utils.platform :as utils.platform] [status-im.utils.platform :as utils.platform]
[status-im.utils.gfycat.core :as gfycat] [status-im.utils.gfycat.core :as gfycat]
[status-im.ui.components.button.view :as buttons] [status-im.ui.components.button.view :as buttons]
[status-im.ui.components.styles :as components.styles]
[status-im.ui.components.common.common :as components.common]
[status-im.ui.components.checkbox.view :as checkbox.views] [status-im.ui.components.checkbox.view :as checkbox.views]
[status-im.ui.components.list.views :as list] [status-im.ui.components.list.views :as list]
[status-im.ui.components.react :as react] [status-im.ui.components.react :as react]
[status-im.ui.components.status-bar.view :as status-bar] [status-im.ui.components.status-bar.view :as status-bar]
[status-im.ui.components.toolbar.view :as toolbar] [status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.components.toolbar.actions :as toolbar.actions] [status-im.ui.components.toolbar.actions :as toolbar.actions]
[status-im.ui.components.text-input.view :as text-input]
[status-im.ui.screens.profile.components.views :as profile.components] [status-im.ui.screens.profile.components.views :as profile.components]
[status-im.ui.screens.pairing.styles :as styles])) [status-im.ui.screens.pairing.styles :as styles]))
(def syncing (reagent/atom false)) (def syncing (reagent/atom false))
(def installation-name (reagent/atom ""))
(defn icon-style [{:keys [width height] :as style}] (defn icon-style [{:keys [width height] :as style}]
(if utils.platform/desktop? (if utils.platform/desktop?
@ -90,7 +95,7 @@
(i18n/label :t/syncing-devices) (i18n/label :t/syncing-devices)
(i18n/label :t/sync-all-devices))]]]]]) (i18n/label :t/sync-all-devices))]]]]])
(defn your-device [installation-id] (defn your-device [installation-id installation-name]
[react/view {:style styles/installation-item} [react/view {:style styles/installation-item}
[react/view {:style (styles/pairing-button true)} [react/view {:style (styles/pairing-button true)}
[icons/icon (if utils.platform/desktop? [icons/icon (if utils.platform/desktop?
@ -101,12 +106,17 @@
[react/view [react/view
[react/text {:style styles/installation-item-name-text} [react/text {:style styles/installation-item-name-text}
(str (str
(gfycat/generate-gfy installation-id) installation-name
" (" " ("
(i18n/label :t/you) (i18n/label :t/you)
", "
(subs installation-id 0 5)
")")]]]]) ")")]]]])
(defn render-row [{:keys [device-type enabled? installation-id]}] (defn render-row [{:keys [name
device-type
enabled?
installation-id]}]
[react/touchable-highlight [react/touchable-highlight
{:accessibility-label :installation-item} {:accessibility-label :installation-item}
[react/view {:style styles/installation-item} [react/view {:style styles/installation-item}
@ -119,7 +129,13 @@
[react/view {:style styles/pairing-actions-text} [react/view {:style styles/pairing-actions-text}
[react/view [react/view
[react/text {:style styles/installation-item-name-text} [react/text {:style styles/installation-item-name-text}
(gfycat/generate-gfy installation-id)]]] (if (string/blank? name)
(str
(i18n/label :t/pairing-no-info)
" ("
(subs installation-id 0 5)
")")
name)]]]
[react/view [react/view
(if utils.platform/ios? (if utils.platform/ios?
;; On IOS switches seems to be broken, they take up value of dev-mode? (so if dev mode is on they all show to be on). ;; On IOS switches seems to be broken, they take up value of dev-mode? (so if dev mode is on they all show to be on).
@ -130,23 +146,46 @@
:value enabled? :value enabled?
:on-value-change (partial toggle-enabled! installation-id enabled?)}])]]]) :on-value-change (partial toggle-enabled! installation-id enabled?)}])]]])
(defn render-rows [installation-id installations] (defn render-rows [installation-id installation-name installations]
[react/scroll-view {:style styles/wrapper} [react/scroll-view {:style styles/wrapper}
[your-device installation-id] [your-device installation-id installation-name]
(when (seq installations) (when (seq installations)
[list/flat-list {:data installations [list/flat-list {:data installations
:default-separator? false :default-separator? false
:key-fn :installation-id :key-fn :installation-id
:render-fn render-row}])]) :render-fn render-row}])])
(defn installations-list [installation-id installations] (views/defview edit-installation-name []
[react/keyboard-avoiding-view styles/edit-installation
[react/scroll-view {:keyboard-should-persist-taps :handled}
[react/view
[react/text (i18n/label :t/pairing-please-set-a-name)]]
[text-input/text-input-with-label
{:placeholder (i18n/label :t/specify-name)
:style styles/input
:container styles/input-container
:default-value @installation-name
:on-change-text #(reset! installation-name %)
:auto-focus true}]]
[react/view styles/bottom-container
[react/view components.styles/flex]
[components.common/bottom-button
{:forward? true
:label (i18n/label :t/continue)
:disabled? (string/blank? @installation-name)
:on-press #(do
(re-frame/dispatch [:pairing.ui/set-name-pressed @installation-name])
(reset! installation-name ""))}]]])
(defn installations-list [installation-id installation-name installations]
[react/view {:style styles/installation-list} [react/view {:style styles/installation-list}
[react/view {:style styles/paired-devices-title} [react/view {:style styles/paired-devices-title}
[react/text (i18n/label :t/paired-devices)]] [react/text (i18n/label :t/paired-devices)]]
(render-rows installation-id installations)]) (render-rows installation-id installation-name installations)])
(views/defview installations [] (views/defview installations []
(views/letsubs [installation-id [:pairing/installation-id] (views/letsubs [installation-id [:pairing/installation-id]
installation-name [:pairing/installation-name]
installations [:pairing/installations]] installations [:pairing/installations]]
[react/view {:flex 1} [react/view {:flex 1}
[status-bar/status-bar] [status-bar/status-bar]
@ -154,6 +193,9 @@
toolbar/default-nav-back toolbar/default-nav-back
[toolbar/content-title (i18n/label :t/devices)]] [toolbar/content-title (i18n/label :t/devices)]]
[react/scroll-view {:style {:background-color :white}} [react/scroll-view {:style {:background-color :white}}
[pair-this-device] (if (string/blank? installation-name)
[installations-list installation-id installations]] [edit-installation-name]
[react/view
[pair-this-device]
[installations-list installation-id installation-name installations]])]
(when (seq installations) [footer syncing])])) (when (seq installations) [footer syncing])]))

View File

@ -98,7 +98,9 @@
:source source :source source
:value value}])) :value value}]))
(defn- my-profile-settings [{:keys [seed-backed-up? mnemonic]} {:keys [settings]} currency logged-in?] (defn- my-profile-settings [{:keys [seed-backed-up? mnemonic]}
{:keys [dev-mode?
settings]} currency logged-in?]
(let [show-backup-seed? (and (not seed-backed-up?) (not (string/blank? mnemonic)))] (let [show-backup-seed? (and (not seed-backed-up?) (not (string/blank? mnemonic)))]
[react/view [react/view
[profile.components/settings-title (i18n/label :t/settings)] [profile.components/settings-title (i18n/label :t/settings)]
@ -125,6 +127,13 @@
{:label-kw :t/backup-your-recovery-phrase {:label-kw :t/backup-your-recovery-phrase
:action-fn #(re-frame/dispatch [:navigate-to :backup-seed]) :action-fn #(re-frame/dispatch [:navigate-to :backup-seed])
:icon-content [components.common/counter {:size 22} 1]}]) :icon-content [components.common/counter {:size 22} 1]}])
(when (config/pairing-enabled? dev-mode?)
[profile.components/settings-item-separator])
(when (config/pairing-enabled? dev-mode?)
[profile.components/settings-item
{:label-kw :t/devices
:action-fn #(re-frame/dispatch [:navigate-to :installations])
:accessibility-label :pairing-settings-button}])
[profile.components/settings-item-separator] [profile.components/settings-item-separator]
[profile.components/settings-switch-item [profile.components/settings-switch-item
{:label-kw :t/web3-opt-in {:label-kw :t/web3-opt-in
@ -193,13 +202,6 @@
{:label-kw :t/bootnodes {:label-kw :t/bootnodes
:action-fn #(re-frame/dispatch [:navigate-to :bootnodes-settings]) :action-fn #(re-frame/dispatch [:navigate-to :bootnodes-settings])
:accessibility-label :bootnodes-settings-button}]) :accessibility-label :bootnodes-settings-button}])
(when (config/pairing-enabled? dev-mode?)
[profile.components/settings-item-separator])
(when (config/pairing-enabled? dev-mode?)
[profile.components/settings-item
{:label-kw :t/devices
:action-fn #(re-frame/dispatch [:navigate-to :installations])
:accessibility-label :pairing-settings-button}])
(when dev-mode? (when dev-mode?
[profile.components/settings-item-separator]) [profile.components/settings-item-separator])
(when dev-mode? (when dev-mode?

View File

@ -171,12 +171,14 @@
"2" {:has-bundle? false "2" {:has-bundle? false
:installation-id "2"}}}} :installation-id "2"}}}}
pair-message {:device-type "ios" pair-message {:device-type "ios"
:name "name"
:installation-id "1"}] :installation-id "1"}]
(testing "not coming from us" (testing "not coming from us"
(is (not (pairing/handle-pair-installation cofx pair-message 1 "not-us")))) (is (not (pairing/handle-pair-installation cofx pair-message 1 "not-us"))))
(testing "coming from us" (testing "coming from us"
(is (= {"1" {:has-bundle? true (is (= {"1" {:has-bundle? true
:installation-id "1" :installation-id "1"
:name "name"
:last-paired 1 :last-paired 1
:device-type "ios"} :device-type "ios"}
"2" {:has-bundle? false "2" {:has-bundle? false

View File

@ -3,6 +3,7 @@
"transaction-details": "Transaction details", "transaction-details": "Transaction details",
"confirm": "Confirm", "confirm": "Confirm",
"warning": "Warning", "warning": "Warning",
"continue": "Continue",
"public-chat": "Public chat", "public-chat": "Public chat",
"description": "Description", "description": "Description",
"devices": "Devices", "devices": "Devices",
@ -22,6 +23,8 @@
"pairing-new-installation-detected-title": "New device detected", "pairing-new-installation-detected-title": "New device detected",
"pairing-new-installation-detected-content": "A new device has been detected.\nIn order to use your devices correctly, it's important to pair and enable them before using them.\nPlease go to the device section under settings to pair your devices.", "pairing-new-installation-detected-content": "A new device has been detected.\nIn order to use your devices correctly, it's important to pair and enable them before using them.\nPlease go to the device section under settings to pair your devices.",
"pairing-go-to-installation": "Go to pairing settings", "pairing-go-to-installation": "Go to pairing settings",
"pairing-please-set-a-name": "Please set a name for your device.",
"pairing-no-info": "No info",
"currency-display-name-tzs": "Tanzanian Shilling", "currency-display-name-tzs": "Tanzanian Shilling",
"currency-display-name-brl": "Brazil Real", "currency-display-name-brl": "Brazil Real",
"mainnet-network": "Main network", "mainnet-network": "Main network",