feature #4255 - backup recovery phrase in desktop app

Signed-off-by: Goran Jovic <goranjovic@gmail.com>
This commit is contained in:
Goran Jovic 2018-09-28 15:34:04 +02:00
parent 5dec44340d
commit 22119ccf27
No known key found for this signature in database
GPG Key ID: D429D1A9B2EB8A8E
8 changed files with 69 additions and 43 deletions

View File

@ -53,11 +53,12 @@
:disabled active?
:on-press #(re-frame/dispatch [:show-desktop-tab view-id])}
[react/view
[content active? (if (= view-id :home) cnt nil)]]]))
[content active? cnt]]]))
(views/defview main-tabs []
(views/letsubs [current-tab [:get-in [:desktop/desktop :tab-view-id]]]
[react/view
[react/view {:style tabs.styles/tabs-container}
(for [[index {:keys [content view-id count-subscription]}] tabs-list-indexed]
^{:key index} [tab index content view-id (= current-tab view-id) count-subscription])]]))
^{:key index}
[tab index content view-id (= current-tab view-id) count-subscription])]]))

View File

@ -2,7 +2,6 @@
(:require-macros [status-im.utils.views :as views])
(:require [re-frame.core :as re-frame]
[status-im.ui.components.react :as react]
[status-im.ui.screens.profile.user.views :as profile]
[status-im.utils.build :as build]
[status-im.utils.utils :as utils]
[status-im.ui.components.colors :as colors]
@ -13,7 +12,9 @@
[status-im.ui.screens.offline-messaging-settings.views :as offline-messaging.views]
[status-im.ui.components.qr-code-viewer.views :as qr-code-viewer]
[status-im.ui.screens.desktop.main.tabs.profile.styles :as styles]
[status-im.ui.screens.profile.user.views :as profile]))
[status-im.ui.screens.profile.user.views :as profile]
[status-im.ui.screens.profile.seed.views :as profile.recovery]
[status-im.ui.components.common.common :as components.common]))
(defn profile-badge [{:keys [name photo-path]} editing?]
[react/view styles/profile-badge
@ -82,6 +83,9 @@
[react/view {:style {:margin-vertical 8}}
[render-fn node]])]])))
(views/defview backup-recovery-phrase []
[profile.recovery/backup-seed])
(defn share-contact-code []
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :qr-code])}
[react/view {:style styles/share-contact-code}
@ -92,10 +96,12 @@
:accessibility-label :share-my-contact-code-button}
[vector-icons/icon :icons/qr {:style {:tint-color colors/blue}}]]]])
(views/defview profile [user]
(views/defview profile [{:keys [seed-backed-up? mnemonic] :as user}]
(views/letsubs [current-view-id [:get :view-id]
editing? [:get :my-profile/editing?]] ;; TODO janherich: refactor my-profile, unnecessary complicated structure in db (could be just `:staged-name`/`:editing?` fields in account map) and horrible way to access it woth `:get`/`:set` subs/events
(let [adv-settings-open? (= current-view-id :advanced-settings)]
(let [adv-settings-open? (= current-view-id :advanced-settings)
backup-recovery-phrase-open? (= current-view-id :backup-recovery-phrase)
show-backup-seed? (and (not seed-backed-up?) (not (string/blank? mnemonic)))]
[react/view
[react/view {:style styles/profile-edit}
[react/touchable-highlight {:on-press #(re-frame/dispatch (if editing?
@ -113,6 +119,14 @@
:font (if adv-settings-open? :medium :default)}
(i18n/label :t/advanced-settings)]
[vector-icons/icon :icons/forward {:style {:tint-color colors/gray}}]]]
(when show-backup-seed?
[react/touchable-highlight {:style (styles/profile-row backup-recovery-phrase-open?)
:on-press #(re-frame/dispatch [:navigate-to :backup-recovery-phrase])}
[react/view {:style styles/adv-settings}
[react/text {:style (styles/profile-row-text colors/black)
:font (if backup-recovery-phrase-open? :medium :default)}
(i18n/label :wallet-backup-recovery-title)]
[components.common/counter {:size 22} 1]]])
[react/view {:style (styles/profile-row false)}
[react/touchable-highlight {:on-press #(re-frame/dispatch [:accounts.logout.ui/logout-confirmed])}
[react/text {:style (styles/profile-row-text colors/red)} (i18n/label :t/logout)]]

View File

@ -30,6 +30,7 @@
:qr-code profile.views/qr-code
:advanced-settings profile.views/advanced-settings
:chat-profile chat.views/chat-profile
:backup-recovery-phrase profile.views/backup-recovery-phrase
status-view)]
[react/view {:style {:flex 1}}
[component]])))

View File

@ -24,9 +24,11 @@
:contact-toggle-list contact-toggle-list
(:new-contact
:advanced-settings
:chat :home
:chat
:home
:qr-code
:chat-profile) main.views/main-views
:chat-profile
:backup-recovery-phrase) main.views/main-views
:login login.views/login
react/view)]
[react/view {:style {:flex 1}}

View File

@ -9,10 +9,6 @@
:source source
:value value})))
(defmethod navigation/preload-data! :backup-seed
[db]
(assoc db :my-profile/seed {:step :intro}))
(defmethod navigation/unload-data! :my-profile
[db]
(dissoc db :my-profile/editing?))

View File

@ -37,7 +37,7 @@
{:flex-direction :row})
(def six-word-num
{:width 20
{:width 25
:text-align :right
:opacity 0.4
:font-size 15

View File

@ -19,7 +19,8 @@
[status-im.utils.utils :as utils]
[status-im.ui.screens.profile.seed.styles :as styles]
[status-im.i18n :as i18n]
[status-im.ui.components.styles :as common.styles]))
[status-im.ui.components.styles :as common.styles]
[status-im.utils.platform :as platform]))
(def steps-numbers
{:intro 1
@ -36,8 +37,9 @@
(defn intro []
[react/view {:style styles/intro-container}
(when-not platform/desktop?
[components.common/image-contain {:container-style styles/intro-image}
(:lock resources/ui)]
(:lock resources/ui)])
[react/i18n-text {:style styles/intro-text
:key :your-data-belongs-to-you}]
[react/i18n-text {:style styles/intro-description
@ -80,7 +82,7 @@
{:forward? true
:on-press #(re-frame/dispatch [:my-profile/enter-two-random-words])}]]]))
(defview input [error]
(defview input [error next-handler]
(letsubs [ref (reagent/atom nil)]
{:component-did-mount (fn [_] (when config/testfairy-enabled?
(.hideView js-dependencies/testfairy @ref)))}
@ -89,26 +91,11 @@
:ref (partial reset! ref)
:auto-focus true
:on-change-text #(re-frame/dispatch [:set-in [:my-profile/seed :word] %])
:on-submit-editing next-handler
:error error}]))
(defn enter-word [step [idx word] error entered-word]
^{:key word}
[react/view {:style styles/enter-word-container}
[react/view {:style styles/enter-word-row}
[react/text {:style styles/enter-word-label}
(i18n/label :t/check-your-recovery-phrase)]
[react/text {:style styles/enter-word-n}
(i18n/label :t/word-n {:number (inc idx)})]]
[input error]
[react/text {:style styles/enter-word-n-description}
(i18n/label :t/word-n-description {:number (inc idx)})]
[react/view styles/twelve-words-spacer]
[react/view styles/twelve-words-button-container
[components.common/bottom-button
{:forward? (not= :second-word step)
:label (when (= :second-word step) (i18n/label :t/done))
:disabled? (string/blank? entered-word)
:on-press (fn [_]
(defn next-handler [word entered-word step]
(fn [_]
(cond (not= word entered-word)
(re-frame/dispatch [:set-in [:my-profile/seed :error] (i18n/label :t/wrong-word)])
@ -119,7 +106,26 @@
(utils/show-question
(i18n/label :t/are-you-sure?)
(i18n/label :t/are-you-sure-description)
#(re-frame/dispatch [:my-profile/finish]))))}]]])
#(re-frame/dispatch [:my-profile/finish])))))
(defn enter-word [step [idx word] error entered-word]
^{:key word}
[react/view {:style styles/enter-word-container}
[react/view {:style styles/enter-word-row}
[react/text {:style styles/enter-word-label}
(i18n/label :t/check-your-recovery-phrase)]
[react/text {:style styles/enter-word-n}
(i18n/label :t/word-n {:number (inc idx)})]]
[input error (next-handler word entered-word step)]
[react/text {:style styles/enter-word-n-description}
(i18n/label :t/word-n-description {:number (inc idx)})]
[react/view styles/twelve-words-spacer]
[react/view styles/twelve-words-button-container
[components.common/bottom-button
{:forward? (not= :second-word step)
:label (when (= :second-word step) (i18n/label :t/done))
:disabled? (string/blank? entered-word)
:on-press (next-handler word entered-word step)}]]])
(defn finish []
[react/view {:style styles/finish-container}
@ -136,12 +142,12 @@
(defview backup-seed []
(letsubs [current-account [:get-current-account]
{:keys [step first-word second-word error word]} [:get :my-profile/seed]]
{:keys [step first-word second-word error word]} [:my-profile/recovery]]
[react/keyboard-avoiding-view {:style styles/backup-seed-container}
[status-bar/status-bar]
[toolbar/toolbar
nil
(when-not (#{:finish} step)
(when-not (= :finish step)
(toolbar/nav-button (actions/back #(step-back step))))
[react/view
[react/text {:style styles/backup-seed}

View File

@ -1,21 +1,27 @@
(ns status-im.ui.screens.profile.subs
(:require [re-frame.core :refer [reg-sub]]
(:require [re-frame.core :as re-frame]
[clojure.string :as string]
[status-im.utils.build :as build]
[status-im.utils.platform :as platform]))
(reg-sub
(re-frame/reg-sub
:get-profile-unread-messages-number
:<- [:get-current-account]
(fn [{:keys [seed-backed-up? mnemonic]}]
(if (or seed-backed-up? (string/blank? mnemonic)) 0 1)))
(reg-sub
(re-frame/reg-sub
:get-app-version
(fn [{:keys [web3-node-version]}]
(let [version (if platform/desktop? build/version build/build-no)]
(str build/version " (" version "); node " (or web3-node-version "N/A") ""))))
(reg-sub :get-device-UUID
(re-frame/reg-sub
:get-device-UUID
(fn [db]
(:device-UUID db)))
(re-frame/reg-sub
:my-profile/recovery
(fn [db]
(or (:my-profile/seed db) {:step :intro})))