quo channel component refactor (#17070)
This commit is contained in:
parent
f433956657
commit
dfa30fd14f
|
@ -12,16 +12,19 @@
|
||||||
|
|
||||||
(defn container
|
(defn container
|
||||||
[{:keys [type label container-style customization-color theme value max-value]}]
|
[{:keys [type label container-style customization-color theme value max-value]}]
|
||||||
(let [width (case (count label)
|
(let [label-length (count label)
|
||||||
1 16
|
width (case label-length
|
||||||
2 20
|
1 16
|
||||||
28)]
|
2 20
|
||||||
|
28)]
|
||||||
(cond-> (merge
|
(cond-> (merge
|
||||||
{:align-items :center
|
{:align-items :center
|
||||||
:justify-content :center
|
:justify-content :center
|
||||||
:border-radius 6
|
:border-radius 6
|
||||||
:width width
|
:width width
|
||||||
:height 16}
|
:margin-vertical 2
|
||||||
|
:margin-horizontal (if (= label-length 1) 2 0)
|
||||||
|
:height 16}
|
||||||
container-style)
|
container-style)
|
||||||
(= type :outline)
|
(= type :outline)
|
||||||
(merge {:border-width 1
|
(merge {:border-width 1
|
||||||
|
|
|
@ -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])])]]))
|
|
|
@ -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))))
|
|
@ -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})
|
|
@ -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))
|
|
@ -60,7 +60,7 @@
|
||||||
quo2.components.links.url-preview-list.view
|
quo2.components.links.url-preview-list.view
|
||||||
quo2.components.links.url-preview.view
|
quo2.components.links.url-preview.view
|
||||||
quo2.components.list-items.account-list-card.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.community.view
|
||||||
quo2.components.list-items.dapp.view
|
quo2.components.list-items.dapp.view
|
||||||
quo2.components.list-items.menu-item
|
quo2.components.list-items.menu-item
|
||||||
|
@ -244,7 +244,7 @@
|
||||||
|
|
||||||
;;;; List items
|
;;;; List items
|
||||||
(def account-list-card quo2.components.list-items.account-list-card.view/view)
|
(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 dapp quo2.components.list-items.dapp.view/view)
|
||||||
(def menu-item quo2.components.list-items.menu-item/menu-item)
|
(def menu-item quo2.components.list-items.menu-item/menu-item)
|
||||||
(def preview-list quo2.components.list-items.preview-list.view/view)
|
(def preview-list quo2.components.list-items.preview-list.view/view)
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
[quo2.components.links.link-preview.component-spec]
|
[quo2.components.links.link-preview.component-spec]
|
||||||
[quo2.components.links.url-preview-list.component-spec]
|
[quo2.components.links.url-preview-list.component-spec]
|
||||||
[quo2.components.links.url-preview.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.community.component-spec]
|
||||||
[quo2.components.list-items.dapp.component-spec]
|
[quo2.components.list-items.dapp.component-spec]
|
||||||
[quo2.components.list-items.token-value.component-spec]
|
[quo2.components.list-items.token-value.component-spec]
|
||||||
|
|
|
@ -257,9 +257,11 @@
|
||||||
color-keyword (keyword color)
|
color-keyword (keyword color)
|
||||||
base-color (get-in colors-map
|
base-color (get-in colors-map
|
||||||
[color-keyword suffix])]
|
[color-keyword suffix])]
|
||||||
(if hex?
|
(cond
|
||||||
color
|
(and opacity hex?) (alpha color (/ opacity 100))
|
||||||
(if opacity (alpha base-color (/ opacity 100)) base-color)))))))
|
opacity (alpha base-color (/ opacity 100))
|
||||||
|
hex? color
|
||||||
|
:else base-color))))))
|
||||||
|
|
||||||
(defn custom-color-by-theme
|
(defn custom-color-by-theme
|
||||||
"(custom-color-by-theme color suffix-light suffix-dark opacity-light opacity-dark)
|
"(custom-color-by-theme color suffix-light suffix-dark opacity-light opacity-dark)
|
||||||
|
|
|
@ -47,21 +47,31 @@
|
||||||
(oops/oget event "nativeEvent.layout.y"))
|
(oops/oget event "nativeEvent.layout.y"))
|
||||||
|
|
||||||
(defn- channel-chat-item
|
(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
|
(let [sheet-content [actions/chat-actions
|
||||||
(assoc chat
|
(assoc chat
|
||||||
:chat-type constants/community-chat-type
|
:chat-type constants/community-chat-type
|
||||||
:chat-id (str community-id id))
|
:chat-id (str community-id id))
|
||||||
false]
|
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)}]
|
:content (fn [] sheet-content)}]
|
||||||
[rn/view {:key id :style {:margin-top 4}}
|
[rn/view {:key id}
|
||||||
[quo/channel-list-item
|
[quo/channel
|
||||||
(assoc chat
|
(merge channel-options
|
||||||
:default-color community-color
|
{:on-press on-press
|
||||||
:on-long-press #(rf/dispatch [:show-bottom-sheet channel-sheet-data])
|
:on-long-press #(rf/dispatch [:show-bottom-sheet channel-sheet-data])})]]))
|
||||||
:muted? (or muted?
|
|
||||||
(rf/sub [:chat/check-channel-muted? community-id id])))]]))
|
|
||||||
|
|
||||||
(defn channel-list-component
|
(defn channel-list-component
|
||||||
[{:keys [on-category-layout community-id community-color on-first-channel-height-changed]}
|
[{:keys [on-category-layout community-id community-color on-first-channel-height-changed]}
|
||||||
|
|
|
@ -1,19 +1,27 @@
|
||||||
(ns status-im2.contexts.quo-preview.list-items.channel
|
(ns status-im2.contexts.quo-preview.list-items.channel
|
||||||
(:require [quo2.core :as quo]
|
(:require [quo2.core :as quo]
|
||||||
[reagent.core :as reagent]
|
[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
|
(def descriptor
|
||||||
[{:key :muted?
|
[{:key :name
|
||||||
:type :boolean}
|
|
||||||
{:key :name
|
|
||||||
:type :text}
|
: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
|
{:key :mentions-count
|
||||||
:type :text}
|
:type :text}
|
||||||
{:key :unread-messages?
|
|
||||||
:type :boolean}
|
|
||||||
{:key :emoji
|
{:key :emoji
|
||||||
:type :text}
|
:type :text}
|
||||||
|
(preview/customization-color-option)
|
||||||
{:key :locked?
|
{:key :locked?
|
||||||
:type :select
|
:type :select
|
||||||
:options [{:key nil
|
:options [{:key nil
|
||||||
|
@ -21,28 +29,19 @@
|
||||||
{:key false
|
{:key false
|
||||||
:value "Unlocked"}
|
:value "Unlocked"}
|
||||||
{:key true
|
{:key true
|
||||||
:value "Locked"}]}
|
: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"}]}])
|
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
(let [state (reagent/atom {:is-active-channel? false
|
(let [state (reagent/atom {:name "channel"
|
||||||
:muted? false
|
:notification nil
|
||||||
:unread-messages? false
|
:mentions-count "5"
|
||||||
:emoji "🍑"
|
:emoji "🍑"
|
||||||
:channel-color "#4360DF"
|
:customization-color :blue
|
||||||
:mentions-count "5"
|
:locked? nil})]
|
||||||
:name "channel"
|
|
||||||
:locked? true})]
|
|
||||||
(fn []
|
(fn []
|
||||||
[preview/preview-container {:state state :descriptor descriptor}
|
(let [customization-color (colors/custom-color-by-theme (:customization-color @state) 50 60)]
|
||||||
[quo/channel-list-item @state]])))
|
[preview/preview-container
|
||||||
|
{:state state
|
||||||
|
:descriptor descriptor}
|
||||||
|
[quo/channel (assoc @state :customization-color customization-color)]]))))
|
||||||
|
|
Loading…
Reference in New Issue