max / goingson
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
1 file changed,
+91 insertions,
-44 deletions
| @@ -42,7 +42,7 @@ | |||
| 42 | 42 | //! exist and both are counted. The count starts falling at the flip. Progress is | |
| 43 | 43 | //! the first list, not the number. | |
| 44 | 44 | //! | |
| 45 | - | //! ## Described, and retires at the flip (32 files, 239 sites) | |
| 45 | + | //! ## Described, and retires at the flip (35 files, 259 sites) | |
| 46 | 46 | //! | |
| 47 | 47 | //! | Module | JS counterpart | Sites | | |
| 48 | 48 | //! |---|---|---| | |
| @@ -54,14 +54,16 @@ | |||
| 54 | 54 | //! | [`day_planning`] | `day-planning-render.js` 8, `day-planning-schedule.js` 4, `day-planning-paint.js` 1 | 13 | | |
| 55 | 55 | //! | [`problems`] | `problems.js` | 10 | | |
| 56 | 56 | //! | [`monthly_review`] | `monthly-review.js` 3, `monthly-review-render.js` 5 | 8 | | |
| 57 | - | //! | [`settings`] | `settings.js` | 11 | | |
| 57 | + | //! | [`settings`] | `settings.js` 11, `email-accounts.js` 10, `notifs.js` 0 | 21 | | |
| 58 | 58 | //! | [`board`] | `tasks-kanban.js` 3, `task-board.js` 1 | 4 | | |
| 59 | 59 | //! | [`task_list`] | `tasks.js` 2, `tasks-render.js` 8, `tasks-filter.js` 2, `task-forms.js` 1, `saved-views.js` 1 | 14 | | |
| 60 | 60 | //! | [`data`] | `import-external.js` 11, `import.js` 5, `export.js` 2 | 18 | | |
| 61 | 61 | //! | [`time_tracking`] | `time-tracking.js` 6, `time-summary.js` 3 | 9 | | |
| 62 | + | //! | [`events`] | `events.js` | 10 | | |
| 62 | 63 | //! | |
| 63 | - | //! [`projects`] carries its dashboard as a submodule, which is the thirteenth | |
| 64 | - | //! described screen against twelve modules here. | |
| 64 | + | //! Two rows carry a second screen as a submodule: [`projects`] its dashboard, | |
| 65 | + | //! and [`settings`] its email accounts section. So the fourteen rows here are | |
| 66 | + | //! sixteen described screens. | |
| 65 | 67 | //! | |
| 66 | 68 | //! [`time_tracking`] is the one row here that is two things: the app's chrome, | |
| 67 | 69 | //! described because the floating widget belongs to no screen, and the Timer | |
| @@ -84,52 +86,51 @@ | |||
| 84 | 86 | //! the rarer direction, a described screen's shape ported back, and it deletes | |
| 85 | 87 | //! at the flip like the rest of the row, along with `commands::notifs`. | |
| 86 | 88 | //! | |
| 87 | - | //! ## Stays JavaScript, by decision (4 files, 50 sites) | |
| 89 | + | //! `email-accounts.js` moved into that row on 2026-08-21 (`012ba4a`), out of | |
| 90 | + | //! the by-decision list below. The section had been called host-bound on the | |
| 91 | + | //! strength of its loudest feature; what is host-bound is the OAuth handshake, | |
| 92 | + | //! and the accounts themselves are `State<Arc<AppState>>` and synchronous | |
| 93 | + | //! throughout. [`settings::email`] describes them, and the handshake, Test | |
| 94 | + | //! Connection and Sync Now are what it refuses. | |
| 88 | 95 | //! | |
| 89 | - | //! - `settings-sync.js` 17, `settings-sharing.js` 14, `email-accounts.js` 10. | |
| 90 | - | //! Host-bound: OAuth flow, credential handling, `invoke(`. | |
| 96 | + | //! ## Stays JavaScript, by decision (3 files, 40 sites) | |
| 97 | + | //! | |
| 98 | + | //! - `settings-sync.js` 17, `settings-sharing.js` 14. Every group and sync | |
| 99 | + | //! command awaits a network client (12 `.await` sites in `commands/group.rs` | |
| 100 | + | //! alone) and a route handler is synchronous, so it cannot await one. | |
| 101 | + | //! Measured 2026-08-21, and it is a different reason from the `AppHandle` one | |
| 102 | + | //! this list used to give: `group.rs` never mentions `AppHandle`. | |
| 91 | 103 | //! - `search.js` 9. Settled 2026-08-13 (quasicoherent `d52884b0`): a described | |
| 92 | 104 | //! field's state is its value, and the caret is the renderer's. | |
| 93 | 105 | //! | |
| 94 | - | //! These 50 never reach zero by porting. Retiring `escape.js` means giving them | |
| 95 | - | //! typed escaping some other way, or accepting that four files keep an escaper. | |
| 106 | + | //! These 40 never reach zero by porting. Retiring `escape.js` means giving them | |
| 107 | + | //! typed escaping some other way, or accepting that three files keep an escaper. | |
| 96 | 108 | //! | |
| 97 | - | //! ## Un-ported screens (1 file, 10 sites) | |
| 109 | + | //! ## Un-ported screens (0 files, 0 sites) | |
| 98 | 110 | //! | |
| 99 | 111 | //! A described counterpart could exist and does not. This is the candidate list, | |
| 100 | - | //! and it is the only place to look for what is portable next. | |
| 112 | + | //! and it is the only place to look for what is portable next. It is empty as of | |
| 113 | + | //! 2026-08-21, for the first time since it was written: every screen the app has | |
| 114 | + | //! is described. | |
| 101 | 115 | //! | |
| 102 | - | //! The task list left this list on 2026-08-15 and is [`task_list`] now. It was | |
| 103 | - | //! the largest candidate here and the one this table had to name twice, because | |
| 104 | - | //! it is neither [`tasks`] (the single-task drawer at `GET /tasks/{id}`) nor | |
| 105 | - | //! [`board`] (the kanban). The three import and export files left it on | |
| 106 | - | //! 2026-08-16 and are [`data`] now — with a caveat this table cannot carry in a | |
| 107 | - | //! count: three exports and the on-demand backup are described nowhere, because | |
| 108 | - | //! a save destination has no word in the vocabulary and a described write cannot | |
| 109 | - | //! be offloaded. Their `esc()` sites are inside files that do retire, so the | |
| 110 | - | //! arithmetic here is honest and the screen is not yet whole. [`data`]'s findings | |
| 111 | - | //! 1 and 2 are what the flip waits on. `time-tracking.js` and `time-summary.js` | |
| 112 | - | //! left on 2026-08-20 and are [`time_tracking`]'s row above. | |
| 116 | + | //! What left it, in order. The task list on 2026-08-15, the largest candidate | |
| 117 | + | //! here and the one this table had to name twice because it is neither | |
| 118 | + | //! [`tasks`] (the single-task drawer at `GET /tasks/{id}`) nor [`board`] (the | |
| 119 | + | //! kanban). The three import and export files on 2026-08-16, now [`data`], with | |
| 120 | + | //! a caveat this table cannot carry in a count: three exports and the on-demand | |
| 121 | + | //! backup are described nowhere, because a save destination has no word in the | |
| 122 | + | //! vocabulary and a described write cannot be offloaded. Their `esc()` sites are | |
| 123 | + | //! inside files that do retire, so the arithmetic here is honest and the screen | |
| 124 | + | //! is not yet whole. [`data`]'s findings 1 and 2 are what the flip waits on. | |
| 125 | + | //! `time-tracking.js` and `time-summary.js` on 2026-08-20, now | |
| 126 | + | //! [`time_tracking`]'s row. `events.js` on 2026-08-21, now [`events`]: the | |
| 127 | + | //! largest file in `frontend/js/` at 1,037 lines, and the tab the thirteen flip | |
| 128 | + | //! tasks did not name. | |
| 113 | 129 | //! | |
| 114 | - | //! - `events.js` 10. Measured 2026-08-21, and the sentence that stood here was | |
| 115 | - | //! wrong twice over: there is no grid in the file, and all ten sites are | |
| 116 | - | //! describable. It is three lists, a form and a detail modal — no calendar | |
| 117 | - | //! rendering of any kind, which lives elsewhere. Sites 543/553/558 and | |
| 118 | - | //! 618/623 are `renderEventRow`'s title, location and recurrence-pattern | |
| 119 | - | //! cells (a described table), 791/798/802/805 are the detail modal | |
| 120 | - | //! (`Region::Modal` plus text), and 123 is the reminder-preset checkbox list | |
| 121 | - | //! (a `Choice` set). The whole file is a real candidate, which is more than | |
| 122 | - | //! the old note claimed and not less. | |
| 123 | - | //! | |
| 124 | - | //! Three things the port will meet, none of them blockers. The three | |
| 125 | - | //! `VirtualScroller`s over `renderEventRow` are the case [`task_list`]'s | |
| 126 | - | //! finding 2 and [`emails`]'s `list` already settled: windowing rows you hold | |
| 127 | - | //! is a renderer technique, and a described list answers it with `Rest`. | |
| 128 | - | //! `start_time`/`end_time` carry a `transform` that natural-parses the text | |
| 129 | - | //! before submit and an `onInput` preview beside the box, which is host | |
| 130 | - | //! behaviour on either side of a `Field` rather than something the field | |
| 131 | - | //! says. The `timezone` field's validity depends on `tz_kind`, so a described | |
| 132 | - | //! form either validates it on the server or the two travel together. | |
| 130 | + | //! An empty list is not the end of the porting. It means the remaining | |
| 131 | + | //! JavaScript is in the three categories that are not screens: the by-decision | |
| 132 | + | //! files above, the bespoke one below, and the shell, which no row here reaches | |
| 133 | + | //! and which is the real remainder. It has its own section below. | |
| 133 | 134 | //! | |
| 134 | 135 | //! ## Bespoke (1 file, 6 sites) | |
| 135 | 136 | //! | |
| @@ -155,9 +156,53 @@ | |||
| 155 | 156 | //! `autocomplete.js` 2, `bulk-actions.js` 2, `plan-review-toggle.js` 2, | |
| 156 | 157 | //! `snooze.js` 2, `form-modal.js` 1, `groups.js` 1. | |
| 157 | 158 | //! | |
| 158 | - | //! Together with the 50 above, these 77 sites are what the done-condition | |
| 159 | + | //! Together with the 40 above, these 67 sites are what the done-condition | |
| 159 | 160 | //! actually has to answer for. Porting every candidate screen leaves them. | |
| 160 | 161 | //! | |
| 162 | + | //! ## The shell, which no row above reaches (38 files, 9,114 lines) | |
| 163 | + | //! | |
| 164 | + | //! Measured 2026-08-22, and it is the reason a table that looks complete is | |
| 165 | + | //! not. The four categories above account for every `esc()` call site in the | |
| 166 | + | //! tree and for 49 of the 87 files under `frontend/js/`. The other 38 are 9,114 | |
| 167 | + | //! lines and appear in no category, because the accounting here is `esc()`- | |
| 168 | + | //! centric and the shell concatenates almost nothing: it wires, routes, and | |
| 169 | + | //! switches panes. A file with no call site was invisible to every count on | |
| 170 | + | //! this page, so the remainder never read as missing. | |
| 171 | + | //! | |
| 172 | + | //! The largest of them, and what each is: `utils.js` 704, `components.js` 594 | |
| 173 | + | //! (context menu, action sheet), `navigation.js` 545 (view switching, the tab | |
| 174 | + | //! bar, window title), `api.js` 500, `app.js` 471 (bootstrap, the Tauri menu), | |
| 175 | + | //! `virtual-scroller.js` 453, `mobile.js` 447 and `touch.js` 444, | |
| 176 | + | //! `keyboard.js` 279 (the shortcut table and the help overlay), `themes.js` | |
| 177 | + | //! 277, `router.js` 107, `dispatch.js` 109, `state.js` 158. | |
| 178 | + | //! | |
| 179 | + | //! Nothing on the described side draws any of it. [`quasi_router::Chrome`] | |
| 180 | + | //! carries key bindings and one panel, and goingson declares the panel as | |
| 181 | + | //! [`time_tracking::chrome`], the running-timer band. That is the whole of the | |
| 182 | + | //! app furniture that exists on this side. A tab bar is a second always-present | |
| 183 | + | //! thing and there is no second panel, which is a vocabulary question rather | |
| 184 | + | //! than a porting one: quasicoherent `71aa29b4`, with the goingson half on | |
| 185 | + | //! `24aa5833`. | |
| 186 | + | //! | |
| 187 | + | //! Four files in the remainder are screen controllers rather than shell, and | |
| 188 | + | //! are candidates for a pairing row once somebody reads them against the | |
| 189 | + | //! description: `day-planning.js` 541 (the day plan's own load and render, next | |
| 190 | + | //! to the three files [`day_planning`] already pairs), `compose-page.js` 304 | |
| 191 | + | //! (Max's call on `3fb2526a`, compose becomes a widget of primitives), | |
| 192 | + | //! `focus-timer.js` 283 (the Focus control [`time_tracking`] leaves out, waiting | |
| 193 | + | //! on goingson `44cfcac7`), and `emails-threads.js` 116. They are named here | |
| 194 | + | //! rather than paired, because pairing one makes the drift check watch it from | |
| 195 | + | //! the commit the module was added, and each wants its own read first. | |
| 196 | + | //! | |
| 197 | + | //! ## Modules that describe no screen | |
| 198 | + | //! | |
| 199 | + | //! Read by `witchbroom`'s `described-drift` check, which otherwise takes every | |
| 200 | + | //! `pub mod` under this root for a screen whose pairing row somebody forgot. | |
| 201 | + | //! | |
| 202 | + | //! - [`assets`]. The stylesheets, scripts and fonts a described document asks | |
| 203 | + | //! for. It answers at addresses no route claims and pairs with nothing under | |
| 204 | + | //! `frontend/js/`. | |
| 205 | + | //! | |
| 161 | 206 | //! # The ports checked against their counterparts | |
| 162 | 207 | //! | |
| 163 | 208 | //! Swept 2026-08-15, after [`tasks`] turned out to be describing a screen that | |
| @@ -180,9 +225,11 @@ | |||
| 180 | 225 | //! | [`projects`] | `0df3488`, both markers on the dashboard card | [`Availability::marker`] | | |
| 181 | 226 | //! | [`day_planning`] | `0df3488`, the unblocks marker in the pool | [`Availability::frees_marker`] | | |
| 182 | 227 | //! | [`projects`], [`tasks`] | `5e16cc1`, a CSS class rename across six files | presentational only: nothing a description can say changed | | |
| 228 | + | //! | [`settings`] | `dda9a7c`, the knob half of the notifications pane | already generated: [`quasi_notifs::pane`] emits a control per declared knob and [`settings`] reads the registry, so this is the shipped screen catching up | | |
| 229 | + | //! | [`task_list`] | `c238caa`, a pinned saved view's U+2022 became a `data-pinned` attribute | presentational, and inside saved views, which this module's finding 4 declines to describe | | |
| 183 | 230 | //! | |
| 184 | - | //! Clean: [`contacts`], [`settings`], [`weekly_review`], [`emails`], | |
| 185 | - | //! [`monthly_review`], [`problems`]. Four of those now have a commit touching | |
| 231 | + | //! Clean: [`contacts`], [`weekly_review`], [`emails`], [`monthly_review`], | |
| 232 | + | //! [`problems`], [`events`]. Four of those now have a commit touching | |
| 186 | 233 | //! their JS since the port, and each of those touched the description in the | |
| 187 | 234 | //! same commit, which is the arrangement that works. [`weekly_review`] joined | |
| 188 | 235 | //! them when the focus picker learned to name what a candidate waits on: the |