From de4e233884f938b0b4c7a5e127c9ffb2bfa9f6ca Mon Sep 17 00:00:00 2001 From: Ulises Manuel <90291778+ulisesmac@users.noreply.github.com> Date: Thu, 7 Dec 2023 17:44:24 -0600 Subject: [PATCH] [#17974] text combinations - username component (#17987) * Move docstring to be available while using `colors/resolve-color` * Add text combinations - username component and tests * Add username related svg icons --- src/quo/components/icons/svg.cljs | 60 ++++++++++++++-- .../username/component_spec.cljs | 68 +++++++++++++++++++ .../text_combinations/username/style.cljs | 30 ++++++++ .../text_combinations/username/view.cljs | 57 ++++++++++++++++ src/quo/core.cljs | 2 + src/quo/core_spec.cljs | 1 + src/quo/foundations/colors.cljs | 11 +-- src/status_im2/contexts/quo_preview/main.cljs | 5 +- .../text_combinations/username.cljs | 52 ++++++++++++++ .../contexts/wallet/common/utils.cljs | 1 + 10 files changed, 275 insertions(+), 12 deletions(-) create mode 100644 src/quo/components/text_combinations/username/component_spec.cljs create mode 100644 src/quo/components/text_combinations/username/style.cljs create mode 100644 src/quo/components/text_combinations/username/view.cljs create mode 100644 src/status_im2/contexts/quo_preview/text_combinations/username.cljs diff --git a/src/quo/components/icons/svg.cljs b/src/quo/components/icons/svg.cljs index bc82ed608e..9cdfc46f71 100644 --- a/src/quo/components/icons/svg.cljs +++ b/src/quo/components/icons/svg.cljs @@ -118,13 +118,61 @@ "M2.79504 9.01494C2.89473 8.85584 3.00297 8.70977 3.11963 8.5761C3.90594 7.67512 4.97212 7.45024 5.99992 7.45024C7.02772 7.45024 8.0939 7.67512 8.88021 8.5761C8.99688 8.70978 9.10512 8.85585 9.2048 9.01495C8.9501 9.28561 8.66149 9.52401 8.34577 9.72335C8.25403 9.55824 8.15512 9.41818 8.05145 9.29939C7.56503 8.74204 6.88121 8.55024 5.99992 8.55024C5.11862 8.55024 4.43481 8.74204 3.94839 9.29939C3.84472 9.41818 3.74582 9.55824 3.65408 9.72334C3.33835 9.524 3.04975 9.2856 2.79504 9.01494ZM5.99992 3.5502C5.47525 3.5502 5.04992 3.97552 5.04992 4.5002C5.04992 5.02487 5.47525 5.4502 5.99992 5.4502C6.52459 5.4502 6.94992 5.02487 6.94992 4.5002C6.94992 3.97552 6.52459 3.5502 5.99992 3.5502ZM3.94992 4.5002C3.94992 3.36801 4.86773 2.4502 5.99992 2.4502C7.1321 2.4502 8.04992 3.36801 8.04992 4.5002C8.04992 5.63238 7.1321 6.5502 5.99992 6.5502C4.86773 6.5502 3.94992 5.63238 3.94992 4.5002Z" :fill color-2}]]) +(defn- contact-20 + [{:keys [color color-2] + :or {color colors/neutral-100 + color-2 colors/white} + :as props}] + [container props + [svg/circle + {:cx 10 + :cy 10 + :r 7.5 + :fill color}] + [svg/path + {:d + "M8.65002 7.99998C8.65002 7.25439 9.25443 6.64998 10 6.64998C10.7456 6.64998 11.35 7.25439 11.35 7.99998C11.35 8.74556 10.7456 9.34998 10 9.34998C9.25443 9.34998 8.65002 8.74556 8.65002 7.99998ZM10 5.34998C8.53646 5.34998 7.35002 6.53642 7.35002 7.99998C7.35002 9.46353 8.53646 10.65 10 10.65C11.4636 10.65 12.65 9.46353 12.65 7.99998C12.65 6.53642 11.4636 5.34998 10 5.34998ZM10 13.65C8.67557 13.65 7.53064 14.4186 6.98692 15.5341C6.60094 15.3235 6.23942 15.0737 5.90771 14.79C6.69408 13.3369 8.23179 12.35 10 12.35C11.7682 12.35 13.306 13.3369 14.0923 14.79C13.7606 15.0737 13.3991 15.3235 13.0131 15.5341C12.4694 14.4186 11.3245 13.65 10 13.65Z" + :fill color-2}]]) + +(defn- verified-20 + [{:keys [color color-2] + :or {color colors/neutral-100 + color-2 colors/white} + :as props}] + [container props + [svg/path + {:d + "M18 10C18 8.77003 17.1118 7.74751 15.9418 7.53891C16.6216 6.56407 16.5267 5.21294 15.6569 4.34321C14.7872 3.47344 13.436 3.37852 12.4611 4.05845C12.2526 2.88834 11.23 2 10 2C8.77 2 7.74747 2.88827 7.53889 4.05832C6.56406 3.37846 5.21292 3.47339 4.34318 4.34313C3.47343 5.21288 3.3785 6.56404 4.05839 7.53888C2.88831 7.74743 2 8.76998 2 10C2 11.23 2.88824 12.2525 4.05826 12.4611C3.3784 13.4359 3.47333 14.7871 4.34307 15.6568C5.21284 16.5266 6.56403 16.6215 7.53887 15.9416C7.74741 17.1117 8.76996 18 10 18C11.23 18 12.2525 17.1117 12.4611 15.9417C13.4359 16.6215 14.7871 16.5266 15.6568 15.6569C16.5265 14.7871 16.6215 13.436 15.9416 12.4611C17.1117 12.2526 18 11.23 18 10Z" + :fill color}] + [svg/path + {:d "M7.25 10.75L9.25 12.25L12.75 7.75" + :stroke color-2 + :stroke-width "1.2"}]]) + +(defn- untrustworthy-20 + [{:keys [color color-2] + :or {color colors/neutral-100 + color-2 colors/white} + :as props}] + [container props + [svg/path + {:d "M10 2L15.6569 4.34315L18 10L15.6569 15.6569L10 18L4.34315 15.6569L2 10L4.34315 4.34315L10 2Z" + :fill color}] + [svg/path + {:d + "M10.75 5.5L10.55 11.5H9.45L9.25 5.5H10.75ZM10 13C10.4142 13 10.75 13.3358 10.75 13.75C10.75 14.1642 10.4142 14.5 10 14.5C9.58579 14.5 9.25 14.1642 9.25 13.75C9.25 13.3358 9.58579 13 10 13Z" + :fill color-2}]]) + (def ^:private icons - {:i/clear-20 clear-20 - :i/dropdown-20 dropdown-20 - :i/pullup-20 pullup-20 - :i/dropdown-12 dropdown-12 - :i/pullup-12 pullup-12 - :i/contact-12 contact-12}) + {:i/clear-20 clear-20 + :i/dropdown-20 dropdown-20 + :i/pullup-20 pullup-20 + :i/dropdown-12 dropdown-12 + :i/pullup-12 pullup-12 + :i/contact-12 contact-12 + :i/contact-20 contact-20 + :i/verified-20 verified-20 + :i/untrustworthy-20 untrustworthy-20}) (defn- append-to-keyword [k & xs] diff --git a/src/quo/components/text_combinations/username/component_spec.cljs b/src/quo/components/text_combinations/username/component_spec.cljs new file mode 100644 index 0000000000..a410cb3332 --- /dev/null +++ b/src/quo/components/text_combinations/username/component_spec.cljs @@ -0,0 +1,68 @@ +(ns quo.components.text-combinations.username.component-spec + (:require [quo.components.text-combinations.username.view :as username] + [test-helpers.component :as h])) + +(defn test-all-status + [component-to-render component-props] + (h/test "Verified status" + (h/render [component-to-render (assoc component-props :status :verified)]) + (h/is-truthy (h/get-by-label-text :username-status-icon))) + + (h/test "Contact status" + (h/render [component-to-render (assoc component-props :status :contact)]) + (h/is-truthy (h/get-by-label-text :username-status-icon))) + + (h/test "Untrustworthy status" + (h/render [component-to-render (assoc component-props :status :untrustworthy)]) + (h/is-truthy (h/get-by-label-text :username-status-icon))) + + (h/test "Untrustworthy contact status" + (h/render [component-to-render (assoc component-props :status :untrustworthy-contact)]) + (let [icons (h/get-all-by-label-text :username-status-icon)] + (h/is-truthy (aget icons 0)) + (h/is-truthy (aget icons 1)))) + + (h/test "Blocked status" + (h/render [component-to-render (assoc component-props :status :blocked)]) + (h/is-truthy (h/get-by-label-text :username-status-icon)))) + +(h/describe "Text combinations - Username" + (h/test "Renders default" + (h/render [username/view {:username "Test username"}]) + (h/is-truthy (h/get-by-text "Test username"))) + + (h/describe "Render different :name-type values" + (h/describe "default" + (let [props {:name-type :default + :username "Test username"}] + + (h/test "default render" + (h/render [username/view props]) + (h/is-truthy (h/get-by-text "Test username"))) + + (h/describe "All status are rendered" + (test-all-status username/view props)))) + + (h/describe "ens" + (let [props {:name-type :ens + :username "test-username.eth"}] + + (h/test "no status render" + (h/render [username/view props]) + (h/is-truthy (h/get-by-text "test-username.eth"))) + + (h/describe "All status are rendered" + (test-all-status username/view props)))) + + (h/describe "nickname" + (let [props {:name-type :nickname + :username "Nickname" + :name "Real name"}] + + (h/test "no status render" + (h/render [username/view props]) + (h/is-truthy (h/get-by-text "Nickname")) + (h/is-truthy (h/get-by-text "Real name"))) + + (h/describe "All status are rendered" + (test-all-status username/view props)))))) diff --git a/src/quo/components/text_combinations/username/style.cljs b/src/quo/components/text_combinations/username/style.cljs new file mode 100644 index 0000000000..3d46b7e43e --- /dev/null +++ b/src/quo/components/text_combinations/username/style.cljs @@ -0,0 +1,30 @@ +(ns quo.components.text-combinations.username.style + (:require [quo.foundations.colors :as colors])) + +(def container + {:flex-direction :row + :height 32}) + +(def username-text-container + {:flex-direction :row + :align-items :flex-end}) + +(defn real-name-text + [theme blur?] + {:color (if blur? + (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme) + (colors/theme-colors colors/neutral-60 colors/neutral-40 theme))}) + +(defn real-name-dot + [theme blur?] + (assoc (real-name-text theme blur?) :margin-horizontal 6)) + +(defn status-icon-container + [name-type status] + (cond-> {:flex-direction :row + :margin-left 4} + (#{:default :ens} name-type) (assoc :margin-top 8 + :margin-bottom 4) + (= :nickname name-type) (assoc :margin-top 10 + :margin-bottom 2) + (= status :untrustworthy-contact) (assoc :margin-right 2))) diff --git a/src/quo/components/text_combinations/username/view.cljs b/src/quo/components/text_combinations/username/view.cljs new file mode 100644 index 0000000000..df7170dc84 --- /dev/null +++ b/src/quo/components/text_combinations/username/view.cljs @@ -0,0 +1,57 @@ +(ns quo.components.text-combinations.username.view + (:require [quo.components.icon :as icon] + [quo.components.markdown.text :as text] + [quo.components.text-combinations.username.style :as style] + [quo.foundations.colors :as colors] + [quo.theme] + [react-native.core :as rn])) + +(defn- username-text + [{:keys [theme name-type username blur?] + real-name :name}] + [rn/view {:style style/username-text-container} + [text/text + {:size :heading-1 + :weight :semi-bold} + username] + (when (= name-type :nickname) + [:<> + [text/text + {:style (style/real-name-dot theme blur?) + :size :paragraph-1 + :weight :medium} + "∙"] + [text/text + {:style (style/real-name-text theme blur?) + :size :paragraph-1 + :weight :medium} + real-name]])]) + +(defn- icon-20 + [icon-name theme color] + [icon/icon icon-name + {:accessibility-label :username-status-icon + :size 20 + :color (colors/resolve-color color theme)}]) + +(defn status-icon + [{:keys [theme name-type status] + :or {name-type :default}}] + [rn/view {:style (style/status-icon-container name-type status)} + (case status + :verified [icon-20 :i/verified theme :success] + :contact [icon-20 :i/contact theme :blue] + :untrustworthy [icon-20 :i/untrustworthy theme :danger] + :blocked [icon-20 :i/block theme :danger] + :untrustworthy-contact [:<> + [icon-20 :i/untrustworthy theme :danger] + [icon-20 :i/contact theme :blue]] + nil)]) + +(defn view-internal + [props] + [rn/view {:style style/container} + [username-text props] + [status-icon props]]) + +(def view (quo.theme/with-theme view-internal)) diff --git a/src/quo/core.cljs b/src/quo/core.cljs index 85e3930987..b76d15d858 100644 --- a/src/quo/core.cljs +++ b/src/quo/core.cljs @@ -141,6 +141,7 @@ quo.components.tags.token-tag.view quo.components.text-combinations.channel-name.view quo.components.text-combinations.standard-title.view + quo.components.text-combinations.username.view quo.components.text-combinations.view quo.components.wallet.account-card.view quo.components.wallet.account-origin.view @@ -385,6 +386,7 @@ (def channel-name quo.components.text-combinations.channel-name.view/view) (def standard-title quo.components.text-combinations.standard-title.view/view) (def text-combinations quo.components.text-combinations.view/view) +(def username quo.components.text-combinations.username.view/view) ;;;; Wallet (def account-card quo.components.wallet.account-card.view/view) diff --git a/src/quo/core_spec.cljs b/src/quo/core_spec.cljs index a7ab024cf4..ca9beb8c58 100644 --- a/src/quo/core_spec.cljs +++ b/src/quo/core_spec.cljs @@ -77,6 +77,7 @@ [quo.components.tags.summary-tag.component-spec] [quo.components.tags.tiny-tag.component-spec] [quo.components.text-combinations.channel-name.component-spec] + [quo.components.text-combinations.username.component-spec] [quo.components.wallet.account-card.component-spec] [quo.components.wallet.account-origin.component-spec] [quo.components.wallet.account-overview.component-spec] diff --git a/src/quo/foundations/colors.cljs b/src/quo/foundations/colors.cljs index e0146141f2..f01051d06d 100644 --- a/src/quo/foundations/colors.cljs +++ b/src/quo/foundations/colors.cljs @@ -285,10 +285,6 @@ (get-in colors-map [color suffix])))) (defn- resolve-color* - "(resolve-color color theme opacity) - color hex string or keyword (resolves from custom, network and semantic colors) - theme :light/:dark - opacity 0-100 (optional) - if set theme is ignored and goes to 50 suffix internally" ([color theme] (resolve-color* color theme nil)) ([color theme opacity] @@ -300,7 +296,12 @@ suffix (get-from-colors-map suffix) opacity (alpha (/ opacity 100)))))) -(def resolve-color (memoize resolve-color*)) +(def resolve-color + "(resolve-color color theme opacity) + color hex string or keyword (resolves from custom, network and semantic colors) + theme :light/:dark + opacity 0-100 (optional) - if set theme is ignored and goes to 50 suffix internally" + (memoize resolve-color*)) (def ^{:deprecated true :superseded-by "resolve-color"} custom-color diff --git a/src/status_im2/contexts/quo_preview/main.cljs b/src/status_im2/contexts/quo_preview/main.cljs index c9754bc8d0..9980aca0ae 100644 --- a/src/status_im2/contexts/quo_preview/main.cljs +++ b/src/status_im2/contexts/quo_preview/main.cljs @@ -166,6 +166,7 @@ [status-im2.contexts.quo-preview.text-combinations.preview :as text-combinations] [status-im2.contexts.quo-preview.text-combinations.standard-title :as standard-title] + [status-im2.contexts.quo-preview.text-combinations.username :as username] [status-im2.contexts.quo-preview.wallet.account-card :as account-card] [status-im2.contexts.quo-preview.wallet.account-origin :as account-origin] [status-im2.contexts.quo-preview.wallet.account-overview :as @@ -461,7 +462,9 @@ {:name :channel-name :component channel-name/view} {:name :standard-title - :component standard-title/view}] + :component standard-title/view} + {:name :username + :component username/view}] :wallet [{:name :account-card :component account-card/view} {:name :account-origin :component account-origin/view} {:name :account-overview diff --git a/src/status_im2/contexts/quo_preview/text_combinations/username.cljs b/src/status_im2/contexts/quo_preview/text_combinations/username.cljs new file mode 100644 index 0000000000..5db53001da --- /dev/null +++ b/src/status_im2/contexts/quo_preview/text_combinations/username.cljs @@ -0,0 +1,52 @@ +(ns status-im2.contexts.quo-preview.text-combinations.username + (:require [quo.core :as quo] + [reagent.core :as reagent] + [status-im2.contexts.quo-preview.preview :as preview])) + +(def descriptor + [{:key :name-type + :type :select + :options [{:key :default} + {:key :ens + :value "ENS"} + {:key :nickname}]} + {:key :username + :type :text} + {:key :name + :type :text} + {:key :status + :type :select + :options [{:key nil + :value "(Nothing)"} + {:key :verified} + {:key :contact} + {:key :untrustworthy} + {:key :untrustworthy-contact} + {:key :blocked}]} + {:key :blur? + :type :boolean}]) + +(defn- set-username-based-on-name-type + [_ ratom {previous-type :name-type} {new-type :name-type}] + (when (not= previous-type new-type) + (swap! ratom assoc + :username + (if (= new-type :ens) + "juan.eth" + "Juanito Mdz")))) + +(defn view + [] + (let [state (reagent/atom {:name-type :default + :username "Juanito Mdz" + :name "Juan Méndez" + :status nil + :blur? true}) + _ (add-watch state :on-state-change set-username-based-on-name-type)] + (fn [] + [preview/preview-container + {:state state + :descriptor descriptor + :show-blur-background? true + :blur? (:blur? @state)} + [quo/username @state]]))) diff --git a/src/status_im2/contexts/wallet/common/utils.cljs b/src/status_im2/contexts/wallet/common/utils.cljs index c7a6f9cb73..9bca9454a9 100644 --- a/src/status_im2/contexts/wallet/common/utils.cljs +++ b/src/status_im2/contexts/wallet/common/utils.cljs @@ -15,6 +15,7 @@ (defn get-derivation-path [number-of-accounts] (str constants/path-wallet-root "/" number-of-accounts)) + (defn format-derivation-path [path] (string/replace path "/" " / "))