A time session records which feature started it, and what it counts down to
Track and Focus wrote the same row and nothing in the store told them apart.
`time-tracking.js` held the answer in `activeMode` and `focus-timer.js` held the
countdown in `remainingSeconds`, both variables in the JS process, and the file
said so itself: a timer found running after a reload read as Tracking whichever
it had been.
Migration 068 gives `time_sessions` a `mode` and an `ends_at`. `mode` defaults to
'track', which is what every existing row was displayed as anyway, so no backfill
is owed. `ends_at` stays NULL on Track sessions and on a Focus session started
before the column existed; there is no honest value to invent for one, and the
band shows elapsed time instead of a countdown it cannot rebuild.
Two entry points rather than a mode parameter: `start_timer` is Track and
`start_focus_session` is Focus, because there are two features and a caller
cannot pick the wrong one by accident. The end instant is computed server-side
from the split, off the same clock `started_at` is stamped from.
WHAT IT UNBLOCKS ON THE DESCRIBED SIDE, both recorded as refusals in
`quasi::time_tracking`'s header since the port. The band names the mode off the
session. A focus session's readout is `Node::Until` holding the instant it was
started for where a tracked one is `Node::Since` holding its start, so the
countdown survives a reload and neither is a number a route computed. And the
Timer row offers Focus again, spending the split the address carries at the
moment it is pressed, with the minutes in the label because a description has no
`title` to hide them in.
The overlay is still refused. `focus-timer.js` draws a full-screen countdown and
an overlay needs a container quasi-webview emits only alongside a chrome
binding, which is quasicoherent `858be2a6`. What this draws instead is the band,
on every screen, counting to the same instant. The reason the control was left
out was that a Focus button differing from Track only in its toast is worse than
its absence; that is no longer what it would be.
Reaching `ends_at` is not a state change. Nothing closes the session there: it
ends when somebody stops it, the same as Track.
Sync carries both columns, the triggers name them, restore writes them, and the
shipped JS reads the mode off the session rather than out of its own process.
Nine tests: the two entry points, a round trip through the store, a manual entry
(started by no feature, so Track with no countdown), the one-timer rule not
caring which feature asked, both bands, and the split the screen spends.
Closes goingson 44cfcac7.
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
18 files changed,
+580 insertions,
-81 deletions
| 68 |
68 |
|
065 734a797c90c0447e413fb4fde8a19d26a52752adbea385ca30f2b2369a281bc4275e57d088a8fe73c6d5adef816a195e
|
| 69 |
69 |
|
066 ddea0b76234ce4d2aa4482b01ac304efb64624c854aa916ca7ad6a43bc978bce5a8f890378880c5b0d2469c8f753d50d
|
| 70 |
70 |
|
067 6ac04d5280e01472180139ba6a5ae83be242dbcae8ca5b1adf90c15ad01507f734047262fd987bc8eb50c238f96621d8
|
|
71 |
+ |
068 ccdddaa4176f36169bb90b1eec191ae776a87ee1cd56ba2bd789f905fb212bcd2b04b884e820498fab8b6d03fb7e5c6d
|
| 339 |
339 |
|
$crate::commands::import_ics,
|
| 340 |
340 |
|
// Time Tracking
|
| 341 |
341 |
|
$crate::commands::start_timer,
|
|
342 |
+ |
$crate::commands::start_focus_session,
|
| 342 |
343 |
|
$crate::commands::stop_timer,
|
| 343 |
344 |
|
$crate::commands::discard_timer,
|
| 344 |
345 |
|
$crate::commands::get_active_timer,
|
| 92 |
92 |
|
ProjectStatus, ProjectType, Recurrence, RecurrenceRule, SavedView, SortDirection, SortField,
|
| 93 |
93 |
|
StatusToken, Subtask, SyncAccount, TOKEN_KIND_COMMIT, Task, TaskDependency, TaskEstimate,
|
| 94 |
94 |
|
TaskFilterQuery, TaskGraph, TaskGraphNode, TaskSortColumn, TaskStatus, TimeReport,
|
| 95 |
|
- |
TimeReportProject, TimeSession, TimeSummaryPanel, TimeSummaryProject, TimeTrackingSummary,
|
| 96 |
|
- |
TokenState, TzKind, UpdateEmailAccount, UpdateEvent, UpdateProject, UpdateTask, User,
|
| 97 |
|
- |
ViewFilters, ViewType, WeeklyReview, format_file_size, mime_from_extension,
|
|
95 |
+ |
TimeReportProject, TimeSession, TimeSessionMode, TimeSummaryPanel, TimeSummaryProject,
|
|
96 |
+ |
TimeTrackingSummary, TokenState, TzKind, UpdateEmailAccount, UpdateEvent, UpdateProject,
|
|
97 |
+ |
UpdateTask, User, ViewFilters, ViewType, WeeklyReview, format_file_size, mime_from_extension,
|
| 98 |
98 |
|
roll_up_time_report, roll_up_time_summary, sanitize_reminder_offsets, snap_all_day_span,
|
| 99 |
99 |
|
split_description,
|
| 100 |
100 |
|
};
|