import { useIsFocused, useRoute } from '@react-navigation/native' import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { Pressable, StyleSheet, Text, View } from 'react-native' import Carousel from 'react-native-reanimated-carousel' import { responsiveHeight } from 'react-native-responsive-dimensions' import { projectsRef } from '../../config/firebase' import useDataFromRef from '../../hooks/useDataFromRef' import usePlayer from '../../hooks/usePlayer' import PlaybackItem from './components/PlaybackItem' import PlaybackCharts from './components/PlaybackCharts' import { Palette } from '../../styles' import { FONT_FAMILY } from '../../styles/Fonts' const Playbacks = () => { const [activeIndex, setActiveIndex] = useState(0) const userCache = useRef(new Map()) const isFocused = useIsFocused() const wasFocusedRef = useRef(false) const route = useRoute() const { stop } = usePlayer() || {} const initialFocusProjectId = route?.params?.projectId || route?.params?.focusId || null const [focusProjectId, setFocusProjectId] = useState(initialFocusProjectId) const [viewMode, setViewMode] = useState(initialFocusProjectId ? 'feed' : 'charts') const { data: rawPlaybacks = [], loadMore } = useDataFromRef({ ref: projectsRef.where('playbackUrl', '!=', null), simpleRef: false, listener: false, usePagination: true, batchSize: 6, }) const focusIndex = useMemo(() => { if (!focusProjectId) return -1 return rawPlaybacks.findIndex((p) => p?.id === focusProjectId) }, [focusProjectId, rawPlaybacks]) const playbacks = useMemo(() => { if (focusIndex < 0) return rawPlaybacks const target = rawPlaybacks[focusIndex] const before = rawPlaybacks.slice(0, focusIndex) const after = rawPlaybacks.slice(focusIndex + 1) return [target, ...after, ...before] }, [focusIndex, rawPlaybacks]) const onSnap = useCallback( (index) => { setActiveIndex(index) if (index >= (playbacks?.length || 0) - 6) { loadMore?.() } }, [playbacks?.length, loadMore] ) const triedLoadMoreRef = useRef(0) const focusLoadAttemptsRef = useRef(0) const hasAppliedFocusRef = useRef(false) useEffect(() => { focusLoadAttemptsRef.current = 0 hasAppliedFocusRef.current = false if (!focusProjectId) { setActiveIndex(0) } }, [focusProjectId]) useEffect(() => { if (loadMore && triedLoadMoreRef.current < 6) { triedLoadMoreRef.current += 1 loadMore() } }, [loadMore, playbacks]) useEffect(() => { if (!focusProjectId) return if (focusIndex >= 0 && !hasAppliedFocusRef.current) { hasAppliedFocusRef.current = true setActiveIndex(0) return } if (loadMore && focusLoadAttemptsRef.current < 6) { focusLoadAttemptsRef.current += 1 loadMore() } }, [focusIndex, focusProjectId, loadMore, playbacks]) useEffect(() => { const nextFocusId = route?.params?.projectId || route?.params?.focusId || null setFocusProjectId(nextFocusId) if (nextFocusId) { setViewMode('feed') } }, [route?.params?.focusId, route?.params?.projectId]) useEffect(() => { if (isFocused && !wasFocusedRef.current) { stop?.().catch(() => {}) } wasFocusedRef.current = isFocused }, [isFocused, stop]) useEffect(() => { if (viewMode !== 'feed') { return } setActiveIndex(0) }, [viewMode]) const showFeed = viewMode === 'feed' const openFeedForPlayback = useCallback((project) => { const nextId = project && typeof project === 'object' ? project?.id || project?.projectId || null : project || null if (!nextId) { return } setFocusProjectId(nextId) setViewMode('feed') }, []) if (!showFeed) { return } return ( ( )} /> setViewMode('charts')} accessibilityLabel="Revenir au classement des playbacks" > Classement ) } export default Playbacks const styles = StyleSheet.create({ backToCharts: { position: 'absolute', top: 32, right: 20, paddingVertical: 8, paddingHorizontal: 12, borderRadius: 12, backgroundColor: 'rgba(0,0,0,0.55)', zIndex: 20, }, backToChartsText: { color: Palette.white, fontSize: 12, fontFamily: FONT_FAMILY.InterSemiBold, }, })