From 5755d2e21ab297befb990549747ace6d7f055238 Mon Sep 17 00:00:00 2001 From: Omar Basem Date: Fri, 7 Jul 2023 17:10:04 +0400 Subject: [PATCH] Lightbox text sheet (#16471) * feat: lightbox text --- src/js/worklets/lightbox.js | 7 ++ src/quo2/foundations/colors.cljs | 1 + .../contexts/chat/lightbox/bottom_view.cljs | 21 +++-- .../contexts/chat/lightbox/constants.cljs | 13 ++-- .../contexts/chat/lightbox/style.cljs | 26 +++++-- .../chat/lightbox/text_sheet/style.cljs | 60 ++++++++++++++ .../chat/lightbox/text_sheet/utils.cljs | 70 +++++++++++++++++ .../chat/lightbox/text_sheet/view.cljs | 78 +++++++++++++++++++ .../contexts/chat/lightbox/top_view.cljs | 38 +++++---- .../contexts/chat/lightbox/utils.cljs | 16 ++-- .../contexts/chat/lightbox/view.cljs | 31 ++++---- .../chat/lightbox/zoomable_image/utils.cljs | 2 +- .../chat/messages/content/text/view.cljs | 6 +- src/utils/worklets/lightbox.cljs | 4 + 14 files changed, 311 insertions(+), 62 deletions(-) create mode 100644 src/status_im2/contexts/chat/lightbox/text_sheet/style.cljs create mode 100644 src/status_im2/contexts/chat/lightbox/text_sheet/utils.cljs create mode 100644 src/status_im2/contexts/chat/lightbox/text_sheet/view.cljs diff --git a/src/js/worklets/lightbox.js b/src/js/worklets/lightbox.js index 101eaa62b4..45acd84f9a 100644 --- a/src/js/worklets/lightbox.js +++ b/src/js/worklets/lightbox.js @@ -6,3 +6,10 @@ export function infoLayout(input, isTop) { return isTop ? input.value : -input.value; }); } + +export function textSheet(input, isHeight) { + return useDerivedValue(function () { + 'worklet'; + return isHeight ? input.value : -input.value; + }); +} diff --git a/src/quo2/foundations/colors.cljs b/src/quo2/foundations/colors.cljs index ec9e5a9568..8713c645c4 100644 --- a/src/quo2/foundations/colors.cljs +++ b/src/quo2/foundations/colors.cljs @@ -88,6 +88,7 @@ (def neutral-100-opa-5 (alpha neutral-100 0.05)) (def neutral-100-opa-10 (alpha neutral-100 0.1)) (def neutral-100-opa-30 (alpha neutral-100 0.3)) +(def neutral-100-opa-50 (alpha neutral-100 0.5)) (def neutral-100-opa-60 (alpha neutral-100 0.6)) (def neutral-100-opa-70 (alpha neutral-100 0.7)) (def neutral-100-opa-80 (alpha neutral-100 0.8)) diff --git a/src/status_im2/contexts/chat/lightbox/bottom_view.cljs b/src/status_im2/contexts/chat/lightbox/bottom_view.cljs index df6aa2429c..e2a0dc1499 100644 --- a/src/status_im2/contexts/chat/lightbox/bottom_view.cljs +++ b/src/status_im2/contexts/chat/lightbox/bottom_view.cljs @@ -1,5 +1,6 @@ (ns status-im2.contexts.chat.lightbox.bottom-view (:require + [quo2.foundations.colors :as colors] [react-native.core :as rn] [react-native.platform :as platform] [react-native.reanimated :as reanimated] @@ -7,7 +8,7 @@ [utils.re-frame :as rf] [status-im2.contexts.chat.lightbox.animations :as anim] [status-im2.contexts.chat.lightbox.constants :as c] - [status-im2.contexts.chat.messages.content.text.view :as message-view])) + [status-im2.contexts.chat.lightbox.text-sheet.view :as text-sheet])) (defn get-small-item-layout [_ index] @@ -48,20 +49,16 @@ [item index _ render-data] [:f> f-small-image item index _ render-data]) + (defn bottom-view - [messages index scroll-index insets animations derived item-width props] - (let [{:keys [chat-id content]} (first messages) - padding-horizontal (- (/ item-width 2) (/ c/focused-image-size 2))] + [messages index scroll-index insets animations derived item-width props state] + (let [padding-horizontal (- (/ item-width 2) (/ c/focused-image-size 2))] [reanimated/linear-gradient - {:colors [:black :transparent] + {:colors [colors/neutral-100-opa-100 colors/neutral-100-opa-50] :start {:x 0 :y 1} :end {:x 0 :y 0} :style (style/gradient-container insets animations derived)} - (when c/image-description-in-lightbox? - [message-view/render-parsed-text - {:content content - :chat-id chat-id - :style-override style/text-style}]) + [text-sheet/view messages animations state] [rn/flat-list {:ref #(reset! (:small-list-ref props) %) :key-fn :message-id @@ -75,4 +72,6 @@ :get-item-layout get-small-item-layout :separator [rn/view {:style {:width 8}}] :initial-scroll-index index - :content-container-style (style/content-container padding-horizontal)}]])) + :content-container-style (style/content-container padding-horizontal)}] + ;; This is needed so that text does not show in the bottom inset part as it is transparent + [rn/view {:style (style/bottom-inset-cover-up insets)}]])) diff --git a/src/status_im2/contexts/chat/lightbox/constants.cljs b/src/status_im2/contexts/chat/lightbox/constants.cljs index 3332296965..1fbd74c313 100644 --- a/src/status_im2/contexts/chat/lightbox/constants.cljs +++ b/src/status_im2/contexts/chat/lightbox/constants.cljs @@ -1,19 +1,16 @@ (ns status-im2.contexts.chat.lightbox.constants) (def ^:const small-image-size 40) - (def ^:const focused-extra-size 16) - (def ^:const focused-image-size (+ small-image-size focused-extra-size)) - (def ^:const small-list-height 80) - (def ^:const small-list-padding-vertical 12) - (def ^:const top-view-height 56) - (def ^:const separator-width 16) - (def ^:const drag-threshold 100) -(def ^:const image-description-in-lightbox? false) +;;; TEXT SHEET +(def ^:const text-margin 12) +(def ^:const bar-container-height 30) +(def ^:const line-height 22) +(def ^:const text-min-height (+ bar-container-height (* line-height 2) 4)) diff --git a/src/status_im2/contexts/chat/lightbox/style.cljs b/src/status_im2/contexts/chat/lightbox/style.cljs index f2f6e47309..b3fcf8ffc4 100644 --- a/src/status_im2/contexts/chat/lightbox/style.cljs +++ b/src/status_im2/contexts/chat/lightbox/style.cljs @@ -66,6 +66,7 @@ {:transform [{:translateY bottom-layout}] :opacity opacity} {:position :absolute + :overflow :visible :bottom 0 :padding-bottom (:bottom insets) :z-index 3})) @@ -77,8 +78,23 @@ :align-items :center :justify-content :center}) -(def text-style - {:color colors/white - :align-self :center - :margin-horizontal 20 - :margin-vertical 12}) + +(defn background + [{:keys [overlay-opacity]} z-index] + (reanimated/apply-animations-to-style + {:opacity overlay-opacity} + {:background-color colors/neutral-100-opa-70 + :position :absolute + :top 0 + :bottom 0 + :z-index z-index + :left 0 + :right 0})) + +(defn bottom-inset-cover-up + [insets] + {:height (:bottom insets) + :position :absolute + :bottom 0 + :left 0 + :right 0}) diff --git a/src/status_im2/contexts/chat/lightbox/text_sheet/style.cljs b/src/status_im2/contexts/chat/lightbox/text_sheet/style.cljs new file mode 100644 index 0000000000..778cbd2573 --- /dev/null +++ b/src/status_im2/contexts/chat/lightbox/text_sheet/style.cljs @@ -0,0 +1,60 @@ +(ns status-im2.contexts.chat.lightbox.text-sheet.style + (:require [quo2.foundations.colors :as colors] + [react-native.reanimated :as reanimated] + [status-im2.contexts.chat.lightbox.constants :as constants])) + +(defn sheet-container + [{:keys [height top]}] + (reanimated/apply-animations-to-style + {:height height + :top top} + {:position :absolute + :left 0 + :right 0})) + +(def text-style + {:color colors/white + :align-self :center + :margin-horizontal 20 + :margin-bottom constants/text-margin + :flex-grow 1}) + +(def bar-container + {:height constants/bar-container-height + :left 0 + :right 0 + :top 0 + :justify-content :center + :align-items :center}) + +(def bar + {:width 32 + :height 4 + :border-radius 100 + :background-color colors/white-opa-40 + :border-width 0.5 + :border-color colors/neutral-100}) + +(defn top-gradient + [{:keys [gradient-opacity]} insets] + (reanimated/apply-animations-to-style + {:opacity gradient-opacity} + {:position :absolute + :left 0 + :right 0 + :top (- (+ (:top insets) + constants/top-view-height)) + :height (+ (:top insets) + constants/top-view-height + constants/bar-container-height + constants/text-margin + (* constants/line-height 2)) + :z-index 1})) + +(def bottom-gradient + {:position :absolute + :left 0 + :right 0 + :height 28 + :bottom 0 + :z-index 1}) diff --git a/src/status_im2/contexts/chat/lightbox/text_sheet/utils.cljs b/src/status_im2/contexts/chat/lightbox/text_sheet/utils.cljs new file mode 100644 index 0000000000..a0eeb8149c --- /dev/null +++ b/src/status_im2/contexts/chat/lightbox/text_sheet/utils.cljs @@ -0,0 +1,70 @@ +(ns status-im2.contexts.chat.lightbox.text-sheet.utils + (:require [react-native.gesture :as gesture] + [react-native.reanimated :as reanimated] + [oops.core :as oops] + [status-im2.contexts.chat.lightbox.constants :as constants] + [utils.worklets.lightbox :as worklet])) + +(defn sheet-gesture + [{:keys [derived-value saved-top overlay-opacity gradient-opacity]} + expanded-height max-height overlay-z-index expanded? dragging?] + (-> (gesture/gesture-pan) + (gesture/on-start (fn [] + (reset! overlay-z-index 1) + (reset! dragging? true) + (reanimated/animate gradient-opacity 0))) + (gesture/on-update + (fn [e] + (let [new-value (+ (reanimated/get-shared-value saved-top) (oops/oget e "translationY")) + bounded-value (max (min (- new-value) expanded-height) constants/text-min-height) + progress (/ (- new-value) max-height)] + (reanimated/set-shared-value overlay-opacity progress) + (reanimated/set-shared-value derived-value bounded-value)))) + (gesture/on-end + (fn [] + (if (or (> (- (reanimated/get-shared-value derived-value)) + (reanimated/get-shared-value saved-top)) + (= (reanimated/get-shared-value derived-value) + constants/text-min-height)) + (do ; minimize + (reanimated/animate derived-value constants/text-min-height) + (reanimated/animate overlay-opacity 0) + (reanimated/set-shared-value saved-top (- constants/text-min-height)) + (reset! expanded? false) + (js/setTimeout #(reset! overlay-z-index 0) 300)) + (reanimated/set-shared-value saved-top + (- (reanimated/get-shared-value derived-value)))) + (when (= (reanimated/get-shared-value derived-value) expanded-height) + (reset! expanded? true)) + (reset! dragging? false))))) + +(defn expand-sheet + [{:keys [derived-value overlay-opacity saved-top]} + expanded-height max-height overlay-z-index expanded?] + (reanimated/animate derived-value expanded-height) + (reanimated/animate overlay-opacity (/ expanded-height max-height)) + (reanimated/set-shared-value saved-top (- expanded-height)) + (reset! overlay-z-index 1) + (reset! expanded? true)) + +(defn on-scroll + [e expanded? dragging? {:keys [gradient-opacity]}] + (if (and (> (oops/oget e "nativeEvent.contentOffset.y") 0) expanded? (not dragging?)) + (reanimated/animate gradient-opacity 1) + (reanimated/animate gradient-opacity 0))) + +(defn on-layout + [e text-height] + (reset! text-height (oops/oget e "nativeEvent.layout.height"))) + +(defn init-animations + [overlay-opacity] + {:derived-value (reanimated/use-shared-value constants/text-min-height) + :saved-top (reanimated/use-shared-value (- constants/text-min-height)) + :gradient-opacity (reanimated/use-shared-value 0) + :overlay-opacity overlay-opacity}) + +(defn init-derived-animations + [{:keys [derived-value]}] + {:height (worklet/text-sheet derived-value true) + :top (worklet/text-sheet derived-value false)}) diff --git a/src/status_im2/contexts/chat/lightbox/text_sheet/view.cljs b/src/status_im2/contexts/chat/lightbox/text_sheet/view.cljs new file mode 100644 index 0000000000..2471fbc194 --- /dev/null +++ b/src/status_im2/contexts/chat/lightbox/text_sheet/view.cljs @@ -0,0 +1,78 @@ +(ns status-im2.contexts.chat.lightbox.text-sheet.view + (:require + [quo2.foundations.colors :as colors] + [react-native.core :as rn] + [react-native.gesture :as gesture] + [react-native.linear-gradient :as linear-gradient] + [react-native.platform :as platform] + [react-native.reanimated :as reanimated] + [react-native.safe-area :as safe-area] + [reagent.core :as reagent] + [status-im2.contexts.chat.lightbox.constants :as constants] + [status-im2.contexts.chat.lightbox.text-sheet.style :as style] + [status-im2.contexts.chat.lightbox.text-sheet.utils :as utils] + [status-im2.contexts.chat.messages.content.text.view :as message-view])) + +(defn bar + [text-height] + (when (> text-height (* constants/line-height 2)) + [rn/view {:style style/bar-container} + [rn/view {:style style/bar}]])) + +(defn text-sheet + [messages overlay-opacity overlay-z-index] + (let [text-height (reagent/atom 0) + expanded? (reagent/atom false) + dragging? (atom false)] + (fn [] + (let [{:keys [chat-id content]} (first messages) + insets (safe-area/get-insets) + window-height (:height (rn/get-window)) + max-height (- window-height + constants/text-min-height + constants/top-view-height + (:bottom insets) + (when platform/ios? (:top insets))) + expanded-height (min max-height + (+ constants/bar-container-height + @text-height + constants/text-margin)) + animations (utils/init-animations overlay-opacity) + derived (utils/init-derived-animations animations)] + [gesture/gesture-detector + {:gesture (utils/sheet-gesture animations + expanded-height + max-height + overlay-z-index + expanded? + dragging?)} + [reanimated/touchable-opacity + {:active-opacity 1 + :on-press + #(utils/expand-sheet animations expanded-height max-height overlay-z-index expanded?) + :style (style/sheet-container derived)} + [bar @text-height] + [reanimated/linear-gradient + {:colors [colors/neutral-100-opa-0 colors/neutral-100] + :start {:x 0 :y 1} + :end {:x 0 :y 0} + :style (style/top-gradient animations insets)}] + [linear-gradient/linear-gradient + {:colors [colors/neutral-100-opa-50 colors/neutral-100-opa-0] + :start {:x 0 :y 1} + :end {:x 0 :y 0} + :style style/bottom-gradient}] + [gesture/scroll-view + {:scroll-enabled @expanded? + :scroll-event-throttle 16 + :on-scroll #(utils/on-scroll % @expanded? @dragging? animations) + :style {:height (- max-height constants/bar-container-height)}} + [message-view/render-parsed-text + {:content content + :chat-id chat-id + :style-override style/text-style + :on-layout #(utils/on-layout % text-height)}]]]])))) + +(defn view + [messages {:keys [overlay-opacity]} {:keys [overlay-z-index]}] + [:f> text-sheet messages overlay-opacity overlay-z-index]) diff --git a/src/status_im2/contexts/chat/lightbox/top_view.cljs b/src/status_im2/contexts/chat/lightbox/top_view.cljs index af936fdf2a..86c54e70da 100644 --- a/src/status_im2/contexts/chat/lightbox/top_view.cljs +++ b/src/status_im2/contexts/chat/lightbox/top_view.cljs @@ -43,9 +43,10 @@ (anim/animate top-view-bg colors/neutral-100-opa-0))))) (defn drawer - [content] - (let [uri (http/replace-port (:image content) - (rf/sub [:mediaserver/port]))] + [messages index] + (let [{:keys [content]} (nth messages index) + uri (http/replace-port (:image content) + (rf/sub [:mediaserver/port]))] [quo/action-drawer [[{:icon :i/save :accessibility-label :save-image @@ -61,17 +62,23 @@ :container-style {:bottom (when platform/android? 20)} :text (i18n/label :t/photo-saved)}])))}]]])) +(defn share-image + [messages index] + (let [{:keys [content]} (nth messages index) + uri (http/replace-port (:image content) + (rf/sub [:mediaserver/port]))] + (images/share-image uri))) + (defn top-view [messages insets index animations derived landscape? screen-width] - (let [{:keys [from timestamp content]} (nth @messages @index) - display-name (first (rf/sub [:contacts/contact-two-names-by-identity - from])) - bg-color (if landscape? - colors/neutral-100-opa-70 - colors/neutral-100-opa-0) - {:keys [background-color opacity]} animations - uri (http/replace-port (:image content) - (rf/sub [:mediaserver/port]))] + (let [{:keys [from timestamp]} (first messages) + display-name (first (rf/sub [:contacts/contact-two-names-by-identity + from])) + bg-color (if landscape? + colors/neutral-100-opa-70 + colors/neutral-100-opa-0) + {:keys [background-color opacity + overlay-opacity]} animations] [reanimated/view {:style (style/top-view-container (:top insets) screen-width bg-color landscape? animations derived)} @@ -87,6 +94,7 @@ {:on-press (fn [] (anim/animate background-color :transparent) (anim/animate opacity 0) + (anim/animate overlay-opacity 0) (rf/dispatch (if platform/ios? [:chat.ui/exit-lightbox-signal @index] [:navigate-back]))) @@ -100,15 +108,15 @@ [quo/text {:weight :medium :size :paragraph-2 - :style {:color colors/neutral-40}} (datetime/to-short-str timestamp)]]] + :style {:color colors/neutral-40}} (when timestamp (datetime/to-short-str timestamp))]]] [rn/view {:style style/top-right-buttons} [rn/touchable-opacity {:active-opacity 1 - :on-press #(images/share-image uri) + :on-press #(share-image messages @index) :style (merge style/close-container {:margin-right 12})} [quo/icon :share {:size 20 :color colors/white}]] [rn/touchable-opacity {:active-opacity 1 - :on-press #(rf/dispatch [:show-bottom-sheet {:content (fn [] [drawer content])}]) + :on-press #(rf/dispatch [:show-bottom-sheet {:content (fn [] [drawer messages @index])}]) :style style/close-container} [quo/icon :options {:size 20 :color colors/white}]]]])) diff --git a/src/status_im2/contexts/chat/lightbox/utils.cljs b/src/status_im2/contexts/chat/lightbox/utils.cljs index 5149f1c042..3aa9064cfa 100644 --- a/src/status_im2/contexts/chat/lightbox/utils.cljs +++ b/src/status_im2/contexts/chat/lightbox/utils.cljs @@ -31,14 +31,18 @@ (fn [] (reagent/next-tick (fn [] (when @flat-list-ref - (.scrollToIndex ^js @flat-list-ref - #js {:animated false :index index})))) + (.scrollToOffset ^js @flat-list-ref + #js + {:animated false + :offset (* (+ (:width (rn/get-window)) + constants/separator-width) + index)})))) (swap! timers assoc :mount-animation (js/setTimeout (fn [] (anim/animate opacity 1) (anim/animate layout 0) - (anim/animate border 12)) + (anim/animate border 16)) (if platform/ios? 250 100))) (swap! timers assoc :mount-index-lock (js/setTimeout #(reset! scroll-index-lock? false) 300)) (fn [] @@ -135,13 +139,15 @@ {:data (reagent/atom (if (number? index) [(nth messages index)] [])) :scroll-index (reagent/atom index) :transparent? (reagent/atom false) - :set-full-height? (reagent/atom false)}) + :set-full-height? (reagent/atom false) + :overlay-z-index (reagent/atom 0)}) (defn init-animations [] {:background-color (anim/use-val colors/neutral-100-opa-0) - :border (anim/use-val (if platform/ios? 0 12)) + :border (anim/use-val (if platform/ios? 0 16)) :opacity (anim/use-val 0) + :overlay-opacity (anim/use-val 0) :rotate (anim/use-val "0deg") :layout (anim/use-val -10) :top-view-y (anim/use-val 0) diff --git a/src/status_im2/contexts/chat/lightbox/view.cljs b/src/status_im2/contexts/chat/lightbox/view.cljs index 685c0b27c3..a2a9155b0b 100644 --- a/src/status_im2/contexts/chat/lightbox/view.cljs +++ b/src/status_im2/contexts/chat/lightbox/view.cljs @@ -43,8 +43,8 @@ [rn/view {:style {:width constants/separator-width}}]]) (defn lightbox-content - [props {:keys [data transparent? scroll-index set-full-height?]} animations derived messages index - callback] + [props {:keys [data transparent? scroll-index set-full-height?] :as state} + animations derived messages index handle-items-changed] (let [insets (safe-area/get-insets) window (rn/get-window) window-width (:width window) @@ -66,7 +66,7 @@ {:style (reanimated/apply-animations-to-style {:background-color (:background-color animations)} {:height screen-height})} (when-not @transparent? - [:f> top-view/top-view data insets scroll-index animations derived landscape? + [:f> top-view/top-view messages insets scroll-index animations derived landscape? screen-width]) [gesture/gesture-detector {:gesture (utils/drag-gesture animations (and landscape? platform/ios?) set-full-height?)} @@ -75,6 +75,7 @@ {:transform [{:translateY (:pan-y animations)} {:translateX (:pan-x animations)}]} {})} + [reanimated/view {:style (style/background animations @(:overlay-z-index state))}] [gesture/flat-list {:ref #(reset! (:flat-list-ref props) %) :key-fn :message-id @@ -99,28 +100,28 @@ :wait-for-interaction true} :shows-vertical-scroll-indicator false :shows-horizontal-scroll-indicator false - :on-viewable-items-changed callback}]]] + :on-viewable-items-changed handle-items-changed}]]] (when (and (not @transparent?) (not landscape?)) [:f> bottom-view/bottom-view messages index scroll-index insets animations derived - item-width props])])) + item-width props state])])) (defn- f-lightbox - [{:keys [messages index]}] - (let [props (utils/init-props) - state (utils/init-state messages index)] - (fn [{:keys [messages index]}] + [] + (let [{:keys [messages index]} (rf/sub [:get-screen-params]) + props (utils/init-props) + state (utils/init-state messages index) + handle-items-changed (fn [e] + (on-viewable-items-changed e props state))] + (fn [] (let [animations (utils/init-animations) - derived (utils/init-derived-animations animations) - callback (fn [e] - (on-viewable-items-changed e props state))] + derived (utils/init-derived-animations animations)] (anim/animate (:background-color animations) colors/neutral-100) (reset! (:data state) messages) (when platform/ios? ; issue: https://github.com/wix/react-native-navigation/issues/7726 (utils/orientation-change props state animations)) (utils/effect props animations index) - [:f> lightbox-content props state animations derived messages index callback])))) + [:f> lightbox-content props state animations derived messages index handle-items-changed])))) (defn lightbox [] - (let [screen-params (rf/sub [:get-screen-params])] - [:f> f-lightbox screen-params])) + [:f> f-lightbox]) diff --git a/src/status_im2/contexts/chat/lightbox/zoomable_image/utils.cljs b/src/status_im2/contexts/chat/lightbox/zoomable_image/utils.cljs index 639bec5176..a06590a1ea 100644 --- a/src/status_im2/contexts/chat/lightbox/zoomable_image/utils.cljs +++ b/src/status_im2/contexts/chat/lightbox/zoomable_image/utils.cljs @@ -135,7 +135,7 @@ :show-2 (js/setTimeout #(navigation/merge-options "lightbox" {:statusBar {:visible true}}) (if platform/ios? 150 50)))))) - (anim/animate border-value (if (= opacity 1) 0 12)))) + (anim/animate border-value (if (= opacity 1) 0 16)))) ;;; Dimensions (defn get-dimensions diff --git a/src/status_im2/contexts/chat/messages/content/text/view.cljs b/src/status_im2/contexts/chat/messages/content/text/view.cljs index a134f4a175..7e311c3212 100644 --- a/src/status_im2/contexts/chat/messages/content/text/view.cljs +++ b/src/status_im2/contexts/chat/messages/content/text/view.cljs @@ -139,9 +139,11 @@ (conj parsed-text {:type :edited-block :children [edited-tag]})))) (defn render-parsed-text - [{:keys [content chat-id edited-at style-override]}] + [{:keys [content chat-id edited-at style-override on-layout]}] ^{:key (:parsed-text content)} - [rn/view {:style style-override} + [rn/view + {:style style-override + :on-layout on-layout} (reduce (fn [acc e] (render-block acc e chat-id style-override)) [:<>] diff --git a/src/utils/worklets/lightbox.cljs b/src/utils/worklets/lightbox.cljs index bec6e5ebec..5804710cda 100644 --- a/src/utils/worklets/lightbox.cljs +++ b/src/utils/worklets/lightbox.cljs @@ -5,3 +5,7 @@ (defn info-layout [input top?] (.infoLayout ^js layout-worklets input top?)) + +(defn text-sheet + [input height?] + (.textSheet ^js layout-worklets input height?))