From c5e6bd790d1df1a9babfee319ff6e3d0e6ab425e Mon Sep 17 00:00:00 2001 From: Omar Basem Date: Fri, 2 Jun 2023 15:56:39 +0400 Subject: [PATCH] Lightbox refactoring (#16096) * refactor: lightbox --- .../contexts/chat/lightbox/utils.cljs | 50 +++++++++----- .../contexts/chat/lightbox/view.cljs | 6 +- .../chat/lightbox/zoomable_image/utils.cljs | 35 ++++++---- .../chat/lightbox/zoomable_image/view.cljs | 65 +++++++++---------- src/status_im2/navigation/options.cljs | 4 +- 5 files changed, 94 insertions(+), 66 deletions(-) diff --git a/src/status_im2/contexts/chat/lightbox/utils.cljs b/src/status_im2/contexts/chat/lightbox/utils.cljs index 7a96899851..07af95e8de 100644 --- a/src/status_im2/contexts/chat/lightbox/utils.cljs +++ b/src/status_im2/contexts/chat/lightbox/utils.cljs @@ -15,24 +15,37 @@ [status-im2.contexts.chat.lightbox.constants :as constants] [utils.worklets.lightbox :as worklet])) +(defn clear-timers + [timers] + (js/clearTimeout (:mount-animation @timers)) + (js/clearTimeout (:mount-index-lock @timers)) + (js/clearTimeout (:hide-0 @timers)) + (js/clearTimeout (:hide-1 @timers)) + (js/clearTimeout (:show-0 @timers)) + (js/clearTimeout (:show-1 @timers)) + (js/clearTimeout (:show-2 @timers))) (defn effect - [{:keys [flat-list-ref scroll-index-lock?]} {:keys [opacity layout border]} index] - (rn/use-effect (fn [] - (reagent/next-tick (fn [] - (when @flat-list-ref - (.scrollToIndex ^js @flat-list-ref - #js {:animated false :index index})))) - (js/setTimeout (fn [] - (anim/animate opacity 1) - (anim/animate layout 0) - (anim/animate border 12)) - (if platform/ios? 250 100)) - (js/setTimeout #(reset! scroll-index-lock? false) 300) - (fn [] - (rf/dispatch [:chat.ui/zoom-out-signal nil]) - (when platform/android? - (rf/dispatch [:chat.ui/lightbox-scale 1])))))) + [{:keys [flat-list-ref scroll-index-lock? timers]} {:keys [opacity layout border]} index] + (rn/use-effect + (fn [] + (reagent/next-tick (fn [] + (when @flat-list-ref + (.scrollToIndex ^js @flat-list-ref + #js {:animated false :index index})))) + (swap! timers assoc + :mount-animation + (js/setTimeout (fn [] + (anim/animate opacity 1) + (anim/animate layout 0) + (anim/animate border 12)) + (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]) + (when platform/android? + (rf/dispatch [:chat.ui/lightbox-scale 1])) + (clear-timers timers))))) (defn handle-orientation [result {:keys [flat-list-ref]} {:keys [scroll-index]} animations] @@ -102,7 +115,7 @@ (anim/animate opacity 0) (rf/dispatch [:navigate-back])) (do - #(reset! set-full-height? true) + (reset! set-full-height? true) (anim/animate (if x? pan-x pan-y) 0) (anim/animate opacity 1) (anim/animate layout 0))))))) @@ -111,7 +124,8 @@ [] {:flat-list-ref (atom nil) :small-list-ref (atom nil) - :scroll-index-lock? (atom true)}) + :scroll-index-lock? (atom true) + :timers (atom {})}) (defn init-state [messages index] diff --git a/src/status_im2/contexts/chat/lightbox/view.cljs b/src/status_im2/contexts/chat/lightbox/view.cljs index f311b91490..8906835073 100644 --- a/src/status_im2/contexts/chat/lightbox/view.cljs +++ b/src/status_im2/contexts/chat/lightbox/view.cljs @@ -88,7 +88,8 @@ :screen-width screen-width :window-height window-height :window-width window-width - :props props} + :props props + :curr-orientation curr-orientation} :horizontal horizontal? :inverted inverted? :paging-enabled true @@ -113,7 +114,8 @@ (on-viewable-items-changed e props state))] (anim/animate (:background-color animations) "rgba(0,0,0,1)") (reset! (:data state) messages) - (utils/orientation-change props state animations) + (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])))) 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 5077a43e3b..639bec5176 100644 --- a/src/status_im2/contexts/chat/lightbox/zoomable_image/utils.cljs +++ b/src/status_im2/contexts/chat/lightbox/zoomable_image/utils.cljs @@ -107,23 +107,34 @@ (defn toggle-opacity [index {:keys [opacity-value border-value transparent? props]} portrait?] - (let [{:keys [small-list-ref]} props - opacity (reanimated/get-shared-value opacity-value)] + (let [{:keys [small-list-ref timers]} props + opacity (reanimated/get-shared-value opacity-value)] (if (= opacity 1) (do - (when platform/ios? - ;; status-bar issue: https://github.com/status-im/status-mobile/issues/15343 - (js/setTimeout #(navigation/merge-options "lightbox" {:statusBar {:visible false}}) 75)) + (js/clearTimeout (:show-0 @timers)) + (js/clearTimeout (:show-1 @timers)) + (js/clearTimeout (:show-2 @timers)) + (swap! timers assoc + :hide-0 + (js/setTimeout #(navigation/merge-options "lightbox" {:statusBar {:visible false}}) + (if platform/ios? 75 0))) (anim/animate opacity-value 0) - (js/setTimeout #(reset! transparent? (not @transparent?)) 400)) + (swap! timers assoc :hide-1 (js/setTimeout #(reset! transparent? (not @transparent?)) 400))) (do + (js/clearTimeout (:hide-0 @timers)) + (js/clearTimeout (:hide-1 @timers)) (reset! transparent? (not @transparent?)) - (js/setTimeout #(anim/animate opacity-value 1) 50) - (js/setTimeout #(when @small-list-ref - (.scrollToIndex ^js @small-list-ref #js {:animated false :index index})) - 100) - (when (and platform/ios? portrait?) - (js/setTimeout #(navigation/merge-options "lightbox" {:statusBar {:visible true}}) 150)))) + (swap! timers assoc :show-0 (js/setTimeout #(anim/animate opacity-value 1) 50)) + (swap! timers assoc + :show-1 + (js/setTimeout #(when @small-list-ref + (.scrollToIndex ^js @small-list-ref #js {:animated false :index index})) + 100)) + (when portrait? + (swap! timers assoc + :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)))) ;;; Dimensions diff --git a/src/status_im2/contexts/chat/lightbox/zoomable_image/view.cljs b/src/status_im2/contexts/chat/lightbox/zoomable_image/view.cljs index c6abced6f7..e492b55e54 100644 --- a/src/status_im2/contexts/chat/lightbox/zoomable_image/view.cljs +++ b/src/status_im2/contexts/chat/lightbox/zoomable_image/view.cljs @@ -228,36 +228,35 @@ :style (style/image dimensions animations (:border-value render-data))}]]])) (defn zoomable-image - [{:keys [image-width image-height content message-id]} index render-data] - (let [state (utils/init-state) - shared-element-id (rf/sub [:shared-element-id]) - exit-lightbox-signal (rf/sub [:lightbox/exit-signal]) - zoom-out-signal (rf/sub [:lightbox/zoom-out-signal]) - curr-orientation (or (rf/sub [:lightbox/orientation]) - orientation/portrait) - {:keys [set-full-height?]} render-data - focused? (= shared-element-id message-id) - dimensions (utils/get-dimensions - (or image-width c/default-dimension) - (or image-height c/default-duration) - curr-orientation - render-data) - animations (utils/init-animations) - rescale (fn [value exit?] - (utils/rescale-image value - exit? - dimensions - animations - state))] - (rn/use-effect (fn [] - (js/setTimeout #(reset! set-full-height? true) 500))) - (when platform/ios? - (utils/handle-orientation-change curr-orientation focused? dimensions animations state) - (utils/handle-exit-lightbox-signal exit-lightbox-signal - index - (anim/get-val (:scale animations)) - 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? - index render-data])) + [] + (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]) + 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) + dimensions (utils/get-dimensions + (or image-width c/default-dimension) + (or image-height c/default-duration) + curr-orientation + render-data) + animations (utils/init-animations) + rescale (fn [value exit?] + (utils/rescale-image value + exit? + dimensions + animations + state))] + (rn/use-effect (fn [] + (js/setTimeout (fn [] (reset! set-full-height? true)) 500))) + (when platform/ios? + (utils/handle-orientation-change curr-orientation focused? dimensions animations state) + (utils/handle-exit-lightbox-signal exit-lightbox-signal + index + (anim/get-val (:scale animations)) + 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? + index render-data])))) diff --git a/src/status_im2/navigation/options.cljs b/src/status_im2/navigation/options.cljs index 25122e980b..6570da712e 100644 --- a/src/status_im2/navigation/options.cljs +++ b/src/status_im2/navigation/options.cljs @@ -105,7 +105,9 @@ :translucent true} :navigationBar {:backgroundColor colors/black} :layout {:componentBackgroundColor :transparent - :backgroundColor :transparent} + :backgroundColor :transparent + ;; issue: https://github.com/wix/react-native-navigation/issues/7726 + :orientation (if platform/ios? ["portrait" "landscape"] ["portrait"])} :animations {:push {:sharedElementTransitions [{:fromId :shared-element :toId :shared-element :interpolation {:type :decelerate