Lightbox refactoring (#16096)

* refactor: lightbox
This commit is contained in:
Omar Basem 2023-06-02 15:56:39 +04:00 committed by GitHub
parent b29d248a9b
commit c5e6bd790d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 94 additions and 66 deletions

View File

@ -15,24 +15,37 @@
[status-im2.contexts.chat.lightbox.constants :as constants] [status-im2.contexts.chat.lightbox.constants :as constants]
[utils.worklets.lightbox :as worklet])) [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 (defn effect
[{:keys [flat-list-ref scroll-index-lock?]} {:keys [opacity layout border]} index] [{:keys [flat-list-ref scroll-index-lock? timers]} {:keys [opacity layout border]} index]
(rn/use-effect (fn [] (rn/use-effect
(reagent/next-tick (fn [] (fn []
(when @flat-list-ref (reagent/next-tick (fn []
(.scrollToIndex ^js @flat-list-ref (when @flat-list-ref
#js {:animated false :index index})))) (.scrollToIndex ^js @flat-list-ref
(js/setTimeout (fn [] #js {:animated false :index index}))))
(anim/animate opacity 1) (swap! timers assoc
(anim/animate layout 0) :mount-animation
(anim/animate border 12)) (js/setTimeout (fn []
(if platform/ios? 250 100)) (anim/animate opacity 1)
(js/setTimeout #(reset! scroll-index-lock? false) 300) (anim/animate layout 0)
(fn [] (anim/animate border 12))
(rf/dispatch [:chat.ui/zoom-out-signal nil]) (if platform/ios? 250 100)))
(when platform/android? (swap! timers assoc :mount-index-lock (js/setTimeout #(reset! scroll-index-lock? false) 300))
(rf/dispatch [:chat.ui/lightbox-scale 1])))))) (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 (defn handle-orientation
[result {:keys [flat-list-ref]} {:keys [scroll-index]} animations] [result {:keys [flat-list-ref]} {:keys [scroll-index]} animations]
@ -102,7 +115,7 @@
(anim/animate opacity 0) (anim/animate opacity 0)
(rf/dispatch [:navigate-back])) (rf/dispatch [:navigate-back]))
(do (do
#(reset! set-full-height? true) (reset! set-full-height? true)
(anim/animate (if x? pan-x pan-y) 0) (anim/animate (if x? pan-x pan-y) 0)
(anim/animate opacity 1) (anim/animate opacity 1)
(anim/animate layout 0))))))) (anim/animate layout 0)))))))
@ -111,7 +124,8 @@
[] []
{:flat-list-ref (atom nil) {:flat-list-ref (atom nil)
:small-list-ref (atom nil) :small-list-ref (atom nil)
:scroll-index-lock? (atom true)}) :scroll-index-lock? (atom true)
:timers (atom {})})
(defn init-state (defn init-state
[messages index] [messages index]

View File

@ -88,7 +88,8 @@
:screen-width screen-width :screen-width screen-width
:window-height window-height :window-height window-height
:window-width window-width :window-width window-width
:props props} :props props
:curr-orientation curr-orientation}
:horizontal horizontal? :horizontal horizontal?
:inverted inverted? :inverted inverted?
:paging-enabled true :paging-enabled true
@ -113,7 +114,8 @@
(on-viewable-items-changed e props state))] (on-viewable-items-changed e props state))]
(anim/animate (:background-color animations) "rgba(0,0,0,1)") (anim/animate (:background-color animations) "rgba(0,0,0,1)")
(reset! (:data state) messages) (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) (utils/effect props animations index)
[:f> lightbox-content props state animations derived messages index callback])))) [:f> lightbox-content props state animations derived messages index callback]))))

View File

@ -107,23 +107,34 @@
(defn toggle-opacity (defn toggle-opacity
[index {:keys [opacity-value border-value transparent? props]} portrait?] [index {:keys [opacity-value border-value transparent? props]} portrait?]
(let [{:keys [small-list-ref]} props (let [{:keys [small-list-ref timers]} props
opacity (reanimated/get-shared-value opacity-value)] opacity (reanimated/get-shared-value opacity-value)]
(if (= opacity 1) (if (= opacity 1)
(do (do
(when platform/ios? (js/clearTimeout (:show-0 @timers))
;; status-bar issue: https://github.com/status-im/status-mobile/issues/15343 (js/clearTimeout (:show-1 @timers))
(js/setTimeout #(navigation/merge-options "lightbox" {:statusBar {:visible false}}) 75)) (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) (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 (do
(js/clearTimeout (:hide-0 @timers))
(js/clearTimeout (:hide-1 @timers))
(reset! transparent? (not @transparent?)) (reset! transparent? (not @transparent?))
(js/setTimeout #(anim/animate opacity-value 1) 50) (swap! timers assoc :show-0 (js/setTimeout #(anim/animate opacity-value 1) 50))
(js/setTimeout #(when @small-list-ref (swap! timers assoc
(.scrollToIndex ^js @small-list-ref #js {:animated false :index index})) :show-1
100) (js/setTimeout #(when @small-list-ref
(when (and platform/ios? portrait?) (.scrollToIndex ^js @small-list-ref #js {:animated false :index index}))
(js/setTimeout #(navigation/merge-options "lightbox" {:statusBar {:visible true}}) 150)))) 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)))) (anim/animate border-value (if (= opacity 1) 0 12))))
;;; Dimensions ;;; Dimensions

View File

@ -228,36 +228,35 @@
:style (style/image dimensions animations (:border-value render-data))}]]])) :style (style/image dimensions animations (:border-value render-data))}]]]))
(defn zoomable-image (defn zoomable-image
[{:keys [image-width image-height content message-id]} index render-data] []
(let [state (utils/init-state) (let [state (utils/init-state)]
shared-element-id (rf/sub [:shared-element-id]) (fn [{:keys [image-width image-height content message-id]} index render-data]
exit-lightbox-signal (rf/sub [:lightbox/exit-signal]) (let [shared-element-id (rf/sub [:shared-element-id])
zoom-out-signal (rf/sub [:lightbox/zoom-out-signal]) exit-lightbox-signal (rf/sub [:lightbox/exit-signal])
curr-orientation (or (rf/sub [:lightbox/orientation]) zoom-out-signal (rf/sub [:lightbox/zoom-out-signal])
orientation/portrait) {:keys [set-full-height? curr-orientation]} render-data
{:keys [set-full-height?]} render-data focused? (= shared-element-id message-id)
focused? (= shared-element-id message-id) dimensions (utils/get-dimensions
dimensions (utils/get-dimensions (or image-width c/default-dimension)
(or image-width c/default-dimension) (or image-height c/default-duration)
(or image-height c/default-duration) curr-orientation
curr-orientation render-data)
render-data) animations (utils/init-animations)
animations (utils/init-animations) rescale (fn [value exit?]
rescale (fn [value exit?] (utils/rescale-image value
(utils/rescale-image value exit?
exit? dimensions
dimensions animations
animations state))]
state))] (rn/use-effect (fn []
(rn/use-effect (fn [] (js/setTimeout (fn [] (reset! set-full-height? true)) 500)))
(js/setTimeout #(reset! set-full-height? true) 500))) (when platform/ios?
(when platform/ios? (utils/handle-orientation-change curr-orientation focused? dimensions animations state)
(utils/handle-orientation-change curr-orientation focused? dimensions animations state) (utils/handle-exit-lightbox-signal exit-lightbox-signal
(utils/handle-exit-lightbox-signal exit-lightbox-signal index
index (anim/get-val (:scale animations))
(anim/get-val (:scale animations)) rescale
rescale set-full-height?))
set-full-height?)) (utils/handle-zoom-out-signal zoom-out-signal index (anim/get-val (:scale animations)) rescale)
(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 content focused? index render-data]))))
index render-data]))

View File

@ -105,7 +105,9 @@
:translucent true} :translucent true}
:navigationBar {:backgroundColor colors/black} :navigationBar {:backgroundColor colors/black}
:layout {:componentBackgroundColor :transparent :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 :animations {:push {:sharedElementTransitions [{:fromId :shared-element
:toId :shared-element :toId :shared-element
:interpolation {:type :decelerate :interpolation {:type :decelerate