feat(ui,store): live today clock, rail as lane filter, b toggle, quick look on space

This commit is contained in:
hh
2026-08-23 16:44:57 +02:00
parent 83ca32d98e
commit 0a7742eb5e
19 changed files with 1236 additions and 192 deletions
+34 -2
View File
@@ -67,6 +67,14 @@ function stepTray(view: ViewContext, direction: Direction): void {
if (direction === "up") store.toggleUndated();
}
/**
* Runs one action as if its key had been pressed, so a button drawn anywhere
* does exactly what the sheet says the key does.
*/
export function perform(view: ViewContext, action: Action): Promise<void> {
return run(view, action);
}
async function run(view: ViewContext, action: Action): Promise<void> {
const { app, store } = view;
const task = store.taskById(store.cursorTask);
@@ -100,7 +108,10 @@ async function run(view: ViewContext, action: Action): Promise<void> {
else store.cursorTask = null;
return;
case "taskOpen":
if (task) await revealInFile(view, task);
if (task) {
store.peeking = false;
await revealInFile(view, task);
}
return;
case "taskToggle":
if (task) await setStatus(app, task, isOpen(task.status) ? "x" : " ");
@@ -109,11 +120,17 @@ async function run(view: ViewContext, action: Action): Promise<void> {
if (task) store.edit(task.id);
return;
case "taskEditRaw":
if (task) await editInTasks(view, task);
if (task) {
store.peeking = false;
await editInTasks(view, task);
}
return;
case "taskPriority":
if (task) store.request = "priority";
return;
case "taskPeek":
store.peek();
return;
case "taskBack":
if (task) await shift(view, task, -1);
return;
@@ -161,6 +178,12 @@ async function run(view: ViewContext, action: Action): Promise<void> {
case "railChoose":
store.chooseRail();
return;
case "railToggleRow":
store.toggleRailRow();
return;
case "railLeave":
store.leaveRail();
return;
case "create":
openComposer(view);
@@ -258,6 +281,15 @@ export function handleKey(view: ViewContext, event: KeyboardEvent): void {
return;
}
// The quick look is a lens, not a layer: every key still reaches the task
// underneath, and only Escape is taken to put the lens away.
if (store.peeking && event.key === "Escape") {
event.preventDefault();
event.stopPropagation();
store.peeking = false;
return;
}
const action = resolve(event, scopesFor(view));
if (!action) return;
event.preventDefault();