Files
Chromacase/front/components/Metronome.tsx
2023-10-28 08:04:23 +02:00

68 lines
1.8 KiB
TypeScript

/* eslint-disable @typescript-eslint/no-var-requires */
import { useEffect, useRef, useState } from 'react';
import { Slider, Switch, Text, View } from 'native-base';
import { Audio } from 'expo-av';
const MetronomeToggle = (props: { enabled: boolean, onToggle: (stateAfterToggle: boolean) => void }) => {
const [isEnabled, setEnabled] = useState(false);
useEffect(() => {
setEnabled(props.enabled)
}, [props.enabled])
return <Switch value={isEnabled} onToggle={() => {
console.log(isEnabled);
props.onToggle(!isEnabled);
setEnabled(!isEnabled);
}} />
}
export const Metronome = ({ paused = false, bpm }: { paused?: boolean; bpm: number }) => {
const audio = useRef<Audio.Sound | null>(null);
const enabled = useRef<boolean>(false);
const volume = useRef<number>(50);
useEffect(() => {
if (!enabled) {
return;
} else if (!audio.current) {
Audio.Sound.createAsync(require('../assets/metronome.mp3')).then((a) => {
audio.current = a.sound;
});
}
return () => {
audio.current?.unloadAsync();
};
}, [enabled]);
useEffect(() => {
if (paused) return;
const int = setInterval(() => {
if (!enabled.current) return;
if (!audio.current) return;
audio.current?.playAsync();
}, 60000 / bpm);
return () => clearInterval(int);
}, [bpm, paused]);
useEffect(() => {
audio.current?.setVolumeAsync(volume.current / 100);
}, [volume.current]);
return (
<View>
<Text>Metronome Settings</Text>
<Text>Enabled:</Text>
<MetronomeToggle enabled={enabled.current} onToggle={(e) => (enabled.current = e)} />
<Text>Volume:</Text>
<Slider
maxWidth={'500px'}
value={volume.current}
onChange={(x) => (volume.current = x)}
>
<Slider.Track>
<Slider.FilledTrack />
</Slider.Track>
<Slider.Thumb />
</Slider>
</View>
);
};