[feature] every meeting in one list, read down a calendar - #337
Merged
Merged
Conversation
The library could only be browsed a folder at a time. `LibraryNode` had exactly two shapes — a folder, or 還沒歸檔 — so there was no node meaning "everything", and the only other way in was the home screen's six most recent. Finding a recording therefore required remembering which folder you filed it in, which is precisely the thing people forget. Adds an `all` node above the folders. It is a VIEW rather than a home: it matches every recording instead of owning any, so `ownerNode` can never return it and it stays out of the `countByNode` pass (folding it in would double every recording in the tree total). Its count is simply the number of summaries — still a count of exactly what clicking it opens, which is the #195 invariant. The node renders a timeline, not the card grid. A folder answers "what is in here" and a card is the right shape for that; this node answers "what did I sit through lately", which is a scanning question — rows read down a column, date headers give the eye somewhere to stop, and roughly twice as many recordings fit on screen. Grouping is 今天 / 昨天 / 本週稍早 and then by month, computed by a pure clock-injected module so the boundaries are pinned down by tests rather than by waiting until midnight. Yesterday deliberately outranks the week boundary: on a Monday, "昨天" beats "上個月" for something recorded on the Sunday. Rows carry the same four actions as a card (move, share, rename, delete) by reusing `CardActions` — filing something you have just found is most of the point of a view that spans every folder. The home screen keeps its six and gains a way out of them; the ⌘K palette gains the node too, so the two ways of naming a place stay in step. Closes #330
Three things only showed up once the component was on screen:
The 12-hour clock zh-TW produces ("下午02:38") wrapped the narrow leading
column onto two lines. A dense list of meetings wants a tabular 24-hour clock
anyway.
The folder chip was right-aligned inside the flexible half of the row, so how
far right it landed depended on how wide that row's stats happened to be — a
ragged column that read as noise. It belongs beside the title, with a spacer
taking the slack so the stats stay pinned to the right edge.
Re-filing from the all node dropped the row out of the list, because `move`
assumed a node the recording could leave. It can leave a folder; it cannot
leave "everything". There, only the folder chip changes.
✅ SonarQube Quality Gate passed — pathorsAI_parley0 open issues on this PR. |
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #330.
The problem
The library could only be browsed a folder at a time.
LibraryNodehad exactly two shapes — a folder, or 還沒歸檔 — so no node meant "everything", and the only other way in was the home screen's six most recent. Finding a recording therefore required remembering which folder you filed it in, which is precisely the thing people forget.The node
Adds an all node above the folders. It is a view rather than a home: it matches every recording instead of owning any, so
ownerNodecan never return it and it stays out of thecountByNodepass — folding it in would double every recording in the tree total. Its count is simply the number of summaries, so it is still a count of exactly what clicking it opens, which is the invariant #195 established.Scope is personal recordings only. 組織共享 keeps its own node: a recording shared into an org would otherwise appear twice, and the org scopes load through a different path.
Why a timeline and not the card grid
A folder answers "what is in here", and a card — title, snippet, four stats — is the right shape for that. This node answers "what did I sit through lately", which is a scanning question. Rows read down a column, the date headers give the eye somewhere to stop, and roughly twice as many recordings fit on screen. Nothing about the folder grid changes; the two live side by side on purpose.
Grouping is 今天 / 昨天 / 本週稍早 and then by calendar month, in a pure clock-injected module (
lib/library/timeline.ts) so the boundaries are pinned down by tests rather than by waiting until midnight. Two rules worth calling out:Rows carry the same four actions as a card (move, share, rename, delete) by reusing
CardActions— filing something you have just found is most of the point of a view that spans every folder.Elsewhere
The home screen keeps its six and gains a way out of them. The ⌘K palette gains the node too, so the two ways of naming a place stay in step.
What it looks like
The timeline rendered from the real component. The app itself could not be launched to shoot it in place —
tauri-plugin-single-instancehands off to the installed Parley.app, which was running.Verification
bunx tsc --noEmitandbunx vitest run(342 tests) both pass. New tests cover the date bucketing (13 cases, including the DST-safe boundaries and the Monday rule) and the all node's behaviour inscope.test.ts— that it takes every recording, thatownerNodecan never return it, and that the tree total is not doubled.The three fixes in the second commit are things that only showed up once the component was rendered and looked at, not caught by types or tests: zh-TW's 12-hour clock wrapped the narrow leading column onto two lines, the folder chip's right alignment made a ragged column, and re-filing from this node dropped the row out of a list it had not actually left.
🤖 Generated with Claude Code