diff --git a/front/components/Play/PartitionMagic.tsx b/front/components/Play/PartitionMagic.tsx index e4b2365..2ad6c72 100644 --- a/front/components/Play/PartitionMagic.tsx +++ b/front/components/Play/PartitionMagic.tsx @@ -16,7 +16,7 @@ import { SplendidGrandPiano } from 'smplr'; export type ParitionMagicProps = { playType: 'practice' | 'normal' | null; - timestamp: number; + timestamp: React.MutableRefObject; songID: number; shouldPlay: boolean; onEndReached: () => void; @@ -48,6 +48,8 @@ const getCursorToPlay = ( const transitionDuration = 50; +export let updateCursor: (() => void) | undefined = undefined; + const PartitionMagic = ({ playType, timestamp, @@ -78,7 +80,36 @@ const PartitionMagic = ({ const cursorTop = (data?.cursors[cursorDisplayIdx]?.y ?? 0) - cursorPaddingVertical; const cursorLeft = (data?.cursors[0]?.x ?? 0) - cursorPaddingHorizontal; - console.log(melodySound.current?._loaded); + updateCursor = () => { + if (!shouldPlay) return; + if (!data || data?.cursors.length === 0) return; + getCursorToPlay( + data!.cursors, + currentCurIdx.current, + timestamp.current + transitionDuration, + (cursor, idx) => { + currentCurIdx.current = idx; + partitionOffset.value = withTiming( + -(cursor.x - data!.cursors[0]!.x) / partitionDims[0], + { + duration: transitionDuration, + easing: Easing.inOut(Easing.ease), + } + ); + if (idx === data!.cursors.length - 1) { + setEndPartitionReached(true); + } + if (playType === 'practice') return; + if (!isPianoLoaded) return; + cursor.notes.forEach((note) => { + piano.current?.start({ + note: note.note, + duration: note.duration, + }); + }); + } + ); + }; if (!endPartitionReached && currentCurIdx.current + 1 === data?.cursors.length) { // weird contraption but the mobile don't want classic functions to be called @@ -166,58 +197,7 @@ const PartitionMagic = ({ } }, [endPartitionReached]); - React.useEffect(() => { - if (!melodySound.current || !melodySound.current._loaded) return; - if (!data || data?.cursors.length === 0) return; - - melodySound.current.setOnPlaybackStatusUpdate((status) => { - //@ts-expect-error positionMillis is not in the type - const timestamp = status?.positionMillis ?? 0; - getCursorToPlay( - data!.cursors, - currentCurIdx.current, - timestamp + transitionDuration, - (cursor, idx) => { - currentCurIdx.current = idx; - partitionOffset.value = withTiming( - -(cursor.x - data!.cursors[0]!.x) / partitionDims[0], - { - duration: transitionDuration, - easing: Easing.inOut(Easing.ease), - } - ); - } - ); - }); - }, [data?.cursors, melodySound.current?._loaded]); - - React.useEffect(() => { - if (!shouldPlay) return; - if (!isPianoLoaded || melodySound.current) return; - if (!data || data?.cursors.length === 0) return; - getCursorToPlay( - data!.cursors, - currentCurIdx.current, - timestamp + transitionDuration, - (cursor, idx) => { - currentCurIdx.current = idx; - partitionOffset.value = withTiming( - -(cursor.x - data!.cursors[0]!.x) / partitionDims[0], - { - duration: transitionDuration, - easing: Easing.inOut(Easing.ease), - } - ); - if (playType === 'practice') return; - cursor.notes.forEach((note) => { - piano.current?.start({ - note: note.note, - duration: note.duration, - }); - }); - } - ); - }, [timestamp, data?.cursors, isPianoLoaded]); + React.useEffect(updateCursor, [data?.cursors, isPianoLoaded, timestamp.current]); const animatedStyle = useAnimatedStyle(() => ({ left: `${partitionOffset.value * 100}%`, diff --git a/front/components/Play/PlayTimestampShow.tsx b/front/components/Play/PlayTimestampShow.tsx new file mode 100644 index 0000000..a974172 --- /dev/null +++ b/front/components/Play/PlayTimestampShow.tsx @@ -0,0 +1,35 @@ +import { Text, useTheme } from 'native-base'; +import { MutableRefObject, useEffect, useState } from 'react'; + +export let updateTime: (() => void) | undefined = undefined; + +type PlayTimestampShowProps = { + paused: boolean; + time: MutableRefObject; +}; + +export const PlayTimestampShow = ({ paused, time }: PlayTimestampShowProps) => { + const { colors } = useTheme(); + const textColor = colors.text; + const [timeD, setTimeD] = useState(time.current); + + updateTime = () => { + setTimeD(time.current); + }; + + useEffect(updateTime, [time]); + return ( + + {timeD < 0 + ? paused + ? '0:00' + : Math.floor((timeD % 60000) / 1000) + .toFixed(0) + .toString() + : `${Math.floor(timeD / 60000)}:${Math.floor((timeD % 60000) / 1000) + .toFixed(0) + .toString() + .padStart(2, '0')}`} + + ); +}; diff --git a/front/components/Play/PlayViewControlBar.tsx b/front/components/Play/PlayViewControlBar.tsx index 397eb49..33bda51 100644 --- a/front/components/Play/PlayViewControlBar.tsx +++ b/front/components/Play/PlayViewControlBar.tsx @@ -6,11 +6,12 @@ import { MetronomeControls } from '../Metronome'; import StarProgress from '../StarProgress'; import Song from '../../models/Song'; import { useTheme } from 'native-base'; +import { PlayTimestampShow } from './PlayTimestampShow'; type PlayViewControlBarProps = { playType: 'practice' | 'normal' | null; song: Song; - time: number; + time: React.MutableRefObject; paused: boolean; score: number; disabled: boolean; @@ -132,18 +133,7 @@ const PlayViewControlBar = ({ }} onPress={onEnd} /> - - {time < 0 - ? paused - ? '0:00' - : Math.floor((time % 60000) / 1000) - .toFixed(0) - .toString() - : `${Math.floor(time / 60000)}:${Math.floor((time % 60000) / 1000) - .toFixed(0) - .toString() - .padStart(2, '0')}`} - + { const webSocket = useRef(); const [paused, setPause] = useState(true); const stopwatch = useStopwatch(); - const [time, setTime] = useState(0); + // const [time, setTime] = useState(0); + const time = useRef(0); const [endResult, setEndResult] = useState(); const [shouldPlay, setShouldPlay] = useState(false); const songHistory = useQuery(API.getSongHistory(songId)); @@ -195,7 +197,10 @@ const PlayView = ({ songId }: PlayViewProps) => { setScore(Math.floor((Math.max(points, 0) * 100) / maxPoints)); if (data.type == 'step') { - setTime(data.timestamp); + // setTime(data.timestamp); + time.current = data.timestamp; + updateCursor?.(); + updateTimeControlBar?.(); return; } let formattedMessage = ''; @@ -261,7 +266,9 @@ const PlayView = ({ songId }: PlayViewProps) => { if (playType == 'practice') return; const interval = setInterval(() => { - setTime(() => getElapsedTime()); + time.current = getElapsedTime(); + updateCursor?.(); + updateTimeControlBar?.(); }, 200); return () => clearInterval(interval); }, [playType]);