From 8999b2b9e83e67d3cd24907d95e32c76778b29c1 Mon Sep 17 00:00:00 2001 From: Volodymyr Kozieiev Date: Thu, 25 Jan 2024 10:58:12 +0000 Subject: [PATCH] Implement collectible image preview (#18449) * Lightbox refactored and moved to common screens that can be reused * Events renamed * Unify constants namespace importing --- .../lightbox/animations.cljs | 2 +- .../lightbox/bottom_view.cljs | 40 ++++--- .../lightbox/constants.cljs | 2 +- .../lightbox/effects.cljs | 6 +- src/status_im/common/lightbox/events.cljs | 37 ++++++ .../messenger => common}/lightbox/style.cljs | 12 +- .../lightbox/text_sheet/style.cljs | 8 +- .../lightbox/text_sheet/utils.cljs | 8 +- .../lightbox/text_sheet/view.cljs | 64 +++++------ .../lightbox/top_view.cljs | 50 ++++---- .../messenger => common}/lightbox/utils.cljs | 16 +-- .../messenger => common}/lightbox/view.cljs | 107 +++++++++++------- .../lightbox/zoomable_image/constants.cljs | 2 +- .../lightbox/zoomable_image/style.cljs | 2 +- .../lightbox/zoomable_image/utils.cljs | 8 +- .../lightbox/zoomable_image/view.cljs | 22 ++-- src/status_im/contexts/chat/events.cljs | 47 +++----- .../chat/messenger/lightbox/events.cljs | 23 ---- .../messages/content/album/view.cljs | 41 ++++--- .../messages/content/image/view.cljs | 17 ++- .../messages/content/lightbox/style.cljs | 10 ++ .../messages/content/lightbox/utils.cljs | 14 +++ .../messages/content/lightbox/view.cljs | 18 +++ .../contexts/wallet/collectible/view.cljs | 33 ++++-- src/status_im/navigation/screens.cljs | 2 +- src/status_im/subs/root.cljs | 2 +- 26 files changed, 343 insertions(+), 250 deletions(-) rename src/status_im/{contexts/chat/messenger => common}/lightbox/animations.cljs (92%) rename src/status_im/{contexts/chat/messenger => common}/lightbox/bottom_view.cljs (66%) rename src/status_im/{contexts/chat/messenger => common}/lightbox/constants.cljs (89%) rename src/status_im/{contexts/chat/messenger => common}/lightbox/effects.cljs (86%) create mode 100644 src/status_im/common/lightbox/events.cljs rename src/status_im/{contexts/chat/messenger => common}/lightbox/style.cljs (90%) rename src/status_im/{contexts/chat/messenger => common}/lightbox/text_sheet/style.cljs (89%) rename src/status_im/{contexts/chat/messenger => common}/lightbox/text_sheet/utils.cljs (95%) rename src/status_im/{contexts/chat/messenger => common}/lightbox/text_sheet/view.cljs (56%) rename src/status_im/{contexts/chat/messenger => common}/lightbox/top_view.cljs (72%) rename src/status_im/{contexts/chat/messenger => common}/lightbox/utils.cljs (93%) rename src/status_im/{contexts/chat/messenger => common}/lightbox/view.cljs (60%) rename src/status_im/{contexts/chat/messenger => common}/lightbox/zoomable_image/constants.cljs (79%) rename src/status_im/{contexts/chat/messenger => common}/lightbox/zoomable_image/style.cljs (94%) rename src/status_im/{contexts/chat/messenger => common}/lightbox/zoomable_image/utils.cljs (97%) rename src/status_im/{contexts/chat/messenger => common}/lightbox/zoomable_image/view.cljs (93%) delete mode 100644 src/status_im/contexts/chat/messenger/lightbox/events.cljs create mode 100644 src/status_im/contexts/chat/messenger/messages/content/lightbox/style.cljs create mode 100644 src/status_im/contexts/chat/messenger/messages/content/lightbox/utils.cljs create mode 100644 src/status_im/contexts/chat/messenger/messages/content/lightbox/view.cljs diff --git a/src/status_im/contexts/chat/messenger/lightbox/animations.cljs b/src/status_im/common/lightbox/animations.cljs similarity index 92% rename from src/status_im/contexts/chat/messenger/lightbox/animations.cljs rename to src/status_im/common/lightbox/animations.cljs index 0f06dde7ad..837379c90d 100644 --- a/src/status_im/contexts/chat/messenger/lightbox/animations.cljs +++ b/src/status_im/common/lightbox/animations.cljs @@ -1,4 +1,4 @@ -(ns status-im.contexts.chat.messenger.lightbox.animations +(ns status-im.common.lightbox.animations (:require [react-native.reanimated :as reanimated])) diff --git a/src/status_im/contexts/chat/messenger/lightbox/bottom_view.cljs b/src/status_im/common/lightbox/bottom_view.cljs similarity index 66% rename from src/status_im/contexts/chat/messenger/lightbox/bottom_view.cljs rename to src/status_im/common/lightbox/bottom_view.cljs index 3a01c1c0a4..f9675eec4a 100644 --- a/src/status_im/contexts/chat/messenger/lightbox/bottom_view.cljs +++ b/src/status_im/common/lightbox/bottom_view.cljs @@ -1,25 +1,25 @@ -(ns status-im.contexts.chat.messenger.lightbox.bottom-view +(ns status-im.common.lightbox.bottom-view (:require [quo.foundations.colors :as colors] [react-native.core :as rn] [react-native.platform :as platform] [react-native.reanimated :as reanimated] - [status-im.contexts.chat.messenger.lightbox.animations :as anim] - [status-im.contexts.chat.messenger.lightbox.constants :as c] - [status-im.contexts.chat.messenger.lightbox.style :as style] - [status-im.contexts.chat.messenger.lightbox.text-sheet.view :as text-sheet] + [status-im.common.lightbox.animations :as anim] + [status-im.common.lightbox.constants :as constants] + [status-im.common.lightbox.style :as style] + [status-im.common.lightbox.text-sheet.view :as text-sheet] [utils.re-frame :as rf])) (defn get-small-item-layout [_ index] #js - {:length c/small-image-size - :offset (* (+ c/small-image-size 8) index) + {:length constants/small-image-size + :offset (* (+ constants/small-image-size 8) index) :index index}) (defn- f-small-image [item index _ {:keys [scroll-index props]}] - (let [size (if (= @scroll-index index) c/focused-image-size c/small-image-size) + (let [size (if (= @scroll-index index) constants/focused-image-size constants/small-image-size) size-value (anim/use-val size) {:keys [scroll-index-lock? small-list-ref flat-list-ref]} props] @@ -27,7 +27,7 @@ [rn/touchable-opacity {:active-opacity 1 :on-press (fn [] - (rf/dispatch [:chat.ui/zoom-out-signal @scroll-index]) + (rf/dispatch [:lightbox/zoom-out-signal @scroll-index]) (reset! scroll-index-lock? true) (js/setTimeout #(reset! scroll-index-lock? false) 500) (js/setTimeout @@ -38,9 +38,9 @@ (.scrollToIndex ^js @flat-list-ref #js {:animated true :index index})) (if platform/ios? 50 150)) - (rf/dispatch [:chat.ui/update-shared-element-id (:message-id item)]))} + (rf/dispatch [:lightbox/update-animation-shared-element-id (:id item)]))} [reanimated/fast-image - {:source {:uri (:image (:content item))} + {:source {:uri (:image item)} :style (reanimated/apply-animations-to-style {:width size-value :height size-value} {:border-radius 10})}]])) @@ -50,20 +50,26 @@ [:f> f-small-image item index _ render-data]) (defn bottom-view - [messages index scroll-index insets animations derived item-width props state transparent?] - (let [padding-horizontal (- (/ item-width 2) (/ c/focused-image-size 2))] + [{:keys [images index scroll-index insets animations derived item-width props state transparent? + bottom-text-component]}] + (let [padding-horizontal (- (/ item-width 2) (/ constants/focused-image-size 2))] [reanimated/linear-gradient {:colors [colors/neutral-100-opa-100 colors/neutral-100-opa-80 colors/neutral-100-opa-0] :location [0.2 0.9] :start {:x 0 :y 1} :end {:x 0 :y 0} :style (style/gradient-container insets animations derived transparent?)} - [text-sheet/view messages animations state props] + (when bottom-text-component + [text-sheet/view + {:overlay-opacity (:overlay-opacity animations) + :overlay-z-index (:overlay-z-index state) + :text-sheet-lock? (:text-sheet-lock? props) + :text-component bottom-text-component}]) [rn/flat-list {:ref #(reset! (:small-list-ref props) %) - :key-fn :message-id - :style {:height c/small-list-height} - :data messages + :key-fn :id + :style {:height constants/small-list-height} + :data images :render-fn small-image :render-data {:scroll-index scroll-index :props props} diff --git a/src/status_im/contexts/chat/messenger/lightbox/constants.cljs b/src/status_im/common/lightbox/constants.cljs similarity index 89% rename from src/status_im/contexts/chat/messenger/lightbox/constants.cljs rename to src/status_im/common/lightbox/constants.cljs index 1af54b2c40..85c7ffe74c 100644 --- a/src/status_im/contexts/chat/messenger/lightbox/constants.cljs +++ b/src/status_im/common/lightbox/constants.cljs @@ -1,4 +1,4 @@ -(ns status-im.contexts.chat.messenger.lightbox.constants) +(ns status-im.common.lightbox.constants) (def ^:const small-image-size 40) (def ^:const focused-extra-size 16) diff --git a/src/status_im/contexts/chat/messenger/lightbox/effects.cljs b/src/status_im/common/lightbox/effects.cljs similarity index 86% rename from src/status_im/contexts/chat/messenger/lightbox/effects.cljs rename to src/status_im/common/lightbox/effects.cljs index 6effa3d9cf..f00910d0da 100644 --- a/src/status_im/contexts/chat/messenger/lightbox/effects.cljs +++ b/src/status_im/common/lightbox/effects.cljs @@ -1,4 +1,4 @@ -(ns status-im.contexts.chat.messenger.lightbox.effects +(ns status-im.common.lightbox.effects (:require [react-native.blob :as blob] [react-native.cameraroll :as cameraroll] [react-native.fs :as fs] @@ -10,7 +10,7 @@ {:trusty platform/ios? :path (str (fs/cache-dir) "/StatusIm_Image.jpeg")}) -(rf/reg-fx :effects.chat/share-image +(rf/reg-fx :effects.lightbox/share-image (fn [uri] (blob/fetch uri config @@ -20,7 +20,7 @@ #(fs/unlink downloaded-url) #(fs/unlink downloaded-url)))))) -(rf/reg-fx :effects.chat/save-image-to-gallery +(rf/reg-fx :effects.lightbox/save-image-to-gallery (fn [[uri on-success]] (blob/fetch uri config diff --git a/src/status_im/common/lightbox/events.cljs b/src/status_im/common/lightbox/events.cljs new file mode 100644 index 0000000000..5cd3566884 --- /dev/null +++ b/src/status_im/common/lightbox/events.cljs @@ -0,0 +1,37 @@ +(ns status-im.common.lightbox.events + (:require [reagent.core :as reagent] + status-im.common.lightbox.effects + [utils.re-frame :as rf])) + +(rf/reg-event-fx :lightbox/navigate-to-lightbox + (fn [{:keys [db]} [animation-shared-element-id screen-params]] + (reagent/next-tick #(rf/dispatch [:navigate-to :lightbox screen-params])) + {:db (assoc db :animation-shared-element-id animation-shared-element-id)})) + +(rf/reg-event-fx :lightbox/update-animation-shared-element-id + (fn [{:keys [db]} [animation-shared-element-id]] + {:db (assoc db :animation-shared-element-id animation-shared-element-id)})) + +(rf/reg-event-fx :lightbox/exit-lightbox-signal + (fn [{:keys [db]} [value]] + {:db (assoc db :lightbox/exit-signal value)})) + +(rf/reg-event-fx :lightbox/zoom-out-signal + (fn [{:keys [db]} [value]] + {:db (assoc db :lightbox/zoom-out-signal value)})) + +(rf/reg-event-fx :lightbox/orientation-change + (fn [{:keys [db]} [value]] + {:db (assoc db :lightbox/orientation value)})) + +(rf/reg-event-fx :lightbox/lightbox-scale + (fn [{:keys [db]} [value]] + {:db (assoc db :lightbox/scale value)})) + +(rf/reg-event-fx :lightbox/share-image + (fn [_ [uri]] + {:effects.lightbox/share-image uri})) + +(rf/reg-event-fx :lightbox/save-image-to-gallery + (fn [_ [uri on-success]] + {:effects.lightbox/save-image-to-gallery [uri on-success]})) diff --git a/src/status_im/contexts/chat/messenger/lightbox/style.cljs b/src/status_im/common/lightbox/style.cljs similarity index 90% rename from src/status_im/contexts/chat/messenger/lightbox/style.cljs rename to src/status_im/common/lightbox/style.cljs index ace3e743db..0109394d8b 100644 --- a/src/status_im/contexts/chat/messenger/lightbox/style.cljs +++ b/src/status_im/common/lightbox/style.cljs @@ -1,9 +1,9 @@ -(ns status-im.contexts.chat.messenger.lightbox.style +(ns status-im.common.lightbox.style (:require [quo.foundations.colors :as colors] [react-native.platform :as platform] [react-native.reanimated :as reanimated] - [status-im.contexts.chat.messenger.lightbox.constants :as c])) + [status-im.common.lightbox.constants :as constants])) ;;;; VIEW (defn image @@ -33,7 +33,7 @@ {:position :absolute :padding-horizontal 20 :top (if (or platform/ios? (not landscape?)) top-inset 0) - :height c/top-view-height + :height constants/top-view-height :z-index 4 :flex-direction :row :justify-content :space-between @@ -44,7 +44,7 @@ (defn top-gradient [insets] {:position :absolute - :height (+ c/top-view-height (:top insets) 0) + :height (+ constants/top-view-height (:top insets) 0) :top (- (:top insets)) :left 0 :right 0}) @@ -71,12 +71,12 @@ :display (if @transparent? :none :flex) :bottom 0 :padding-bottom (:bottom insets) - :padding-top c/text-min-height + :padding-top constants/text-min-height :z-index 3})) (defn content-container [padding-horizontal] - {:padding-vertical c/small-list-padding-vertical + {:padding-vertical constants/small-list-padding-vertical :padding-horizontal padding-horizontal :align-items :center :justify-content :center}) diff --git a/src/status_im/contexts/chat/messenger/lightbox/text_sheet/style.cljs b/src/status_im/common/lightbox/text_sheet/style.cljs similarity index 89% rename from src/status_im/contexts/chat/messenger/lightbox/text_sheet/style.cljs rename to src/status_im/common/lightbox/text_sheet/style.cljs index 181b0dad01..83de40364c 100644 --- a/src/status_im/contexts/chat/messenger/lightbox/text_sheet/style.cljs +++ b/src/status_im/common/lightbox/text_sheet/style.cljs @@ -1,8 +1,8 @@ -(ns status-im.contexts.chat.messenger.lightbox.text-sheet.style +(ns status-im.common.lightbox.text-sheet.style (:require [quo.foundations.colors :as colors] [react-native.reanimated :as reanimated] - [status-im.contexts.chat.messenger.lightbox.constants :as constants])) + [status-im.common.lightbox.constants :as constants])) (defn sheet-container [{:keys [height top]}] @@ -14,10 +14,10 @@ :right 0})) (defn text-style - [expanding-message?] + [expandable-text?] {:color colors/white :margin-horizontal 20 - :align-items (when-not expanding-message? :center) + :align-items (when-not expandable-text? :center) :flex-grow 1}) (def bar-container diff --git a/src/status_im/contexts/chat/messenger/lightbox/text_sheet/utils.cljs b/src/status_im/common/lightbox/text_sheet/utils.cljs similarity index 95% rename from src/status_im/contexts/chat/messenger/lightbox/text_sheet/utils.cljs rename to src/status_im/common/lightbox/text_sheet/utils.cljs index a1fa8e7870..b751579cbe 100644 --- a/src/status_im/contexts/chat/messenger/lightbox/text_sheet/utils.cljs +++ b/src/status_im/common/lightbox/text_sheet/utils.cljs @@ -1,10 +1,10 @@ -(ns status-im.contexts.chat.messenger.lightbox.text-sheet.utils +(ns status-im.common.lightbox.text-sheet.utils (:require [oops.core :as oops] [react-native.gesture :as gesture] [react-native.reanimated :as reanimated] [reagent.core :as r] - [status-im.contexts.chat.messenger.lightbox.constants :as constants])) + [status-im.common.lightbox.constants :as constants])) (defn- collapse-sheet [{:keys [derived-value overlay-opacity saved-top expanded? overlay-z-index]}] @@ -16,10 +16,10 @@ (defn sheet-gesture [{:keys [derived-value saved-top overlay-opacity gradient-opacity]} - expanded-height max-height full-height overlay-z-index expanded? dragging? expanding-message?] + expanded-height max-height full-height overlay-z-index expanded? dragging? expandable-text?] (let [disable-gesture-update (r/atom false)] (-> (gesture/gesture-pan) - (gesture/enabled expanding-message?) + (gesture/enabled expandable-text?) (gesture/on-start (fn [] (reset! overlay-z-index 1) (reset! dragging? true) diff --git a/src/status_im/contexts/chat/messenger/lightbox/text_sheet/view.cljs b/src/status_im/common/lightbox/text_sheet/view.cljs similarity index 56% rename from src/status_im/contexts/chat/messenger/lightbox/text_sheet/view.cljs rename to src/status_im/common/lightbox/text_sheet/view.cljs index 16e5113a0b..7fa9ccb512 100644 --- a/src/status_im/contexts/chat/messenger/lightbox/text_sheet/view.cljs +++ b/src/status_im/common/lightbox/text_sheet/view.cljs @@ -1,4 +1,4 @@ -(ns status-im.contexts.chat.messenger.lightbox.text-sheet.view +(ns status-im.common.lightbox.text-sheet.view (:require [quo.foundations.colors :as colors] [react-native.core :as rn] @@ -8,33 +8,31 @@ [react-native.reanimated :as reanimated] [react-native.safe-area :as safe-area] [reagent.core :as reagent] - [status-im.contexts.chat.messenger.lightbox.constants :as constants] - [status-im.contexts.chat.messenger.lightbox.text-sheet.style :as style] - [status-im.contexts.chat.messenger.lightbox.text-sheet.utils :as utils] - [status-im.contexts.chat.messenger.messages.content.text.view :as message-view])) + [status-im.common.lightbox.constants :as constants] + [status-im.common.lightbox.text-sheet.style :as style] + [status-im.common.lightbox.text-sheet.utils :as utils])) (defn- text-sheet - [messages overlay-opacity overlay-z-index text-sheet-lock?] + [_] (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))) - full-height (+ constants/bar-container-height - constants/text-margin - constants/line-height - @text-height) - expanded-height (min max-height full-height) - animations (utils/init-animations overlay-opacity) - derived (utils/init-derived-animations animations) - expanding-message? (> @text-height (* constants/line-height 2))] + (fn [{:keys [overlay-opacity overlay-z-index text-sheet-lock? text-component]}] + (let [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))) + full-height (+ constants/bar-container-height + constants/text-margin + constants/line-height + @text-height) + expanded-height (min max-height full-height) + animations (utils/init-animations overlay-opacity) + derived (utils/init-derived-animations animations) + expandable-text? (> @text-height (* constants/line-height 2))] [rn/view [reanimated/linear-gradient {:colors [colors/neutral-100-opa-0 colors/neutral-100] @@ -51,10 +49,10 @@ overlay-z-index expanded? dragging? - expanding-message?)} + expandable-text?)} [gesture/gesture-detector {:gesture (-> (gesture/gesture-tap) - (gesture/enabled (and expanding-message? (not @expanded?))) + (gesture/enabled (and expandable-text? (not @expanded?))) (gesture/on-start (fn [] (utils/expand-sheet animations expanded-height @@ -63,7 +61,7 @@ expanded? text-sheet-lock?))))} [reanimated/view {:style (style/sheet-container derived)} - (when expanding-message? + (when expandable-text? [rn/view {:style style/bar-container} [rn/view {:style style/bar}]]) [linear-gradient/linear-gradient @@ -72,19 +70,17 @@ :end {:x 0 :y 0} :locations [0.7 0.8 1] :style (style/bottom-gradient (:bottom insets))}] + [gesture/scroll-view {:scroll-enabled false :scroll-event-throttle 16 :bounces false :style {:height (- max-height constants/bar-container-height)} - :content-container-style {:padding-top (when (not expanding-message?) + :content-container-style {:padding-top (when (not expandable-text?) constants/bar-container-height)}} - [message-view/render-parsed-text - {:content content - :chat-id chat-id - :style-override (style/text-style expanding-message?) - :on-layout #(utils/on-layout % text-height)}]]]]]])))) + [rn/view {:on-layout #(utils/on-layout % text-height)} + text-component]]]]]])))) (defn view - [messages {:keys [overlay-opacity]} {:keys [overlay-z-index]} {:keys [text-sheet-lock?]}] - [:f> text-sheet messages overlay-opacity overlay-z-index text-sheet-lock?]) + [props] + [:f> text-sheet props]) diff --git a/src/status_im/contexts/chat/messenger/lightbox/top_view.cljs b/src/status_im/common/lightbox/top_view.cljs similarity index 72% rename from src/status_im/contexts/chat/messenger/lightbox/top_view.cljs rename to src/status_im/common/lightbox/top_view.cljs index 5fb1fa2143..72a1fb0c7c 100644 --- a/src/status_im/contexts/chat/messenger/lightbox/top_view.cljs +++ b/src/status_im/common/lightbox/top_view.cljs @@ -1,4 +1,4 @@ -(ns status-im.contexts.chat.messenger.lightbox.top-view +(ns status-im.common.lightbox.top-view (:require [quo.core :as quo] [quo.foundations.colors :as colors] @@ -6,10 +6,9 @@ [react-native.orientation :as orientation] [react-native.platform :as platform] [react-native.reanimated :as reanimated] - [status-im.contexts.chat.messenger.lightbox.animations :as anim] - [status-im.contexts.chat.messenger.lightbox.constants :as c] - [status-im.contexts.chat.messenger.lightbox.style :as style] - [utils.datetime :as datetime] + [status-im.common.lightbox.animations :as anim] + [status-im.common.lightbox.constants :as constants] + [status-im.common.lightbox.style :as style] [utils.i18n :as i18n] [utils.re-frame :as rf] [utils.url :as url])) @@ -17,7 +16,7 @@ (defn animate-rotation [result screen-width screen-height insets {:keys [rotate top-view-y top-view-x top-view-width top-view-bg]}] - (let [top-x (+ (/ c/top-view-height 2) (:top insets))] + (let [top-x (+ (/ constants/top-view-height 2) (:top insets))] (cond (= result orientation/landscape-left) (do @@ -42,9 +41,9 @@ (anim/animate top-view-bg colors/neutral-100-opa-0))))) (defn drawer - [messages index] - (let [{:keys [content]} (nth messages index) - uri (url/replace-port (:image content) (rf/sub [:mediaserver/port]))] + [images index] + (let [{:keys [image]} (nth images index) + uri (url/replace-port image (rf/sub [:mediaserver/port]))] [quo/action-drawer [[{:icon :i/save :accessibility-label :save-image @@ -52,7 +51,7 @@ :on-press (fn [] (rf/dispatch [:hide-bottom-sheet]) (rf/dispatch - [:chat.ui/save-image-to-gallery + [:lightbox/save-image-to-gallery uri #(rf/dispatch [:toasts/upsert {:id :random-id @@ -61,20 +60,19 @@ :text (i18n/label :t/photo-saved)}])]))}]]])) (defn share-image - [messages index] - (let [{:keys [content]} (nth messages index) - uri (url/replace-port (:image content) (rf/sub [:mediaserver/port]))] - (rf/dispatch [:chat.ui/share-image uri]))) + [images index] + (let [{:keys [image]} (nth images index) + uri (url/replace-port image (rf/sub [:mediaserver/port]))] + (rf/dispatch [:lightbox/share-image uri]))) (defn top-view - [messages insets index animations derived landscape? screen-width] - (let [{:keys [from timestamp]} (first messages) - [primary-name _] (rf/sub [:contacts/contact-two-names-by-identity from]) - bg-color (if landscape? - colors/neutral-100-opa-70 - colors/neutral-100-opa-0) + [images insets index animations derived landscape? screen-width] + (let [{:keys [description header]} (nth images @index) + bg-color (if landscape? + colors/neutral-100-opa-70 + colors/neutral-100-opa-0) {:keys [background-color opacity - overlay-opacity]} animations] + overlay-opacity]} animations] [reanimated/view {:style (style/top-view-container (:top insets) screen-width bg-color landscape? animations derived)} @@ -92,7 +90,7 @@ (anim/animate opacity 0) (anim/animate overlay-opacity 0) (rf/dispatch (if platform/ios? - [:chat.ui/exit-lightbox-signal @index] + [:lightbox/exit-lightbox-signal @index] [:navigate-back]))) :style style/close-container} [quo/icon :close {:size 20 :color colors/white}]] @@ -100,22 +98,22 @@ [quo/text {:weight :semi-bold :size :paragraph-1 - :style {:color colors/white}} primary-name] + :style {:color colors/white}} header] [quo/text {:weight :medium :size :paragraph-2 - :style {:color colors/neutral-40}} (when timestamp (datetime/to-short-str timestamp))]]] + :style {:color colors/neutral-40}} description]]] [rn/view {:style style/top-right-buttons} [rn/touchable-opacity {:active-opacity 1 :accessibility-label :share-image - :on-press #(share-image messages @index) + :on-press #(share-image images @index) :style (merge style/close-container {:margin-right 12})} [quo/icon :share {:size 20 :color colors/white}]] [rn/touchable-opacity {:active-opacity 1 :accessibility-label :image-options :on-press #(rf/dispatch [:show-bottom-sheet - {:content (fn [] [drawer messages @index])}]) + {:content (fn [] [drawer images @index])}]) :style style/close-container} [quo/icon :options {:size 20 :color colors/white}]]]])) diff --git a/src/status_im/contexts/chat/messenger/lightbox/utils.cljs b/src/status_im/common/lightbox/utils.cljs similarity index 93% rename from src/status_im/contexts/chat/messenger/lightbox/utils.cljs rename to src/status_im/common/lightbox/utils.cljs index 93c23eeb36..2f6e71b711 100644 --- a/src/status_im/contexts/chat/messenger/lightbox/utils.cljs +++ b/src/status_im/common/lightbox/utils.cljs @@ -1,4 +1,4 @@ -(ns status-im.contexts.chat.messenger.lightbox.utils +(ns status-im.common.lightbox.utils (:require [clojure.string :as string] [oops.core :as oops] @@ -9,9 +9,9 @@ [react-native.platform :as platform] [react-native.safe-area :as safe-area] [reagent.core :as reagent] - [status-im.contexts.chat.messenger.lightbox.animations :as anim] - [status-im.contexts.chat.messenger.lightbox.constants :as constants] - [status-im.contexts.chat.messenger.lightbox.top-view :as top-view] + [status-im.common.lightbox.animations :as anim] + [status-im.common.lightbox.constants :as constants] + [status-im.common.lightbox.top-view :as top-view] [utils.re-frame :as rf] [utils.worklets.chat.messenger.lightbox :as worklet])) @@ -46,7 +46,7 @@ (if platform/ios? 250 100))) (swap! timers assoc :mount-index-lock (js/setTimeout #(reset! scroll-index-lock? false) 300)) (fn [] - (rf/dispatch [:chat.ui/zoom-out-signal nil]) + (rf/dispatch [:lightbox/zoom-out-signal nil]) (when platform/android? (rf/dispatch [:chat.ui/lightbox-scale 1])) (clear-timers timers))))) @@ -69,7 +69,7 @@ landscape? (string/includes? result orientation/landscape) item-width (if (and landscape? platform/ios?) screen-height screen-width)] (when (or landscape? (= result orientation/portrait)) - (rf/dispatch [:chat.ui/orientation-change result])) + (rf/dispatch [:lightbox/orientation-change result])) (cond landscape? (orientation/lock-to-landscape "lightbox") @@ -148,11 +148,11 @@ :timers (atom {})}) (defn init-state - [messages index] + [images index] ;; The initial value of data is the image that was pressed (and not the whole album) in order ;; for the transition animation to execute properly, otherwise it would animate towards ;; outside the screen (even if we have `initialScrollIndex` set). - {:data (reagent/atom (if (number? index) [(nth messages index)] [])) + {:data (reagent/atom (if (number? index) [(nth images index)] [])) :scroll-index (reagent/atom index) :transparent? (reagent/atom false) :set-full-height? (reagent/atom false) diff --git a/src/status_im/contexts/chat/messenger/lightbox/view.cljs b/src/status_im/common/lightbox/view.cljs similarity index 60% rename from src/status_im/contexts/chat/messenger/lightbox/view.cljs rename to src/status_im/common/lightbox/view.cljs index 29af399328..5c8eab8fff 100644 --- a/src/status_im/contexts/chat/messenger/lightbox/view.cljs +++ b/src/status_im/common/lightbox/view.cljs @@ -1,4 +1,4 @@ -(ns status-im.contexts.chat.messenger.lightbox.view +(ns status-im.common.lightbox.view (:require [clojure.string :as string] [oops.core :as oops] @@ -9,13 +9,13 @@ [react-native.platform :as platform] [react-native.reanimated :as reanimated] [react-native.safe-area :as safe-area] - [status-im.contexts.chat.messenger.lightbox.animations :as anim] - [status-im.contexts.chat.messenger.lightbox.bottom-view :as bottom-view] - [status-im.contexts.chat.messenger.lightbox.constants :as constants] - [status-im.contexts.chat.messenger.lightbox.style :as style] - [status-im.contexts.chat.messenger.lightbox.top-view :as top-view] - [status-im.contexts.chat.messenger.lightbox.utils :as utils] - [status-im.contexts.chat.messenger.lightbox.zoomable-image.view :as zoomable-image] + [status-im.common.lightbox.animations :as anim] + [status-im.common.lightbox.bottom-view :as bottom-view] + [status-im.common.lightbox.constants :as constants] + [status-im.common.lightbox.style :as style] + [status-im.common.lightbox.top-view :as top-view] + [status-im.common.lightbox.utils :as utils] + [status-im.common.lightbox.zoomable-image.view :as zoomable-image] [utils.re-frame :as rf])) (defn get-item-layout @@ -33,9 +33,10 @@ (reset! scroll-index index) (when @small-list-ref (.scrollToIndex ^js @small-list-ref #js {:animated true :index index})) - (rf/dispatch [:chat.ui/update-shared-element-id (:message-id (oops/oget changed :item))])))) + (rf/dispatch [:lightbox/update-animation-shared-element-id + (:id (oops/oget changed :item))])))) -(defn image +(defn image-view [message index _ {:keys [screen-width screen-height] :as args}] [rn/view {:style (style/image (+ screen-width constants/separator-width) screen-height)} @@ -43,30 +44,31 @@ [rn/view {:style {:width constants/separator-width}}]]) (defn lightbox-content - [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) - window-height (if platform/android? - (+ (:height window) (:top insets)) - (:height window)) - curr-orientation (or (rf/sub [:lightbox/orientation]) orientation/portrait) - landscape? (string/includes? curr-orientation orientation/landscape) - horizontal? (or platform/android? (not landscape?)) - inverted? (and platform/ios? (= curr-orientation orientation/landscape-right)) - screen-width (if (or platform/ios? (= curr-orientation orientation/portrait)) - window-width - window-height) - screen-height (if (or platform/ios? (= curr-orientation orientation/portrait)) - window-height - window-width) - item-width (if (and landscape? platform/ios?) screen-height screen-width)] + [{:keys [props state animations derived images index handle-items-changed bottom-text-component]}] + (let [{:keys [data transparent? scroll-index + set-full-height?]} state + insets (safe-area/get-insets) + window (rn/get-window) + window-width (:width window) + window-height (if platform/android? + (+ (:height window) (:top insets)) + (:height window)) + curr-orientation (or (rf/sub [:lightbox/orientation]) orientation/portrait) + landscape? (string/includes? curr-orientation orientation/landscape) + horizontal? (or platform/android? (not landscape?)) + inverted? (and platform/ios? (= curr-orientation orientation/landscape-right)) + screen-width (if (or platform/ios? (= curr-orientation orientation/portrait)) + window-width + window-height) + screen-height (if (or platform/ios? (= curr-orientation orientation/portrait)) + window-height + window-width) + item-width (if (and landscape? platform/ios?) screen-height screen-width)] [reanimated/view {:style (reanimated/apply-animations-to-style {:background-color (:background-color animations)} {:height screen-height})} (when-not @transparent? - [:f> top-view/top-view messages insets scroll-index animations derived landscape? + [:f> top-view/top-view images insets scroll-index animations derived landscape? screen-width]) [gesture/gesture-detector {:gesture (utils/drag-gesture animations (and landscape? platform/ios?) set-full-height?)} @@ -92,7 +94,7 @@ :scroll-event-throttle 8 :style {:width (+ screen-width constants/separator-width)} :data @data - :render-fn image + :render-fn image-view :render-data {:opacity-value (:opacity animations) :overlay-opacity (:overlay-opacity animations) :border-value (:border animations) @@ -118,26 +120,47 @@ ;; NOTE: not un-mounting bottom-view based on `transparent?` (like we do with the top-view ;; above), since we need to save the state of the text-sheet position. Instead, we use ;; the `:display` style property to hide the bottom-sheet. - (when (not landscape?) - [:f> bottom-view/bottom-view messages index scroll-index insets animations derived - item-width props state transparent?])])) + (when (and (not landscape?) (or bottom-text-component (> (count images) 1))) + [:f> bottom-view/bottom-view + {:images images + :index index + :scroll-index scroll-index + :insets insets + :animations animations + :derived derived + :item-width item-width + :props props + :state state + :transparent? transparent? + :bottom-text-component bottom-text-component}])])) (defn- f-lightbox [] - (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))] + (let [{:keys [images index bottom-text-component]} (rf/sub [:get-screen-params]) + props + (utils/init-props) + state + (utils/init-state images index) + handle-items-changed + (fn [e] + (on-viewable-items-changed e props state))] (fn [] - (let [animations (utils/init-animations (count messages) index) + (let [animations (utils/init-animations (count images) index) derived (utils/init-derived-animations animations)] (anim/animate (:background-color animations) colors/neutral-100) - (reset! (:data state) messages) + (reset! (:data state) images) (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 handle-items-changed])))) + [:f> lightbox-content + {:props props + :state state + :animations animations + :derived derived + :images images + :index index + :handle-items-changed handle-items-changed + :bottom-text-component bottom-text-component}])))) (defn lightbox [] diff --git a/src/status_im/contexts/chat/messenger/lightbox/zoomable_image/constants.cljs b/src/status_im/common/lightbox/zoomable_image/constants.cljs similarity index 79% rename from src/status_im/contexts/chat/messenger/lightbox/zoomable_image/constants.cljs rename to src/status_im/common/lightbox/zoomable_image/constants.cljs index 8b1668e3a7..3ae95e222e 100644 --- a/src/status_im/contexts/chat/messenger/lightbox/zoomable_image/constants.cljs +++ b/src/status_im/common/lightbox/zoomable_image/constants.cljs @@ -1,4 +1,4 @@ -(ns status-im.contexts.chat.messenger.lightbox.zoomable-image.constants) +(ns status-im.common.lightbox.zoomable-image.constants) (def ^:const min-scale 1) diff --git a/src/status_im/contexts/chat/messenger/lightbox/zoomable_image/style.cljs b/src/status_im/common/lightbox/zoomable_image/style.cljs similarity index 94% rename from src/status_im/contexts/chat/messenger/lightbox/zoomable_image/style.cljs rename to src/status_im/common/lightbox/zoomable_image/style.cljs index 4280de7640..ef7cab3879 100644 --- a/src/status_im/contexts/chat/messenger/lightbox/zoomable_image/style.cljs +++ b/src/status_im/common/lightbox/zoomable_image/style.cljs @@ -1,4 +1,4 @@ -(ns status-im.contexts.chat.messenger.lightbox.zoomable-image.style +(ns status-im.common.lightbox.zoomable-image.style (:require [react-native.platform :as platform] [react-native.reanimated :as reanimated])) diff --git a/src/status_im/contexts/chat/messenger/lightbox/zoomable_image/utils.cljs b/src/status_im/common/lightbox/zoomable_image/utils.cljs similarity index 97% rename from src/status_im/contexts/chat/messenger/lightbox/zoomable_image/utils.cljs rename to src/status_im/common/lightbox/zoomable_image/utils.cljs index 46381459f6..0a529e7807 100644 --- a/src/status_im/contexts/chat/messenger/lightbox/zoomable_image/utils.cljs +++ b/src/status_im/common/lightbox/zoomable_image/utils.cljs @@ -1,4 +1,4 @@ -(ns status-im.contexts.chat.messenger.lightbox.zoomable-image.utils +(ns status-im.common.lightbox.zoomable-image.utils (:require [clojure.string :as string] [react-native.core :as rn] @@ -6,8 +6,8 @@ [react-native.orientation :as orientation] [react-native.platform :as platform] [reagent.core :as reagent] - [status-im.contexts.chat.messenger.lightbox.animations :as anim] - [status-im.contexts.chat.messenger.lightbox.zoomable-image.constants :as constants] + [status-im.common.lightbox.animations :as anim] + [status-im.common.lightbox.zoomable-image.constants :as constants] [utils.re-frame :as rf])) ;;; Helpers @@ -97,7 +97,7 @@ (rescale constants/min-scale true) (js/setTimeout #(rf/dispatch [:navigate-back]) 70)) (rf/dispatch [:navigate-back])) - (js/setTimeout #(rf/dispatch [:chat.ui/exit-lightbox-signal nil]) 500))) + (js/setTimeout #(rf/dispatch [:lightbox/exit-lightbox-signal nil]) 500))) (defn handle-zoom-out-signal "Zooms out when pressing on another photo from the small bottom list" diff --git a/src/status_im/contexts/chat/messenger/lightbox/zoomable_image/view.cljs b/src/status_im/common/lightbox/zoomable_image/view.cljs similarity index 93% rename from src/status_im/contexts/chat/messenger/lightbox/zoomable_image/view.cljs rename to src/status_im/common/lightbox/zoomable_image/view.cljs index 49681ae508..a82e4f015c 100644 --- a/src/status_im/contexts/chat/messenger/lightbox/zoomable_image/view.cljs +++ b/src/status_im/common/lightbox/zoomable_image/view.cljs @@ -1,4 +1,4 @@ -(ns status-im.contexts.chat.messenger.lightbox.zoomable-image.view +(ns status-im.common.lightbox.zoomable-image.view (:require [oops.core :refer [oget]] [react-native.core :as rn] @@ -7,10 +7,10 @@ [react-native.platform :as platform] [react-native.reanimated :as reanimated] [reagent.core :as r] - [status-im.contexts.chat.messenger.lightbox.animations :as anim] - [status-im.contexts.chat.messenger.lightbox.zoomable-image.constants :as c] - [status-im.contexts.chat.messenger.lightbox.zoomable-image.style :as style] - [status-im.contexts.chat.messenger.lightbox.zoomable-image.utils :as utils] + [status-im.common.lightbox.animations :as anim] + [status-im.common.lightbox.zoomable-image.constants :as c] + [status-im.common.lightbox.zoomable-image.style :as style] + [status-im.common.lightbox.zoomable-image.utils :as utils] [utils.re-frame :as rf] [utils.url :as url])) @@ -206,7 +206,7 @@ (anim/animate-decay pan-y-start velocity [lower-bound upper-bound])))))))) (defn- f-zoomable-image - [dimensions animations state rescale curr-orientation content focused? index render-data + [dimensions animations state rescale curr-orientation image focused? index render-data image-dimensions-nil?] (let [{:keys [transparent? set-full-height?]} render-data portrait? (= curr-orientation orientation/portrait) @@ -229,7 +229,7 @@ (= curr-orientation orientation/portrait))} [reanimated/fast-image (merge - {:source {:uri (url/replace-port (:image content) (rf/sub [:mediaserver/port]))} + {:source {:uri (url/replace-port image (rf/sub [:mediaserver/port]))} :native-ID (when focused? :shared-element) :style (style/image dimensions animations render-data index)} (when image-dimensions-nil? @@ -238,12 +238,12 @@ (defn zoomable-image [] (let [state (utils/init-state)] - (fn [{:keys [image-width image-height content message-id]} index render-data] - (let [shared-element-id (rf/sub [:shared-element-id]) + (fn [{:keys [image-width image-height image id]} index render-data] + (let [animation-shared-element-id (rf/sub [:animation-shared-element-id]) exit-lightbox-signal (rf/sub [:lightbox/exit-signal]) zoom-out-signal (rf/sub [:lightbox/zoom-out-signal]) {:keys [set-full-height? curr-orientation]} render-data - focused? (= shared-element-id message-id) + focused? (= animation-shared-element-id id) ;; TODO - remove `image-dimensions` check, once ;; https://github.com/status-im/status-desktop/issues/10944 is fixed image-dimensions-nil? (not (and image-width image-height)) @@ -269,5 +269,5 @@ rescale set-full-height?)) (utils/handle-zoom-out-signal zoom-out-signal index (anim/get-val (:scale animations)) rescale) - [:f> f-zoomable-image dimensions animations state rescale curr-orientation content focused? + [:f> f-zoomable-image dimensions animations state rescale curr-orientation image focused? index render-data image-dimensions-nil?])))) diff --git a/src/status_im/contexts/chat/events.cljs b/src/status_im/contexts/chat/events.cljs index 06b1a83707..5b02b553ac 100644 --- a/src/status_im/contexts/chat/events.cljs +++ b/src/status_im/contexts/chat/events.cljs @@ -4,13 +4,12 @@ [legacy.status-im.chat.models.loading :as loading] [legacy.status-im.data-store.chats :as chats-store] [re-frame.core :as re-frame] - [reagent.core :as reagent] + status-im.common.lightbox.events [status-im.common.muting.helpers :refer [format-mute-till]] [status-im.constants :as constants] [status-im.contexts.chat.contacts.events :as contacts-store] status-im.contexts.chat.effects [status-im.contexts.chat.messenger.composer.link-preview.events :as link-preview] - status-im.contexts.chat.messenger.lightbox.events status-im.contexts.chat.messenger.messages.content.reactions.events [status-im.contexts.chat.messenger.messages.delete-message-for-me.events :as delete-for-me] [status-im.contexts.chat.messenger.messages.delete-message.events :as delete-message] @@ -394,38 +393,6 @@ [cofx chat-id] (navigation/navigate-to cofx :chat-pinned-messages {:chat-id chat-id})) - -(rf/defn update-shared-element-id - {:events [:chat.ui/update-shared-element-id]} - [{:keys [db]} shared-element-id] - {:db (assoc db :shared-element-id shared-element-id)}) - -(rf/defn navigate-to-lightbox - {:events [:chat.ui/navigate-to-lightbox]} - [{:keys [db]} shared-element-id screen-params] - (reagent/next-tick #(rf/dispatch [:navigate-to :lightbox screen-params])) - {:db (assoc db :shared-element-id shared-element-id)}) - -(rf/defn exit-lightbox-signal - {:events [:chat.ui/exit-lightbox-signal]} - [{:keys [db]} value] - {:db (assoc db :lightbox/exit-signal value)}) - -(rf/defn zoom-out-signal - {:events [:chat.ui/zoom-out-signal]} - [{:keys [db]} value] - {:db (assoc db :lightbox/zoom-out-signal value)}) - -(rf/defn orientation-change - {:events [:chat.ui/orientation-change]} - [{:keys [db]} value] - {:db (assoc db :lightbox/orientation value)}) - -(rf/defn lightbox-scale - {:events [:chat.ui/lightbox-scale]} - [{:keys [db]} value] - {:db (assoc db :lightbox/scale value)}) - (rf/defn check-last-chat {:events [:chat/check-last-chat]} [{:keys [db]}] @@ -452,3 +419,15 @@ {:events [:chat.ui/scroll-to-bottom]} [_] {:effects.chat/scroll-to-bottom nil}) + +(rf/reg-event-fx :chat.ui/clear-sending-images + (fn [{:keys [db]}] + {:db (update-in db [:chat/inputs (:current-chat-id db) :metadata] assoc :sending-image {})})) + +(rf/reg-event-fx :chat.ui/image-unselected + (fn [{:keys [db]} [original]] + (let [current-chat-id (:current-chat-id db)] + {:db (update-in db + [:chat/inputs current-chat-id :metadata :sending-image] + dissoc + (:uri original))}))) diff --git a/src/status_im/contexts/chat/messenger/lightbox/events.cljs b/src/status_im/contexts/chat/messenger/lightbox/events.cljs deleted file mode 100644 index 765eead1f1..0000000000 --- a/src/status_im/contexts/chat/messenger/lightbox/events.cljs +++ /dev/null @@ -1,23 +0,0 @@ -(ns status-im.contexts.chat.messenger.lightbox.events - (:require status-im.contexts.chat.messenger.lightbox.effects - [utils.re-frame :as rf])) - -(rf/reg-event-fx :chat.ui/clear-sending-images - (fn [{:keys [db]}] - {:db (update-in db [:chat/inputs (:current-chat-id db) :metadata] assoc :sending-image {})})) - -(rf/reg-event-fx :chat.ui/image-unselected - (fn [{:keys [db]} [original]] - (let [current-chat-id (:current-chat-id db)] - {:db (update-in db - [:chat/inputs current-chat-id :metadata :sending-image] - dissoc - (:uri original))}))) - -(rf/reg-event-fx :chat.ui/share-image - (fn [_ [uri]] - {:effects.chat/share-image uri})) - -(rf/reg-event-fx :chat.ui/save-image-to-gallery - (fn [_ [uri on-success]] - {:effects.chat/save-image-to-gallery [uri on-success]})) diff --git a/src/status_im/contexts/chat/messenger/messages/content/album/view.cljs b/src/status_im/contexts/chat/messenger/messages/content/album/view.cljs index 59ea395933..ea03af0446 100644 --- a/src/status_im/contexts/chat/messenger/messages/content/album/view.cljs +++ b/src/status_im/contexts/chat/messenger/messages/content/album/view.cljs @@ -7,6 +7,8 @@ [status-im.constants :as constants] [status-im.contexts.chat.messenger.messages.content.album.style :as style] [status-im.contexts.chat.messenger.messages.content.image.view :as image] + [status-im.contexts.chat.messenger.messages.content.lightbox.utils :as lightbox-utils] + [status-im.contexts.chat.messenger.messages.content.lightbox.view :as lightbox] [status-im.contexts.chat.messenger.messages.content.text.view :as text] [utils.re-frame :as rf] [utils.url :as url])) @@ -21,17 +23,19 @@ (defn album-message [{:keys [albumize?] :as message} context on-long-press message-container-data] - (let [shared-element-id (rf/sub [:shared-element-id]) - media-server-port (rf/sub [:mediaserver/port]) - first-image (first (:album message)) - album-style (if (> (:image-width first-image) (:image-height first-image)) - :landscape - :portrait) - images-count (count (:album message)) + (let [animation-shared-element-id (rf/sub [:animation-shared-element-id]) + media-server-port (rf/sub [:mediaserver/port]) + album-messages (:album message) + first-image (first album-messages) + album-style (if (> (:image-width first-image) (:image-height first-image)) + :landscape + :portrait) + images-count (count album-messages) ;; album images are always square, except when we have 3 images, then they must be ;; rectangular ;; (portrait or landscape) - portrait? (and (= images-count rectangular-style-count) (= album-style :portrait))] + portrait? (and (= images-count rectangular-style-count) + (= album-style :portrait))] (if (and albumize? (> images-count 1)) [:<> [rn/view {:style {:margin-bottom 4}} [text/text-content first-image]] @@ -52,14 +56,21 @@ {:key (:message-id item) :active-opacity 1 :on-long-press #(on-long-press message context) - :on-press #(rf/dispatch [:chat.ui/navigate-to-lightbox - (:message-id item) - {:messages (:album message) - :index index}])} + :on-press #(rf/dispatch + [:lightbox/navigate-to-lightbox + (:message-id item) + {:index index + :images (into [] + (map + lightbox-utils/convert-message-to-lightbox-image + album-messages)) + :bottom-text-component + [lightbox/bottom-text-for-lightbox + first-image]}])} [fast-image/fast-image {:style (style/image dimensions index portrait? images-count) :source {:uri (url/replace-port (:image (:content item)) media-server-port)} - :native-ID (when (and (= shared-element-id (:message-id item)) + :native-ID (when (and (= animation-shared-element-id (:message-id item)) (< index constants/max-album-photos)) :shared-element)}] (when (and (> images-count constants/max-album-photos) @@ -71,11 +82,11 @@ :size :heading-2 :style {:color colors/white}} (str "+" (- images-count (dec constants/max-album-photos)))]])])) - (:album message))]] + album-messages)]] [:<> (map-indexed (fn [index item] [:<> {:key (:message-id item)} [image/image-message index item {:on-long-press #(on-long-press message context)} message-container-data]]) - (:album message))]))) + album-messages)]))) diff --git a/src/status_im/contexts/chat/messenger/messages/content/image/view.cljs b/src/status_im/contexts/chat/messenger/messages/content/image/view.cljs index d3cf723b55..05d8410101 100644 --- a/src/status_im/contexts/chat/messenger/messages/content/image/view.cljs +++ b/src/status_im/contexts/chat/messenger/messages/content/image/view.cljs @@ -4,6 +4,8 @@ [react-native.fast-image :as fast-image] [react-native.safe-area :as safe-area] [status-im.constants :as constants] + [status-im.contexts.chat.messenger.messages.content.lightbox.utils :as lightbox-utils] + [status-im.contexts.chat.messenger.messages.content.lightbox.view :as lightbox] [status-im.contexts.chat.messenger.messages.content.text.view :as text] [utils.re-frame :as rf] [utils.url :as url])) @@ -39,7 +41,7 @@ image-height max-container-width max-container-height) - shared-element-id (rf/sub [:shared-element-id]) + animation-shared-element-id (rf/sub [:animation-shared-element-id]) image-local-url (url/replace-port (:image content) (rf/sub [:mediaserver/port]))] [:<> (when (= index 0) @@ -48,13 +50,16 @@ {:active-opacity 1 :style {:margin-top 4} :on-long-press on-long-press - :on-press #(rf/dispatch [:chat.ui/navigate-to-lightbox + :on-press #(rf/dispatch [:lightbox/navigate-to-lightbox message-id - {:messages [message] - :index 0 - :insets insets}])} + {:images [(lightbox-utils/convert-message-to-lightbox-image + message)] + :index 0 + :insets insets + :bottom-text-component + [lightbox/bottom-text-for-lightbox message]}])} [fast-image/fast-image {:source {:uri image-local-url} :style (merge dimensions {:border-radius 12}) - :native-ID (when (= shared-element-id message-id) :shared-element) + :native-ID (when (= animation-shared-element-id message-id) :shared-element) :accessibility-label :image-message}]]])) diff --git a/src/status_im/contexts/chat/messenger/messages/content/lightbox/style.cljs b/src/status_im/contexts/chat/messenger/messages/content/lightbox/style.cljs new file mode 100644 index 0000000000..85bd1ff0a3 --- /dev/null +++ b/src/status_im/contexts/chat/messenger/messages/content/lightbox/style.cljs @@ -0,0 +1,10 @@ +(ns status-im.contexts.chat.messenger.messages.content.lightbox.style + (:require + [quo.foundations.colors :as colors])) + +(defn bottom-text + [expandable-text?] + {:color colors/white + :margin-horizontal 20 + :align-items (when-not expandable-text? :center) + :flex-grow 1}) diff --git a/src/status_im/contexts/chat/messenger/messages/content/lightbox/utils.cljs b/src/status_im/contexts/chat/messenger/messages/content/lightbox/utils.cljs new file mode 100644 index 0000000000..34fb8687a6 --- /dev/null +++ b/src/status_im/contexts/chat/messenger/messages/content/lightbox/utils.cljs @@ -0,0 +1,14 @@ +(ns status-im.contexts.chat.messenger.messages.content.lightbox.utils + (:require + [utils.datetime :as datetime] + [utils.re-frame :as rf])) + +(defn convert-message-to-lightbox-image + [{:keys [timestamp image-width image-height message-id from content]}] + (let [[primary-name _] (rf/sub [:contacts/contact-two-names-by-identity from])] + {:image (:image content) + :image-width image-width + :image-height image-height + :id message-id + :header primary-name + :description (when timestamp (datetime/to-short-str timestamp))})) diff --git a/src/status_im/contexts/chat/messenger/messages/content/lightbox/view.cljs b/src/status_im/contexts/chat/messenger/messages/content/lightbox/view.cljs new file mode 100644 index 0000000000..247599bcfe --- /dev/null +++ b/src/status_im/contexts/chat/messenger/messages/content/lightbox/view.cljs @@ -0,0 +1,18 @@ +(ns status-im.contexts.chat.messenger.messages.content.lightbox.view + (:require + [oops.core :as oops] + [reagent.core :as reagent] + [status-im.common.lightbox.constants :as constants] + [status-im.contexts.chat.messenger.messages.content.lightbox.style :as style] + [status-im.contexts.chat.messenger.messages.content.text.view :as message-view])) + +(defn bottom-text-for-lightbox + [_] + (let [text-height (reagent/atom 0)] + (fn [{:keys [content chat-id] :as _message}] + (let [expandable-text? (> @text-height (* constants/line-height 2))] + [message-view/render-parsed-text + {:content content + :chat-id chat-id + :style-override (style/bottom-text expandable-text?) + :on-layout #(reset! text-height (oops/oget % "nativeEvent.layout.height"))}])))) diff --git a/src/status_im/contexts/wallet/collectible/view.cljs b/src/status_im/contexts/wallet/collectible/view.cljs index 0fcc27df67..c24ce1dfe4 100644 --- a/src/status_im/contexts/wallet/collectible/view.cljs +++ b/src/status_im/contexts/wallet/collectible/view.cljs @@ -75,12 +75,14 @@ (let [selected-tab (reagent/atom :overview) on-tab-change #(reset! selected-tab %)] (fn [] - (let [collectible (rf/sub [:wallet/last-collectible-details]) + (let [collectible (rf/sub [:wallet/last-collectible-details]) + animation-shared-element-id (rf/sub [:animation-shared-element-id]) {:keys [collectible-data preview-url - collection-data]} collectible + collection-data id]} collectible + token-id (:token-id id) {collection-image :image-url - collection-name :name} collection-data - {collectible-name :name} collectible-data] + collection-name :name} collection-data + {collectible-name :name} collectible-data] [scroll-page/scroll-page {:navigate-back? true :height 148 @@ -95,9 +97,26 @@ :picture preview-url}} [rn/view {:style style/container} [rn/view {:style style/preview-container} - [rn/image - {:source preview-url - :style style/preview}]] + [rn/touchable-opacity + {:active-opacity 1 + :on-press #(rf/dispatch [:lightbox/navigate-to-lightbox + token-id + {:images [{:image preview-url + :image-width 300 ; collectibles don't have + ; width/height but we need + ; to pass something + :image-height 300 ; without it animation + ; doesn't work smoothly and + ; :border-radius not + ; applied + :id token-id + :header collectible-name + :description collection-name}] + :index 0}])} + [rn/image + {:source preview-url + :style style/preview + :native-ID (when (= animation-shared-element-id token-id) :shared-element)}]]] [header collectible-name collection-name collection-image] [cta-buttons] [quo/tabs diff --git a/src/status_im/navigation/screens.cljs b/src/status_im/navigation/screens.cljs index 08eacb98e2..ddf4c7261b 100644 --- a/src/status_im/navigation/screens.cljs +++ b/src/status_im/navigation/screens.cljs @@ -2,13 +2,13 @@ (:require [legacy.status-im.ui.screens.screens :as old-screens] [status-im.common.emoji-picker.view :as emoji-picker] + [status-im.common.lightbox.view :as lightbox] [status-im.config :as config] [status-im.contexts.chat.group-details.view :as group-details] [status-im.contexts.chat.home.add-new-contact.scan.scan-profile-qr-page :as scan-profile-qr-page] [status-im.contexts.chat.home.add-new-contact.views :as add-new-contact] [status-im.contexts.chat.home.new-chat.view :as new-chat] [status-im.contexts.chat.messenger.camera.view :as camera-screen] - [status-im.contexts.chat.messenger.lightbox.view :as lightbox] [status-im.contexts.chat.messenger.messages.view :as chat] [status-im.contexts.chat.messenger.photo-selector.view :as photo-selector] [status-im.contexts.communities.actions.accounts-selection.view :as communities.accounts-selection] diff --git a/src/status_im/subs/root.cljs b/src/status_im/subs/root.cljs index 5af0344949..db168fe887 100644 --- a/src/status_im/subs/root.cljs +++ b/src/status_im/subs/root.cljs @@ -23,7 +23,7 @@ ;;view (reg-root-key-sub :view-id :view-id) (reg-root-key-sub :screen-params :navigation/screen-params) -(reg-root-key-sub :shared-element-id :shared-element-id) +(reg-root-key-sub :animation-shared-element-id :animation-shared-element-id) ;;bottom sheet (reg-root-key-sub :bottom-sheet :bottom-sheet)