feat: fix player
This commit is contained in:
@@ -15,7 +15,7 @@ import { responsiveHeight, responsiveWidth } from 'react-native-responsive-dimen
|
||||
import { useGlobal } from 'reactn'
|
||||
import { background, icons } from '../../assets'
|
||||
import PressableScale from '../../components/PressableScale'
|
||||
import Slider from '../../components/Slider'
|
||||
import ProgressSlider from '../../components/player/ProgressSlider'
|
||||
import { arrayRemove, arrayUnion, increment, projectsRef, usersRef } from '../../config/firebase'
|
||||
import useDataFromRef from '../../hooks/useDataFromRef'
|
||||
import usePlayer from '../../hooks/usePlayer'
|
||||
@@ -44,9 +44,6 @@ const MusicDetails = ({ route }) => {
|
||||
const projectId = params?.projectId || null
|
||||
const [fav, setFav] = useState(false)
|
||||
const [currentUID] = useGlobal('currentUID')
|
||||
const wasPlayingBeforeSeek = useRef(false)
|
||||
const hasCapturedSeekStateRef = useRef(false)
|
||||
const lastSeekTargetMsRef = useRef(null)
|
||||
const listenedMsRef = useRef(0)
|
||||
const incrementDoneRef = useRef(false)
|
||||
const timerRef = useRef(null)
|
||||
@@ -274,15 +271,6 @@ const MusicDetails = ({ route }) => {
|
||||
return clearTimer
|
||||
}, [isTrackPlaying, projectId])
|
||||
|
||||
const fmt = (ms) => {
|
||||
const total = Math.max(0, Math.floor((ms || 0) / 1000))
|
||||
const m = Math.floor(total / 60)
|
||||
.toString()
|
||||
.padStart(1, '0')
|
||||
const s = (total % 60).toString().padStart(2, '0')
|
||||
return `${m}:${s}`
|
||||
}
|
||||
|
||||
const togglePlay = useCallback(async () => {
|
||||
if (!trackDescriptor) return
|
||||
try {
|
||||
@@ -308,42 +296,26 @@ const MusicDetails = ({ route }) => {
|
||||
resumeTrack,
|
||||
])
|
||||
|
||||
const handleSliderSeekStart = useCallback(async () => {
|
||||
const handleSliderSeekStart = useCallback(() => {
|
||||
if (!trackDescriptor) return
|
||||
lastSeekTargetMsRef.current = null
|
||||
if (!hasCapturedSeekStateRef.current) {
|
||||
hasCapturedSeekStateRef.current = true
|
||||
wasPlayingBeforeSeek.current = isTrackPlaying
|
||||
}
|
||||
try {
|
||||
if (!isCurrentTrack) {
|
||||
await ensureLoaded({ startPositionMs: positionMs, autoPlay: false })
|
||||
}
|
||||
if (isTrackPlaying) {
|
||||
await pauseTrack()
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('MusicDetails seek start error', e?.message)
|
||||
}
|
||||
}, [trackDescriptor, isTrackPlaying, isCurrentTrack, ensureLoaded, positionMs, pauseTrack])
|
||||
}, [trackDescriptor])
|
||||
|
||||
const handleSliderSeek = useCallback(
|
||||
async (ratio) => {
|
||||
async (targetMs) => {
|
||||
const dur = sliderDurationMs || 0
|
||||
if (!trackDescriptor || dur <= 0) return
|
||||
const targetMs = Math.max(0, Math.floor(dur * ratio))
|
||||
lastSeekTargetMsRef.current = targetMs
|
||||
const bounded = Math.max(0, Math.min(dur, Math.floor(targetMs)))
|
||||
try {
|
||||
if (!isCurrentTrack) {
|
||||
await ensureLoaded({ startPositionMs: targetMs, autoPlay: false })
|
||||
await ensureLoaded({ startPositionMs: bounded, autoPlay: false })
|
||||
} else {
|
||||
await seekTrackTo(targetMs)
|
||||
await seekTrackTo(bounded)
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('MusicDetails seek error', e?.message)
|
||||
}
|
||||
},
|
||||
[sliderDurationMs, trackDescriptor, isCurrentTrack, ensureLoaded, seekTrackTo]
|
||||
[trackDescriptor, sliderDurationMs, isCurrentTrack, ensureLoaded, seekTrackTo]
|
||||
)
|
||||
|
||||
const handleToggleLoop = useCallback(async () => {
|
||||
@@ -392,34 +364,6 @@ const MusicDetails = ({ route }) => {
|
||||
resumeTrack,
|
||||
])
|
||||
|
||||
const handleSliderSeekEnd = useCallback(async () => {
|
||||
const targetMs =
|
||||
typeof lastSeekTargetMsRef.current === 'number'
|
||||
? Math.max(0, lastSeekTargetMsRef.current)
|
||||
: null
|
||||
try {
|
||||
if (wasPlayingBeforeSeek.current) {
|
||||
if (!isCurrentTrack) {
|
||||
await ensureLoaded({
|
||||
startPositionMs: targetMs !== null && Number.isFinite(targetMs) ? targetMs : positionMs,
|
||||
autoPlay: true,
|
||||
})
|
||||
} else {
|
||||
if (targetMs !== null && Number.isFinite(targetMs)) {
|
||||
await seekTrackTo(targetMs)
|
||||
}
|
||||
await resumeTrack()
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('MusicDetails seek end error', e?.message)
|
||||
} finally {
|
||||
wasPlayingBeforeSeek.current = false
|
||||
hasCapturedSeekStateRef.current = false
|
||||
lastSeekTargetMsRef.current = null
|
||||
}
|
||||
}, [ensureLoaded, isCurrentTrack, positionMs, resumeTrack, seekTrackTo])
|
||||
|
||||
const handleSeekBySeconds = useCallback(
|
||||
async (deltaSeconds) => {
|
||||
if (!trackDescriptor) return
|
||||
@@ -816,18 +760,15 @@ const MusicDetails = ({ route }) => {
|
||||
</View>
|
||||
{songUrl && (
|
||||
<View style={{ paddingTop: 22 }}>
|
||||
<Slider
|
||||
value={fmt(positionMs)}
|
||||
maxValue={fmt(sliderDurationMs)}
|
||||
progress={
|
||||
sliderDurationMs
|
||||
? Math.min(1, Math.max(0, (positionMs || 0) / sliderDurationMs))
|
||||
: 0
|
||||
}
|
||||
seekEnabled={!!songUrl}
|
||||
<ProgressSlider
|
||||
positionMs={positionMs}
|
||||
durationMs={sliderDurationMs}
|
||||
isPlaying={isTrackPlaying}
|
||||
onSeekStart={handleSliderSeekStart}
|
||||
onSeek={handleSliderSeek}
|
||||
onSeekEnd={handleSliderSeekEnd}
|
||||
onPause={pauseTrack}
|
||||
onPlay={resumeTrack}
|
||||
disabled={!songUrl}
|
||||
/>
|
||||
<View style={{ ...Style.containerRow, gap: 24, alignSelf: 'center' }}>
|
||||
{/* Previous (rewind 10s) */}
|
||||
|
||||
Reference in New Issue
Block a user