fix(properties): harden resume lifecycle

This commit is contained in:
NimBold
2026-08-04 19:37:25 +03:30
parent 3905b3ed89
commit 135ba75a69
7 changed files with 318 additions and 24 deletions
+20
View File
@@ -1,4 +1,5 @@
import { emitTo } from '@tauri-apps/api/event';
import type { UnlistenFn } from '@tauri-apps/api/event';
import type { DownloadProgressEvent } from './bindings/DownloadProgressEvent';
import type { DownloadStatus } from './bindings/DownloadStatus';
import type { DownloadItem } from './store/useDownloadStore';
@@ -303,6 +304,25 @@ export const createFrameCoalescer = (
};
};
// Tauri listener registration is asynchronous. React StrictMode can unmount
// an effect before `listen()` resolves; in that case assigning the late
// unlisten callback after cleanup leaks a second bridge listener. A leaked
// Properties host can process one click twice, observe the queued state from
// the first action, and turn the intended resume into an immediate pause.
export const attachAsyncPropertiesListener = <T extends UnlistenFn>(
listener: Promise<T>,
isDisposed: () => boolean,
assign: (unlisten: T) => void,
): void => {
void listener.then(unlisten => {
if (isDisposed()) {
unlisten();
return;
}
assign(unlisten);
}).catch(() => undefined);
};
export const openPropertiesWindow = (downloadId: string): Promise<string> =>
invoke('open_download_properties_window', { id: downloadId });