quo channel component refactor (#17070)

This commit is contained in:
Ajay Sivan 2023-09-04 08:39:23 -07:00 committed by GitHub
parent f433956657
commit dfa30fd14f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 216 additions and 118 deletions

View File

@ -12,16 +12,19 @@
(defn container
[{:keys [type label container-style customization-color theme value max-value]}]
(let [width (case (count label)
1 16
2 20
28)]
(let [label-length (count label)
width (case label-length
1 16
2 20
28)]
(cond-> (merge
{:align-items :center
:justify-content :center
:border-radius 6
:width width
:height 16}
{:align-items :center
:justify-content :center
:border-radius 6
:width width
:margin-vertical 2
:margin-horizontal (if (= label-length 1) 2 0)
:height 16}
container-style)
(= type :outline)
(merge {:border-width 1

View File

@ -1,68 +0,0 @@
(ns quo2.components.list-items.channel
(:require [quo2.components.avatars.channel-avatar.view :as channel-avatar]
[quo2.components.common.unread-grey-dot.view :as unread-grey-dot]
[quo2.components.counter.counter.view :as counter]
[quo2.components.icon :as quo2.icons]
[quo2.components.markdown.text :as quo2.text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))
(def ^:private custom-props
[:name :locked? :mentions-count :unread-messages?
:muted? :is-active-channel? :emoji :channel-color])
(defn list-item
[{:keys [locked? mentions-count unread-messages?
muted? is-active-channel? emoji channel-color
default-color]
:as props}]
(let [channel-color (or channel-color default-color)
standard-props (apply dissoc props custom-props)
name-text (:name props)]
[rn/touchable-opacity standard-props
[rn/view
{:style (cond-> {:height 48
:border-radius 12
:flex-direction :row
:justify-content :space-between
:align-items :center
:width "100%"
:padding-left 12
:padding-right 12}
is-active-channel? (assoc :background-color
(colors/theme-alpha channel-color 0.05 0.05)))}
[rn/view
{:style {:flex-direction :row
:justify-content :flex-start
:align-items :center}
:accessible true
:accessibility-label :chat-name-text}
[channel-avatar/view
{:size :size/l
:locked? locked?
:full-name (:name props)
:customization-color channel-color
:emoji emoji}]
[quo2.text/text
{:style (cond-> {:margin-left 12}
(and (not locked?) muted?)
(assoc :color (colors/theme-colors colors/neutral-40 colors/neutral-60)))
:weight :medium
:size :paragraph-1}
(str "# " name-text)]]
(when-not locked?
[rn/view {:style {:height 20 :justify-content :center}}
(cond
muted?
[quo2.icons/icon :i/muted
{:size 20
:color colors/neutral-40
:container-style {:margin-right 1 :margin-top 2}}]
(pos? (int mentions-count))
[rn/view {:style {:margin-right 2 :margin-top 2}}
[counter/view {:customization-color channel-color}
mentions-count]]
unread-messages?
[unread-grey-dot/unread-grey-dot :unviewed-messages-public])])]]))

View File

@ -0,0 +1,44 @@
(ns quo2.components.list-items.channel.component-spec
(:require [test-helpers.component :as h]
[quo2.components.list-items.channel.view :as channel]))
(h/describe "list-items/channel Component"
(h/test "default render"
(h/render [channel/view {:name "general"}])
(h/is-truthy (h/query-by-label-text :channel-list-item)))
(h/test "with name & emoji"
(h/render [channel/view
{:name "general"
:emoji "👋"}])
(h/is-truthy (h/query-by-text "# general"))
(h/is-truthy (h/query-by-text "👋")))
(h/test "notification & mentions count"
(h/render [channel/view
{:name "general"
:mentions-count 10
:notification :mention}])
(h/is-truthy (h/query-by-text "10")))
(h/test "unread indicator"
(h/render [channel/view
{:name "general"
:notification :notification}])
(h/is-truthy (h/query-by-label-text :unviewed-messages-public)))
(h/test "on-press event"
(let [on-press (h/mock-fn)]
(h/render [channel/view
{:name "general"
:on-press on-press}])
(h/fire-event :press (h/query-by-label-text :channel-list-item))
(h/was-called on-press)))
(h/test "on-long-press event"
(let [on-long-press (h/mock-fn)]
(h/render [channel/view
{:name "general"
:on-long-press on-long-press}])
(h/fire-event :long-press (h/query-by-label-text :channel-list-item))
(h/was-called on-long-press))))

View File

@ -0,0 +1,46 @@
(ns quo2.components.list-items.channel.style
(:require [quo2.foundations.colors :as colors]))
(defn- get-label-color
[notification theme]
(let [colors {:notification (colors/theme-colors colors/neutral-100
colors/white
theme)
:mention (colors/theme-colors colors/neutral-100
colors/white
theme)
:mute (colors/theme-colors colors/neutral-40
colors/neutral-60
theme)
:default (colors/theme-colors colors/neutral-50
colors/neutral-40
theme)}]
(colors (or notification :default))))
(defn mute-notification-icon-color
[theme]
(colors/theme-colors colors/neutral-40
colors/neutral-60
theme))
(defn container
[pressed? customization-color theme]
{:height 48
:border-radius 12
:padding-horizontal 12
:padding-vertical 8
:align-items :center
:overflow :hidden
:background-color (if pressed?
(colors/theme-colors
(colors/custom-color customization-color 50 5)
(colors/custom-color customization-color 60 5)
theme)
:transparent)
:flex-direction :row})
(defn label
[notification theme]
{:margin-horizontal 12
:color (get-label-color notification theme)
:flex 1})

View File

@ -0,0 +1,61 @@
(ns quo2.components.list-items.channel.view
(:require [quo2.components.list-items.channel.style :as style]
[quo2.theme :as theme]
[react-native.core :as rn]
[quo2.components.avatars.channel-avatar.view :as channel-avatar]
[quo2.components.markdown.text :as quo.text]
[quo2.components.icon :as quo2.icons]
[quo2.components.counter.counter.view :as counter]
[reagent.core :as reagent]))
(defn- view-internal
"Options:
- notification - (nil/:notification/:mention/:mute, default: nil):
- :notification - Display a grey dot.
- :mention - Display a counter.
- :mute - Display a mute icon.
- locked? - (nil/boolean, default: nil):
- When true, display a locked icon.
- When false, display an unlocked icon.
- mentions-count - (default: nil) - Number of mentions to display in the counter with :mention notification.
- customization-color - (default: nil) - Community color.
- emoji - (string, default: nil):
- Emoji to be displayed on the channel avatar.
- If blank, initials of the channel name are displayed.
- name - (string, default: nil) - Channel name.
- on-press - (function, default: nil) - Function called when the component is pressed.
- on-long-press - (function, default: nil) - Function called when the component is long pressed.
- theme - Theme value from with-theme HOC"
[]
(let [pressed? (reagent/atom false)]
(fn [{:keys [notification locked? mentions-count customization-color emoji name on-press
on-long-press theme]}]
[rn/pressable
{:style (style/container @pressed? customization-color theme)
:accessibility-label :channel-list-item
:on-press on-press
:on-long-press on-long-press
:on-press-in #(reset! pressed? true)
:on-press-out #(reset! pressed? false)}
[channel-avatar/view
{:size :size/l
:locked? locked?
:full-name name
:customization-color customization-color
:emoji emoji}]
[quo.text/text
{:style (style/label notification theme)
:weight :medium
:size :paragraph-1} (str "# " name)]
(when-not locked?
(condp = notification
:mute [quo2.icons/icon :i/muted
{:color (style/mute-notification-icon-color theme)}]
:mention [counter/view {:customization-color customization-color}
mentions-count]
:notification [quo2.icons/icon :i/notification
{:color (style/mute-notification-icon-color theme)
:accessibility-label :unviewed-messages-public}]
nil))])))
(def view (theme/with-theme view-internal))

View File

@ -60,7 +60,7 @@
quo2.components.links.url-preview-list.view
quo2.components.links.url-preview.view
quo2.components.list-items.account-list-card.view
quo2.components.list-items.channel
quo2.components.list-items.channel.view
quo2.components.list-items.community.view
quo2.components.list-items.dapp.view
quo2.components.list-items.menu-item
@ -244,7 +244,7 @@
;;;; List items
(def account-list-card quo2.components.list-items.account-list-card.view/view)
(def channel-list-item quo2.components.list-items.channel/list-item)
(def channel quo2.components.list-items.channel.view/view)
(def dapp quo2.components.list-items.dapp.view/view)
(def menu-item quo2.components.list-items.menu-item/menu-item)
(def preview-list quo2.components.list-items.preview-list.view/view)

View File

@ -35,6 +35,7 @@
[quo2.components.links.link-preview.component-spec]
[quo2.components.links.url-preview-list.component-spec]
[quo2.components.links.url-preview.component-spec]
[quo2.components.list-items.channel.component-spec]
[quo2.components.list-items.community.component-spec]
[quo2.components.list-items.dapp.component-spec]
[quo2.components.list-items.token-value.component-spec]

View File

@ -257,9 +257,11 @@
color-keyword (keyword color)
base-color (get-in colors-map
[color-keyword suffix])]
(if hex?
color
(if opacity (alpha base-color (/ opacity 100)) base-color)))))))
(cond
(and opacity hex?) (alpha color (/ opacity 100))
opacity (alpha base-color (/ opacity 100))
hex? color
:else base-color))))))
(defn custom-color-by-theme
"(custom-color-by-theme color suffix-light suffix-dark opacity-light opacity-dark)

View File

@ -47,21 +47,31 @@
(oops/oget event "nativeEvent.layout.y"))
(defn- channel-chat-item
[community-id community-color {:keys [:muted? id] :as chat}]
[community-id community-color
{:keys [name emoji muted? id mentions-count unread-messages? on-press locked?] :as chat}]
(let [sheet-content [actions/chat-actions
(assoc chat
:chat-type constants/community-chat-type
:chat-id (str community-id id))
false]
channel-sheet-data {:selected-item (fn [] [quo/channel-list-item chat])
notification (cond
muted? :mute
(> mentions-count 0) :mention
unread-messages? :notification
:else nil)
channel-options {:name name
:emoji emoji
:customization-color community-color
:mentions-count mentions-count
:locked? locked?
:notification notification}
channel-sheet-data {:selected-item (fn [] [quo/channel channel-options])
:content (fn [] sheet-content)}]
[rn/view {:key id :style {:margin-top 4}}
[quo/channel-list-item
(assoc chat
:default-color community-color
:on-long-press #(rf/dispatch [:show-bottom-sheet channel-sheet-data])
:muted? (or muted?
(rf/sub [:chat/check-channel-muted? community-id id])))]]))
[rn/view {:key id}
[quo/channel
(merge channel-options
{:on-press on-press
:on-long-press #(rf/dispatch [:show-bottom-sheet channel-sheet-data])})]]))
(defn channel-list-component
[{:keys [on-category-layout community-id community-color on-first-channel-height-changed]}

View File

@ -1,19 +1,27 @@
(ns status-im2.contexts.quo-preview.list-items.channel
(:require [quo2.core :as quo]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]))
[status-im2.contexts.quo-preview.preview :as preview]
[quo2.foundations.colors :as colors]))
(def descriptor
[{:key :muted?
:type :boolean}
{:key :name
[{:key :name
:type :text}
{:key :notification
:type :select
:options [{:key nil
:value "None"}
{:key :notification
:value :notification}
{:key :mute
:value :mute}
{:key :mention
:value :mention}]}
{:key :mentions-count
:type :text}
{:key :unread-messages?
:type :boolean}
{:key :emoji
:type :text}
(preview/customization-color-option)
{:key :locked?
:type :select
:options [{:key nil
@ -21,28 +29,19 @@
{:key false
:value "Unlocked"}
{:key true
:value "Locked"}]}
{:key :is-active-channel?
:type :boolean}
{:key :channel-color
:type :select
:options [{:key "#00FFFF"
:value "Blue"}
{:key "#FF00FF"
:value "Pink"}
{:key "#FFFF00"
:value "Yellow"}]}])
:value "Locked"}]}])
(defn view
[]
(let [state (reagent/atom {:is-active-channel? false
:muted? false
:unread-messages? false
:emoji "🍑"
:channel-color "#4360DF"
:mentions-count "5"
:name "channel"
:locked? true})]
(let [state (reagent/atom {:name "channel"
:notification nil
:mentions-count "5"
:emoji "🍑"
:customization-color :blue
:locked? nil})]
(fn []
[preview/preview-container {:state state :descriptor descriptor}
[quo/channel-list-item @state]])))
(let [customization-color (colors/custom-color-by-theme (:customization-color @state) 50 60)]
[preview/preview-container
{:state state
:descriptor descriptor}
[quo/channel (assoc @state :customization-color customization-color)]]))))