feat(desktop): add NIP-ER reminder UI — create, view, and manage encrypted reminders#963
Draft
wpfleger96 wants to merge 6 commits into
Draft
feat(desktop): add NIP-ER reminder UI — create, view, and manage encrypted reminders#963wpfleger96 wants to merge 6 commits into
wpfleger96 wants to merge 6 commits into
Conversation
wpfleger96
pushed a commit
that referenced
this pull request
Jun 11, 2026
wpfleger96
added a commit
that referenced
this pull request
Jun 11, 2026
8b4db46 to
d920ae7
Compare
acfbe1b to
5b2e79c
Compare
wpfleger96
pushed a commit
that referenced
this pull request
Jun 11, 2026
d920ae7 to
275ad4b
Compare
…ypted reminders Implements the desktop client UI for kind:30300 event reminders (NIP-ER): - Service layer (reminderService.ts): create, complete, snooze, and cancel reminders as individual parameterized-replaceable events with NIP-44 encrypt-to-self. Each reminder has a random d-tag, not_before timestamp, and encrypted content containing the target message reference and optional note. - "Remind me later" action: new menu item in MessageActionBar opens a dialog with time presets (30min, 1hr, 3hr, tomorrow 9am, next Monday 9am) and an optional note field. - Reminders panel: accessible from sidebar (Bell icon), shows pending reminders grouped by due status (overdue/today/upcoming) with complete/snooze/cancel action buttons per row. - Due-detection: local 60-second interval checks not_before against Date.now() and fires toast notifications when reminders become due. No relay scheduler dependency for v1 — purely client-side. - RemindMeLaterProvider context avoids prop-threading through 4 intermediate components; MessageRow uses the hook directly. All reminder content is NIP-44 encrypted — never stored or transmitted in plaintext. Completed/cancelled reminders get jittered 30-90 day expiration tags for eventual relay-side cleanup. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Captures 4 screenshots verifying the NIP-ER reminder feature renders correctly: sidebar nav item, message action menu, time-picker dialog, and empty reminders panel. Registered in the smoke project. Co-authored-by: Will Pfleger <wpfleger@squareup.com> Signed-off-by: Will Pfleger <wpfleger@squareup.com>
…enshots Radix UI components animate in via CSS transitions. Playwright's toBeVisible() resolves mid-animation, producing greyed-out or partially-rendered screenshots. - Create shared waitForAnimations(page) utility in tests/helpers/animations.ts - Wire it into screenshot.mjs so the just desktop-screenshot path settles animations automatically before capture - Update reminders-screenshots.spec.ts to call waitForAnimations before every page.screenshot(), add clip regions for focused captures - Update AGENTS.md to reference the shared helper as mandatory Co-authored-by: Will Pfleger <wpfleger@block.xyz> Signed-off-by: Will Pfleger <wpfleger@block.xyz>
dc0ded6 to
7388a58
Compare
Add a "Custom date & time" section below the time presets in the RemindMeLaterDialog, using native date and time inputs styled with the existing Input component. The date picker defaults to today and prevents selecting past dates. A "Set reminder" button creates the reminder at the user-selected timestamp. Also extends the screenshot spec to 6 tests: widens the action menu screenshot clip, adds tests for the reminders panel with active and fired/overdue reminders, and adds KIND_EVENT_REMINDER mock support to the e2e bridge for seeding reminder data in tests. Co-authored-by: Will Pfleger <wpfleger@block.xyz> Signed-off-by: Will Pfleger <wpfleger@block.xyz>
wpfleger96
pushed a commit
that referenced
this pull request
Jun 11, 2026
Collaborator
Author
1. Sidebar — Reminders nav itemThe bell icon in the sidebar navigation opens the Reminders panel. 2. Action menu — "Remind me later"Hovering a message and opening "More actions" reveals the "Remind me later" option in the context menu. 3. Time presets + custom date/time dialogClicking "Remind me later" opens a dialog with preset durations and a custom date/time picker (date defaults to today). 4. Reminders panel — empty stateThe Reminders panel before any reminders are set. 5. Reminders panel — active pending reminderA reminder scheduled for the future, showing in the "Upcoming" or "Today" group. 6. Reminders panel — fired/overdue reminderA reminder past its due time, shown in the "Overdue" group with urgency styling. |
wpfleger96
pushed a commit
that referenced
this pull request
Jun 11, 2026
Co-authored-by: Will Pfleger <wpfleger@squareup.com> Signed-off-by: Will Pfleger <wpfleger@squareup.com>
This was referenced Jun 11, 2026
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.






Summary
Adds the desktop client UI for NIP-ER (kind:30300 event reminders), completing the third PR in the reminder stack.
Users can set reminders on any message via a "Remind me later" action in the message context menu, view and manage all reminders from a dedicated sidebar panel, and receive toast notifications when reminders come due.
Stack: #934 → #957 → this PR
What's included
Service layer (
reminderService.ts)createReminder— builds a kind:30300 parameterized-replaceable event with random d-tag,not_beforetimestamp, and NIP-44 encrypted contentfetchReminders— queries own kind:30300 events and decrypts each individuallycompleteReminder/snoozeReminder/cancelReminder— publish replacement events with updated status and expiration tags"Remind me later" dialog (
RemindMeLaterDialog.tsx)Reminders panel (
RemindersPanel.tsx)/remindersroute)Due-detection (client-side)
setIntervalcomparesnot_beforeagainstDate.now()Wiring
RemindMeLaterProvidercontext avoids prop-threading through 4 intermediate componentsMessageRowusesuseRemindLater()hook to open the dialog with target contextDialogFootercomponent added to the shared dialog UI (was missing)/reminderspathDesign decisions
HomeFeedResponse/event_mentionspipeline. Due-detection is purely client-side.Files changed
desktop/src/shared/constants/kinds.tsKIND_EVENT_REMINDER = 30300desktop/src/shared/ui/dialog.tsxDialogFootercomponentdesktop/src/features/reminders/lib/reminderTypes.tsdesktop/src/features/reminders/lib/reminderService.tsdesktop/src/features/reminders/ui/RemindMeLaterDialog.tsxdesktop/src/features/reminders/ui/RemindMeLaterProvider.tsxdesktop/src/features/reminders/ui/RemindersPanel.tsxdesktop/src/features/reminders/ui/RemindersScreen.tsxdesktop/src/app/routes/reminders.tsxdesktop/src/app/routeTree.gen.ts/remindersroutedesktop/src/app/routes.tsdesktop/src/app/AppShell.tsxdesktop/src/app/navigation/useAppNavigation.tsgoRemindersdesktop/src/features/messages/ui/MessageActionBar.tsxonRemindLaterprop + menu itemdesktop/src/features/messages/ui/MessageRow.tsxuseRemindLaterhookdesktop/src/features/sidebar/ui/AppSidebar.tsx