Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion src/renderer/src/components/WSAudioPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,9 @@ function WSAudioPlayer(props: IProps) {
useContext(HotKeyContext).state;
const [pxPerSec, setPxPerSecx] = useState(maxZoom);
const pxPerSecRef = useRef(maxZoom);
/** When set, the zoom to re-apply after an edit reload (snip/undo) so the
* waveform doesn't snap back to fit-to-width. Cleared once consumed. */
const preserveZoomOnReloadRef = useRef<number | undefined>(undefined);
const insertingRef = useRef(false);
/** Bumped when user stops recording so in-flight preview inserts are ignored after await. */
const recordPreviewGenerationRef = useRef(0);
Expand Down Expand Up @@ -1171,7 +1174,18 @@ function WSAudioPlayer(props: IProps) {
setDuration(duration);
if (loadingAnother) return;
setReady(true);
if (!recordingRef.current) setPxPerSec(wsFillPx());
if (!recordingRef.current) {
// After an edit reload (snip/undo) restore the prior zoom instead of
// snapping to fit-to-width. Only restore when it was zoomed in past fit.
const preserved = preserveZoomOnReloadRef.current;
preserveZoomOnReloadRef.current = undefined;
if (preserved !== undefined && preserved > wsFillPx()) {
setPxPerSec(preserved);
wsZoom(preserved);
} else {
setPxPerSec(wsFillPx());
}
}
if (segmentsRef.current) loadRegions();

if (setBusy) setBusy(false);
Expand Down Expand Up @@ -1275,12 +1289,14 @@ function WSAudioPlayer(props: IProps) {

const handleDeleteRegion = () => {
setPlaying(false);
preserveZoomOnReloadRef.current = pxPerSecRef.current;
wsRegionDelete().then(() => {
handleChanged();
});
};

const handleUndo = useCallback(() => {
preserveZoomOnReloadRef.current = pxPerSecRef.current;
wsUndo().then(() => {
handleChanged();
});
Expand Down
8 changes: 6 additions & 2 deletions src/renderer/src/components/WSAudioPlayerZoom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,15 @@ function WSAudioPlayerZoom(props: IProps) {
};
useEffect(() => {
setZoomMin(fillPx);
// Only sync zoom to fillPx when fillPx actually changes (e.g. resize), not on mount.
// fillPx is the fit-to-width minimum. When it changes (resize, or duration
// change after a snip), only pull the zoom up if the current zoom is now
// below that minimum. Otherwise keep the user's zoom so editing audio
// doesn't reset how far they were zoomed in.
// On mount, curPx effect sets zoom; avoid overwriting with fillPx so menu reopen keeps zoom.
if (
prevFillPxRef.current !== undefined &&
prevFillPxRef.current !== fillPx
prevFillPxRef.current !== fillPx &&
zoomRef.current < fillPx
) {
setZoom(fillPx);
}
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/src/crud/useWaveSurfer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,8 @@ export function useWaveSurfer(
};

const wsUndo = async () => {
if (undoBuffer) await loadDecoded(undoBuffer, 0);
// wsGoto clamps the position to the restored duration on load, so no harm if past end.
if (undoBuffer) await loadDecoded(undoBuffer, progress());
else {
wsClear();
}
Expand Down
Loading