Implement `Account Avatar` Component (#16795)

This commit implements the "Account Avatar" component which is needed for wallet screen development.

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
This commit is contained in:
Mohamed Javid 2023-08-01 00:24:04 +08:00 committed by GitHub
parent 96ff8ab382
commit 81b8c7ca65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 239 additions and 79 deletions

View File

@ -1,41 +0,0 @@
(ns quo2.components.avatars.account-avatar
(:require [quo2.components.icon :as icons]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))
(defn get-border-radius
[size]
(case size
80 16
48 12
32 10
24 8
20 6))
(defn get-inner-icon-sizes
[size]
(case size
80 36
48 24
32 15
24 11
20 11))
(defn account-avatar
[{:keys [size icon color]
:or {size 80
icon :i/placeholder
color :purple}}]
(let [icon-color (colors/custom-color-by-theme color 50 60)
avatar-border-radius (get-border-radius size)
inner-icon-size (get-inner-icon-sizes size)]
[rn/view
{:style {:width size
:background-color icon-color
:height size
:border-radius avatar-border-radius
:justify-content :center
:align-items :center}}
[icons/icon icon
{:no-color true
:size inner-icon-size}]]))

View File

@ -0,0 +1,90 @@
(ns quo2.components.avatars.account-avatar.component-spec
(:require [quo2.components.avatars.account-avatar.view :as account-avatar]
[quo2.components.avatars.account-avatar.style :as style]
[test-helpers.component :as h]
[quo2.foundations.colors :as colors]))
(h/describe "Account Avatar"
(h/test "default render"
(h/render [account-avatar/view])
(h/is-truthy (h/query-by-label-text :account-avatar))
(h/is-truthy (h/query-by-label-text :account-emoji)))
(h/test "with emoji"
(let [emoji "💸"]
(h/render [account-avatar/view {:emoji emoji :size 80}])
(h/is-truthy (h/query-by-label-text :account-avatar))
(h/is-truthy (h/query-by-label-text :account-emoji))
(h/is-truthy (h/query-by-text emoji))))
(h/test "size 80 with emoji, with type - default"
(let [opts {:emoji "🏝️"
:size 80
:type :default
:customization-color :blue}]
(h/render [account-avatar/view opts])
(h/is-truthy (h/query-by-label-text :account-avatar))
(h/has-style (h/get-by-label-text :account-avatar)
{:height (:size opts)
:width (:size opts)
:borderRadius (style/get-border-radius (:size opts))
:backgroundColor (colors/custom-color-by-theme (:customization-color opts) 50 60)})
(h/is-truthy (h/query-by-label-text :account-emoji))
(h/has-style (h/query-by-label-text :account-emoji)
{:fontSize (style/get-emoji-size (:size opts))})
(h/is-truthy (h/query-by-text (:emoji opts)))))
(h/test "size 48 with emoji, with type - watch only"
(let [opts {:emoji "💵"
:size 48
:type :watch-only
:customization-color :purple}]
(h/render [account-avatar/view opts])
(h/is-truthy (h/query-by-label-text :account-avatar))
(h/has-style
(h/get-by-label-text :account-avatar)
{:height (:size opts)
:width (:size opts)
:borderRadius (style/get-border-radius (:size opts))
:borderWidth 1
:backgroundColor (colors/custom-color-by-theme (:customization-color opts) 50 50 10 10)})
(h/is-truthy (h/query-by-label-text :account-emoji))
(h/has-style (h/query-by-label-text :account-emoji)
{:fontSize (style/get-emoji-size (:size opts))})
(h/is-truthy (h/query-by-text (:emoji opts)))))
(h/test "size 28 with emoji, with type - default"
(let [opts {:emoji "🏝️"
:size 28
:type :default
:customization-color :turquoise}]
(h/render [account-avatar/view opts])
(h/is-truthy (h/query-by-label-text :account-avatar))
(h/has-style (h/get-by-label-text :account-avatar)
{:height (:size opts)
:width (:size opts)
:borderRadius (style/get-border-radius (:size opts))
:backgroundColor (colors/custom-color-by-theme (:customization-color opts) 50 60)})
(h/is-truthy (h/query-by-label-text :account-emoji))
(h/has-style (h/query-by-label-text :account-emoji)
{:fontSize (style/get-emoji-size (:size opts))})
(h/is-truthy (h/query-by-text (:emoji opts)))))
(h/test "size 16 with emoji, with type - watch only"
(let [opts {:emoji "🎉"
:size 16
:type :watch-only
:customization-color :copper}]
(h/render [account-avatar/view opts])
(h/is-truthy (h/query-by-label-text :account-avatar))
(h/has-style
(h/get-by-label-text :account-avatar)
{:height (:size opts)
:width (:size opts)
:borderRadius (style/get-border-radius (:size opts))
:borderWidth 0.8
:backgroundColor (colors/custom-color-by-theme (:customization-color opts) 50 50 10 10)})
(h/is-truthy (h/query-by-label-text :account-emoji))
(h/has-style (h/query-by-label-text :account-emoji)
{:fontSize (style/get-emoji-size (:size opts))})
(h/is-truthy (h/query-by-text (:emoji opts))))))

View File

@ -0,0 +1,69 @@
(ns quo2.components.avatars.account-avatar.style
(:require [quo2.foundations.colors :as colors]))
(def default-size 80)
(def default-border-radius 16)
(def default-padding 16)
(def default-emoji-size 36)
(defn get-border-radius
[size]
(case size
80 16
48 12
32 10
28 8
24 8
20 6
16 4
default-border-radius))
(defn get-padding
[size]
(case size
80 16
48 8
32 6
28 6
24 6
20 4
16 2
default-padding))
(defn get-emoji-size
[size]
(case size
80 36
48 24
32 15
28 12
24 11
20 11
16 11
default-emoji-size))
(defn get-border-width
[size]
(case size
16 0.8 ;; 0.8 px is for only size 16
;; Rest of the size will have 1 px
1))
(defn root-container
[{:keys [type size theme customization-color]
:or {size default-size
customization-color :blue}}]
(let [watch-only? (= type :watch-only)]
(cond-> {:width size
:height size
:background-color (colors/custom-color-by-theme customization-color 50 60 nil nil theme)
:border-radius (get-border-radius size)
:border-color (if (= theme :light) colors/neutral-80-opa-5 colors/white-opa-5)
:padding (get-padding size)
:align-items :center
:justify-content :center}
watch-only?
(assoc :border-width (get-border-width size)
:background-color (colors/custom-color-by-theme customization-color 50 50 10 10 theme)))))

View File

@ -0,0 +1,34 @@
(ns quo2.components.avatars.account-avatar.view
(:require [clojure.string :as string]
[quo2.components.avatars.account-avatar.style :as style]
[quo2.theme :as quo.theme]
[react-native.core :as rn]))
(defn- view-internal
"Opts:
:type - keyword -> :default/:watch-only
:emoji - string -> 🍑 [default]
:size - number -> 80 [default] /48/32/28/24/20/16
:customization-color - keyword or hexstring -> :blue/:army/... or #ABCEDF
:theme - keyword -> :light/:dark"
[{:keys [size emoji]
:or {size style/default-size
emoji "🍑"}
:as opts}]
(let [emoji-size (style/get-emoji-size size)]
[rn/view
{:accessible true
:accessibility-label :account-avatar
:style (style/root-container opts)}
[rn/text
{:accessibility-label :account-emoji
:adjusts-font-size-to-fit true
:style {:font-size emoji-size}}
(string/trim emoji)]]))
(def view (quo.theme/with-theme view-internal))

View File

@ -1,5 +1,5 @@
(ns quo2.components.settings.accounts.view
(:require [quo2.components.avatars.account-avatar :as account-avatar]
(:require [quo2.components.avatars.account-avatar.view :as account-avatar]
[quo2.components.buttons.button.view :as button]
[quo2.components.markdown.text :as text]
[quo2.components.settings.accounts.style :as style]
@ -14,7 +14,7 @@
(defn avatar
[avatar-props]
[rn/view {:style (style/avatar-border)}
[account-avatar/account-avatar (assoc avatar-props :size 48)]])
[account-avatar/view (assoc avatar-props :size 48)]])
(defn menu-button
[{:keys [on-press]}]

View File

@ -1,5 +1,6 @@
(ns quo2.components.tabs.account-selector
(:require [quo2.components.markdown.text :as quo2]
(:require [quo2.components.avatars.account-avatar.view :as account-avatar]
[quo2.components.markdown.text :as quo2]
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[react-native.core :as rn]))
@ -31,14 +32,9 @@
{:height 16
:width 16})
(def account-emoji-container
{:background-color (colors/custom-color :purple 50)
:padding 8
:justify-content :center
:align-items :center
:border-radius 10
:margin-left 4
:margin-right 8})
(def account-avatar-container
{:margin-left 4
:margin-right 8})
(defn get-color-by-type
[type k]
@ -66,8 +62,8 @@
:margin-bottom 8}}
label-text])
[rn/view {:style (account-container-row background-color)}
[rn/view {:style account-emoji-container}
[quo2/text account-emoji]]
[rn/view {:style account-avatar-container}
[account-avatar/view {:emoji account-emoji :size 32}]]
[quo2/text
{:weight :medium
:size :paragraph-1

View File

@ -1,7 +1,7 @@
(ns quo2.core
(:refer-clojure :exclude [filter])
(:require
quo2.components.avatars.account-avatar
quo2.components.avatars.account-avatar.view
quo2.components.avatars.channel-avatar.view
quo2.components.avatars.group-avatar
quo2.components.avatars.icon-avatar
@ -106,7 +106,7 @@
(def separator quo2.components.common.separator.view/separator)
;;;; AVATAR
(def account-avatar quo2.components.avatars.account-avatar/account-avatar)
(def account-avatar quo2.components.avatars.account-avatar.view/view)
(def channel-avatar quo2.components.avatars.channel-avatar.view/view)
(def group-avatar quo2.components.avatars.group-avatar/group-avatar)
(def icon-avatar quo2.components.avatars.icon-avatar/icon-avatar)

View File

@ -1,5 +1,6 @@
(ns quo2.core-spec
(:require
[quo2.components.avatars.account-avatar.component-spec]
[quo2.components.avatars.user-avatar.component-spec]
[quo2.components.banners.banner.component-spec]
[quo2.components.buttons.button.component-spec]

View File

@ -1,50 +1,61 @@
(ns status-im2.contexts.quo-preview.avatars.account-avatar
(:require [quo2.components.avatars.account-avatar :as quo2]
(:require [quo2.components.avatars.account-avatar.view :as account-avatar]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]))
(def descriptor
[{:label "Icon"
:key :icon
[{:label "Type"
:key :type
:type :select
:options [{:key :main-icons/wallet
:value "Wallet"}
{:key :main-icons/token
:value "Token"}
{:key :main-icons/status
:value "Status"}]}
:options [{:key :default
:value "default"}
{:key :watch-only
:value "watch only"}]}
{:label "Size"
:key :size
:type :select
:options [{:key 20
:value "Small"}
:options [{:key 16
:value "16"}
{:key 20
:value "20"}
{:key 24
:value "Medium"}
:value "24"}
{:key 28
:value "28"}
{:key 32
:value "Big"}
:value "32"}
{:key 48
:value "Very big"}
:value "48"}
{:key 80
:value "Seriously Big!"}]}])
:value "80"}]}
{:label "Emoji"
:key :emoji
:type :text}
(preview/customization-color-option)])
(defn cool-preview
[]
(let [state (reagent/atom {:size 80
:icon :main-icons/wallet})]
(let [state (reagent/atom {:customization-color :purple
:size 80
:emoji "🍑"
:type :default})]
(fn []
[rn/view
{:margin-bottom 50
:padding 16}
{:style {:margin-bottom 50
:padding 16}}
[preview/customizer state descriptor]
[rn/view
{:padding-vertical 60
:align-items :center}
[quo2/account-avatar @state]]])))
{:style {:padding-vertical 60
:align-items :center}}
[account-avatar/view @state]]])))
(defn preview-account-avatar
[]
[rn/view {:flex 1}
[rn/view
{:style {:flex 1
:background-color (colors/theme-colors colors/white colors/neutral-95)}}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always