Repository navigation
feat(reminders): polish the Reminders page - #1048
Conversation
kalvinnchau
left a comment
There was a problem hiding this comment.
🤖 One note-visibility regression found. Source-only review; no tests or rendered UI checks run.
| display: -webkit-box; | ||
| -webkit-line-clamp: 2; | ||
| -webkit-box-orient: vertical; | ||
| overflow: hidden; |
There was a problem hiding this comment.
🤖 [P2] Keep the full reminder note reachable
The shared two-line clamp now hides the rest of a reminder's note without an expansion action. This is reachable through the existing Remind me form, which accepts 4,096 characters: add a note longer than two wrapped lines, then open Reminders. Opening the row only navigates to the original message, which does not contain that separate note; note-only reminders have no open action at all. Previously the note wrapped in full. Keep notes fully readable, or provide a keyboard/touch-accessible way to expand them before clipping (also when the note is rendered through .preview). This follows the design guide's Responsiveness requirement to let content reflow before clipping.
wpfleger96
left a comment
There was a problem hiding this comment.
🤖 Thanks for this. Blocking: one correctness issue at a5005cbfcbf226016838fb800bbe523d01874ba2, plus agreement with Kalvin's note-clamp comment on this head.
1. The new relative due labels stop updating
dueLabel(model.ts:152) and the Done label (RemindersPage.tsx:381) are computed from the plugin clock the page reads atRemindersPage.tsx:74. That clock only moves incheck()(index.tsx:79), which runs when the reminder list or live snapshot changes, or when the next pending reminder comes due (index.tsx:159). Once every pending reminder is overdue,nextDelay(model.ts:32) schedules nothing, so the clock stops.- Result: a reminder that just came due reads "Overdue · just now" for as long as nothing else happens. A reminder labelled "Tomorrow at 9:00 AM" keeps saying Tomorrow after midnight, and "Done just now" never ages. The old page showed absolute times, so it couldn't go stale. Now the urgency and the due day can both be wrong.
- Reproduced headless in Chromium and WebKit with the real reminder service and plugin timer under a controlled browser clock: "Today at 12:01 PM" → "Overdue · just now" at the due time, and still "Overdue · just now" 11 minutes later. "Tomorrow at 9:00 AM" was unchanged at 00:01.
- Fix: give the mounted page its own display clock that refreshes on a bounded interval (or at the next label boundary) and on resume. Keep the due-notification timer as it is. Add fake-clock tests that cross an overdue-age boundary and midnight with no service events.
2. Long notes can't be read anymore (Kalvin's P2, agreed)
.preview, .notenow clamp to two lines (Reminders.module.css:141-144) with no way to expand. The Remind me form accepts notes up to 4,096 characters (RemindDialog.tsx:113). Opening the row goes to the original message, which doesn't include the note, and reminders with only a note can't be opened at all. Before this change the note wrapped in full.- Fix: show notes in full, or add a keyboard- and touch-reachable way to expand them. This applies to the
.previewpath for note-only reminders too.
What holds
- The action buttons and the row's open button are siblings, so Mark done, Snooze, and the menu don't also open the message. Confirmed in both engines.
- Remind me again goes through
snooze, which writespendingwith a new due time and no expiration. Done → pending survived a reload in both engines. - The "Done … ago" time comes from the replacement event, so it's the completion time.
- The day math in
dueLabelholds across DST transitions, a Saturday → Monday rollover, and a year boundary in several time zones. - The page reuses
NavigationItem,Avatar,IconButton,Menu,Accordion,InlineHeader, andEmptyStatewithout private recipes. 65/65 reminders Vitest tests and the four Chromium/WebKit layout cases pass at this head.
Optional
- The channel chip hand-builds radius, padding, and fill (
Reminders.module.css:116-125).InlineChipwithinteractive={false}already covers it. connection.status !== "ready"in the list condition can't be true whenremindersis set (useRemindersonly returns it when ready). It only narrows the type.- Mark done and Cancel unmount the focused row, so keyboard focus falls to the page body.
- CI: WebKit shards 4/8 (
agent-activity.spec.mjs:872) and 5/8 (unread.spec.mjs:185) failed on specs this PR doesn't touch. Main is red right now too. I've re-run them, and they still need to pass. - No
buzz-review-completedin the description yet.
|
🤖 Carl, Wes's AI agent: both review findings are addressed in 4d03f69.
The earlier WebKit failures ( |
Rows now read like Slack's Later list: the author's avatar and name, the
channel, a two-line message preview, an optional note, and a relative due
label ("Overdue · 2 hours ago", "Tomorrow at 9:00 AM"). The row opens its
message; Mark done, Snooze (each preset shows when it lands) and an
overflow menu with Open message and Cancel reminder appear on hover or
focus. Finished reminders can be brought back with Remind me again.
Groups get counts, Done collapses with the shared Accordion, and empty
pages use EmptyState with a hint for setting a reminder.
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The page's relative labels ("Overdue · just now", "Tomorrow at 9:00 AM",
"Done 5 minutes ago") only moved when a reminder came due or the list
changed, so once nothing was pending they went stale. While the page is
open, the shared clock now also ticks every 30 seconds. The due-time
timer is unchanged.
Only a message preview clamps to two lines, since the row opens the full
message. Notes have nowhere else to be read, so they wrap in full again,
including note-only reminders.
Co-authored-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
4d03f69 to
5509acd
Compare
kalvinnchau
left a comment
There was a problem hiding this comment.
🤖 [P2] Guard out-of-range reminder dates — RemindersPage.tsx:373
The reminder parser and native host accept not_before=8640000000001, but the new toISOString() call throws RangeError: Invalid time value because the value exceeds JavaScript's Date range. Rendering one such pending reminder prevents the entire Reminders page from rendering. Previously, formatDue() returned "Invalid Date" without throwing, leaving the other reminders accessible.
Guard the date conversion, provide a fallback for unsupported dates, and add coverage for this accepted timestamp boundary.
Reproduced using the parser from head 5509acda5b0053be06d3800f8fdb54360cf4f386. Full test suites and rendered app validation were not run. No other findings.
Scores: minimalness 10/10, elegance 10/10, correctness 8/10 because one accepted reminder can break the page. Approval withheld.
The relay accepts any safe-integer not_before, but values past JavaScript's Date range made the due label's toISOString() throw, so one such reminder took down the whole Reminders page. Those rows now render without a due label. Co-authored-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
|
🤖 Carl, an automated reviewer, commenting via Wes's GitHub account. Addressed Kalvin's out-of-range date finding in 0eb5b33: a pending reminder whose |
kalvinnchau
left a comment
There was a problem hiding this comment.
🤖 Prior findings are addressed; no new findings in the reviewed delta. Source-only review; tests and rendered UI checks were not rerun.
…-sessions * origin/main: (28 commits) docs: link the Buzz feedback community and @buzzdotxyz on X (#1091) feat(claude-code): save a thinking level in agent settings (#1089) feat(reminders): polish the Reminders page (#1048) fix(messages): keep thread panes beside channels when space allows (#1093) fix(inbox): show matching mentions instead of ordinary replies (#822) fix(relay): recover from network loss automatically with one retry owner (#992) fix(search): treat a full author lookup page as ambiguous (#1043) Show agent sessions in the profile Activity tab (#1040) fix(direct-messages): search again for people added after the directory completed (#1044) fix(claude-code): offer every model Claude lists (#1086) fix(plugins): reload the exact recorded source folder (#1030) test(browser): stop WebKit trace screenshots leaking macOS WindowServer surfaces (#1071) fix: decode broker request bodies as a utf-8 stream (#1038) fix(linux): use slight GTK hinting for clearer font spacing (#1047) Make Me conversations feel like project chats (#1005) fix(codex): deliver custom instructions without codex truncation (#1059) test(browser): fix the notification-reveal and nested-replies WebKit flakes (#1087) fix(messages): keep following after a notification reveals the latest row (#1085) Add native nsec backup HTTP client (#995) feat(buzz-mcp): add channel and member management tools (#1055) ... Signed-off-by: John Tennant <jtennant@block.xyz> # Conflicts: # src/bundled/sessions/SessionsPage.loading.test.tsx # src/bundled/sessions/SessionsPage.tsx
…lation * origin/main: (29 commits) docs: link the Buzz feedback community and @buzzdotxyz on X (#1091) feat(claude-code): save a thinking level in agent settings (#1089) feat(reminders): polish the Reminders page (#1048) fix(messages): keep thread panes beside channels when space allows (#1093) fix(inbox): show matching mentions instead of ordinary replies (#822) fix(relay): recover from network loss automatically with one retry owner (#992) fix(search): treat a full author lookup page as ambiguous (#1043) Show agent sessions in the profile Activity tab (#1040) fix(direct-messages): search again for people added after the directory completed (#1044) fix(claude-code): offer every model Claude lists (#1086) fix(plugins): reload the exact recorded source folder (#1030) test(browser): stop WebKit trace screenshots leaking macOS WindowServer surfaces (#1071) fix: decode broker request bodies as a utf-8 stream (#1038) fix(linux): use slight GTK hinting for clearer font spacing (#1047) Make Me conversations feel like project chats (#1005) fix(codex): deliver custom instructions without codex truncation (#1059) test(browser): fix the notification-reveal and nested-replies WebKit flakes (#1087) fix(messages): keep following after a notification reveals the latest row (#1085) Add native nsec backup HTTP client (#995) feat(buzz-mcp): add channel and member management tools (#1055) ... Signed-off-by: John Tennant <jtennant@block.xyz>
Summary
The Reminders page now reads like Slack's Later list instead of a stack of text blocks with four pill buttons.
#channelchip, a two-line message preview, an optional note, and a due label: "Overdue · 2 hours ago" (danger tone), "Today at 3:00 PM", "Tomorrow at 9:00 AM", "Friday at 9:00 AM", or a date.Accordion("Done · 2"). Finished reminders get Remind me again, which re-snoozes them through the existingsnoozepath. This one is a small new action; Wes tried it in the redesign.EmptyState("No reminders yet" / "You're all caught up").Built on shared owners:
NavigationItem(same row recipe as Inbox),Avatar,IconButton,Menu,Accordion,InlineHeader,EmptyState. No reminder model, protocol, or persistence changes.Validation
vitest run src/bundled/reminders: 67 passing, including new row-action, note-only, accessible-description, and date-label tests, plus a reminder whosenot_beforeis past JavaScript's Date range (the row renders without a due label instead of the page throwing).tests/browser/reminders-layout.spec.mjsupdated for the new row structure; passes in Chromium and WebKit at 480px and 390px.tsc, biome,design:check, and the commit and push hooks pass.BUZZ_DEV_VIEWER= just desktopwindow from this branch.🤖 Generated with Claude Code