Refactor `toast` component to use theme context (#16711)
This commit refactors the "Toast" component to use theme context for consistency across the codebase. Each toast will have its theme provider, which will help the children to use the context properly without interfering with other toast's context. The following components are refactored to use with-theme / theme-context as it is used in the "Toast": - "text" component - "user-avatar" component - "icon" component - "circle-timer" component This commit also updates the icon keyword used in the ":toasts/upsert" event dispatch to respect icon guidelines. Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
This commit is contained in:
parent
ec6800216b
commit
1721b40b3f
|
@ -41,7 +41,7 @@
|
|||
:border-radius dimensions}))
|
||||
|
||||
(defn initials-avatar
|
||||
[size draw-ring? customization-color]
|
||||
[size draw-ring? customization-color theme]
|
||||
(let [outer-dimensions (get-in sizes [size :outer])
|
||||
inner-dimensions (get-in sizes [size (if draw-ring? :inner :outer)])]
|
||||
{:position :absolute
|
||||
|
@ -52,7 +52,7 @@
|
|||
:border-radius inner-dimensions
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:background-color (colors/custom-color-by-theme customization-color 50 60)}))
|
||||
:background-color (colors/custom-color-by-theme customization-color 50 60 nil nil theme)}))
|
||||
|
||||
(def initials-avatar-text
|
||||
{:color colors/white-opa-70})
|
||||
|
@ -67,7 +67,7 @@
|
|||
:background-color background}))
|
||||
|
||||
(defn dot
|
||||
[size ring?]
|
||||
[size ring? theme]
|
||||
(let [dimensions (get-in sizes [size :status-indicator])
|
||||
border-width (get-in sizes [size :status-indicator-border])
|
||||
right (case size
|
||||
|
@ -89,5 +89,5 @@
|
|||
:height dimensions
|
||||
:border-width border-width
|
||||
:border-radius dimensions
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-100)
|
||||
:border-color (colors/theme-colors colors/white colors/neutral-100)}))
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-100 theme)
|
||||
:border-color (colors/theme-colors colors/white colors/neutral-100 theme)}))
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
(ns quo2.components.avatars.user-avatar.view
|
||||
(:require [quo2.components.avatars.user-avatar.style :as style]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.fast-image :as fast-image]
|
||||
utils.string))
|
||||
|
||||
(defn initials-avatar
|
||||
[{:keys [full-name size draw-ring? customization-color]}]
|
||||
[{:keys [full-name size draw-ring? customization-color theme]}]
|
||||
(let [font-size (get-in style/sizes [size :font-size])
|
||||
amount-initials (if (#{:xs :xxs :xxxs} size) 1 2)]
|
||||
[rn/view
|
||||
{:accessibility-label :initials-avatar
|
||||
:style (style/initials-avatar size draw-ring? customization-color)}
|
||||
:style (style/initials-avatar size draw-ring? customization-color theme)}
|
||||
[text/text
|
||||
{:style style/initials-avatar-text
|
||||
:size font-size
|
||||
|
@ -20,12 +21,12 @@
|
|||
|
||||
(def valid-ring-sizes #{:big :medium :small})
|
||||
|
||||
(defn user-avatar
|
||||
(defn- user-avatar-internal
|
||||
"If no `profile-picture` is given, draws the initials based on the `full-name` and
|
||||
uses `ring-background` to display the ring behind the initials when given. Otherwise,
|
||||
shows the `profile-picture` which already comes with the ring drawn."
|
||||
[{:keys [full-name status-indicator? online? size profile-picture ring-background
|
||||
customization-color static? muted?]
|
||||
customization-color static? muted? theme]
|
||||
:or {status-indicator? true
|
||||
online? true
|
||||
size :big
|
||||
|
@ -49,11 +50,14 @@
|
|||
{:full-name full-name
|
||||
:size size
|
||||
:draw-ring? draw-ring?
|
||||
:customization-color customization-color}])
|
||||
:customization-color customization-color
|
||||
:theme theme}])
|
||||
(when status-indicator?
|
||||
[rn/view
|
||||
{:accessibility-label :status-indicator
|
||||
:style (style/dot size draw-ring?)}
|
||||
:style (style/dot size draw-ring? theme)}
|
||||
[rn/view
|
||||
{:accessibility-label :inner-status-indicator-dot
|
||||
:style (style/inner-dot size online?)}]])]))
|
||||
|
||||
(def user-avatar (quo.theme/with-theme user-avatar-internal))
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
[quo2.components.icons.icons :as icons]
|
||||
[quo2.components.icons.svg :as icons.svg]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn- valid-color?
|
||||
|
@ -12,11 +13,10 @@
|
|||
(not (string/blank? color)))))
|
||||
|
||||
(defn memo-icon-fn
|
||||
[icon-name
|
||||
{:keys [color color-2 no-color
|
||||
container-style size accessibility-label]
|
||||
[{:keys [color color-2 no-color
|
||||
container-style size accessibility-label theme]
|
||||
:or {accessibility-label :icon}}
|
||||
_]
|
||||
icon-name]
|
||||
(let [size (or size 20)]
|
||||
^{:key icon-name}
|
||||
(if-let [svg-icon (icons.svg/get-icon icon-name size)]
|
||||
|
@ -34,15 +34,15 @@
|
|||
(when (not no-color)
|
||||
{:tint-color (if (and (string? color) (not (string/blank? color)))
|
||||
color
|
||||
(colors/theme-colors colors/neutral-100 colors/white))})
|
||||
(colors/theme-colors colors/neutral-100 colors/white theme))})
|
||||
|
||||
container-style)
|
||||
:accessibility-label accessibility-label
|
||||
:source (icons/icon-source (str (name icon-name) size))}])))
|
||||
|
||||
(def themed-icon (memoize memo-icon-fn))
|
||||
(def ^:private themed-icon (memoize (quo.theme/with-theme memo-icon-fn)))
|
||||
|
||||
(defn icon
|
||||
([icon-name] (icon icon-name nil))
|
||||
([icon-name params]
|
||||
(themed-icon icon-name params (colors/dark?))))
|
||||
(themed-icon params icon-name)))
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
(ns quo2.components.markdown.text
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[quo2.foundations.typography :as typography]
|
||||
[quo2.theme :as theme]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn text-style
|
||||
[{:keys [size align weight style]}]
|
||||
[{:keys [size align weight style theme]}]
|
||||
(merge (case (or weight :regular)
|
||||
:regular typography/font-regular
|
||||
:medium typography/font-medium
|
||||
|
@ -25,14 +25,23 @@
|
|||
{:text-align (or align :auto)}
|
||||
(if (:color style)
|
||||
style
|
||||
(assoc style :color (if (= (theme/get-theme) :dark) colors/white colors/neutral-100)))))
|
||||
(assoc style
|
||||
:color
|
||||
(if (= (or theme (quo.theme/get-theme)) :dark) colors/white colors/neutral-100)))))
|
||||
|
||||
(defn- text-view-internal
|
||||
[props & children]
|
||||
(let [style (text-style props)]
|
||||
(into [rn/text
|
||||
(merge {:style style}
|
||||
(dissoc props :style :size :align :weight :color :theme))]
|
||||
children)))
|
||||
|
||||
(def ^:private text-view (quo.theme/with-theme text-view-internal))
|
||||
|
||||
(defn text
|
||||
[]
|
||||
(let [this (reagent/current-component)
|
||||
props (reagent/props this)
|
||||
style (text-style props)]
|
||||
(into [rn/text
|
||||
(merge {:style style}
|
||||
(dissoc props :style :size :align :weight :color))]
|
||||
(reagent/children this))))
|
||||
children (reagent/children this)]
|
||||
(into [text-view props] children)))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
(ns quo2.components.notifications.count-down-circle
|
||||
(:require [goog.string :as gstring]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as theme]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.svg :as svg]
|
||||
[reagent.core :as reagent]))
|
||||
|
@ -48,8 +48,8 @@
|
|||
{:color {:dark colors/neutral-80-opa-40
|
||||
:light colors/white-opa-40}})
|
||||
|
||||
(defn circle-timer
|
||||
[{:keys [color duration size stroke-width trail-color rotation initial-remaining-time]}]
|
||||
(defn- circle-timer-internal
|
||||
[{:keys [color duration size stroke-width trail-color rotation initial-remaining-time theme]}]
|
||||
(let [rotation (or rotation :clockwise)
|
||||
duration (or duration 4)
|
||||
stroke-width (or stroke-width 1)
|
||||
|
@ -98,8 +98,10 @@
|
|||
[svg/path
|
||||
{:d path
|
||||
:fill :none
|
||||
:stroke (or color (get-in themes [:color (theme/get-theme)]))
|
||||
:stroke (or color (get-in themes [:color theme]))
|
||||
:stroke-linecap :square
|
||||
:stroke-width stroke-width
|
||||
:stroke-dasharray path-length
|
||||
:stroke-dashoffset (linear-ease @display-time 0 path-length duration)}])]])})))
|
||||
|
||||
(def circle-timer (quo.theme/with-theme circle-timer-internal))
|
||||
|
|
|
@ -3,10 +3,12 @@
|
|||
[quo2.foundations.colors :as colors]
|
||||
[quo2.foundations.shadows :as shadows]))
|
||||
|
||||
(def box-container
|
||||
(defn box-container
|
||||
[theme]
|
||||
(merge (shadows/get 1 theme)
|
||||
{:margin-horizontal 12
|
||||
:border-radius 12
|
||||
:overflow :hidden})
|
||||
:overflow :hidden}))
|
||||
|
||||
(def blur-container
|
||||
{:height "100%"
|
||||
|
@ -19,35 +21,33 @@
|
|||
|
||||
(defn content-container
|
||||
[theme]
|
||||
(merge
|
||||
(shadows/get 1 theme)
|
||||
{:background-color (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 theme)
|
||||
:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:padding-vertical 8
|
||||
:padding-left 10
|
||||
:padding-right 8
|
||||
:border-radius 12}))
|
||||
:border-radius 12})
|
||||
|
||||
(defn title
|
||||
[override-theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 theme)})
|
||||
|
||||
(defn text
|
||||
[override-theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 theme)})
|
||||
|
||||
(defn icon
|
||||
[override-theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 theme)
|
||||
:container-style {:width 20 :height 20}})
|
||||
|
||||
(def left-side-container {:padding 2})
|
||||
(def right-side-container {:padding 4 :flex 1})
|
||||
|
||||
(defn action-container
|
||||
[override-theme]
|
||||
{:background-color (colors/theme-colors colors/white-opa-5 colors/neutral-80-opa-5 override-theme)
|
||||
[theme]
|
||||
{:background-color (colors/theme-colors colors/white-opa-5 colors/neutral-80-opa-5 theme)
|
||||
:flex-direction :row
|
||||
:padding-vertical 3
|
||||
:padding-horizontal 8
|
||||
|
|
|
@ -4,33 +4,40 @@
|
|||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.notifications.count-down-circle :as count-down-circle]
|
||||
[quo2.components.notifications.toast.style :as style]
|
||||
[quo2.theme :as theme]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn toast-action-container
|
||||
[{:keys [on-press style]} & children]
|
||||
[{:keys [on-press style theme]} & children]
|
||||
[rn/touchable-highlight
|
||||
{:on-press on-press
|
||||
:underlay-color :transparent}
|
||||
[into
|
||||
[rn/view
|
||||
{:style (merge (style/action-container (theme/get-theme)) style)}]
|
||||
{:style (merge (style/action-container theme) style)}]
|
||||
children]])
|
||||
|
||||
(defn toast-undo-action
|
||||
[duration on-press override-theme]
|
||||
[toast-action-container {:on-press on-press :accessibility-label :toast-undo-action}
|
||||
(defn toast-undo-action-internal
|
||||
[{:keys [undo-duration undo-on-press theme]}]
|
||||
[toast-action-container
|
||||
{:on-press undo-on-press
|
||||
:accessibility-label :toast-undo-action
|
||||
:theme theme}
|
||||
[rn/view {:style {:margin-right 5}}
|
||||
[count-down-circle/circle-timer {:duration duration}]]
|
||||
[count-down-circle/circle-timer {:duration undo-duration}]]
|
||||
[text/text
|
||||
{:size :paragraph-2 :weight :medium :style (style/text override-theme)}
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style (style/text theme)}
|
||||
[i18n/label :t/undo]]])
|
||||
|
||||
(defn- toast-container
|
||||
[{:keys [left title text right container-style override-theme]}]
|
||||
[rn/view {:style (merge style/box-container container-style)}
|
||||
(def ^:private toast-undo-action (quo.theme/with-theme toast-undo-action-internal))
|
||||
|
||||
(defn- toast-container-internal
|
||||
[{:keys [left title text right container-style theme]}]
|
||||
[rn/view {:style (merge (style/box-container theme) container-style)}
|
||||
[blur/view
|
||||
{:style style/blur-container
|
||||
:blur-amount 13
|
||||
|
@ -38,7 +45,7 @@
|
|||
:blur-type :transparent
|
||||
:overlay-color :transparent}]
|
||||
|
||||
[rn/view {:style (style/content-container override-theme)}
|
||||
[rn/view {:style (style/content-container theme)}
|
||||
[rn/view {:style style/left-side-container}
|
||||
left]
|
||||
[rn/view {:style style/right-side-container}
|
||||
|
@ -46,25 +53,29 @@
|
|||
[text/text
|
||||
{:size :paragraph-1
|
||||
:weight :semi-bold
|
||||
:style (style/title override-theme)
|
||||
:style (style/title theme)
|
||||
:accessibility-label :toast-title}
|
||||
title])
|
||||
(when text
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style (style/text override-theme)
|
||||
:style (style/text theme)
|
||||
:accessibility-label :toast-content}
|
||||
text])]
|
||||
right]])
|
||||
|
||||
(def ^:private toast-container (quo.theme/with-theme toast-container-internal))
|
||||
|
||||
(defn toast
|
||||
[{:keys [icon icon-color title text action undo-duration undo-on-press container-style
|
||||
override-theme user]}]
|
||||
theme user]}]
|
||||
(let [context-theme (or theme (quo.theme/get-theme))]
|
||||
[quo.theme/provider {:theme context-theme}
|
||||
[toast-container
|
||||
{:left (cond icon
|
||||
[icon/icon icon
|
||||
(cond-> (style/icon override-theme)
|
||||
(cond-> (style/icon context-theme)
|
||||
icon-color
|
||||
(assoc :color icon-color))]
|
||||
|
||||
|
@ -73,7 +84,8 @@
|
|||
:title title
|
||||
:text text
|
||||
:right (if undo-duration
|
||||
[toast-undo-action undo-duration undo-on-press override-theme]
|
||||
[toast-undo-action
|
||||
{:undo-duration undo-duration
|
||||
:undo-on-press undo-on-press}]
|
||||
action)
|
||||
:container-style container-style
|
||||
:override-theme override-theme}])
|
||||
:container-style container-style}]]))
|
||||
|
|
|
@ -262,11 +262,14 @@
|
|||
suffix-light 50/60
|
||||
suffix-dark 50/60
|
||||
opacity-light 0-100 (optional)
|
||||
opacity-dark 0-100 (optional)"
|
||||
opacity-dark 0-100 (optional)
|
||||
theme :light/:dark (optional)"
|
||||
([color suffix-light suffix-dark]
|
||||
(custom-color-by-theme color suffix-light suffix-dark nil nil))
|
||||
(custom-color-by-theme color suffix-light suffix-dark nil nil (theme/get-theme)))
|
||||
([color suffix-light suffix-dark opacity-light opacity-dark]
|
||||
(if (theme/dark?)
|
||||
(custom-color-by-theme color suffix-light suffix-dark opacity-light opacity-dark (theme/get-theme)))
|
||||
([color suffix-light suffix-dark opacity-light opacity-dark theme]
|
||||
(if (= theme :dark)
|
||||
(custom-color color suffix-dark opacity-dark)
|
||||
(custom-color color suffix-light opacity-light))))
|
||||
|
||||
|
|
|
@ -14,5 +14,5 @@
|
|||
[:toasts/upsert
|
||||
{:icon :i/info
|
||||
:icon-color colors/danger-50
|
||||
:override-theme :light
|
||||
:theme :dark
|
||||
:text (i18n/label :t/camera-permission-denied)}])}]))
|
||||
|
|
|
@ -217,7 +217,7 @@
|
|||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :remove-nickname
|
||||
:icon :correct
|
||||
:icon :i/correct
|
||||
:icon-color (colors/theme-colors colors/success-60
|
||||
colors/success-50)
|
||||
:text (i18n/label
|
||||
|
|
|
@ -352,7 +352,7 @@
|
|||
:t/channel-unmuted-successfully))))]
|
||||
{:db (assoc-in db [:chats chat-id :muted-till] muted-till)
|
||||
:dispatch [:toasts/upsert
|
||||
{:icon :correct
|
||||
{:icon :i/correct
|
||||
:icon-color (colors/theme-colors colors/success-60
|
||||
colors/success-50)
|
||||
:text (mute-duration-text (when (some? muted-till)
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
uri
|
||||
#(rf/dispatch [:toasts/upsert
|
||||
{:id :random-id
|
||||
:icon :correct
|
||||
:icon :i/correct
|
||||
:icon-color colors/success-50
|
||||
:container-style {:bottom (when platform/android? 20)}
|
||||
:text (i18n/label :t/photo-saved)}])))}]]]))
|
||||
|
|
|
@ -107,7 +107,7 @@
|
|||
[[:toasts/close :delete-message-for-everyone]
|
||||
[:toasts/upsert
|
||||
{:id :delete-message-for-everyone
|
||||
:icon :info
|
||||
:icon :i/info
|
||||
:icon-color colors/danger-50-opa-40
|
||||
:message-deleted-for-everyone-count toast-count
|
||||
:message-deleted-for-everyone-undos existing-undos
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
:dispatch-n [[:toasts/close :delete-message-for-me]
|
||||
[:toasts/upsert
|
||||
{:id :delete-message-for-me
|
||||
:icon :info
|
||||
:icon :i/info
|
||||
:icon-color colors/danger-50-opa-40
|
||||
:message-deleted-for-me-count toast-count
|
||||
:message-deleted-for-me-undos existing-undos
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
[]
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :random-id
|
||||
:icon :info
|
||||
:icon :i/info
|
||||
:icon-color colors/danger-50-opa-40
|
||||
:container-style {:top (when platform/ios? 20)}
|
||||
:text (i18n/label :t/only-6-images)}]))
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
:undo-duration 4
|
||||
:undo-on-press #(do
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:icon :correct
|
||||
{:icon :i/correct
|
||||
:icon-color colors/success-50-opa-40
|
||||
:text "Undo pressed"}])
|
||||
(rf/dispatch [:toasts/close
|
||||
|
@ -54,7 +54,7 @@
|
|||
#(do
|
||||
(rf/dispatch
|
||||
[:toasts/upsert
|
||||
{:icon :correct :icon-color colors/success-50-opa-40 :text "Undo pressed"}])
|
||||
{:icon :i/correct :icon-color colors/success-50-opa-40 :text "Undo pressed"}])
|
||||
(rf/dispatch [:toasts/close "Toast: with undo action"]))}])
|
||||
|
||||
(defn toast-button-30s-duration
|
||||
|
@ -79,7 +79,7 @@
|
|||
#(rf/dispatch
|
||||
[:toasts/upsert
|
||||
{:id "Toast: 30s duration"
|
||||
:icon :info
|
||||
:icon :i/info
|
||||
:icon-color colors/danger-50-opa-40
|
||||
:text (str "This is an updated example toast" " - " (swap! suffix inc))
|
||||
:duration 3000}])}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
(let [unread-count (rf/sub [:activity-center/unread-count])]
|
||||
[quo/action-drawer
|
||||
[[{:icon :i/mark-as-read
|
||||
:override-theme :dark
|
||||
:label (i18n/label :t/mark-all-notifications-as-read)
|
||||
:disabled? (zero? unread-count)
|
||||
:on-press (fn []
|
||||
|
@ -19,5 +18,5 @@
|
|||
:icon-color colors/success-50
|
||||
:text (i18n/label :t/notifications-marked-as-read
|
||||
{:count unread-count})
|
||||
:override-theme :dark})])
|
||||
:theme :dark})])
|
||||
(rf/dispatch [:hide-bottom-sheet]))}]]]))
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
:type :blur-bg
|
||||
:size 32
|
||||
:accessibility-label :close-activity-center
|
||||
:override-theme :dark
|
||||
:on-press #(rf/dispatch [:navigate-back])}
|
||||
:i/close]
|
||||
[quo/button
|
||||
|
@ -36,10 +35,9 @@
|
|||
:type :blur-bg
|
||||
:size 32
|
||||
:accessibility-label :activity-center-open-more
|
||||
:override-theme :dark
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content drawer/options
|
||||
:override-theme :dark}])}
|
||||
:theme :dark}])}
|
||||
:i/options]]
|
||||
[quo/text
|
||||
{:size :heading-1
|
||||
|
|
|
@ -255,7 +255,7 @@
|
|||
(rf/dispatch [:toasts/upsert
|
||||
{:icon :i/info
|
||||
:icon-color colors/danger-50
|
||||
:override-theme :light
|
||||
:theme :dark
|
||||
:text (i18n/label :t/error-this-is-not-a-sync-qr-code)}]))))
|
||||
|
||||
(defn render-camera
|
||||
|
|
|
@ -122,7 +122,7 @@
|
|||
{:on-press (fn []
|
||||
(clipboard/set-string @code)
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:icon :correct
|
||||
{:icon :i/correct
|
||||
:icon-color colors/success-50
|
||||
:text (i18n/label
|
||||
:t/sharing-copied-to-clipboard)}]))
|
||||
|
|
Loading…
Reference in New Issue