fix: action/reaction drawer UI issue (#19630)

This commit is contained in:
yqrashawn 2024-05-17 20:12:03 +08:00 committed by GitHub
parent afd92d2df1
commit cfe9d6e539
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 289 additions and 240 deletions

View File

@ -6,24 +6,26 @@
(h/describe "Drawers: drawer-action" (h/describe "Drawers: drawer-action"
(h/test "default render" (h/test "default render"
(h/render-with-theme-provider [drawer-action/view {}]) (h/render-with-theme-provider [drawer-action/view {:accessibility-label :container}])
(h/is-truthy (h/query-by-label-text :container))) (h/is-truthy (h/query-by-label-text :container)))
(h/test "on-press-in changes internal state to :pressed" (h/test "on-press-in changes internal state to :pressed"
(h/render-with-theme-provider [drawer-action/view {}]) (h/render-with-theme-provider [drawer-action/view {:accessibility-label :container}])
(h/fire-event :on-press-in (h/get-by-label-text :container)) (h/fire-event :on-press-in (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container) (h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/resolve-color :blue :light 5)}))) {:backgroundColor (colors/resolve-color :blue :light 5)})))
(h/test "render default action with state :selected" (h/test "render default action with state :selected"
(h/render-with-theme-provider [drawer-action/view {:state :selected}]) (h/render-with-theme-provider [drawer-action/view
{:state :selected :accessibility-label :container}])
(h/has-style (h/query-by-label-text :container) (h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/resolve-color :blue :light 5)}) {:backgroundColor (colors/resolve-color :blue :light 5)})
(h/is-truthy (h/query-by-label-text :check-icon))) (h/is-truthy (h/query-by-label-text :check-icon)))
(h/test "call on-press" (h/test "call on-press"
(let [on-press (h/mock-fn)] (let [on-press (h/mock-fn)]
(h/render-with-theme-provider [drawer-action/view {:on-press on-press}]) (h/render-with-theme-provider [drawer-action/view
{:on-press on-press :accessibility-label :container}])
(h/fire-event :on-press (h/get-by-label-text :container)) (h/fire-event :on-press (h/get-by-label-text :container))
(h/was-called on-press))) (h/was-called on-press)))
@ -38,8 +40,9 @@
(h/test "render :toggle action with state :selected" (h/test "render :toggle action with state :selected"
(h/render-with-theme-provider [drawer-action/view (h/render-with-theme-provider [drawer-action/view
{:action :toggle {:accessibility-label :container
:state :selected}]) :action :toggle
:state :selected}])
(h/is-truthy (h/query-by-label-text "toggle-on")) (h/is-truthy (h/query-by-label-text "toggle-on"))
(h/has-style (h/query-by-label-text :container) (h/has-style (h/query-by-label-text :container)
{:backgroundColor :transparent})) {:backgroundColor :transparent}))
@ -51,4 +54,5 @@
:description "Just a small desc"}]) :description "Just a small desc"}])
(h/is-truthy (h/query-by-label-text :left-icon)) (h/is-truthy (h/query-by-label-text :left-icon))
(h/is-truthy (h/query-by-text "Check contact")) (h/is-truthy (h/query-by-text "Check contact"))
(h/has-style (h/query-by-text "Check contact") {:color colors/neutral-100})
(h/is-truthy (h/query-by-text "Just a small desc")))) (h/is-truthy (h/query-by-text "Just a small desc"))))

View File

@ -4,6 +4,8 @@
[:=> [:=>
[:cat [:cat
[:map {:closed true} [:map {:closed true}
[:accessibility-label {:optional true} [:maybe :keyword]]
[:type {:optional true} [:maybe [:enum :main :danger]]]
[:action {:optional true} [:maybe [:enum :arrow :toggle]]] [:action {:optional true} [:maybe [:enum :arrow :toggle]]]
[:icon {:optional true} [:maybe :keyword]] [:icon {:optional true} [:maybe :keyword]]
[:description {:optional true} [:maybe :string]] [:description {:optional true} [:maybe :string]]

View File

@ -28,6 +28,23 @@
{:flex 1 {:flex 1
:margin-right 12}) :margin-right 12})
(defn text
[{:keys [theme blur? type]}]
(let [base {:weight :medium}
theme-with-blur (if blur? :blue theme)
matcher [theme-with-blur type]
color
(case matcher
([:dark :main] [:light :main]) (colors/theme-colors colors/neutral-100
colors/white
theme)
[:blur :main] colors/white-70-blur
([:dark :danger] [:light :danger]) (colors/theme-colors colors/danger-50
colors/danger-60
theme)
[:blur :danger] colors/danger-60)]
(assoc-in base [:style :color] color)))
(defn- neutral-color (defn- neutral-color
[theme blur?] [theme blur?]
(if blur? (if blur?
@ -41,8 +58,14 @@
:margin-top 1}) :margin-top 1})
(defn icon-color (defn icon-color
[{:keys [theme blur?]}] [{:keys [theme blur? type]}]
(neutral-color theme blur?)) (let [theme-with-blur (if blur? :blue theme)
matcher [theme-with-blur type]]
(case matcher
([:dark :main] [:light :main]) (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
[:blur :main] colors/white-70-blur
([:dark :danger] [:light :danger]) (colors/theme-colors colors/danger-50 colors/danger-60 theme)
[:blur :danger] colors/danger-60)))
(defn desc (defn desc
[{:keys [theme blur?]}] [{:keys [theme blur?]}]

View File

@ -10,11 +10,13 @@
[schema.core :as schema])) [schema.core :as schema]))
(defn view-internal (defn view-internal
[{:keys [action icon description state title on-press [{:keys [action icon description state title on-press customization-color
customization-color blur?] blur? accessibility-label]
:or {customization-color :blue action-type :type
blur? false}}] :or {customization-color :blue
blur? false}}]
(let [theme (quo.theme/use-theme) (let [theme (quo.theme/use-theme)
action-type (or action-type :main)
[pressed? set-pressed] (rn/use-state false) [pressed? set-pressed] (rn/use-state false)
on-press-in (rn/use-callback #(set-pressed true)) on-press-in (rn/use-callback #(set-pressed true))
on-press-out (rn/use-callback #(set-pressed false))] on-press-out (rn/use-callback #(set-pressed false))]
@ -29,16 +31,21 @@
:pressed? pressed? :pressed? pressed?
:description? (not-empty description) :description? (not-empty description)
:blur? blur?}) :blur? blur?})
:accessibility-label :container} :accessibility-label accessibility-label}
(when icon (when icon
[icon/icon icon [icon/icon icon
{:accessibility-label :left-icon {:accessibility-label :left-icon
:container-style (style/left-icon) :container-style (style/left-icon)
:color (style/icon-color {:theme theme :color (style/icon-color {:theme theme
:type action-type
:blur? blur?})}]) :blur? blur?})}])
[rn/view {:style (style/text-container)} [rn/view
[text/text {:weight :medium} {:style (style/text-container)}
[text/text
(style/text {:theme theme
:type action-type
:blur? blur?})
title] title]
(when (seq description) (when (seq description)
@ -61,6 +68,7 @@
[icon/icon :i/chevron-right [icon/icon :i/chevron-right
{:accessibility-label :arrow-icon {:accessibility-label :arrow-icon
:color (style/icon-color {:theme theme :color (style/icon-color {:theme theme
:type action-type
:blur? blur?})}] :blur? blur?})}]
(= state :selected) (= state :selected)

View File

@ -3,39 +3,14 @@
[quo.foundations.colors :as colors] [quo.foundations.colors :as colors]
[react-native.platform :as platform])) [react-native.platform :as platform]))
(defn- primary-name-top-offset
[size]
(when (= size 15)
(cond platform/ios? 1
platform/android? -0.5
:else 0)))
(defn- primary-name-margin-bottom-offset
[size]
(when (and (= size 15)
(or platform/ios? platform/android?))
-0.25))
(defn- primary-name-layout-offsets
[size]
;; NOTE(seanstrom): We need to sometimes offset the primary-name to align the baseline of the text
;; while avoiding shifting elements downward.
{:top (primary-name-top-offset size)
:margin-bottom (primary-name-margin-bottom-offset size)})
(defn container (defn container
[size] [size]
{:flex-shrink 1 (cond->
:flex-wrap :nowrap {:flex-shrink 1
:flex-direction :row :flex-wrap :nowrap
:align-items :baseline :flex-direction :row
;; NOTE(seanstrom): Because we're offseting the primary-name we need to inverse the offset on the :align-items :center
;; container to avoid shifting elements downward :height (if (= size 15) 22 18)}))
:top (* -1 (primary-name-top-offset size))})
(def details-container
{:flex-direction :row
:margin-left 8})
(defn middle-dot (defn middle-dot
[theme] [theme]
@ -48,11 +23,15 @@
(defn primary-name (defn primary-name
[muted? theme size] [muted? theme size]
(merge (primary-name-layout-offsets size) {:color (if muted?
{:color (if muted? colors/neutral-50
colors/neutral-50 (colors/theme-colors colors/neutral-100 colors/white theme))
(colors/theme-colors colors/neutral-100 colors/white theme)) ;; iOS: primary-name height is 22.3 / 18.7
:flex-shrink 1})) ;; Android: primary-name height is 21.8 / 18.5
:margin-vertical (if (= size 15)
(if platform/ios? -0.15 0)
(if platform/ios? -0.35 -0.25))
:flex-shrink 1})
(defn secondary-name (defn secondary-name
[theme] [theme]
@ -60,13 +39,9 @@
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}) :color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
(defn icon-container (defn icon-container
[is-first?] [is-first? size]
{:margin-left (if is-first? 4 2) {:margin-left (if is-first? 4 2)
;; NOTE(seanstrom): Because we're using flex baseline to align elements :padding-top (if (= size 15) 6 4)})
;; we need to offset the icon container to match the designs.
:top (cond platform/ios? 1
platform/android? 2
:else 0)})
(defn time-text (defn time-text
[theme] [theme]

View File

@ -13,7 +13,35 @@
[{:keys [primary-name secondary-name style short-chat-key time-str contact? verified? untrustworthy? [{:keys [primary-name secondary-name style short-chat-key time-str contact? verified? untrustworthy?
muted? size] muted? size]
:or {size 13}}] :or {size 13}}]
(let [theme (quo.theme/use-theme)] (let [theme (quo.theme/use-theme)
short-chat-key-component
(when (and (not verified?) short-chat-key)
[text/text
{:weight :monospace
:size :label
:number-of-lines 1
:style (style/chat-key-text theme)}
short-chat-key])
time-str-component
(when time-str
[text/text
{:monospace true
:size :label
:accessibility-label :message-timestamp
:number-of-lines 1
:style (style/time-text theme)}
time-str])
middle-dot-seperator-component
(when (and short-chat-key-component time-str-component)
[text/text
{:monospace true
:size :label
:number-of-lines 1
:style (style/middle-dot theme)}
middle-dot])]
[rn/view [rn/view
{:style (merge (style/container size) style)} {:style (merge (style/container size) style)}
[text/text [text/text
@ -23,7 +51,7 @@
:accessibility-label :author-primary-name :accessibility-label :author-primary-name
:style (style/primary-name muted? theme size)} :style (style/primary-name muted? theme size)}
primary-name] primary-name]
(when (not (string/blank? secondary-name)) (when-not (string/blank? secondary-name)
[:<> [:<>
[text/text [text/text
{:size :label {:size :label
@ -41,38 +69,22 @@
[icons/icon :main-icons2/contact [icons/icon :main-icons2/contact
{:size 12 {:size 12
:no-color true :no-color true
:container-style (style/icon-container true)}]) :container-style (style/icon-container true size)}])
(cond (cond
verified? verified?
[icons/icon :main-icons2/verified [icons/icon :main-icons2/verified
{:size 12 {:size 12
:no-color true :no-color true
:container-style (style/icon-container contact?)}] :container-style (style/icon-container contact? size)}]
untrustworthy? untrustworthy?
[icons/icon :main-icons2/untrustworthy [icons/icon :main-icons2/untrustworthy
{:size 12 {:size 12
:no-color true :no-color true
:container-style (style/icon-container contact?)}]) :container-style (style/icon-container contact? size)}])
[rn/view {:style style/details-container}
(when (and (not verified?) short-chat-key) (when (or short-chat-key-component time-str-component)
[text/text [rn/view {:style {:width 8}}])
{:weight :monospace
:size :label short-chat-key-component
:number-of-lines 1 middle-dot-seperator-component
:style (style/chat-key-text theme)} time-str-component]))
short-chat-key])
(when (and (not verified?) time-str short-chat-key)
[text/text
{:monospace true
:size :label
:number-of-lines 1
:style (style/middle-dot theme)}
middle-dot])
(when time-str
[text/text
{:monospace true
:size :label
:accessibility-label :message-timestamp
:number-of-lines 1
:style (style/time-text theme)}
time-str])]]))

View File

@ -5,7 +5,8 @@
[react-native.core :as rn])) [react-native.core :as rn]))
(defn view (defn view
[{:keys [reactions on-press on-long-press add-reaction? on-press-add use-case container-style]}] [{:keys [reactions on-press on-long-press hide-new-reaction-button? on-press-add use-case
container-style]}]
[rn/view {:style (merge style/container container-style)} [rn/view {:style (merge style/container container-style)}
(for [emoji-reaction reactions (for [emoji-reaction reactions
:let [{:keys [emoji emoji-id emoji-reaction-id quantity own]} emoji-reaction]] :let [{:keys [emoji emoji-id emoji-reaction-id quantity own]} emoji-reaction]]
@ -19,7 +20,7 @@
:on-press #(on-press emoji-reaction) :on-press #(on-press emoji-reaction)
:on-long-press #(on-long-press emoji-reaction) :on-long-press #(on-long-press emoji-reaction)
:accessibility-label (str "emoji-reaction-" emoji-id)}]) :accessibility-label (str "emoji-reaction-" emoji-id)}])
(when add-reaction? (when-not hide-new-reaction-button?
[react-selector/view [react-selector/view
{:on-press on-press-add {:on-press on-press-add
:state :add-reaction :state :add-reaction

View File

@ -1,12 +1,31 @@
(ns quo.components.selectors.reactions-selector.style (ns quo.components.selectors.reactions-selector.style
(:require (:require
[quo.foundations.colors :as colors])) [quo.foundations.colors :as colors]
[react-native.platform :as platform]))
(defn container (defn container
[pressed? theme] [pressed? theme]
{:padding 10 (merge
:border-radius 12 {:border-radius 12
:border-width 1 :border-width 1
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme) :border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:background-color (when pressed? :background-color (when pressed?
(colors/theme-colors colors/neutral-10 colors/neutral-80-opa-40 theme))}) (colors/theme-colors colors/neutral-10 colors/neutral-80-opa-40 theme))}
(if platform/ios?
{:padding 9.5
:padding-horizontal 8}
{:padding 8})))
(def emoji-text-style
(merge
{:line-height 20
:text-align :center}
(if platform/ios?
{:line-height 20
:font-size 17
:text-align :center}
{:font-size 18
:height 24
:width 24
:text-align :center
:text-align-vertical :center})))

View File

@ -20,4 +20,6 @@
:style (merge (style/container pressed? theme) :style (merge (style/container pressed? theme)
container-style) container-style)
:on-press on-press} :on-press on-press}
[rn/text (reactions.resource/system-emojis emoji)]])) [rn/text
{:style style/emoji-text-style}
(reactions.resource/system-emojis emoji)]]))

View File

@ -8,7 +8,6 @@
(defn sheet (defn sheet
[{:keys [max-height]}] [{:keys [max-height]}]
{:position :absolute {:position :absolute
:overflow :hidden
:bottom 0 :bottom 0
:left 0 :left 0
:right 0 :right 0

View File

@ -15,7 +15,7 @@
:emoji-id emoji-id}]))) :emoji-id emoji-id}])))
(defn- on-long-press (defn- on-long-press
[{:keys [message-id emoji-id user-message-content reactions-order theme]}] [{:keys [message-id emoji-id user-message-content-render-fn reactions-order theme]}]
(rf/dispatch (rf/dispatch
[:reactions/get-authors-by-message-id [:reactions/get-authors-by-message-id
{:message-id message-id {:message-id message-id
@ -31,19 +31,19 @@
[drawers/reaction-authors [drawers/reaction-authors
{:reactions-order reactions-order {:reactions-order reactions-order
:theme theme}]) :theme theme}])
:selected-item (fn [] user-message-content) :selected-item (fn [] [user-message-content-render-fn
{:hide-reactions? true}])
:padding-bottom-override 0}]))}])) :padding-bottom-override 0}]))}]))
(defn- on-press-add (defn- on-press-add
[{:keys [chat-id message-id user-message-content]}] [{:keys [chat-id message-id user-message-content-render-fn]}]
(rf/dispatch [:dismiss-keyboard]) (rf/dispatch [:dismiss-keyboard])
(rf/dispatch (rf/dispatch
[:show-bottom-sheet [:show-bottom-sheet
{:content (fn [] [drawers/reactions {:content (fn [] [drawers/reactions
{:chat-id chat-id {:chat-id chat-id
:message-id message-id}]) :message-id message-id}])
:selected-item (fn [] :selected-item (fn [] [user-message-content-render-fn])}]))
user-message-content)}]))
(defn- add-emoji-key (defn- add-emoji-key
[reaction] [reaction]
@ -52,23 +52,25 @@
(get constants/reactions (:emoji-id reaction)))) (get constants/reactions (:emoji-id reaction))))
(defn message-reactions-row (defn message-reactions-row
[{:keys [message-id chat-id pinned-by preview?]} user-message-content] [{:keys [message-id chat-id pinned-by hide-new-reaction-button?]} user-message-content-render-fn]
(let [theme (quo.theme/use-theme) (let [theme (quo.theme/use-theme)
reactions (rf/sub [:chats/message-reactions message-id chat-id])] reactions (rf/sub [:chats/message-reactions message-id chat-id])]
[:<> (when (seq reactions)
(when (seq reactions) [quo/react
[quo/react {:container-style {:margin-left 44
{:container-style {:margin-left 44 :margin-top 8}
:margin-top 8} :reactions (map add-emoji-key reactions)
:reactions (map add-emoji-key reactions) :hide-new-reaction-button? hide-new-reaction-button?
:add-reaction? (not preview?) :use-case (when pinned-by :pinned)
:use-case (when pinned-by :pinned) :on-press #(on-press (assoc % :message-id message-id))
:on-press #(on-press (assoc % :message-id message-id)) :on-long-press #(on-long-press (assoc %
:on-long-press #(on-long-press (assoc % :message-id message-id
:message-id message-id :theme theme
:theme theme :reactions-order (map :emoji-id
:reactions-order (map :emoji-id reactions) reactions)
:user-message-content user-message-content)) :user-message-content-render-fn
:on-press-add #(on-press-add {:chat-id chat-id user-message-content-render-fn))
:message-id message-id :on-press-add #(on-press-add {:chat-id chat-id
:user-message-content user-message-content})}])])) :message-id message-id
:user-message-content-render-fn
user-message-content-render-fn})}])))

View File

@ -16,22 +16,20 @@
(assoc :margin-top 4))) (assoc :margin-top 4)))
(defn user-message-content (defn user-message-content
[{:keys [outgoing outgoing-status six-reactions? window-scale small-screen? preview?]}] [{:keys [outgoing outgoing-status six-reactions? window-scale small-screen?]}]
{:border-radius 16 {:border-radius 16
:padding-horizontal (if preview? 12 8) :padding-horizontal 8
:padding-top (if preview? 8 4) :padding-top 4
:padding-bottom (if preview? :padding-bottom (if (or small-screen?
12 (and
(if (or small-screen? (> 3 window-scale)
(and six-reactions?))
(> 3 window-scale) (* message-padding-scaling-ratio window-scale)
six-reactions?)) 4)
(* message-padding-scaling-ratio window-scale)
4))
:opacity (if (and outgoing (= outgoing-status :sending)) :opacity (if (and outgoing (= outgoing-status :sending))
0.5 0.5
1)}) 1)})
(def drawer-message-container (def drawer-message-container
{:padding-top 4 {:padding-top 4
:padding-bottom 8}) :padding-bottom 4})

View File

@ -35,19 +35,19 @@
(def delivery-state-showing-time-ms 3000) (def delivery-state-showing-time-ms 3000)
(defn avatar-container (defn avatar-container
[{:keys [content last-in-group? pinned-by quoted-message from]} show-reactions? [{:keys [content last-in-group? pinned-by quoted-message from]} hide-reactions?
in-reaction-and-action-menu? show-user-info? in-pinned-view?] in-reaction-or-action-menu? show-user-info? in-pinned-view?]
(if (or (and (seq (:response-to content)) (if (or (and (seq (:response-to content))
quoted-message) quoted-message)
last-in-group? last-in-group?
show-user-info? show-user-info?
pinned-by pinned-by
(not show-reactions?) hide-reactions?
in-reaction-and-action-menu?) in-reaction-or-action-menu?)
[avatar/avatar [avatar/avatar
{:public-key from {:public-key from
:size :small :size :small
:hide-ring? (or in-pinned-view? in-reaction-and-action-menu?)}] :hide-ring? (or in-pinned-view? in-reaction-or-action-menu?)}]
[rn/view {:padding-top 4 :width 32}])) [rn/view {:padding-top 4 :width 32}]))
(defn author (defn author
@ -58,15 +58,15 @@
quoted-message quoted-message
from from
timestamp]} timestamp]}
show-reactions? hide-reactions?
in-reaction-and-action-menu? in-reaction-or-action-menu?
show-user-info?] show-user-info?]
(when (or (and (seq (:response-to content)) quoted-message) (when (or (and (seq (:response-to content)) quoted-message)
last-in-group? last-in-group?
pinned-by pinned-by
show-user-info? show-user-info?
(not show-reactions?) hide-reactions?
in-reaction-and-action-menu?) in-reaction-or-action-menu?)
(let [[primary-name secondary-name] (rf/sub [:contacts/contact-two-names-by-identity from]) (let [[primary-name secondary-name] (rf/sub [:contacts/contact-two-names-by-identity from])
{:keys [ens-verified added?]} (rf/sub [:contacts/contact-by-address from])] {:keys [ens-verified added?]} (rf/sub [:contacts/contact-by-address from])]
[quo/author [quo/author
@ -158,8 +158,8 @@
(defn user-message-content (defn user-message-content
[] []
(let [show-delivery-state? (reagent/atom false)] (let [show-delivery-state? (reagent/atom false)]
(fn [{:keys [message-data context keyboard-shown? show-reactions? in-reaction-and-action-menu? (fn [{:keys [message-data context keyboard-shown? hide-reactions?
show-user-info? preview?]}] in-reaction-or-action-menu? show-user-info?]}]
(let [theme (quo.theme/use-theme) (let [theme (quo.theme/use-theme)
{:keys [content-type quoted-message content outgoing outgoing-status pinned-by pinned {:keys [content-type quoted-message content outgoing outgoing-status pinned-by pinned
last-in-group? message-id chat-id]} message-data last-in-group? message-id chat-id]} message-data
@ -198,13 +198,13 @@
:message-sent) :message-sent)
:underlay-color (colors/theme-colors colors/neutral-5 colors/neutral-90 theme) :underlay-color (colors/theme-colors colors/neutral-5 colors/neutral-90 theme)
:style (style/user-message-content :style (style/user-message-content
{:first-in-group? (:first-in-group? message-data) {:first-in-group? (:first-in-group? message-data)
:outgoing outgoing :outgoing outgoing
:outgoing-status outgoing-status :outgoing-status outgoing-status
:small-screen? rn/small-screen? :small-screen? rn/small-screen?
:window-scale window-scale :window-scale window-scale
:six-reactions? six-reactions? :six-reactions? six-reactions?
:preview? preview?}) :in-reaction-or-action-menu? in-reaction-or-action-menu?})
:on-press (fn [] :on-press (fn []
(if (and platform/ios? keyboard-shown?) (if (and platform/ios? keyboard-shown?)
(do (do
@ -226,18 +226,16 @@
[rn/view [rn/view
{:style {:padding-horizontal 4 {:style {:padding-horizontal 4
:flex-direction :row}} :flex-direction :row}}
[avatar-container message-data show-reactions? in-reaction-and-action-menu? show-user-info? [avatar-container message-data hide-reactions? in-reaction-or-action-menu? show-user-info?
(:in-pinned-view? context)] (:in-pinned-view? context)]
(into (into
(if show-reactions? (if hide-reactions?
[rn/view] [gesture/scroll-view]
[gesture/scroll-view]) [rn/view])
[{:style {:margin-left 8 [{:style {:margin-left 8
:flex 1 :flex 1
:gap 1 :max-height (when hide-reactions? (* 0.4 height))}}
:max-height (when-not show-reactions? [author message-data hide-reactions? in-reaction-or-action-menu? show-user-info?]
(* 0.4 height))}}
[author message-data show-reactions? in-reaction-and-action-menu? show-user-info?]
(condp = content-type (condp = content-type
constants/content-type-text constants/content-type-text
[content.text/text-content message-data context] [content.text/text-content message-data context]
@ -272,17 +270,19 @@
(when @show-delivery-state? (when @show-delivery-state?
[status/status outgoing-status])])] [status/status outgoing-status])])]
(when show-reactions? (when-not hide-reactions?
[reactions/message-reactions-row (assoc message-data :preview? preview?) [reactions/message-reactions-row (assoc message-data :hide-new-reaction-button? true)
[rn/view {:pointer-events :none} (fn [override-opts]
[user-message-content [rn/view
{:theme theme {:pointer-events :none
:message-data message-data :style style/drawer-message-container}
:context context [user-message-content
:in-reaction-and-action-menu? true (merge {:theme theme
:keyboard-shown? keyboard-shown? :message-data message-data
:preview? true :context context
:show-reactions? true}]]])]])))) :in-reaction-or-action-menu? true
:keyboard-shown? keyboard-shown?}
override-opts)]])])]]))))
(defn on-long-press (defn on-long-press
[{:keys [deleted? deleted-for-me?] :as message-data} context keyboard-shown?] [{:keys [deleted? deleted-for-me?] :as message-data} context keyboard-shown?]
@ -299,12 +299,11 @@
{:pointer-events :none {:pointer-events :none
:style style/drawer-message-container} :style style/drawer-message-container}
[user-message-content [user-message-content
{:message-data message-data {:message-data message-data
:context context :context context
:keyboard-shown? keyboard-shown? :keyboard-shown? keyboard-shown?
:in-reaction-and-action-menu? true :in-reaction-or-action-menu? true
:show-user-info? false :show-user-info? false}]]))}]))
:show-reactions? true}]]))}]))
(defn check-if-system-message? (defn check-if-system-message?
[content-type] [content-type]
@ -349,5 +348,4 @@
[user-message-content [user-message-content
{:message-data message-data {:message-data message-data
:context context :context context
:keyboard-shown? keyboard-shown? :keyboard-shown? keyboard-shown?}])]))
:show-reactions? true}])]))

View File

@ -105,61 +105,67 @@
;; https://github.com/status-im/status-mobile/issues/15298 is implemented ;; https://github.com/status-im/status-mobile/issues/15298 is implemented
(not= content-type constants/content-type-image) (not= content-type constants/content-type-image)
(not= content-type constants/content-type-audio)) (not= content-type constants/content-type-audio))
[{:type :main [{:type :main
:on-press #(rf/dispatch [:chat.ui/edit-message message-data]) :on-press #(rf/dispatch [:chat.ui/edit-message message-data])
:label (i18n/label :t/edit-message) :label (i18n/label :t/edit-message)
:icon :i/edit :icon :i/edit
:id :edit}]) :accessibility-label :edit-message
:id :edit}])
(when (and able-to-send-message? (not= outgoing-status :sending) (not (or deleted? deleted-for-me?))) (when (and able-to-send-message? (not= outgoing-status :sending) (not (or deleted? deleted-for-me?)))
[{:type :main [{:type :main
:on-press #(rf/dispatch [:chat.ui/reply-to-message message-data]) :on-press #(rf/dispatch [:chat.ui/reply-to-message message-data])
:label (i18n/label :t/message-reply) :label (i18n/label :t/message-reply)
:icon :i/reply :icon :i/reply
:id :reply}]) :accessibility-label :reply-message
:id :reply}])
(when (and (not (or deleted? deleted-for-me?)) (when (and (not (or deleted? deleted-for-me?))
(not= content-type constants/content-type-audio)) (not= content-type constants/content-type-audio))
[{:type :main [{:type :main
:on-press #(clipboard/set-string :on-press #(clipboard/set-string
(reply/get-quoted-text-with-mentions (reply/get-quoted-text-with-mentions
(get content :parsed-text))) (get content :parsed-text)))
:label (i18n/label :t/copy-text) :label (i18n/label :t/copy-text)
:icon :i/copy :accessibility-label :copy-text
:id :copy}]) :icon :i/copy
:id :copy}])
;; pinning images are temporarily disabled ;; pinning images are temporarily disabled
(when (and message-pin-enabled (when (and message-pin-enabled
(not= content-type constants/content-type-image)) (not= content-type constants/content-type-image))
[{:type :main [{:type :main
:on-press #(pin-message message-data) :on-press #(pin-message message-data)
:label (i18n/label (if pinned-by :label (i18n/label (if pinned-by
(if community? :t/unpin-from-channel :t/unpin-from-chat) (if community? :t/unpin-from-channel :t/unpin-from-chat)
(if community? :t/pin-to-channel :t/pin-to-chat))) (if community? :t/pin-to-channel :t/pin-to-chat)))
:icon :i/pin :accessibility-label (if pinned-by :unpin-message :pin-message)
:id (if pinned-by :unpin :pin)}]) :icon :i/pin
:id (if pinned-by :unpin :pin)}])
(when-not (or deleted? deleted-for-me?) (when-not (or deleted? deleted-for-me?)
[{:type :danger [{:type :danger
:on-press (fn [] :on-press (fn []
(rf/dispatch (rf/dispatch
[:hide-bottom-sheet]) [:hide-bottom-sheet])
(rf/dispatch [:chat.ui/delete-message-for-me message-data (rf/dispatch [:chat.ui/delete-message-for-me message-data
config/delete-message-for-me-undo-time-limit-ms])) config/delete-message-for-me-undo-time-limit-ms]))
:label (i18n/label :t/delete-for-me) :label (i18n/label :t/delete-for-me)
:icon :i/delete :accessibility-label :delete-for-me
:id :delete-for-me}]) :icon :i/delete
:id :delete-for-me}])
(when (cond (when (cond
deleted? false deleted? false
outgoing true outgoing true
community? can-delete-message-for-everyone? community? can-delete-message-for-everyone?
group-chat group-admin? group-chat group-admin?
:else false) :else false)
[{:type :danger [{:type :danger
:on-press (fn [] :on-press (fn []
(rf/dispatch [:hide-bottom-sheet]) (rf/dispatch [:hide-bottom-sheet])
(rf/dispatch [:chat.ui/delete-message message-data (rf/dispatch [:chat.ui/delete-message message-data
config/delete-message-undo-time-limit-ms])) config/delete-message-undo-time-limit-ms]))
:label (i18n/label :t/delete-for-everyone) :label (i18n/label :t/delete-for-everyone)
:icon :i/delete :accessibility-label :delete-for-everyone
:id :delete-for-all}]))) :icon :i/delete
:id :delete-for-all}])))
(defn extract-id (defn extract-id
[reactions id] [reactions id]
@ -180,7 +186,7 @@
[rn/view [rn/view
{:style {:flex-direction :row {:style {:flex-direction :row
:justify-content :space-between :justify-content :space-between
:padding-horizontal 30 :padding-horizontal 22
:padding-top 5 :padding-top 5
:padding-bottom 15}} :padding-bottom 15}}
(for [[id reaction-name] constants/reactions (for [[id reaction-name] constants/reactions
@ -221,10 +227,10 @@
(for [action main-actions] (for [action main-actions]
(let [on-press (:on-press action)] (let [on-press (:on-press action)]
^{:key (:id action)} ^{:key (:id action)}
[quo/menu-item [quo/drawer-action
{:type :main {:type :main
:title (:label action) :title (:label action)
:accessibility-label (:label action) :accessibility-label (:accessibility-label action)
:icon (:icon action) :icon (:icon action)
:on-press (fn [] :on-press (fn []
(rf/dispatch [:hide-bottom-sheet]) (rf/dispatch [:hide-bottom-sheet])
@ -238,10 +244,10 @@
(for [action danger-actions] (for [action danger-actions]
(let [on-press (:on-press action)] (let [on-press (:on-press action)]
^{:key (:id action)} ^{:key (:id action)}
[quo/menu-item [quo/drawer-action
{:type :danger {:type :danger
:title (:label action) :title (:label action)
:accessibility-label (:label action) :accessibility-label (:accessibility-label action)
:icon (:icon action) :icon (:icon action)
:on-press (fn [] :on-press (fn []
(rf/dispatch [:hide-bottom-sheet]) (rf/dispatch [:hide-bottom-sheet])
@ -255,10 +261,10 @@
(for [action admin-actions] (for [action admin-actions]
(let [on-press (:on-press action)] (let [on-press (:on-press action)]
^{:key (:id action)} ^{:key (:id action)}
[quo/menu-item [quo/drawer-action
{:type :danger {:type :danger
:title (:label action) :title (:label action)
:accessibility-label (:label action) :accessibility-label (:accessibility-label action)
:icon (:icon action) :icon (:icon action)
:on-press (fn [] :on-press (fn []
(rf/dispatch [:hide-bottom-sheet]) (rf/dispatch [:hide-bottom-sheet])

View File

@ -15,7 +15,7 @@
(def ^:private memo-gen-quantity (memoize gen-quantity)) (def ^:private memo-gen-quantity (memoize gen-quantity))
(def ^:private descriptor (def ^:private descriptor
[{:key :add-reaction? [{:key :hide-new-reaction-button?
:type :boolean} :type :boolean}
{:label "Reactions" {:label "Reactions"
:key :reaction-ids :key :reaction-ids
@ -37,10 +37,10 @@
(defn preview-react (defn preview-react
[] []
(let [state (reagent/atom {:add-reaction? true (let [state (reagent/atom {:hide-new-reaction-button? true
:max-count 1000 :max-count 1000
:reaction-ids [1 2 3] :reaction-ids [1 2 3]
:use-case :default}) :use-case :default})
pressed-reactions (reagent/atom #{1})] pressed-reactions (reagent/atom #{1})]
(fn [] (fn []
@ -63,14 +63,14 @@
(colors/custom-color :blue 50 10)) (colors/custom-color :blue 50 10))
:align-items :flex-start} :align-items :flex-start}
[quo/react [quo/react
{:reactions reactions {:reactions reactions
:add-reaction? (:add-reaction? @state) :hide-new-reaction-button? (:hide-new-reaction-button? @state)
:use-case (:use-case @state) :use-case (:use-case @state)
:on-press (fn [reaction] :on-press (fn [reaction]
(let [reaction-id (:emoji-id reaction) (let [reaction-id (:emoji-id reaction)
change-pressed (partial swap! pressed-reactions)] change-pressed (partial swap! pressed-reactions)]
(if (contains? @pressed-reactions reaction-id) (if (contains? @pressed-reactions reaction-id)
(change-pressed disj reaction-id) (change-pressed disj reaction-id)
(change-pressed conj reaction-id)))) (change-pressed conj reaction-id))))
:on-long-press identity :on-long-press identity
:on-press-new identity}]]])))) :on-press-new identity}]]]))))