Added a loading dispaly for the play button and removed onProgressUpdate from expo av and reusing the timestamp to advance the cursor despite perf issues

This commit is contained in:
Clément Le Bihan
2024-01-13 18:38:15 +01:00
parent f5136ae59b
commit aae0bbea3a
2 changed files with 35 additions and 54 deletions

View File

@@ -34,6 +34,7 @@ const getCursorToPlay = (
const cursorInfo = cursorInfos[i]!;
if (cursorInfo.timestamp <= timestamp) {
onCursorMove(cursorInfo, i);
return;
}
}
};
@@ -63,7 +64,7 @@ const PartitionMagic = ({ songID }: ParitionMagicProps) => {
const piano = React.useRef<SplendidGrandPiano | null>(null);
const [isPianoLoaded, setIsPianoLoaded] = React.useState(false);
const [timestamp, setTimestamp] = useAtom(timestampAtom);
const shouldPlay = useAtom(shouldPlayAtom)[0];
const [shouldPlay, setShouldPlay] = useAtom(shouldPlayAtom);
const [partitionState, setPartitionState] = useAtom(partitionStateAtom);
const cursorPaddingVertical = 10;
const cursorPaddingHorizontal = 3;
@@ -76,7 +77,7 @@ const PartitionMagic = ({ songID }: ParitionMagicProps) => {
const cursorTop = (data?.cursors[cursorDisplayIdx]?.y ?? 0) - cursorPaddingVertical;
const cursorLeft = (data?.cursors[0]?.x ?? 0) - cursorPaddingHorizontal;
console.log('state', partitionState);
console.log('state', partitionState, timestamp);
if (!endPartitionReached && currentCurIdx.current + 1 === data?.cursors.length) {
// weird contraption but the mobile don't want classic functions to be called
@@ -101,6 +102,8 @@ const PartitionMagic = ({ songID }: ParitionMagicProps) => {
return () => {
setPartitionState('loading');
setTimestamp(0);
setShouldPlay(false);
};
}, [isPartitionSvgLoaded, isLoading, melodySound.current?._loaded, isPianoLoaded]);
@@ -112,14 +115,9 @@ const PartitionMagic = ({ songID }: ParitionMagicProps) => {
setIsPianoLoaded(true);
});
} else if (!melodySound.current) {
Audio.Sound.createAsync(
{
Audio.Sound.createAsync({
uri: API.getPartitionMelodyUrl(songID),
},
{
progressUpdateIntervalMillis: 200,
}
).then((track) => {
}).then((track) => {
melodySound.current = track.sound;
});
}
@@ -141,9 +139,13 @@ const PartitionMagic = ({ songID }: ParitionMagicProps) => {
}, [data]);
React.useEffect(() => {
const interval = setInterval(() => {
const interval = setInterval(
() => {
// if (partitionState !== 'playing') return;
setTimestamp(stopwatch.getElapsedRunningTime());
}, 200);
},
Platform.OS === 'web' ? 200 : 500
);
return () => {
clearInterval(interval);
};
@@ -152,13 +154,13 @@ const PartitionMagic = ({ songID }: ParitionMagicProps) => {
React.useEffect(() => {
if (Platform.OS === 'web') {
if (!piano.current || !isPianoLoaded) return;
startResumePauseWatch(stopwatch, shouldPlay);
setPartitionState(shouldPlay ? 'playing' : 'paused');
startResumePauseWatch(stopwatch, shouldPlay);
return;
}
if (!melodySound.current || !melodySound.current._loaded) return;
startResumePauseWatch(stopwatch, shouldPlay);
setPartitionState(shouldPlay ? 'playing' : 'paused');
startResumePauseWatch(stopwatch, shouldPlay);
if (shouldPlay) {
melodySound.current.playAsync().catch(console.error);
} else {
@@ -167,12 +169,9 @@ const PartitionMagic = ({ songID }: ParitionMagicProps) => {
}, [shouldPlay]);
React.useEffect(() => {
if (!shouldPlay) return;
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,
@@ -186,28 +185,7 @@ const PartitionMagic = ({ songID }: ParitionMagicProps) => {
easing: Easing.inOut(Easing.ease),
}
);
}
);
});
}, [data?.cursors, melodySound.current?._loaded]);
React.useEffect(() => {
if (!shouldPlay) return;
if (!piano.current || !isPianoLoaded) 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),
}
);
cursor.notes.forEach((note) => {
piano.current?.start({
note: note.note,

View File

@@ -1,6 +1,6 @@
import { View } from 'react-native';
import * as React from 'react';
import { Row, Image, Text, useBreakpointValue, IconButton } from 'native-base';
import { Row, Image, Text, useBreakpointValue, IconButton, Button } from 'native-base';
import { Ionicons } from '@expo/vector-icons';
import { MetronomeControls } from '../Metronome';
import StarProgress from '../StarProgress';
@@ -26,7 +26,7 @@ const PlayViewControlBar = ({ song }: PlayViewControlBarProps) => {
const { colors } = useTheme();
const textColor = colors.text;
const isPlaying = partitionState === 'playing';
const disabled = partitionState === 'loading' || partitionState === 'error';
const isPartitionLoading = partitionState === 'loading';
React.useEffect(() => {
return () => {
@@ -109,10 +109,12 @@ const PlayViewControlBar = ({ song }: PlayViewControlBarProps) => {
gap: isPhone ? 10 : 25,
}}
>
{isPartitionLoading ? (
<Button isLoading size="sm" variant="solid" color={colors.coolGray[900]} />
) : (
<IconButton
size="sm"
variant="solid"
disabled={disabled}
_icon={{
as: Ionicons,
color: colors.coolGray[900],
@@ -120,6 +122,7 @@ const PlayViewControlBar = ({ song }: PlayViewControlBarProps) => {
}}
onPress={() => setShouldPlay(!isPlaying)}
/>
)}
<IconButton
size="sm"
colorScheme="coolGray"