Skip to content

Commit

Permalink
feat: add enter scan code view
Browse files Browse the repository at this point in the history
This commit adds the enter sync code UI.

Fixes : #16062

Design link : https://www.figma.com/file/V6nlpAWIf2e1XU8RJ9yQPe/Syncing-for-Mobile?node-id=675%3A179729&mode=dev

Review notes :
We do not make use of quo2/input here because currently that component does not allow stretching to fit in sync code which spans upto 3 lines.
  • Loading branch information
siddarthkay committed Sep 19, 2023
1 parent 9479f02 commit 9a858e7
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 17 deletions.
31 changes: 31 additions & 0 deletions doc/decisions/UI-related/7-august-2023-paste-button-ux.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
### How should the paste button behave when clipboard is empty?

This question first came up as a review comment to this PR
https://github.com/status-im/status-mobile/pull/16852

There were 2 considerations :
- Either keep the paste button disabled when there is nothing in the clipboard OR
- Always keep the paste button enabled

There were positives and negatives for both approaches.

Positives of keeping paste button disabled when there is nothing in clipboard would require us to
check the value of clipboard as soon as the component is mounted (i.e when the user first sees
the screen). In iOS this means a native permissions dialog would appear requesting for permissions
to paste from the clipboard.

Negatives of this approach is that as soon as any user navigates to this screen they are greeted with
this popup which can be annoying sometimes.

Positives of keeping paste button always enabled is that we can trigger a request to the clipboard on
tap of the paste button which would trigger the native permissions dialog requesting for permissions
to paste from the clipboard.
In this case seeing this dialog is okay because the user has initiated a paste action.

Negatives of this approach is that in the event the clipboard is empty the user will still see the
system dialog and on approving nothing will be pasted (because the clipboard was empty).
This behaviour can be confusing.

On consulting the Design Team via discord it was concluded that out of the two approaches
having the paste button always enabled is a better UX overall.

62 changes: 62 additions & 0 deletions src/status_im2/contexts/syncing/enter_sync_code/style.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
(ns status-im2.contexts.syncing.enter-sync-code.style
(:require [quo2.foundations.colors :as colors]
[quo2.foundations.typography :as typography]))

(def container-text-input
{:flex-direction :row
:justify-content :space-between
:padding-horizontal 20})

(defn text-input-container
[invalid?]
{:padding-left 12
:padding-right 7
:min-height 40
:flex 1
:flex-direction :row
:border-width 1
:border-radius 12
:border-color (if invalid?
colors/danger-50-opa-40
colors/neutral-60)})

(defn text-input
[]
(merge typography/monospace
typography/paragraph-1
{:flex 1
:padding-bottom 8
:color colors/white
:text-align-vertical :center}))

(def label-texts-container
{:flex-direction :row
:height 18
:margin-bottom 8})

(def button-paste
{:margin-top 8})

(def clear-icon
{:size 20
:color colors/neutral-80-opa-30})

(def right-icon-touchable-area
{:margin-left 8
:padding-right 4
:padding-top 6
:margin-bottom 4})

(def label-pairing
{:color colors/white-opa-40})

(def label-container
{:flex-direction :row
:margin-left 20
:line-height 18
:margin-top 20
:margin-bottom 8})

(def continue-button-container
{:margin-top 12
:padding-horizontal 22})
76 changes: 76 additions & 0 deletions src/status_im2/contexts/syncing/enter_sync_code/view.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
(ns status-im2.contexts.syncing.enter-sync-code.view
(:require [clojure.string :as string]
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[reagent.core :as reagent]
[react-native.core :as rn]
[react-native.clipboard :as clipboard]
[utils.i18n :as i18n]
[status-im2.contexts.syncing.enter-sync-code.style :as style]
[utils.debounce :as debounce]
[utils.re-frame :as rf]
[status-im2.contexts.syncing.utils :as sync-utils]))

(defn view
[]
(let [sync-code-value (reagent/atom "")]
(fn []
(let [invalid? false
show-paste-button? (string/blank? @sync-code-value)
profile-color (rf/sub [:profile/customization-color])]
[:<>
[rn/view
{:style style/label-container}
[quo/text
{:style style/label-pairing
:weight :medium
:size :paragraph-2}
(i18n/label :t/type-pairing-code)]]
[rn/view {:style style/container-text-input}
[rn/view {:style (style/text-input-container invalid?)}
[rn/text-input
{:style (style/text-input)
:value @sync-code-value
:placeholder (i18n/label :t/scan-sync-code-placeholder)
:on-change-text (fn [scan-code]
(reset! sync-code-value scan-code)
(reagent/flush))
:blur-on-submit true
:return-key-type :done
:accessibility-label :enter-sync-code-input
:auto-capitalize :none
:placeholder-text-color colors/white-opa-40
:multiline true}]
(if show-paste-button?
[quo/button
{:on-press (fn [_]
(clipboard/get-string #(reset! sync-code-value %)))
:type :outline
:container-style style/button-paste
:size 24}
(i18n/label :t/paste)]

[rn/pressable
{:accessibility-label :input-right-icon
:style style/right-icon-touchable-area
:on-press (fn [_]
(reset! sync-code-value nil))}
[quo/icon :i/clear style/clear-icon]])]]
[quo/button
{:type :primary
:disabled? (string/blank? @sync-code-value)
:customization-color profile-color
:container-style style/continue-button-container
:on-press (fn [_]
(if (sync-utils/valid-connection-string? @sync-code-value)
(debounce/debounce-and-dispatch
[:syncing/input-connection-string-for-bootstrapping
@sync-code-value]
300)
(rf/dispatch [:toasts/upsert
{:icon :i/info
:icon-color colors/danger-50
:theme :dark
:text (i18n/label
:t/error-this-is-not-a-sync-qr-code)}])))}
(i18n/label :t/confirm)]]))))
5 changes: 0 additions & 5 deletions src/status_im2/contexts/syncing/scan_sync_code/style.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,6 @@
{:color colors/white-opa-70
:margin-bottom 16})

(def enter-sync-code-container
{:margin-top 20
:justify-content :center
:align-items :center})

(defn bottom-container
[translate-y padding-bottom]
(reanimated/apply-animations-to-style
Expand Down
14 changes: 3 additions & 11 deletions src/status_im2/contexts/syncing/scan_sync_code/view.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
[utils.debounce :as debounce]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.transforms :as transforms]))
[utils.transforms :as transforms]
[status-im2.contexts.syncing.enter-sync-code.view :as enter-sync-code]))

;; Android allow local network access by default. So, we need this check on iOS only.
(defonce preflight-check-passed? (reagent/atom (if platform/ios? false true)))
Expand Down Expand Up @@ -199,15 +200,6 @@
[viewfinder qr-view-finder]
[camera-and-local-network-access-permission-view]))

(defn- enter-sync-code-tab
[]
[rn/view {:style style/enter-sync-code-container}
[quo/text
{:size :paragraph-1
:weight :medium
:style {:color colors/white}}
"Yet to be implemented"]])

(defn- f-bottom-view
[insets translate-y]
[rn/touchable-without-feedback
Expand Down Expand Up @@ -374,7 +366,7 @@
{})}
(case @active-tab
1 [scan-qr-code-tab @qr-view-finder]
2 [enter-sync-code-tab]
2 [enter-sync-code/view]
nil)]
[rn/view {:style style/flex-spacer}]
(when show-bottom-view?
Expand Down
4 changes: 3 additions & 1 deletion translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2326,5 +2326,7 @@
"no-saved-addresses": "No saved addresses",
"you-like-to-type-43-characters": "You like to type 43 characters?",
"no-other-accounts": "No other accounts",
"here-is-a-cat-in-a-box-instead": "Here’s a cat in a box instead"
"here-is-a-cat-in-a-box-instead": "Here’s a cat in a box instead",
"type-pairing-code": "Type or paste pairing code",
"scan-sync-code-placeholder": "cs2:4FH..."
}

0 comments on commit 9a858e7

Please sign in to comment.