feat: add task duration tracking

This commit is contained in:
lesetong
2026-07-28 17:39:45 +08:00
parent 57c3354211
commit 2ff0a314ed
10 changed files with 482 additions and 27 deletions
+25 -8
View File
@@ -3,23 +3,40 @@ import type { TaskState } from "./state.ts";
import { renderProgressHeader, renderTree } from "./ui.ts";
const WIDGET_ID = "pi-todo-herdr";
const TIMER_REFRESH_MS = 1000;
export function clearTaskWidget(ctx: ExtensionContext): void {
ctx.ui.setWidget(WIDGET_ID, undefined);
}
export function updateTaskWidget(state: TaskState, ctx: ExtensionContext, visible: boolean): void {
export function updateTaskWidget(
state: TaskState,
ctx: ExtensionContext,
visible: boolean,
refreshMs = TIMER_REFRESH_MS,
): void {
const tasks = state.list();
if (!visible || tasks.length === 0) {
clearTaskWidget(ctx);
return;
}
const stats = state.stats();
ctx.ui.setWidget(WIDGET_ID, (_tui, theme) => ({
render(width: number): string[] {
return [renderProgressHeader(stats, theme, width), ...renderTree(tasks, theme, width)];
},
invalidate(): void {},
}));
const hasActiveTimer = tasks.some((task) => task.status === "in-progress" && task.startedAt !== undefined);
ctx.ui.setWidget(WIDGET_ID, (tui, theme) => {
const timer = hasActiveTimer
? setInterval(() => tui.requestRender(), Math.max(1, refreshMs))
: undefined;
timer?.unref();
return {
render(width: number): string[] {
const currentTasks = state.list();
return [renderProgressHeader(state.stats(), theme, width), ...renderTree(currentTasks, theme, width)];
},
invalidate(): void {},
dispose(): void {
if (timer !== undefined) clearInterval(timer);
},
};
});
}