feat: album selector animation (#16533)

* feat: album selector animation
This commit is contained in:
Omar Basem 2023-07-11 15:16:24 +04:00 committed by GitHub
parent 7350c88920
commit 704b160964
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 89 additions and 59 deletions

View File

@ -30,7 +30,7 @@
:right 0 :right 0
:top 0 :top 0
:height 20 :height 20
:z-index 1 :z-index 2
:position :absolute :position :absolute
:justify-content :center :justify-content :center
:align-items :center}) :align-items :center})

View File

@ -1,5 +1,17 @@
(ns status-im2.contexts.chat.photo-selector.album-selector.style (ns status-im2.contexts.chat.photo-selector.album-selector.style
(:require [quo2.foundations.colors :as colors])) (:require [quo2.foundations.colors :as colors]
[react-native.reanimated :as reanimated]))
(defn selector-container
[top]
(reanimated/apply-animations-to-style {:top top}
{:position :absolute
:z-index 1
:background-color (colors/theme-colors
colors/white
colors/neutral-100)
:left 0
:right 0}))
(defn album-container (defn album-container
[selected?] [selected?]

View File

@ -3,19 +3,21 @@
[quo2.core :as quo] [quo2.core :as quo]
[react-native.core :as rn] [react-native.core :as rn]
[react-native.gesture :as gesture] [react-native.gesture :as gesture]
[react-native.reanimated :as reanimated]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[utils.re-frame :as rf] [utils.re-frame :as rf]
[quo2.foundations.colors :as colors] [quo2.foundations.colors :as colors]
[status-im2.contexts.chat.photo-selector.album-selector.style :as style])) [status-im2.contexts.chat.photo-selector.album-selector.style :as style]))
(defn render-album (defn render-album
[{title :title size :count uri :uri} index _ {:keys [album? selected-album]}] [{title :title size :count uri :uri} index _ {:keys [album? selected-album top]}]
(let [selected? (= selected-album title)] (let [selected? (= selected-album title)]
[rn/touchable-opacity [rn/touchable-opacity
{:on-press (fn [] {:on-press (fn []
(rf/dispatch [:chat.ui/camera-roll-select-album title]) (rf/dispatch [:chat.ui/camera-roll-select-album title])
(rf/dispatch [:photo-selector/get-photos-for-selected-album]) (rf/dispatch [:photo-selector/get-photos-for-selected-album])
(reset! album? false)) (reanimated/animate top (:height (rn/get-window)))
(js/setTimeout #(reset! album? false) 300))
:style (style/album-container selected?) :style (style/album-container selected?)
:accessibility-label (str "album-" index)} :accessibility-label (str "album-" index)}
[rn/image [rn/image
@ -52,20 +54,27 @@
[item index] [item index]
(str (:title item) index)) (str (:title item) index))
(defn album-selector (defn- f-album-selector
[{:keys [scroll-enabled on-scroll]} album? selected-album] [{:keys [scroll-enabled on-scroll]} album? selected-album top]
(let [albums (rf/sub [:camera-roll/albums]) (let [albums (rf/sub [:camera-roll/albums])
albums-sections [{:title no-title :data (:smart-albums albums)} albums-sections [{:title no-title :data (:smart-albums albums)}
{:title (i18n/label :t/my-albums) :data (:my-albums albums)}]] {:title (i18n/label :t/my-albums) :data (:my-albums albums)}]
[gesture/section-list window-height (:height (rn/get-window))]
{:data albums-sections [reanimated/view {:style (style/selector-container top)}
:sections albums-sections [gesture/section-list
:render-data {:album? album? :selected-album selected-album} {:data albums-sections
:render-fn render-album :sections albums-sections
:sticky-section-headers-enabled false :render-data {:album? album? :selected-album selected-album :top top}
:render-section-header-fn section-header :render-fn render-album
:content-container-style {:padding-top 64 :sticky-section-headers-enabled false
:padding-bottom 40} :render-section-header-fn section-header
:key-fn key-fn :content-container-style {:padding-top 64
:scroll-enabled @scroll-enabled :padding-bottom 40}
:on-scroll on-scroll}])) :key-fn key-fn
:scroll-enabled @scroll-enabled
:on-scroll on-scroll
:style {:height window-height}}]]))
(defn album-selector
[sheet album? selected-album top]
[:f> f-album-selector sheet album? selected-album top])

View File

@ -1,6 +1,7 @@
(ns status-im2.contexts.chat.photo-selector.view (ns status-im2.contexts.chat.photo-selector.view
(:require (:require
[react-native.gesture :as gesture] [react-native.gesture :as gesture]
[react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area] [react-native.safe-area :as safe-area]
[react-native.platform :as platform] [react-native.platform :as platform]
[utils.i18n :as i18n] [utils.i18n :as i18n]
@ -96,43 +97,51 @@
sending-image (into [] (vals (rf/sub [:chats/sending-image]))) sending-image (into [] (vals (rf/sub [:chats/sending-image])))
selected-images (reagent/atom sending-image) selected-images (reagent/atom sending-image)
window-width (:width (rn/get-window))] window-width (:width (rn/get-window))]
(fn [] [:f>
(let [camera-roll-photos (rf/sub [:camera-roll/photos]) (fn []
end-cursor (rf/sub [:camera-roll/end-cursor]) (let [camera-roll-photos (rf/sub [:camera-roll/photos])
loading? (rf/sub [:camera-roll/loading-more]) end-cursor (rf/sub [:camera-roll/end-cursor])
has-next-page? (rf/sub [:camera-roll/has-next-page]) loading? (rf/sub [:camera-roll/loading-more])
selected-album (or (rf/sub [:camera-roll/selected-album]) (i18n/label :t/recent)) has-next-page? (rf/sub [:camera-roll/has-next-page])
blur-active? (> @current-scroll min-scroll-to-blur)] selected-album (or (rf/sub [:camera-roll/selected-album]) (i18n/label :t/recent))
[rn/view {:style {:flex 1 :margin-top -20}} blur-active? (> @current-scroll min-scroll-to-blur)
(if @album? window-height (:height (rn/get-window))
[album-selector/album-selector sheet album? selected-album] top (reanimated/use-shared-value window-height)]
[:<> [rn/view {:style {:flex 1 :margin-top -20}}
[gesture/flat-list (when @album?
{:key-fn identity [album-selector/album-selector sheet album? selected-album top])
:render-fn render-image [:<>
:render-data {:window-width window-width :selected selected-images} [gesture/flat-list
:data camera-roll-photos {:key-fn identity
:num-columns 3 :render-fn render-image
:content-container-style {:width "100%" :render-data {:window-width window-width :selected selected-images}
:padding-bottom (+ (safe-area/get-bottom) 100) :data camera-roll-photos
:padding-top 64} :num-columns 3
:on-scroll on-scroll :content-container-style {:width "100%"
:scroll-enabled @scroll-enabled :padding-bottom (+ (safe-area/get-bottom) 100)
:on-end-reached (fn [] :padding-top 64}
(when (and (not loading?) has-next-page?) :on-scroll on-scroll
(rf/dispatch [:photo-selector/camera-roll-loading-more true]) :scroll-enabled @scroll-enabled
(rf/dispatch [:photo-selector/get-photos-for-selected-album :on-end-reached (fn []
end-cursor])))}] (when (and (not loading?) has-next-page?)
[confirm-button @selected-images sending-image close]]) (rf/dispatch [:photo-selector/camera-roll-loading-more true])
[rn/view {:style style/buttons-container} (rf/dispatch [:photo-selector/get-photos-for-selected-album
[quo/dropdown end-cursor])))}]
{:type :blurred [confirm-button @selected-images sending-image close]]
:size 32 [rn/view {:style style/buttons-container}
:on-change (fn [] [quo/dropdown
(swap! album? not) {:type :blurred
(reset! current-scroll 0)) :size 32
:selected @album? :on-change (fn []
:blur-active? (and (not @album?) blur-active?) (if-not @album?
:override-background-color (when-not @album? :transparent)} (do
selected-album] (reset! album? true)
[clear-button @album? selected-images blur-active?]]])))) (reanimated/animate top 0))
(do
(reanimated/animate top window-height)
(js/setTimeout #(reset! album? false) 300))))
:selected @album?
:blur-active? (and (not @album?) blur-active?)
:override-background-color (when-not @album? :transparent)}
selected-album]
[clear-button @album? selected-images blur-active?]]]))]))