Add internal-link component for #17116 (#18109)

This commit is contained in:
Ibrahem Khalil 2024-01-09 14:31:00 +02:00 committed by GitHub
parent 6d5ef17a31
commit 9ff70ed990
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 681 additions and 3 deletions

View File

@ -8,7 +8,7 @@
utils.money))
(defn view-internal
[{:keys [value icon theme style accessibility-label]}]
[{:keys [value icon theme style accessibility-label text-size]}]
[rn/view
{:style (merge style/container style)
:accessibility-label accessibility-label}
@ -19,7 +19,7 @@
:resize-mode :center
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}]
[quo.text/text
{:size :paragraph-1
{:size (or text-size :paragraph-1)
:weight :regular
:style (style/text theme)} (utils.money/format-amount value)]])

View File

@ -0,0 +1,72 @@
(ns quo.components.links.internal-link-card.channel.style
(:require [quo.foundations.colors :as colors]))
(defn loading-circle
[theme]
{:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
:margin-right 4
:width 16
:height 16
:border-radius 16})
(defn loading-first-line-bar
[theme margin-right?]
{:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
:width 72
:margin-right (when margin-right? 4)
:height 16
:border-radius 6})
(defn loading-second-line-bar
[theme]
{:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
:width 112
:height 8
:border-radius 6
:margin-bottom 17})
(defn loading-thumbnail-box
[theme size]
{:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
:height (if (= :message size) 139 160)
:border-radius 12})
(defn thumbnail
[size]
{:width "100%"
:height (if (= :message size) 139 160)
:margin-top 8
:border-radius 12})
(defn container
[size theme]
{:border-width 1
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:background-color (colors/theme-colors colors/white colors/neutral-80-opa-40 theme)
:border-radius 16
:padding-horizontal 12
:padding-top 10
:padding-bottom 12
:height (if (= :message size) 215 236)
:width (if (= :message size) 295 335)})
(def header-container
{:flex-direction :row
:align-items :center})
(def title
{:margin-bottom 2})
(def logo
{:margin-right 6
:width 16
:height 16
:border-radius 8})
(defn channel-chevron-props
[theme]
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
(def row-spacing
{:flex-direction :row
:margin-bottom 13})

View File

@ -0,0 +1,92 @@
(ns quo.components.links.internal-link-card.channel.view
(:require
[quo.components.icon :as icon]
[quo.components.links.internal-link-card.channel.style :as style]
[quo.components.links.internal-link-card.schema :as component-schema]
[quo.components.markdown.text :as text]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[schema.core :as schema]))
(defn- description-comp
[description]
[rn/view {:style {:margin-bottom 4}}
[text/text
{:size :paragraph-2
:number-of-lines 3
:accessibility-label :description}
description]])
(defn- title-comp
[title channel-name theme]
[rn/view
{:style {:flex-direction :row
:align-items :center}}
[text/text
{:size :paragraph-1
:number-of-lines 1
:weight :semi-bold
:style style/title
:accessibility-label :title}
title]
[icon/icon :i/chevron-right (style/channel-chevron-props theme)]
[text/text
{:size :paragraph-1
:number-of-lines 1
:weight :semi-bold
:style style/title
:accessibility-label :title}
channel-name]])
(defn- banner-comp
[thumbnail size]
[rn/image
{:style (style/thumbnail size)
:source thumbnail
:accessibility-label :banner}])
(defn- logo-comp
[logo]
[rn/image
{:accessibility-label :logo
:source logo
:style (assoc style/logo :margin-bottom 2)}])
(defn- loading-view
[theme size]
[rn/view
{:accessibility-label :loading-channel-link-view
:style {:height 215}}
[rn/view {:style {:flex-direction :row}}
[rn/view {:style style/row-spacing}
[rn/view {:style (style/loading-circle theme)}]
[rn/view {:style (style/loading-first-line-bar theme true)}]]
[rn/view {:style style/row-spacing}
[rn/view {:style (style/loading-circle theme)}]
[rn/view {:style (style/loading-first-line-bar theme false)}]]]
[rn/view {:style (style/loading-second-line-bar theme)}]
[rn/view {:style (style/loading-thumbnail-box theme size)}]])
(defn view-internal
[{:keys [title description loading? icon banner
theme on-press channel-name size]
:or {channel-name "empty name"}}]
[rn/pressable
{:style (style/container size theme)
:accessibility-label :internal-link-card
:on-press on-press}
(if loading?
[loading-view theme size]
[:<>
[rn/view {:style style/header-container}
(when icon
[logo-comp icon])
[title-comp title channel-name theme]]
(when description
[description-comp description])
(when banner
[banner-comp banner size])])])
(def view
(quo.theme/with-theme
(schema/instrument #'view-internal component-schema/?schema)))

View File

@ -0,0 +1,87 @@
(ns quo.components.links.internal-link-card.community.style
(:require [quo.foundations.colors :as colors]))
(defn loading-circle
[theme]
{:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
:margin-right 4
:width 16
:height 16
:border-radius 16})
(defn loading-stat
[theme]
{:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
:margin-right 4
:width 32
:height 8
:border-radius 16})
(def loading-stat-container
{:flex-direction :row
:align-items :center
:margin-right 12
:margin-bottom -6})
(defn loading-first-line-bar
[theme]
{:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
:width 145
:height 16
:border-radius 6})
(defn loading-second-line-bar
[theme]
{:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
:width 112
:height 8
:border-radius 6
:margin-bottom 17})
(defn loading-thumbnail-box
[theme size]
{:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
:height (if (= :message size) 139 160)
:border-radius 12})
(defn thumbnail
[size]
{:width "100%"
:height (if (= :message size) 139 160)
:margin-top 6
:border-radius 12})
(defn container
[size theme]
{:border-width 1
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:background-color (colors/theme-colors colors/white colors/neutral-80-opa-40 theme)
:border-radius 16
:padding-horizontal 12
:padding-top 10
:padding-bottom 12
:height (if (= :message size) 245 266)
:width (if (= :message size) 295 335)})
(def header-container
{:flex-direction :row
:align-items :center})
(def title
{:margin-bottom 2})
(def logo
{:width 16
:height 16
:border-radius 8
:margin-right 4
:margin-bottom 2})
(def row-spacing
{:flex-direction :row
:margin-bottom 12
:margin-top 4})
(def stat-container
{:flex-direction :row
:margin-top 12})

View File

@ -0,0 +1,96 @@
(ns quo.components.links.internal-link-card.community.view
(:require
[quo.components.community.community-stat.view :as community-stat]
[quo.components.links.internal-link-card.community.style :as style]
[quo.components.links.internal-link-card.schema :as component-schema]
[quo.components.markdown.text :as text]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[schema.core :as schema]))
(defn- description-comp
[description members-count active-members-count]
[rn/view
[text/text
{:size :paragraph-2
:number-of-lines 3
:accessibility-label :description}
description]
[rn/view {:style style/stat-container}
[community-stat/view
{:value members-count
:icon :i/members
:accessibility-label :members-count
:style {:margin-right 12}
:text-size :paragraph-2}]
(when active-members-count
[community-stat/view
{:value active-members-count
:icon :i/active-members
:accessibility-label :active-members-count
:text-size :paragraph-2}])]])
(defn- title-comp
[title]
[text/text
{:size :paragraph-1
:number-of-lines 1
:weight :semi-bold
:style style/title
:accessibility-label :title}
title])
(defn- thumbnail-comp
[thumbnail size]
[rn/image
{:style (style/thumbnail size)
:source thumbnail
:accessibility-label :thumbnail}])
(defn- logo-comp
[logo]
[rn/image
{:accessibility-label :logo
:source logo
:style style/logo}])
(defn- stat-loading
[theme]
[rn/view {:style style/loading-stat-container}
[rn/view {:style (style/loading-circle theme)}]
[rn/view {:style (style/loading-stat theme)}]])
(defn- loading-view
[theme size]
[rn/view {:accessibility-label :loading-community-link-view}
[rn/view {:style style/row-spacing}
[rn/view {:style (style/loading-circle theme)}]
[rn/view {:style (style/loading-first-line-bar theme)}]]
[rn/view {:style (style/loading-second-line-bar theme)}]
[rn/view {:style style/row-spacing}
[stat-loading theme]
[stat-loading theme]]
[rn/view {:style (style/loading-thumbnail-box theme size)}]])
(defn- view-internal
[{:keys [title description loading? icon banner members-count active-members-count
theme on-press size]}]
[rn/pressable
{:style (style/container size theme)
:accessibility-label :internal-link-card
:on-press on-press}
(if loading?
[loading-view theme size]
[:<>
[rn/view {:style style/header-container}
(when icon
[logo-comp icon])
[title-comp title]]
(when description
[description-comp description members-count active-members-count])
(when banner
[thumbnail-comp banner size])])])
(def view
(quo.theme/with-theme
(schema/instrument #'view-internal component-schema/?schema)))

View File

@ -0,0 +1,81 @@
(ns quo.components.links.internal-link-card.component-spec
(:require
[quo.components.links.internal-link-card.view :as view]
[test-helpers.component :as h]))
(defn- render
[component]
(h/render-with-theme-provider component :light))
(def user-props
{:title "Some title"
:subtitle "Some description"
:loading? false
:icon "data:image/png,logo-x"
:type :user
:customization-color "#ff0000"
:emoji-hash "🌟🚀🐠🌈🏰🔮🦉🐼🍉🎨🚲🌙🍔🌵"})
(h/describe "Internal link card - User"
(h/test "renders with most common props"
(render [view/view user-props])
(h/is-truthy (h/query-by-text (:title user-props)))
(h/is-truthy (h/query-by-text (:subtitle user-props))))
(h/test "does not render logo if prop is not present"
(render [view/view (dissoc user-props :icon)])
(h/is-null (h/query-by-label-text :logo))))
(def community-props
{:title "Some title"
:description "Some description"
:icon "data:image/png,logo-x"
:banner "data:image/png,whatever"
:members-count "20"
:loading? false
:active-members-count "15"
:type :community})
(h/describe "Internal link card - Community"
(h/test "renders with most common props"
(render [view/view community-props])
(h/is-truthy (h/query-by-text (:title community-props)))
(h/is-truthy (h/query-by-text (:description community-props)))
(h/is-truthy (h/query-by-text (:members-count community-props)))
(h/is-truthy (h/query-by-text (:active-members-count community-props)))
(h/is-truthy (h/query-by-label-text :logo))
(h/is-truthy (h/query-by-label-text :thumbnail)))
(h/test "does not render thumbnail if prop is not present"
(render [view/view (dissoc community-props :banner)])
(h/is-null (h/query-by-label-text :thumbnail)))
(h/test "does not render logo if prop is not present"
(render [view/view (dissoc community-props :icon)])
(h/is-null (h/query-by-label-text :logo))))
(def channel-props
{:title "Doodles"
:description "Coloring the world with joy • ᴗ •"
:icon "data:image/png,logo-x"
:banner "data:image/png,whatever"
:loading? false
:channel-name "#general"
:type :channel})
(h/describe "Internal link card - Channel"
(h/test "renders with most common props"
(render [view/view channel-props])
(h/is-truthy (h/query-by-text (:title channel-props)))
(h/is-truthy (h/query-by-text (:description channel-props)))
(h/is-truthy (h/query-by-text (:channel-name channel-props)))
(h/is-truthy (h/query-by-label-text :logo))
(h/is-truthy (h/query-by-label-text :banner)))
(h/test "does not render banner if prop is not present"
(render [view/view (dissoc channel-props :banner)])
(h/is-null (h/query-by-label-text :banner)))
(h/test "does not render logo if prop is not present"
(render [view/view (dissoc channel-props :icon)])
(h/is-null (h/query-by-label-text :logo))))

View File

@ -0,0 +1,23 @@
(ns quo.components.links.internal-link-card.schema)
(def ?schema
[:=>
[:catn
[:props
[:map {:closed true}
[:title {:optional true} [:maybe :string]]
[:description {:optional true} [:maybe :string]]
[:channel-name {:optional true} [:maybe :string]]
[:loading? {:optional true} [:maybe :boolean]]
[:subtitle {:optional true} [:maybe :string]]
[:icon {:optional true} [:maybe [:or :string :int]]]
[:banner {:optional true} [:maybe [:or :string :int]]]
[:type {:optional true} [:maybe :keyword]]
[:on-press {:optional true} [:maybe fn?]]
[:members-count {:optional true} [:maybe [:or :int :string]]]
[:active-members-count {:optional true} [:maybe [:or :int :string]]]
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
[:emoji-hash {:optional true} [:maybe :string]]
[:size {:optional true} [:maybe :keyword]]
[:theme :schema.common/theme]]]]
:any])

View File

@ -0,0 +1,66 @@
(ns quo.components.links.internal-link-card.user.style
(:require [quo.foundations.colors :as colors]))
(defn loading-circle
[theme]
{:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
:margin-right 4
:width 16
:height 16
:border-radius 16})
(defn loading-first-line-bar
[theme]
{:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
:width 145
:height 16
:border-radius 6})
(defn loading-second-line-bar
[theme]
{:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
:width 112
:height 8
:border-radius 6
:margin-bottom 17})
(defn last-bar-line-bar
[theme]
{:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
:width 271
:height 16
:border-radius 6})
(defn gradient-start-color
[customization-color theme]
(colors/theme-colors (colors/resolve-color customization-color theme 10)
(colors/resolve-color customization-color theme 20)
theme))
(defn container
[loading? theme size]
{:border-width 1
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:background-color (colors/theme-colors colors/white colors/neutral-80-opa-40 theme)
:border-radius 16
:padding-horizontal 12
:padding-top 10
:padding-bottom 12
:height (if loading? 92 110)
:width (if (= :message size) 295 335)})
(def header-container
{:flex-direction :row
:align-items :center})
(def title
{:margin-bottom 2})
(def logo
{:margin-right 6
:width 16
:height 16
:border-radius 8
:margin-bottom 2})
(def row-spacing {:flex-direction :row :margin-bottom 12})

View File

@ -0,0 +1,83 @@
(ns quo.components.links.internal-link-card.user.view
(:require
[quo.components.links.internal-link-card.schema :as component-schema]
[quo.components.links.internal-link-card.user.style :as style]
[quo.components.markdown.text :as text]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[react-native.linear-gradient :as linear-gradient]
[schema.core :as schema]))
(defn- subtitle-comp
[subtitle emoji-hash]
[rn/view
[text/text
{:size :paragraph-2
:number-of-lines 2
:accessibility-label :subtitle
:style {:margin-bottom 12}}
subtitle]
[rn/view {:style {:flex-direction :row}}
[text/text
{:size :paragraph-2
:number-of-lines 1
:weight :regular
:accessibility-label :emoji-hash}
emoji-hash]]])
(defn- title-comp
[title]
[text/text
{:size :paragraph-1
:number-of-lines 1
:weight :semi-bold
:style style/title
:accessibility-label :title}
title])
(defn- logo-comp
[logo]
[rn/image
{:accessibility-label :logo
:source logo
:style style/logo}])
(defn- loading-view
[theme]
[rn/view {:accessibility-label :loading-user-link-view}
[rn/view {:style style/row-spacing}
[rn/view {:style (style/loading-circle theme)}]
[rn/view {:style (style/loading-first-line-bar theme)}]]
[rn/view {:style (style/loading-second-line-bar theme)}]
[rn/view {:style (style/last-bar-line-bar theme)}]])
(defn- linear-gradient-props
[theme customization-color]
[(style/gradient-start-color customization-color theme) :transparent])
(defn view-internal
[{:keys [title loading? icon
theme on-press subtitle emoji-hash customization-color size]}]
(if loading?
[rn/pressable
{:accessibility-label :internal-link-card
:on-press on-press
:style (style/container loading? theme size)}
[loading-view theme]]
[linear-gradient/linear-gradient
(assoc {:style (style/container loading? theme size)}
:colors
(linear-gradient-props theme customization-color))
[rn/pressable
{:accessibility-label :internal-link-card
:on-press on-press}
[rn/view {:style style/header-container}
(when icon
[logo-comp icon])
[title-comp title]]
(when subtitle
[subtitle-comp subtitle emoji-hash])]]))
(def view
(quo.theme/with-theme
(schema/instrument #'view-internal component-schema/?schema)))

View File

@ -0,0 +1,11 @@
(ns quo.components.links.internal-link-card.view
(:require [quo.components.links.internal-link-card.channel.view :as channel.view]
[quo.components.links.internal-link-card.community.view :as community.view]
[quo.components.links.internal-link-card.user.view :as user.view]))
(defn view
[{card-type :type :as props}]
(case card-type
:community [community.view/view props]
:channel [channel.view/view props]
:user [user.view/view props]))

View File

@ -69,6 +69,7 @@
quo.components.inputs.title-input.view
quo.components.ios.drawer-bar.view
quo.components.keycard.view
quo.components.links.internal-link-card.view
quo.components.links.link-preview.view
quo.components.links.url-preview-list.view
quo.components.links.url-preview.view
@ -288,6 +289,7 @@
(def numbered-keyboard quo.components.numbered-keyboard.numbered-keyboard.view/view)
;;;; Links
(def internal-link-card quo.components.links.internal-link-card.view/view)
(def link-preview quo.components.links.link-preview.view/view)
(def url-preview quo.components.links.url-preview.view/view)
(def url-preview-list quo.components.links.url-preview-list.view/view)

View File

@ -39,6 +39,7 @@
quo.components.inputs.recovery-phrase.component-spec
quo.components.inputs.title-input.component-spec
quo.components.keycard.component-spec
quo.components.links.internal-link-card.component-spec
quo.components.links.link-preview.component-spec
quo.components.links.url-preview-list.component-spec
quo.components.links.url-preview.component-spec

View File

@ -0,0 +1,60 @@
(ns status-im.contexts.preview.quo.links.internal-link-card
(:require
[quo.core :as quo]
[reagent.core :as reagent]
[status-im.common.resources :as resources]
[status-im.contexts.preview.quo.preview :as preview]))
(def descriptor
[{:key :size
:type :select
:options [{:key :message}
{:key :full-page}]}
{:type :text
:key :title}
{:type :text
:key :subtitle}
{:type :text
:key :description}
{:type :text
:key :emoji-hash}
{:type :boolean
:key :loading?}
{:type :number
:key :members-count}
{:type :number
:key :active-members-count}
{:key :type
:type :select
:options [{:key :community}
{:key :channel}
{:key :user}]}
{:key :banner
:type :select
:options (mapv (fn [k] {:key k})
(keys resources/mock-images))}
(preview/customization-color-option)])
(defn view
[]
(let [state (reagent/atom
{:title "Doodles"
:description "Coloring the world with joy • ᴗ •"
:members-count 24
:emoji-hash "🌟🚀🐠🌈🏰🔮🦉🐼🍉🎨🚲🌙🍔🌵"
:active-members-count 12
:loading? false
:customization-color :purple
:banner :light-blur-background
:type :user
:subtitle "Web 3.0 Designer @ethstatus - DJ, Producer - Dad - YouTuber"})]
(fn []
(let [banner (get resources/mock-images (:banner @state) :bored-ape)]
[preview/preview-container
{:state state
:descriptor descriptor}
[quo/internal-link-card
(assoc @state
:banner banner
:icon (resources/get-mock-image :status-logo)
:on-press #(js/alert "You clicked me!"))]]))))

View File

@ -81,6 +81,7 @@
[status-im.contexts.preview.quo.inputs.title-input :as title-input]
[status-im.contexts.preview.quo.ios.drawer-bar :as drawer-bar]
[status-im.contexts.preview.quo.keycard.keycard :as keycard]
[status-im.contexts.preview.quo.links.internal-link-card :as internal-link-card]
[status-im.contexts.preview.quo.links.link-preview :as link-preview]
[status-im.contexts.preview.quo.links.url-preview :as url-preview]
[status-im.contexts.preview.quo.links.url-preview-list :as
@ -326,7 +327,10 @@
:component keyboard-key/view}
{:name :numbered-keyboard
:component numbered-keyboard/view}]
:links [{:name :url-preview
:links [{:name :internal-link-card
:options {:insets {:top true}}
:component internal-link-card/view}
{:name :url-preview
:options {:insets {:top? true}}
:component url-preview/view}
{:name :url-preview-list