feat: playbacks leaderboard
This commit is contained in:
@@ -1,6 +1,14 @@
|
||||
import { useIsFocused, useRoute } from '@react-navigation/native'
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { FlatList, Image, Pressable, StyleSheet, View, useWindowDimensions } from 'react-native'
|
||||
import {
|
||||
FlatList,
|
||||
Image,
|
||||
Pressable,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
useWindowDimensions,
|
||||
} from 'react-native'
|
||||
import { icons } from '../../assets'
|
||||
import { projectsRef } from '../../config/firebase'
|
||||
import useDataFromRef from '../../hooks/useDataFromRef'
|
||||
@@ -8,12 +16,15 @@ import { useUser } from '../../providers/UserDataProvider'
|
||||
import { Palette } from '../../styles'
|
||||
import { FONT_FAMILY } from '../../styles/Fonts'
|
||||
import PlaybackItem from './components/PlaybackItem.web'
|
||||
import PlaybackCharts from './components/PlaybackCharts'
|
||||
|
||||
const Playbacks = () => {
|
||||
const { height: windowHeight } = useWindowDimensions()
|
||||
const [activeIndex, setActiveIndex] = useState(0)
|
||||
const route = useRoute()
|
||||
const focusProjectId = route?.params?.projectId || route?.params?.focusId || null
|
||||
const initialFocusProjectId = route?.params?.projectId || route?.params?.focusId || null
|
||||
const [focusProjectId, setFocusProjectId] = useState(initialFocusProjectId)
|
||||
const [viewMode, setViewMode] = useState(initialFocusProjectId ? 'feed' : 'charts')
|
||||
const userCache = useRef(new Map())
|
||||
const { getUserByUid } = useUser() || {}
|
||||
const isFocused = useIsFocused()
|
||||
@@ -44,9 +55,6 @@ const Playbacks = () => {
|
||||
|
||||
const activePlayback = playbacks?.[activeIndex] || null
|
||||
const activeVideoUrl = activePlayback?.playbackUrl || null
|
||||
const activeTitle = typeof activePlayback?.title === 'string' ? activePlayback.title.trim() : ''
|
||||
|
||||
const activeCreatorName = activePlayback?.userName
|
||||
const backgroundVideoRef = useRef(null)
|
||||
const lastActiveIndexRef = useRef(0)
|
||||
const backgroundSeekPendingRef = useRef(false)
|
||||
@@ -161,7 +169,6 @@ const Playbacks = () => {
|
||||
}
|
||||
}, [activeVideoUrl])
|
||||
|
||||
const triedLoadMoreRef = useRef(0)
|
||||
const hasAppliedFocusRef = useRef(false)
|
||||
const focusLoadAttemptsRef = useRef(0)
|
||||
|
||||
@@ -189,6 +196,27 @@ const Playbacks = () => {
|
||||
}
|
||||
}, [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 (viewMode !== 'feed') {
|
||||
return
|
||||
}
|
||||
lastActiveIndexRef.current = 0
|
||||
setActiveIndex(0)
|
||||
requestAnimationFrame(() => {
|
||||
try {
|
||||
listRef.current?.scrollToOffset?.({ offset: 0, animated: false })
|
||||
} catch (_e) {}
|
||||
})
|
||||
}, [viewMode])
|
||||
|
||||
// === FlatList (one real page per item) ===
|
||||
// keep active index in sync with scroll
|
||||
const onMomentumScrollEnd = useCallback(
|
||||
@@ -294,6 +322,24 @@ const Playbacks = () => {
|
||||
[activeIndex, handleActiveIndexChange, hasMore, loadMore, playbacks.length, windowHeight]
|
||||
)
|
||||
|
||||
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 <PlaybackCharts onPlaybackPress={openFeedForPlayback} />
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.screen}>
|
||||
{activeVideoUrl ? (
|
||||
@@ -396,6 +442,14 @@ const Playbacks = () => {
|
||||
</Pressable>
|
||||
</View>
|
||||
)}
|
||||
<Pressable
|
||||
style={styles.backToCharts}
|
||||
hitSlop={12}
|
||||
onPress={() => setViewMode('charts')}
|
||||
accessibilityLabel="Revenir au classement des playbacks"
|
||||
>
|
||||
<Text style={styles.backToChartsText}>Classement</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
// </Page>
|
||||
)
|
||||
@@ -505,4 +559,19 @@ const styles = StyleSheet.create({
|
||||
fontFamily: FONT_FAMILY.InterMedium,
|
||||
textAlign: 'center',
|
||||
},
|
||||
backToCharts: {
|
||||
position: 'absolute',
|
||||
top: 32,
|
||||
right: 24,
|
||||
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,
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user