Skip to content

Commit

Permalink
[#19946] feat: add key pair QR code view
Browse files Browse the repository at this point in the history
  • Loading branch information
mohsen-ghafouri committed May 20, 2024
1 parent 4cdbfb6 commit edcd1f0
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,21 @@
[data]
(rf/dispatch [:open-modal :screen/settings.rename-keypair data]))

(defn on-show-qr
[data]
(rf/dispatch [:open-modal :screen/settings.encrypted-key-pair-qr data]))

(defn view
[props data]
[:<>
[quo/drawer-top props]
[quo/action-drawer
[(when (= (:type props) :keypair)
(when (= (:type props) :keypair)
[[{:icon :i/qr-code
:accessibility-label :show-key-pr-qr
:label (i18n/label :t/show-encrypted-qr-of-key-pairs)
:on-press #(on-show-qr data)}]
[{:icon :i/edit
:accessibility-label :rename-key-pair
:label (i18n/label :t/rename-key-pair)
:on-press #(on-rename-request data)}])]]])
:on-press #(on-rename-request data)}]])]])
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.countdown.view
(:require
[quo.core :as quo]
[quo.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.hooks :as hooks]
[utils.datetime :as datetime]
[utils.i18n :as i18n]))

(def code-valid-for-ms 120000)
(def one-min-ms 60000)

(defn current-ms
[]
(* 1000 (js/Math.ceil (/ (datetime/timestamp) 1000))))

(defn view
[on-clear]
(let [[valid-for-ms set-valid-for-ms] (rn/use-state code-valid-for-ms)
[timestamp set-timestamp] (rn/use-state current-ms)
clock (rn/use-callback (fn []
(let [remaining (- code-valid-for-ms
(- (current-ms)
timestamp))]
(when (pos? remaining)
(set-valid-for-ms remaining))
(when (zero? remaining)
(set-timestamp (current-ms))
(set-valid-for-ms code-valid-for-ms)
(on-clear))))
[code-valid-for-ms])]
(hooks/use-interval clock on-clear 1000)
[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)})]))
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.style
(:require
[quo.foundations.colors :as colors]
[react-native.safe-area :as safe-area]))

(defn container-main
[]
{:background-color colors/neutral-95
:padding-top (safe-area/get-top)
:flex 1})

(def page-container
{:margin-top 14
:margin-horizontal 20})

(def title-container
{:flex-direction :row
:align-items :center
:justify-content :space-between})

(def standard-auth
{:margin-top 12
:flex 1})

(def qr-container
{:margin-top 12
:background-color colors/white-opa-5
:border-radius 20
:flex 1
:padding 12})

(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 warning-text
{:margin-horizontal 16
:margin-top 20
:text-align :center
:color colors/white-opa-70})
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.view
(:require
[quo.core :as quo]
[quo.foundations.colors :as colors]
[react-native.clipboard :as clipboard]
[react-native.core :as rn]
[status-im.common.qr-codes.view :as qr-codes]
[status-im.common.resources :as resources]
[status-im.common.standard-authentication.core :as standard-auth]
[status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.countdown.view :as countdown]
[status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.style :as style]
[status-im.contexts.syncing.utils :as sync-utils]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))

(defn navigate-back [] (rf/dispatch [:navigate-back]))

(defn view
[]
(let [{:keys [customization-color]} (rf/sub [:profile/profile-with-image])
[code set-code] (rn/use-state nil)
validate-and-set-code (rn/use-callback (fn [connection-string]
(when (sync-utils/valid-connection-string?
connection-string)
(set-code connection-string))))
cleanup-clock (rn/use-callback #(set-code nil))
on-auth-success (fn [entered-password]
(rf/dispatch [:syncing/get-connection-string entered-password
validate-and-set-code]))]
[rn/view {:style (style/container-main)}
[rn/scroll-view
[quo/page-nav
{:type :no-title
:icon-name :i/close
:background :blur
:on-press navigate-back}]
[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/encrypted-key-pairs)]]
[rn/view {:style style/qr-container}
(if (sync-utils/valid-connection-string? code)
[qr-codes/qr-code {:url code}]
[rn/view {:style {:flex-direction :row}}
[rn/image
{:source (resources/get-image :qr-code)
:style {:width "100%"
:background-color colors/white-opa-70
:border-radius 12
:aspect-ratio 1}}]])
(when (sync-utils/valid-connection-string? 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/encrypted-key-pairs-code)]
[countdown/view cleanup-clock]]
[quo/input
{:default-value code
:type :password
:default-shown? true
:editable false}]
[quo/button
{:on-press (fn []
(clipboard/set-string code)
(rf/dispatch [:toasts/upsert
{:type :positive
:text (i18n/label
:t/sharing-copied-to-clipboard)}]))
:type :grey
:container-style {:margin-top 12}
:icon-left :i/copy}
(i18n/label :t/copy-qr)]])
(when-not (sync-utils/valid-connection-string? code)
[rn/view {:style style/standard-auth}
[standard-auth/slide-button
{:blur? true
:size :size-40
:track-text (i18n/label :t/slide-to-reveal-qr-code)
:customization-color customization-color
:on-auth-success on-auth-success
:auth-button-label (i18n/label :t/reveal-qr-code)
:auth-button-icon-left :i/reveal}]])]]
(when-not (sync-utils/valid-connection-string? code)
[quo/text
{:size :paragraph-2
:style style/warning-text}
(i18n/label :t/make-sure-no-camera-warning)])]]))
6 changes: 6 additions & 0 deletions src/status_im/navigation/screens.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
[status-im.contexts.profile.settings.screens.password.change-password.view :as change-password]
[status-im.contexts.profile.settings.screens.password.view :as settings-password]
[status-im.contexts.profile.settings.view :as settings]
[status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.view :as
encrypted-key-pair-qr]
[status-im.contexts.settings.wallet.keypairs-and-accounts.rename.view :as keypair-rename]
[status-im.contexts.settings.wallet.keypairs-and-accounts.view :as keypairs-and-accounts]
[status-im.contexts.settings.wallet.network-settings.view :as network-settings]
Expand Down Expand Up @@ -509,6 +511,10 @@
:options (assoc options/dark-screen :sheet? true)
:component keypair-rename/view}

{:name :screen/settings.encrypted-key-pair-qr
:options options/transparent-screen-options
:component encrypted-key-pair-qr/view}

{:name :screen/settings.saved-addresses
:options options/transparent-modal-screen-options
:component saved-addresses-settings/view}
Expand Down
6 changes: 6 additions & 0 deletions translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,8 @@
"enable": "Enable",
"enable-notifications-sub-title": "Receive notifications about your new messages or wallet transactions",
"encrypt-with-password": "Encrypt with password",
"encrypted-key-pairs": "Encrypted key pairs",
"encrypted-key-pairs-code": "Encrypted key pairs code",
"ending-not-allowed": "{{ending}} ending is not allowed",
"ends-with-space": "Cannot end with space",
"ens-10-SNT": "10 SNT",
Expand Down Expand Up @@ -939,6 +941,7 @@
"main-wallet": "Main Wallet",
"make-admin": "Make admin",
"make-moderator": "Make moderator",
"make-sure-no-camera-warning": "Make sure no camera or person can see this screen before revealing",
"manage-keys-and-storage": "Manage keys and storage",
"mark-as-read": "Mark as read",
"mark-all-read": "Mark all read",
Expand Down Expand Up @@ -1272,6 +1275,7 @@
"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",
"reveal-qr-code": "Reveal QR code",
"revoke-access": "Revoke access",
"save": "Save",
"save-address": "Save address",
Expand Down Expand Up @@ -1337,6 +1341,7 @@
"show-more": "Show more",
"show-qr": "Show QR code",
"show-transaction-data": "Show transaction data",
"show-encrypted-qr-of-key-pairs": "Show encrypted QR of key pairs on device",
"sign-and-send": "Sign and send",
"sign-in": "Sign in",
"sign-message": "Sign Message",
Expand Down Expand Up @@ -1970,6 +1975,7 @@
"slide-to-request-to-join": "Slide to request to join",
"slide-to-reveal-code": "Slide to reveal code",
"slide-to-create-account": "Slide to create account",
"slide-to-reveal-qr-code": "Slide to reveal QR code",
"minimum-received": "Minimum received",
"powered-by-paraswap": "Powered by Paraswap",
"priority": "Priority",
Expand Down

0 comments on commit edcd1f0

Please sign in to comment.