Moved the Loading display to partition Magic to better display svg loading

This commit is contained in:
Clément Le Bihan
2023-11-29 23:48:11 +01:00
parent dd581a8418
commit ff4926fa80
+63 -42
View File
@@ -8,6 +8,7 @@ import { CursorInfoItem } from '../../models/SongCursorInfos';
import { PianoNotes } from '../../state/SoundPlayerSlice'; import { PianoNotes } from '../../state/SoundPlayerSlice';
import { Audio } from 'expo-av'; import { Audio } from 'expo-av';
import { SvgContainer } from './SvgContainer'; import { SvgContainer } from './SvgContainer';
import LoadingComponent from '../Loading';
// note we are also using timestamp in a context // note we are also using timestamp in a context
export type ParitionMagicProps = { export type ParitionMagicProps = {
@@ -41,6 +42,7 @@ const getCursorToPlay = (
const PartitionMagic = ({ songID, onEndReached, onError, onReady }: ParitionMagicProps) => { const PartitionMagic = ({ songID, onEndReached, onError, onReady }: ParitionMagicProps) => {
const { data, isLoading, isError } = useQuery(API.getSongCursorInfos(songID)); const { data, isLoading, isError } = useQuery(API.getSongCursorInfos(songID));
const [currentCurIdx, setCurrentCurIdx] = React.useState(-1); const [currentCurIdx, setCurrentCurIdx] = React.useState(-1);
const [isPartitionSvgLoaded, setIsPartitionSvgLoaded] = React.useState(false);
const partitionOffset = useSharedValue(0); const partitionOffset = useSharedValue(0);
const pianoCC = React.useContext(PianoCC); const pianoCC = React.useContext(PianoCC);
const pianoSounds = React.useRef<Record<string, Audio.Sound>>(); const pianoSounds = React.useRef<Record<string, Audio.Sound>>();
@@ -55,37 +57,40 @@ const PartitionMagic = ({ songID, onEndReached, onError, onReady }: ParitionMagi
const cursorTop = (data?.cursors[cursorDisplayIdx]?.y ?? 0) - cursorPaddingVertical; const cursorTop = (data?.cursors[cursorDisplayIdx]?.y ?? 0) - cursorPaddingVertical;
const cursorLeft = (data?.cursors[0]?.x ?? 0) - cursorPaddingHorizontal; const cursorLeft = (data?.cursors[0]?.x ?? 0) - cursorPaddingHorizontal;
React.useEffect(() => { // React.useEffect(() => {
if (!pianoSounds.current) { // if (!pianoSounds.current) {
Promise.all( // Promise.all(
Object.entries(PianoNotes).map(([midiNumber, noteResource]) => // Object.entries(PianoNotes).map(([midiNumber, noteResource]) =>
Audio.Sound.createAsync(noteResource, { // Audio.Sound.createAsync(noteResource, {
volume: 1, // volume: 1,
progressUpdateIntervalMillis: 100, // progressUpdateIntervalMillis: 100,
}).then((sound) => [midiNumber, sound.sound] as const) // }).then((sound) => [midiNumber, sound.sound] as const)
) // )
).then( // ).then(
(res) => // (res) =>
(pianoSounds.current = res.reduce( // (pianoSounds.current = res.reduce(
(prev, curr) => ({ ...prev, [curr[0]]: curr[1] }), // (prev, curr) => ({ ...prev, [curr[0]]: curr[1] }),
{} // {}
)) // ))
); // );
} // }
}, []); // }, []);
const partitionDims = React.useMemo<[number, number]>(() => { const partitionDims = React.useMemo<[number, number]>(() => {
return [data?.pageWidth ?? 0, data?.pageHeight ?? 1]; return [data?.pageWidth ?? 0, data?.pageHeight ?? 1];
}, [data]); }, [data]);
React.useEffect(() => { React.useEffect(() => {
if (isLoading) {
return;
}
if (isError) { if (isError) {
onError('Error while loading partition'); onError('Error while loading partition');
return; return;
} }
}, [isLoading, isError]); }, [isError]);
React.useEffect(() => {
if (isPartitionSvgLoaded && !isLoading) {
onReady();
}
}, [isPartitionSvgLoaded, isLoading]);
const transitionDuration = 200; const transitionDuration = 200;
@@ -94,17 +99,17 @@ const PartitionMagic = ({ songID, onEndReached, onError, onReady }: ParitionMagi
currentCurIdx, currentCurIdx,
pianoCC.timestamp - transitionDuration, pianoCC.timestamp - transitionDuration,
(cursor, idx) => { (cursor, idx) => {
cursor.notes.forEach(({ note, duration }) => { // cursor.notes.forEach(({ note, duration }) => {
try { // try {
const sound = pianoSounds.current![note]!; // const sound = pianoSounds.current![note]!;
sound.playAsync().catch(console.error); // sound.playAsync().catch(console.error);
setTimeout(() => { // setTimeout(() => {
sound.stopAsync(); // sound.stopAsync();
}, duration - 10); // }, duration - 10);
} catch (e) { // } catch (e) {
console.log(e); // console.log(e);
} // }
}); // });
partitionOffset.value = withTiming( partitionOffset.value = withTiming(
-(cursor.x - data!.cursors[0]!.x) / partitionDims[0], -(cursor.x - data!.cursors[0]!.x) / partitionDims[0],
{ {
@@ -130,6 +135,22 @@ const PartitionMagic = ({ songID, onEndReached, onError, onReady }: ParitionMagi
overflow: 'hidden', overflow: 'hidden',
}} }}
> >
{(!isPartitionSvgLoaded || isLoading) && (
<View
style={{
position: 'absolute',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
height: '100%',
zIndex: 50,
backgroundColor: 'rgba(0,0,0,0.5)',
}}
>
<LoadingComponent />
</View>
)}
<View <View
style={{ style={{
position: 'absolute', position: 'absolute',
@@ -148,15 +169,15 @@ const PartitionMagic = ({ songID, onEndReached, onError, onReady }: ParitionMagi
justifyContent: 'flex-start', justifyContent: 'flex-start',
}} }}
> >
{!isLoading && !isError && ( <SvgContainer
<SvgContainer url={getSVGURL(songID)}
url={getSVGURL(songID)} onReady={() => {
onReady={onReady} setIsPartitionSvgLoaded(true);
style={{ }}
aspectRatio: partitionDims[0] / partitionDims[1], style={{
}} aspectRatio: partitionDims[0] / partitionDims[1],
/> }}
)} />
</Animated.View> </Animated.View>
<Animated.View <Animated.View
style={{ style={{