50 lines
1.3 KiB
TypeScript
50 lines
1.3 KiB
TypeScript
import type { TaskState } from "./state.ts";
|
|
|
|
export const TODO_AUTO_CLEAR_DELAY_MS = 10_000;
|
|
|
|
export interface CompletedTaskAutoClear {
|
|
sync(forceRestart?: boolean): void;
|
|
cancel(): void;
|
|
}
|
|
|
|
export function createCompletedTaskAutoClear(
|
|
state: TaskState,
|
|
tryClear: () => boolean,
|
|
delayMs = TODO_AUTO_CLEAR_DELAY_MS,
|
|
): CompletedTaskAutoClear {
|
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
let scheduledKey: string | undefined;
|
|
|
|
const completionKey = () => {
|
|
const tasks = state.list();
|
|
if (tasks.length === 0 || tasks.some((task) => task.status !== "done")) return undefined;
|
|
return tasks.map((task) => `${task.id}:${task.status}`).join("|");
|
|
};
|
|
|
|
const cancel = () => {
|
|
if (timer !== undefined) clearTimeout(timer);
|
|
timer = undefined;
|
|
scheduledKey = undefined;
|
|
};
|
|
|
|
const sync = (forceRestart = false) => {
|
|
const nextKey = completionKey();
|
|
if (nextKey === undefined) {
|
|
cancel();
|
|
return;
|
|
}
|
|
if (!forceRestart && timer !== undefined && scheduledKey === nextKey) return;
|
|
|
|
cancel();
|
|
scheduledKey = nextKey;
|
|
timer = setTimeout(() => {
|
|
timer = undefined;
|
|
if (completionKey() !== scheduledKey) return;
|
|
if (!tryClear()) sync();
|
|
}, Math.max(0, delayMs));
|
|
timer.unref?.();
|
|
};
|
|
|
|
return { sync, cancel };
|
|
}
|