From bd26a2fb29ee74b862394dd2d2dfa5d82e2a8516 Mon Sep 17 00:00:00 2001 From: leon-morival Date: Thu, 23 Oct 2025 15:15:32 +0200 Subject: [PATCH] scroll indactor playbacks web --- src/screens/Playbacks/Playbacks.web.js | 162 +++++++++++++++++++++++- src/screens/Production/DownloadSongs.js | 2 +- 2 files changed, 160 insertions(+), 4 deletions(-) diff --git a/src/screens/Playbacks/Playbacks.web.js b/src/screens/Playbacks/Playbacks.web.js index b1aa4a1..3878187 100644 --- a/src/screens/Playbacks/Playbacks.web.js +++ b/src/screens/Playbacks/Playbacks.web.js @@ -1,6 +1,19 @@ import { useIsFocused, useRoute } from "@react-navigation/native"; -import React, { useCallback, useEffect, useRef, useState } from "react"; -import { FlatList, StyleSheet, View, useWindowDimensions } from "react-native"; +import React, { + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from "react"; +import { + FlatList, + Image, + StyleSheet, + View, + useWindowDimensions, +} from "react-native"; +import { icons } from "../../assets"; import { projectsRef } from "../../config/firebase"; import useDataFromRef from "../../hooks/useDataFromRef"; import { useUser } from "../../providers/UserDataProvider"; @@ -17,7 +30,12 @@ const Playbacks = () => { const userCache = useRef(new Map()); const { getUserByUid } = useUser() || {}; const isFocused = useIsFocused(); - const { data: playbacks = [], loadMore } = useDataFromRef({ + const { + data: playbacks = [], + loadMore, + hasMore, + loading, + } = useDataFromRef({ ref: projectsRef.where("playbackUrl", "!=", null), simpleRef: false, listener: false, @@ -213,6 +231,47 @@ const Playbacks = () => { [windowHeight] ); + const total = playbacks.length; + const indicatorItems = useMemo(() => { + if (total <= 0) return []; + const maxVisible = 7; + let start = 0; + let end = total - 1; + if (total > maxVisible) { + const half = Math.floor(maxVisible / 2); + start = activeIndex - half; + end = start + maxVisible - 1; + if (start < 0) { + end += -start; + start = 0; + } + if (end >= total) { + const overshoot = end - (total - 1); + start = Math.max(0, start - overshoot); + end = total - 1; + } + } + const items = []; + for (let i = start; i <= end; i += 1) { + items.push({ + key: `indicator-${i}`, + isActive: i === activeIndex, + isPast: i < activeIndex, + }); + } + return items; + }, [total, activeIndex]); + + const canScrollUp = total > 0 && activeIndex > 0; + const atLastLoaded = total > 0 && activeIndex >= total - 1; + const canScrollDown = total > 0 && (!atLastLoaded || hasMore); + const showIndicators = total > 0; + const indicatorLabel = useMemo(() => { + if (total <= 0) return null; + if (hasMore || loading) return `${activeIndex + 1}+`; + return `${activeIndex + 1}/${total}`; + }, [total, activeIndex, hasMore, loading]); + return ( {activeVideoUrl ? ( @@ -264,6 +323,50 @@ const Playbacks = () => { onScroll={onScroll} scrollEventThrottle={16} /> + {showIndicators && ( + + + + {indicatorItems.map((item, index) => ( + + ))} + {canScrollDown && hasMore && ( + + )} + + {/* {indicatorLabel ? ( + {indicatorLabel} + ) : null} */} + + + )} // ); @@ -319,4 +422,57 @@ const styles = StyleSheet.create({ fontFamily: FONT_FAMILY.InterMedium, opacity: 0.9, }, + indicatorContainer: { + position: "absolute", + left: 20, + top: 0, + bottom: 0, + justifyContent: "center", + alignItems: "center", + gap: 16, + }, + indicatorArrow: { + width: 20, + height: 20, + tintColor: Palette.white, + opacity: 0.8, + }, + indicatorArrowUp: { + transform: [{ rotate: "180deg" }], + }, + indicatorArrowDisabled: { + opacity: 0.25, + }, + indicatorDotsWrapper: { + alignItems: "center", + }, + indicatorDot: { + width: 6, + height: 12, + borderRadius: 3, + backgroundColor: "rgba(255,255,255,0.3)", + }, + indicatorDotPast: { + backgroundColor: "rgba(255,255,255,0.55)", + }, + indicatorDotActive: { + backgroundColor: Palette.white, + height: 20, + }, + indicatorDotSpacing: { + marginVertical: 5, + }, + indicatorMoreDot: { + width: 4, + height: 4, + borderRadius: 2, + backgroundColor: Palette.white, + opacity: 0.7, + }, + indicatorLabel: { + color: Palette.white, + fontSize: 12, + fontFamily: FONT_FAMILY.InterMedium, + textAlign: "center", + }, }); diff --git a/src/screens/Production/DownloadSongs.js b/src/screens/Production/DownloadSongs.js index 72937f4..0e1c24b 100644 --- a/src/screens/Production/DownloadSongs.js +++ b/src/screens/Production/DownloadSongs.js @@ -43,7 +43,7 @@ const uploadSourceRecording = async ({ uri, uid, projectId }) => { const extension = guessExtension(uri); const sourcePath = `users/${uid}/projects/${projectId}/recordings/source-${Date.now()}.${extension}`; - + console.log("source path : ", sourcePath); console.log("[DownloadSongs] uploadSourceRecording source path", { extension, sourcePath,