import { useEffect, useState, useRef, useCallback } from "react"; import { PitchContour } from "@renderer/components"; import WaveSurfer from "wavesurfer.js"; import { Button, Skeleton } from "@renderer/components/ui"; import { PlayIcon, PauseIcon } from "lucide-react"; import { useIntersectionObserver } from "@uidotdev/usehooks"; import { secondsToTimestamp } from "@renderer/lib/utils"; export const PostRecording = (props: { recording: RecordingType; height?: number; }) => { const { recording, height = 80 } = props; const [initialized, setInitialized] = useState(false); const [isPlaying, setIsPlaying] = useState(false); const [wavesurfer, setWavesurfer] = useState(null); const containerRef = useRef(); const [ref, entry] = useIntersectionObserver({ threshold: 1, }); const [duration, setDuration] = useState(0); const onPlayClick = useCallback(() => { wavesurfer.isPlaying() ? wavesurfer.pause() : wavesurfer.play(); }, [wavesurfer]); useEffect(() => { // use the intersection observer to only create the wavesurfer instance // when the player is visible if (!entry?.isIntersecting) return; if (!recording.src) return; if (wavesurfer) return; const ws = WaveSurfer.create({ container: containerRef.current, url: recording.src, height, barWidth: 1, cursorWidth: 0, autoCenter: true, autoScroll: true, dragToSeek: true, hideScrollbar: true, minPxPerSec: 100, waveColor: "rgba(0, 0, 0, 0.25)", progressColor: "rgba(0, 0, 0, 0.5)", }); setWavesurfer(ws); }, [recording.src, entry]); useEffect(() => { if (!wavesurfer) return; const subscriptions = [ wavesurfer.on("play", () => { setIsPlaying(true); }), wavesurfer.on("pause", () => { setIsPlaying(false); }), wavesurfer.on("decode", () => { setDuration(wavesurfer.getDuration()); const peaks = wavesurfer.getDecodedData().getChannelData(0); const sampleRate = wavesurfer.options.sampleRate; wavesurfer.renderer.getWrapper().appendChild( PitchContour({ peaks, sampleRate, height, }) ); setInitialized(true); }), ]; return () => { subscriptions.forEach((unsub) => unsub()); wavesurfer?.destroy(); }; }, [wavesurfer]); return (
{secondsToTimestamp(duration)}
{!initialized && (
)}
{ recording.referenceText && (
{recording.referenceText}
) }
); };