diff --git a/audio-service/src/routes/__pycache__/metadata.cpython-313.pyc b/audio-service/src/routes/__pycache__/metadata.cpython-313.pyc index fda7d27..f9f2d29 100644 Binary files a/audio-service/src/routes/__pycache__/metadata.cpython-313.pyc and b/audio-service/src/routes/__pycache__/metadata.cpython-313.pyc differ diff --git a/audio-service/src/routes/__pycache__/recording.cpython-313.pyc b/audio-service/src/routes/__pycache__/recording.cpython-313.pyc index 435c7c2..84216e3 100644 Binary files a/audio-service/src/routes/__pycache__/recording.cpython-313.pyc and b/audio-service/src/routes/__pycache__/recording.cpython-313.pyc differ diff --git a/audio-service/src/routes/__pycache__/settings.cpython-313.pyc b/audio-service/src/routes/__pycache__/settings.cpython-313.pyc index d859b80..b6a5a62 100644 Binary files a/audio-service/src/routes/__pycache__/settings.cpython-313.pyc and b/audio-service/src/routes/__pycache__/settings.cpython-313.pyc differ diff --git a/electron-ui/src/renderer/components/AudioTrimer.tsx b/electron-ui/src/renderer/components/AudioTrimer.tsx index 1c63530..5e5280d 100644 --- a/electron-ui/src/renderer/components/AudioTrimer.tsx +++ b/electron-ui/src/renderer/components/AudioTrimer.tsx @@ -44,6 +44,8 @@ export default function AudioTrimmer({ useSortable({ id: metadata.filename }); // Dialog state for editing name + const rootRef = useRef(null); + const [isVisible, setIsVisible] = useState(false); const [editDialogOpen, setEditDialogOpen] = useState(false); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [dropdownOpen, setDropdownOpen] = useState(false); @@ -202,25 +204,40 @@ export default function AudioTrimmer({ }, [onRegionCreated, onRegionUpdated, plugins]); useEffect(() => { - let url: string | null = null; + const node = rootRef.current; + if (!node) return; + const observer = new window.IntersectionObserver( + ([entry]) => { + if (entry.isIntersecting) { + setIsVisible(true); + } + }, + { threshold: 0.1 }, + ); + observer.observe(node); + return () => { + observer.disconnect(); + }; + }, []); + + useEffect(() => { + if (!isVisible) return; + let cancelled = false; async function fetchAudio() { - // console.log('Loading audio buffer for file:', filename); const buffer = await window.audio.loadAudioBuffer(metadata.filename); - // console.log('Received buffer:', buffer.buffer); + if (cancelled) return; if (buffer.buffer && !buffer.error) { const audioData = buffer.buffer ? new Uint8Array(buffer.buffer) : buffer; - url = URL.createObjectURL(new Blob([audioData])); - // console.log('Created blob URL:', url); - setBlobUrl(url); + wavesurfer?.loadBlob(new Blob([audioData])); } } fetchAudio(); return () => { - if (url) URL.revokeObjectURL(url); + cancelled = true; }; - }, [metadata.filename]); + }, [isVisible, metadata.filename, wavesurfer]); const onPlayPause = () => { if (wavesurfer === null) return; @@ -245,7 +262,10 @@ export default function AudioTrimmer({ return (
{ + setNodeRef(el); + rootRef.current = el; + }} style={{ transform: CSS.Transform.toString(transform), transition,