From 1c8361d45b499b9854e1db3330fd255d65c8008b Mon Sep 17 00:00:00 2001 From: Xiaohan-Tian <157918347+Xiaohan-Tian@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:34:26 -0800 Subject: [PATCH] feat: implemented playback looping; fixed an linter error in Toolbar.tsx --- src/components/MainContent.tsx | 24 ++++++++++++++---------- src/components/Toolbar.tsx | 2 +- src/stores/projectStore.ts | 8 +++++++- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/components/MainContent.tsx b/src/components/MainContent.tsx index b905f6b..76e742c 100644 --- a/src/components/MainContent.tsx +++ b/src/components/MainContent.tsx @@ -20,15 +20,15 @@ interface MainContentProps { const MainContent: React.FC = ({ onTrackClick = () => {} // Default to empty function if not provided }) => { - const { - tracks, - maxBars, - reorderTracks, + const { + tracks, + maxBars, + reorderTracks, updateTrack, - updateTrackProperties, - timeSignature, - setPlayheadPosition, - clearAllSelections, + updateTrackProperties, + timeSignature, + setPlayheadPosition, + clearAllSelections, setSelectedTrack, showPianoRoll, activeRegionId, @@ -448,8 +448,6 @@ const MainContent: React.FC = ({ setActiveRegionId(null); }; - - /** * Add keyboard event listener for region deletion * Handles Backspace (Windows) and Delete (Mac) keys to delete selected regions @@ -622,6 +620,12 @@ const MainContent: React.FC = ({ originalSettings.loopingRange[1] !== currentLoopingRange[1]; if (settingsChanged) { + // Stop playback if currently playing (get fresh state from store) + const { isPlaying: currentIsPlaying, stopPlaying: currentStopPlaying } = useProjectStore.getState(); + if (currentIsPlaying) { + currentStopPlaying(); + } + // Revert to original state first (since we updated in real-time) core.getCurrentProject().setIsLooping(originalSettings.isLooping); core.getCurrentProject().setLoopingRange(originalSettings.loopingRange); diff --git a/src/components/Toolbar.tsx b/src/components/Toolbar.tsx index 432c97c..8ebef89 100644 --- a/src/components/Toolbar.tsx +++ b/src/components/Toolbar.tsx @@ -246,7 +246,7 @@ const Toolbar: React.FC = () => { const midiData = convertProjectToMidi(currentProject); // Create a downloadable blob - const blob = new Blob([midiData], { type: 'audio/midi' }); + const blob = new Blob([midiData.buffer as ArrayBuffer], { type: 'audio/midi' }); // Create a temporary download link const url = URL.createObjectURL(blob); diff --git a/src/stores/projectStore.ts b/src/stores/projectStore.ts index 2f30d18..78c7a2a 100644 --- a/src/stores/projectStore.ts +++ b/src/stores/projectStore.ts @@ -573,7 +573,13 @@ export const useProjectStore = create((set, get) => { }, toggleLoop: () => { - const { isLooping, loopingRange, maxBars } = get(); + const { isLooping, loopingRange, maxBars, isPlaying, stopPlaying } = get(); + + // Stop playback if currently playing + if (isPlaying) { + stopPlaying(); + } + toggleLoop(isLooping, loopingRange, maxBars); },