Quo2 Wallet: Keypair component (#17019)

* Quo2 Wallet: Keypair component
This commit is contained in:
Omar Basem 2023-08-21 16:25:50 +04:00 committed by GitHub
parent 50f3bb005e
commit 4c9ccf3069
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 313 additions and 3 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1,6 +1,7 @@
(ns quo2.components.avatars.icon-avatar
(:require [quo2.components.icon :as icons]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[react-native.core :as rn]))
(def sizes
@ -8,8 +9,8 @@
:medium 32
:small 20})
(defn icon-avatar
[{:keys [size icon color opacity]
(defn icon-avatar-internal
[{:keys [size icon color opacity border? theme]
:or {opacity 20}}]
(let [component-size (size sizes)
circle-color (colors/custom-color color 50 opacity)
@ -22,9 +23,13 @@
{:style {:width component-size
:height component-size
:border-radius component-size
:border-width (when border? 1)
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:background-color circle-color
:justify-content :center
:align-items :center}}
[icons/icon icon
{:size icon-size
:color icon-color}]]))
(def icon-avatar (quo.theme/with-theme icon-avatar-internal))

View File

@ -0,0 +1,61 @@
(ns quo2.components.wallet.keypair.component-spec
(:require [test-helpers.component :as h]
[quo2.components.wallet.keypair.view :as keypair]))
(def accounts
[{:account-props {:customization-color :turquoise
:size 32
:emoji "\uD83C\uDFB2"
:type :default
:name "Trip to Vegas"
:address "0x0ah...71a"}
:networks [:ethereum :optimism]
:state :default
:action :none}])
(def default-details
{:full-name "John Doe"
:address "zQ3...6fBd2"})
(def other-details {:full-name "Metamask"})
(h/describe "Wallet: Keypair"
(h/test "Default keypair title renders"
(h/render [keypair/view
{:accounts accounts
:customization-color :blue
:type :default-keypair
:stored :on-device
:action :selector
:details default-details}])
(h/is-truthy (h/get-by-label-text :title)))
(h/test "On device renders"
(h/render [keypair/view
{:accounts accounts
:customization-color :blue
:type :other
:stored :on-device
:action :selector
:details other-details}])
(h/is-truthy (h/get-by-label-text :details)))
(h/test "Selector action renders"
(h/render [keypair/view
{:accounts accounts
:customization-color :blue
:type :other
:stored :on-keycard
:action :selector
:details other-details}])
(h/is-truthy (h/get-by-label-text :radio-on)))
(h/test "Options action renders"
(h/render [keypair/view
{:accounts accounts
:customization-color :blue
:type :other
:stored :on-keycard
:action :options
:details other-details}])
(h/is-truthy (h/get-by-label-text :options-button))))

View File

@ -0,0 +1,26 @@
(ns quo2.components.wallet.keypair.style
(:require [quo2.foundations.colors :as colors]))
(defn container
[selected? customization-color theme]
{:border-radius 20
:border-width 1
:border-color (if selected?
(colors/theme-colors (colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
theme)
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))
:padding-bottom 8})
(def header-container
{:padding-horizontal 12
:padding-top 8
:padding-bottom 12
:flex-direction :row
:align-items :center})
(def title-container
{:flex-direction :row
:align-items :center
:justify-content :space-between
:flex 1})

View File

@ -0,0 +1,93 @@
(ns quo2.components.wallet.keypair.view
(:require
[quo2.components.avatars.icon-avatar :as icon-avatar]
[quo2.components.avatars.user-avatar.view :as user-avatar]
[quo2.components.icon :as icon]
[quo2.components.list-items.account-list-card.view :as account-list-card]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[react-native.core :as rn]
[quo2.components.selectors.selectors.view :as selectors]
[reagent.core :as reagent]
[utils.i18n :as i18n]
[quo2.components.wallet.keypair.style :as style]
[clojure.string :as string]))
(defn keypair-string
[full-name]
(let [first-name (first (string/split full-name #" "))]
(i18n/label :t/keypair-title {:name first-name})))
(defn details-string
[address stored]
(str (when address (str address " ∙ "))
(if (= stored :on-device) (i18n/label :t/on-device) (i18n/label :t/on-keycard))))
(defn avatar
[type full-name customization-color]
(if (= type :default-keypair)
[user-avatar/user-avatar
{:full-name full-name
:ring? true
:size :small
:customization-color customization-color}]
[icon-avatar/icon-avatar
{:size :medium
:icon :i/placeholder
:border? true}]))
(defn title-view
[full-name action selected? type customization-color on-options-press theme]
[rn/view
{:style style/title-container
:accessibility-label :title}
[text/text {:weight :semi-bold}
(if (= type :default-keypair) (keypair-string full-name) full-name)]
(if (= action :selector)
[selectors/radio
{:checked? selected?
:customization-color customization-color}]
[rn/pressable {:on-press on-options-press}
[icon/icon :i/options
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:accessibility-label :options-button}]])])
(defn details-view
[address stored theme]
[rn/view
{:style {:flex-direction :row
:align-items :center}}
[text/text
{:size :paragraph-2
:accessibility-label :details
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
(details-string address stored)]
(when (= stored :on-keycard)
[rn/view {:style {:margin-left 4}}
[icon/icon :i/keycard-card
{:size 16
:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}]])])
(defn- view-internal
[]
(let [selected? (reagent/atom true)]
(fn [{:keys [theme accounts customization-color type details stored action on-options-press]}]
(let [{:keys [address full-name]} details]
[rn/pressable
{:style (style/container @selected? customization-color theme)
:on-press #(when (= action :selector) (reset! selected? (not @selected?)))}
[rn/view {:style style/header-container}
[avatar type full-name customization-color]
[rn/view
{:style {:margin-left 8
:flex 1}}
[title-view full-name action @selected? type customization-color on-options-press theme]
[details-view address stored theme]]]
[rn/flat-list
{:data accounts
:render-fn account-list-card/view
:separator [rn/view {:style {:height 8}}]
:style {:padding-horizontal 8}}]]))))
(def view (quo.theme/with-theme view-internal))

View File

@ -111,6 +111,7 @@
quo2.components.text-combinations.title.view
quo2.components.wallet.account-overview.view
quo2.components.wallet.account-card.view
quo2.components.wallet.keypair.view
quo2.components.wallet.network-amount.view
quo2.components.wallet.network-bridge.view
quo2.components.wallet.progress-bar.view
@ -317,6 +318,7 @@
;;;; Wallet
(def account-card quo2.components.wallet.account-card.view/view)
(def account-overview quo2.components.wallet.account-overview.view/view)
(def keypair quo2.components.wallet.keypair.view/view)
(def network-amount quo2.components.wallet.network-amount.view/view)
(def network-bridge quo2.components.wallet.network-bridge.view/view)
(def progress-bar quo2.components.wallet.progress-bar.view/view)

View File

@ -56,6 +56,7 @@
[quo2.components.tags.status-tags-component-spec]
[quo2.components.wallet.account-overview.component-spec]
[quo2.components.wallet.account-card.component-spec]
[quo2.components.wallet.keypair.component-spec]
[quo2.components.wallet.network-amount.component-spec]
[quo2.components.wallet.network-bridge.component-spec]
[quo2.components.wallet.progress-bar.component-spec]

View File

@ -112,6 +112,7 @@
[status-im2.contexts.quo-preview.gradient.gradient-cover :as gradient-cover]
[status-im2.contexts.quo-preview.wallet.account-overview :as account-overview]
[status-im2.contexts.quo-preview.wallet.account-card :as account-card]
[status-im2.contexts.quo-preview.wallet.keypair :as keypair]
[status-im2.contexts.quo-preview.wallet.network-amount :as network-amount]
[status-im2.contexts.quo-preview.wallet.network-bridge :as network-bridge]
[status-im2.contexts.quo-preview.wallet.progress-bar :as progress-bar]
@ -337,6 +338,9 @@
:component account-card/preview-account-card}
{:name :account-overview
:component account-overview/preview-account-overview}
{:name :keypair
:options {:topBar {:visible true}}
:component keypair/preview}
{:name :network-amount
:component network-amount/preview}
{:name :network-bridge

View File

@ -0,0 +1,115 @@
(ns status-im2.contexts.quo-preview.wallet.keypair
(:require
[quo2.core :as quo]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]))
(def accounts
[{:account-props {:customization-color :turquoise
:size 32
:emoji "\uD83C\uDFB2"
:type :default
:name "Trip to Vegas"
:address "0x0ah...71a"}
:networks [:ethereum :optimism]
:state :default
:action :none}
{:account-props {:customization-color :purple
:size 32
:emoji "\uD83C\uDF7F"
:type :default
:name "My savings"
:address "0x0ah...72b"}
:networks [:ethereum :optimism]
:state :default
:action :none}
{:account-props {:customization-color :army
:size 32
:emoji "\uD83D\uDCC8"
:type :default
:name "Coin vault"
:address "0x0ah...73c"}
:networks [:ethereum :optimism]
:state :default
:action :none}
{:account-props {:customization-color :orange
:size 32
:emoji "\uD83C\uDFF0"
:type :default
:name "Crypto fortress"
:address "0x0ah...74e"}
:networks [:ethereum :optimism]
:state :default
:action :none}
{:account-props {:customization-color :yellow
:size 32
:emoji "\uD83C\uDFDD"
:type :default
:name "Block treasure"
:address "0x0ah...75f"}
:networks [:ethereum :optimism]
:state :default
:action :none}])
(def descriptor
[{:label "Stored:"
:key :stored
:type :select
:options [{:key :on-device
:value "On device"}
{:key :on-keycard
:value "On Keycard"}]}
{:label "Action:"
:key :action
:type :select
:options [{:key :selector
:value "Selector"}
{:key :options
:value "Options"}]}
{:label "Type:"
:key :type
:type :select
:options [{:key :default-keypair
:value "Default keypair"}
{:key :other
:value "Other"}]}
(preview/customization-color-option)])
(def default-details
{:full-name "John Doe"
:address "zQ3...6fBd2"})
(def other-details {:full-name "Metamask"})
(defn cool-preview
[]
(let [state (reagent/atom {:accounts accounts
:customization-color :blue
:type :default-keypair
:stored :on-device
:on-options-press #(js/alert "Options pressed")
:action :selector})]
(fn []
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
[rn/view {:style {:padding-bottom 150}}
[rn/view {:style {:flex 1}}
[preview/customizer state descriptor]]
[rn/view
{:style {:padding-vertical 30
:flex-direction :row
:justify-content :center}}
[quo/keypair
(merge
@state
{:details (if (= (:type @state) :default-keypair) default-details other-details)})]]]])))
(defn preview
[]
[rn/view
{:style {:flex 1}}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -2282,5 +2282,8 @@
"no-activity": "No activity",
"no-activity-description": "C'mon do something...",
"buy": "Buy",
"bridge": "Bridge"
"bridge": "Bridge",
"on-device": "On device",
"on-keycard": "On Keycard",
"keypair-title": "{{name}}'s default keypair"
}