Update progress on swiping carousel. (#16154)

* Update progress on swiping carousel.

* Fixed feedbacks.
This commit is contained in:
Rahul Pratap 2023-06-09 17:53:06 +05:30 committed by GitHub
parent 83b35f0439
commit 573115c22e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 105 additions and 37 deletions

View File

@ -31,7 +31,7 @@
:source (resources/get-image :onboarding-illustration)}]) :source (resources/get-image :onboarding-illustration)}])
(defonce progress (atom nil)) (defonce progress (atom nil))
(defonce paused (atom nil)) (defonce paused? (atom nil))
(defn store-screen-height (defn store-screen-height
[evt] [evt]
@ -60,14 +60,14 @@
animate? (not dark-overlay?) animate? (not dark-overlay?)
window-width (rf/sub [:dimensions/window-width])] window-width (rf/sub [:dimensions/window-width])]
(when animate? (when animate?
(carousel.animation/use-initialize-animation progress paused animate?)) (carousel.animation/use-initialize-animation progress paused? animate?))
(rn/use-effect (rn/use-effect
(fn [] (fn []
(reanimated/set-shared-value @paused (not= view-id :intro)) (reanimated/set-shared-value @paused? (not= view-id :intro))
(fn [] (fn []
(when (= view-id :generating-keys) (when (= view-id :generating-keys)
(carousel.animation/cleanup-animation progress paused)))) (carousel.animation/cleanup-animation progress paused?))))
[view-id]) [view-id])
[rn/view [rn/view
@ -76,8 +76,10 @@
[carousel/view [carousel/view
{:animate? animate? {:animate? animate?
:progress progress :progress progress
:paused? paused?
:header-text header-text :header-text header-text
:header-background true :header-background true
:swipeable? true
:background [background-image (* 4 window-width)]}] :background [background-image (* 4 window-width)]}]
(when dark-overlay? (when dark-overlay?
[blur/view [blur/view

View File

@ -2,34 +2,76 @@
(:require (:require
[react-native.core :as rn] [react-native.core :as rn]
[react-native.reanimated :as reanimated] [react-native.reanimated :as reanimated]
[utils.worklets.onboarding-carousel :as worklets.onboarding-carousel])) [utils.worklets.onboarding-carousel :as worklets.onboarding-carousel]
[react-native.gesture :as gesture]
[oops.core :as oops]))
(def ^:const progress-bar-animation-delay 300) (def ^:const progress-bar-animation-delay 300)
(def ^:const progress-bar-animation-duration 4000) (def ^:const progress-bar-animation-duration 4000)
(def ^:const initial-division-quotient 5)
(def ^:const progress-threshold 25)
(def ^:const drag-limit 100)
(defn slide-animation (defn slide-animation
[progress-percentage & [delay duration]] [progress-percentage & [duration]]
(reanimated/with-delay (reanimated/with-delay
(or delay progress-bar-animation-delay) progress-bar-animation-delay
(reanimated/with-timing (reanimated/with-timing
progress-percentage progress-percentage
(js-obj "duration" (or duration progress-bar-animation-duration) (js-obj "duration" (or duration progress-bar-animation-duration)
"easing" (:linear reanimated/easings))))) "easing" (:linear reanimated/easings)))))
(defn calculate-remainder
[dividend divisor]
(if (and (pos-int? dividend) (zero? (mod dividend divisor)))
divisor
(mod dividend divisor)))
(defn animation-value
[q index]
(let [next-quotient (+ q index)
dividend (if (>= next-quotient initial-division-quotient)
(* (- next-quotient initial-division-quotient) progress-threshold)
(* next-quotient progress-threshold))]
(calculate-remainder dividend drag-limit)))
(defn animate-progress-value
[value]
(if (zero? value) (slide-animation value 0) (slide-animation value)))
(defn animate-progress (defn animate-progress
[progress paused] [progress paused next-progress]
(let [q (quot next-progress 25)]
(reanimated/set-shared-value (reanimated/set-shared-value
progress progress
(reanimated/with-pause (reanimated/with-pause
(reanimated/with-repeat (reanimated/with-repeat
(reanimated/with-sequence (reanimated/with-sequence
(slide-animation 25) (animate-progress-value (animation-value q 1))
(slide-animation 50) (animate-progress-value (animation-value q 2))
(slide-animation 75) (animate-progress-value (animation-value q 3))
(slide-animation 100) (animate-progress-value (animation-value q 4))
(slide-animation 0 300 0)) (animate-progress-value (calculate-remainder next-progress drag-limit)))
-1) -1)
paused))) paused))))
(defn get-next-progress
[progress]
(let [current-progress (reanimated/get-shared-value @progress)]
(if (>= current-progress drag-limit)
drag-limit
(-> (quot current-progress progress-threshold)
(+ 1)
(* progress-threshold)))))
(defn get-previous-progress
[progress]
(let [current-progress (reanimated/get-shared-value @progress)]
(if (< current-progress progress-threshold)
0
(-> (quot current-progress progress-threshold)
(- 1)
(* progress-threshold)))))
(defn use-initialize-animation (defn use-initialize-animation
[progress paused animate?] [progress paused animate?]
@ -37,7 +79,7 @@
(reset! paused (reanimated/use-shared-value false)) (reset! paused (reanimated/use-shared-value false))
(rn/use-effect (rn/use-effect
(fn [] (fn []
(animate-progress @progress @paused)) (animate-progress @progress @paused 0))
[animate?])) [animate?]))
(defn cleanup-animation (defn cleanup-animation
@ -46,6 +88,26 @@
(reanimated/cancel-animation @progress) (reanimated/cancel-animation @progress)
(reanimated/cancel-animation @paused))) (reanimated/cancel-animation @paused)))
(defn update-progress
[progress paused new-progress]
(reanimated/set-shared-value @progress new-progress)
(animate-progress @progress @paused new-progress))
(defn drag-gesture
[progress paused]
(->
(gesture/gesture-pan)
(gesture/enabled true)
(gesture/max-pointers 1)
(gesture/on-finalize
(fn [event]
(let [next? (< (oops/oget event "translationX") (- drag-limit))
previous? (> (oops/oget event "translationX") drag-limit)]
(when next?
(update-progress progress paused (get-next-progress progress)))
(when previous?
(update-progress progress paused (get-previous-progress progress))))))))
(defn carousel-left-position (defn carousel-left-position
[window-width animate? progress] [window-width animate? progress]
(if animate? (if animate?

View File

@ -5,7 +5,8 @@
[react-native.navigation :as navigation] [react-native.navigation :as navigation]
[react-native.reanimated :as reanimated] [react-native.reanimated :as reanimated]
[status-im2.contexts.onboarding.common.carousel.style :as style] [status-im2.contexts.onboarding.common.carousel.style :as style]
[status-im2.contexts.onboarding.common.carousel.animation :as animation])) [status-im2.contexts.onboarding.common.carousel.animation :as animation]
[react-native.gesture :as gesture]))
(defn header-text-view (defn header-text-view
[index window-width header-text] [index window-width header-text]
@ -49,13 +50,15 @@
:progress-bar-width progress-bar-width}]])) :progress-bar-width progress-bar-width}]]))
(defn f-view (defn f-view
[{:keys [animate? progress header-text background header-background]}] [{:keys [animate? progress paused? header-text background header-background swipeable?]}]
(let [window-width (rf/sub [:dimensions/window-width]) (let [window-width (rf/sub [:dimensions/window-width])
status-bar-height (:status-bar-height @navigation/constants) status-bar-height (:status-bar-height @navigation/constants)
progress-bar-width (- window-width 40) progress-bar-width (- window-width 40)
carousel-left (animation/carousel-left-position window-width animate? progress) carousel-left (animation/carousel-left-position window-width animate? progress)
container-view (if animate? reanimated/view rn/view)] container-view (if animate? reanimated/view rn/view)]
[:<> [:<>
[gesture/gesture-detector
{:gesture (when swipeable? (animation/drag-gesture progress paused?))}
[container-view {:style (style/carousel-container carousel-left animate?)} [container-view {:style (style/carousel-container carousel-left animate?)}
(for [index (range 2)] (for [index (range 2)]
^{:key index} ^{:key index}
@ -65,7 +68,7 @@
:index index :index index
:header-text header-text :header-text header-text
:header-background header-background} :header-background header-background}
(when background background)])] (when background background)])]]
[rn/view [rn/view
{:style (style/progress-bar-container {:style (style/progress-bar-container
progress-bar-width progress-bar-width
@ -79,4 +82,3 @@
:progress progress}]]])) :progress progress}]]]))
(defn view [props] [:f> f-view props]) (defn view [props] [:f> f-view props])

View File

@ -23,16 +23,16 @@
(defn f-view (defn f-view
[] []
(let [progress (atom nil) (let [progress (atom nil)
paused (atom nil) paused? (atom nil)
{:keys [emoji-hash display-name compressed-key {:keys [emoji-hash display-name compressed-key
public-key]} (rf/sub [:multiaccount]) public-key]} (rf/sub [:multiaccount])
{:keys [color]} (rf/sub [:onboarding-2/profile]) {:keys [color]} (rf/sub [:onboarding-2/profile])
photo-path (rf/sub [:chats/photo-path public-key]) photo-path (rf/sub [:chats/photo-path public-key])
emoji-string (string/join emoji-hash)] emoji-string (string/join emoji-hash)]
(carousel.animation/use-initialize-animation progress paused true) (carousel.animation/use-initialize-animation progress paused? true)
(rn/use-effect (rn/use-effect
(fn [] (fn []
(carousel.animation/cleanup-animation progress paused)) (carousel.animation/cleanup-animation progress paused?))
[]) [])
[:<> [:<>
[background/view true] [background/view true]
@ -40,6 +40,8 @@
[carousel/view [carousel/view
{:animate? true {:animate? true
:progress progress :progress progress
:paused? paused?
:swipeable? false
:header-text header-text}] :header-text header-text}]
[rn/view {:style style/content-container} [rn/view {:style style/content-container}
[quo/profile-card [quo/profile-card