fix: harden scheduler, permissions, and download safety

- Implement scheduler hydration barrier to prevent premature triggers
- Track scheduler exact runs using keys to avoid false stops
- Use 'System Events' for accurate macOS automation permissions
- Prevent system-sleep via proper idle assertions
- Ensure download pauses use channel acknowledgements (PauseWithAck)
- Require Firelink ownership before replacing files in add/conflict UI
- Retain partial download assets when removing entries without deletion
- Clear progress state in store when downloads complete or pause to reduce churn
- Handle empty/invalid queue selections gracefully
This commit is contained in:
NimBold
2026-06-22 18:05:04 +03:30
parent 6b3753949b
commit 7c835b022f
17 changed files with 529 additions and 181 deletions
+19 -7
View File
@@ -7,6 +7,7 @@ import { listenEvent as listen } from '../ipc';
interface DownloadProgressState {
progressMap: Record<string, DownloadProgressEvent>;
updateDownloadProgress: (id: string, payload: DownloadProgressEvent) => void;
clearDownloadProgress: (id: string) => void;
}
import { useDownloadStore } from './useDownloadStore';
@@ -20,6 +21,13 @@ export const useDownloadProgressStore = create<DownloadProgressState>((set) => (
[id]: payload,
},
})),
clearDownloadProgress: (id) =>
set((state) => {
if (!(id in state.progressMap)) return state;
const next = { ...state.progressMap };
delete next[id];
return { progressMap: next };
}),
}));
let unlistenProgress: UnlistenFn | null = null;
@@ -36,12 +44,9 @@ export async function initDownloadListener() {
const current = mainStore.downloads.find(d => d.id === payload.id);
if (current) {
const shouldUpdateSize = Boolean(payload.size && (!current.isMedia || payload.size_is_final));
mainStore.updateDownload(payload.id, {
fraction: payload.fraction,
speed: payload.speed,
eta: payload.eta,
...(shouldUpdateSize ? { size: payload.size! } : {}),
});
if (shouldUpdateSize && current.size !== payload.size) {
mainStore.updateDownload(payload.id, { size: payload.size! });
}
}
});
@@ -52,7 +57,11 @@ export async function initDownloadListener() {
const current = mainStore.downloads.find(d => d.id === payload.id);
if (current) {
const status = payload.status as DownloadStatus;
const updates: Partial<any> = { status };
const progress = useDownloadProgressStore.getState().progressMap[payload.id];
const updates: Partial<any> = {
status,
...(progress ? { fraction: progress.fraction } : {})
};
if (status !== 'downloading') {
updates.speed = '-';
updates.eta = '-';
@@ -72,6 +81,9 @@ export async function initDownloadListener() {
} else if (status === 'completed' || status === 'failed') {
mainStore.unregisterBackendIds([payload.id]);
}
if (status === 'completed' || status === 'failed' || status === 'paused') {
useDownloadProgressStore.getState().clearDownloadProgress(payload.id);
}
}
});
}