-
-
Notifications
You must be signed in to change notification settings - Fork 325
Notifications dashboard #738
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
adc7bed to
06e9bbf
Compare
|
Looks awesome! Wanted to mention that it seems the VideoCleanShot.2026-01-08.at.20.08.14.mp4 |
06e9bbf to
3f2ee3b
Compare
Thanks for catching that~ I’ve fixed it now, and pushed an update to this branch |
bc4e144 to
c74dc61
Compare
|
Hey man, I did a quick mockup of how I would like this to look. Things to note:
|
What if the title is too long to fit in one line? e.g., if the user is showing the Preview?
|
I think it's fine to put ellipsis there |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
haven't finished going over all files, but there's enough to start.
thanks for putting all the work in! it looks amazing :)
internal/tui/components/notificationssection/notificationssection.go
Outdated
Show resolved
Hide resolved
This comment was marked as outdated.
This comment was marked as outdated.
7457b67 to
f3a1fd3
Compare
f6cb8f4 to
2991b5e
Compare
2991b5e to
98b0395
Compare
This change adds a new Notifications view to dash that displays GH notifications — allowing you to triage your GH "inbox" within dash. - View unread notifications with type icons (PR, Issue, Discussion, Release) - Mark notifications as done (d) or read (m) - Mark all notifications as done (D) or read (M) - Unsubscribe from notification threads (u) - Bookmark notifications to keep them visible after marking read (b) - Open notifications in browser (o) or view in sidebar (Enter) - Sort by repository (S) - Filter by repo:owner/name and is:unread/read/all/done - Toggle smart filtering to current repo (t) - New-comment count indicator for PR/Issue notifications - Actor display: shows @username of who triggered the notification - Auto-scroll to latest comment when viewing Bookmark system: - Local storage in ~/.config/gh-dash/bookmarks.json - Bookmarked items appear in default view even when read - Explicit "is:unread" search excludes bookmarked+read items Actor display: - Fetches author from latest_comment_url, falls back to PR/Issue author - Appends @username to notification title (helps identify spam) - Color configurable via theme.colors.text.actor The implementation follows existing patterns from PR and Issue views, but in this case with requiring you to explicitly/intentionally initiate the "view" action — to prevent accidental "read" marking.
Implements maintainer feedback from PR review: Row layout now shows three lines per notification: - Line 1: repo/name #number + bookmark icon if bookmarked (SecondaryText for unread, FaintText for read) - Line 2: Title (PrimaryText, bold for unread notifications) - Line 3: Activity description (FaintText color) Activity descriptions are generated based on notification reason and actor: - comment: "@username commented on this pull request/issue" - review_requested: "@username requested your review" - mention: "@username mentioned you" - author: "Activity on your thread" - assign: "You were assigned" - state_change: "Pull request/Issue state changed" - ci_activity: "CI activity" - subscribed: "@username commented on this pull request/issue" Preview pane prompt improvements: - Added "S sort by repo" to the actions list - "(Note: this will mark it as read)" now appears for all notification types - Non-PR/Issue types show "Press Enter to open in browser" (simplified) Technical changes: - Bookmark icon moved to end of line 1 (removed separate bookmark column) - Row content uses raw ANSI codes without resets to preserve background colors - Title truncation handled dynamically by table based on actual column width - Table adds ellipsis when truncating multi-line content - getStylePrefix() helper extracts ANSI codes from lipgloss styles without reset - Columns reduced from 5 to 4 (type, title block, activity count, timestamp)
- Use blue dot below icon to indicate unread notifications instead of faint text styling — the dot is the sole visual indicator of read status - Keep notifications marked as read visible in the inbox until the user manually refreshes or restarts (sessionMarkedRead tracking) - Respect smartFilteringAtLaunch setting — scope to current repo by default when running from a clone directory, show repo:owner/name in search input to indicate active filtering - Footer view switcher improvements: - Gold/yellow color for notification bell when active - Solid bell icon for active, outline bell for inactive - Add column-alignment documentation (align: left/right/center)
…ow runs The GH API just returns subject.url=null for CheckSuite notifications — making it impossible to deterministically identify the specific workflow it came from, and directly link to it. So, this change: - Adds async URL resolution that fetches recent workflow runs, and finds the best match based on timestamp proximity to the notification - Initially shows /actions page as a placeholder; updates to specific run URL once resolved - Adds ResolvedUrl field to notification data for async-resolved URLs - Exposes a FindBestWorkflowRunMatch() function for testability - Adds a bunch of tests for workflow-run matching logic
- Add pagination support for notifications (fetches more as user scrolls) - Add `defaults.notificationsLimit` config option (default: 20) - Update docs and DESIGN.md with new configuration
…highlighting All notification row columns now render 3 lines to match the Title column. This ensures the selected row background color extends properly across all columns. Uses raw ANSI codes without resets to preserve parent background.
…ation content When viewing a PR or Issue notification in the preview pane, the keybindings from the PR and Issue tabs are now available: PR notifications: - [/] sidebar tabs, v approve, a assign, A unassign, c comment - d diff, C checkout, x close, W ready, X reopen, m merge, u update - e summary view more Issue notifications: - L label, a assign, A unassign, c comment, x close, X reopen Note: PR/Issue keybindings take precedence over notification keybindings when viewing content (e.g., 'd' triggers diff instead of markAsDone).
…hboard This change adds multiple configurable sections in the Notifications dashboard — to parallel the behavior we have for PRs and Issues. Users can define their own custom sections — just as for PRs and Issues. Default sections: - All, Created, Participating, Mentioned, Review Requested, Assigned, Subscribed, Team Mentioned New features: - reason: filter support (author, comment, mention, review-requested, assign, subscribed, team-mention, state-change, ci-activity) - reason:participating meta-filter expands to multiple reasons - Search section (magnifying glass) for one-off queries - Search section respects smartFilteringAtLaunch setting - Client-side reason filtering after API fetch
This changes fetching of notifications such that now, bookmarked and session-marked-read notifications are fetched separately by thread ID on the first page — allowing the main fetch to use the user's intended filter (“show unread” by default). That keeps unread notifications consolidated, and keeps pagination working correctly. Otherwise, without this change, when bookmarks or session-marked-read notifications exist, the fetch logic switched to “all=true” to include read notifications. But that causes unread notifications to be scattered across many pages (mixed with “read” ones) — breaking pagination: users would only see ~20 notifications instead of all their unread items.
This change adds local tracking of “Done” notification IDs in a persistent local store (“~/.local/state/gh-dash/done.json”) — similar to how we handle Bookmarked notifications. And so now we never show the user any notifications they have locally marked as “Done” in dash. Otherwise, without this change, we have a fundamental problem: GitHub’s “mark as done” API doesn’t actually delete notifications; instead, they still appear in “all=true” API responses. And that causes users to see those “Done” notifications when they filter to “is:read” or “is:all”. This change also refactors our BookmarkStore around a shared NotificationIDStore implementation that we use for our DoneStore, too.
… locally This change ensures that users see a full page of results even when many notifications have been marked as done locally — by making these changes: - Switch to calculating HasNextPage _before_ read-state filtering, based on raw API response count - Add a loop that fetches additional pages until the requested limit is reached, or all pages are exhausted Otherwise, without this change: When filtering to “is:read”, most notifications might be filtered out by the local “Done” store, leaving very few visible. So, pagination would end prematurely, because HasNextPage was calculated _after_ read-state filtering. So, if 20 notifications were fetched but only 5 were read, HasNextPage would be false (5 < 20).
…avior - Add notification-section to docs sidebar (astro.config.mjs) - Change getStateFilePath to return (string, error) for proper error handling - Update outline bell icon to nf-fa-bell_o (U+F0A2) - Apply gold color to both icon and label in active notifications view - Extract viewSeparator const in footer - Use distinct icons for open/closed issues (U+F41B/U+F41D) - Update discussion icon to nf-oct-comment_discussion (U+F442) with white color - Update release icon to nf-oct-tag (U+F412) with blue color - Extract GetStylePrefix to utils package for reuse - Add clarifying comment for markAllAsDone scope - Advance cursor to next notification after marking as read
Move the notification subject cache (subjectPR, subjectIssue, subjectId) from the top-level Model in ui.go to notificationview.Model where it logically belongs. This improves encapsulation by keeping the cached subject data in the component responsible for displaying it.
… descriptors Have prview.Update() and issueview.Update() recognize all PR/Issue keys and return action descriptors, allowing the UI to forward key messages and handle the returned actions. This reduces duplication in notification view key handling and means adding a new keybinding only requires changes in the respective view's Update(). Changes: - Add PRAction type and PRActionType enum in new action.go file - Add IssueAction type and IssueActionType enum - Change prview.Update() signature to return (Model, tea.Cmd, *PRAction) - Change issueview.Update() signature to return (Model, tea.Cmd, *IssueAction) - Add key matching for all PR/Issue keys in respective Update() functions - Update all call sites in ui.go - Consolidate notification view key handling to use returned actions - Add comprehensive tests for action types and key handling
…rity - Extract markNotificationAsRead helper to consolidate duplicate notification read state update logic - Extract updateNotificationSections helper for section updates - Rename notification view functions for better clarity
Use tea.Batch to run the mark-as-read API call in parallel with fetching PR/Issue data, so the content displays without waiting for the mark-as-read to complete. This matches the pattern already used in the default case.
…ection module Move openInBrowser, DiffPR, and CheckoutPR commands from ui.go to notificationssection/commands.go, following the pattern established by prssection (checkout.go, diff.go). - Add openInBrowser() method to handle the Open key in the section - Add DiffPR() and CheckoutPR() standalone functions that accept PR data - Update ui.go to pass Open key to section and call standalone functions - Add tests for DiffPR and CheckoutPR - Document the command architecture in DESIGN.md
Move the DiffPR function from notificationssection to the common package so it can be shared between prssection and notificationssection without duplication.
…tifications Parse workflow-run notification titles for “failed”/“succeeded” keywords and indicate the status in dash by setting the icon accordingly, in the appropriate green or not-green color — similar to what gitify does.
7218e69 to
245daed
Compare
- Add notificationrow_test.go with tests for reason descriptions, CheckSuite status parsing, activity rendering, and state handling - Add filter parsing edge case tests for whitespace, duplicate filters, and combined filter scenarios - Add bookmark store edge case tests for file I/O errors, special characters, and idempotent operations - Add GetStylePrefix tests for various lipgloss style types
245daed to
8834945
Compare
- Parallelize API calls for missing bookmarked/session-marked-read notifications using goroutines instead of sequential fetches - Convert filter slices to maps for O(1) lookups (reason filters, repo filters, bookmark IDs) - Make bookmark/done store file I/O async to avoid blocking UI - Add Flush() method for test synchronization with async saves
Change prview.Update from returning (Model, tea.Cmd, *PRAction) to the standard Bubble Tea signature (Model, tea.Cmd). Key-to-action mapping is now handled by a separate MsgToAction function that callers invoke after checking IsTextInputBoxFocused(). This makes the API more idiomatic and explicit about when action detection should occur.
Extract repeated patterns into reusable helper methods: - openSidebarForPRInput: opens sidebar with GoToFirstTab for PR actions - openSidebarForInput: opens sidebar and syncs content - promptConfirmation: shows confirmation prompt on section Reduces 16 instances of duplicated 5–6 line blocks across PRsView, IssuesView, and NotificationsView handlers to single-line calls.
The NotificationIDStore.Add() method spawns async goroutines calling save(). Multiple concurrent saves could race on os.WriteFile, which truncates before writing — causing readers to see empty files. Fix by using unique temp files (os.CreateTemp) with atomic rename.
Expose the PR author's username as {{.Author}} in custom keybinding
command templates for both PR and branch views.
…to prView) This change makes us unconditionally sync the sidebar and return after updating prView — ensuring tab changes get reflected in the UI. Otherwise, without this change, tab navigation in the PR sidebar wasn't working when viewing a PR notification. The code only returned after prView.Update() when prCmd was non-nil – but tab navigation (carousel.MoveLeft/MoveRight) updates state without returning a command.


Summary
This change adds a new Notifications view to dash that displays GH notifications — allowing you to triage you GH "inbox" within dash. Fixes #141
Bookmark system:
The implementation follows existing patterns from PR and Issue views, but in this case with requiring you to explicitly/intentionally initiate the "view" action — to prevent accidental "read" marking.
How did you test this change?
Added new tests:
Images/Videos