Skip to content

feat(notifications): type filters, date grouping, compact rows#6209

Closed
tsahimatsliah wants to merge 44 commits into
mainfrom
claude/quizzical-bose-994274
Closed

feat(notifications): type filters, date grouping, compact rows#6209
tsahimatsliah wants to merge 44 commits into
mainfrom
claude/quizzical-bose-994274

Conversation

@tsahimatsliah

@tsahimatsliah tsahimatsliah commented Jun 17, 2026

Copy link
Copy Markdown
Member

Changes

Redesigns the notifications page for better scannability and less scrolling, based on a review of best-in-class notification inboxes (GitHub, Facebook):

  • Type filters — a filter bar buckets the 51 notification types into 5 human-friendly categories: All · Mentions & replies · Reactions · Following · Squads · Updates. Chips only render for categories present in the loaded data, and the bar hides entirely when only one category exists (so it never adds noise).
    • Filtering is client-side over loaded pages — the notifications GraphQL API has no server-side type filter. This is complete for typical users (page size 100) and refines as heavy users scroll. Documented inline.
  • Date grouping — notifications are grouped under Today / Yesterday / Wed, 12 Jun … headers, reusing the existing getReadHistoryDateFormat helper.
  • Compact rows — tightened NotificationItem density (py-4→py-3, avatar mb-4→mb-2, description mt-2→mt-1).

Auto-mark-all-as-read behavior is intentionally unchanged (no Unread tab).

Events

No new tracking events.

Experiment

No new experiments.

Manual Testing

Verified: strict typecheck on changed files, ESLint clean (webapp + shared), NotificationItem unit tests (14/14). A visual sanity pass in the webapp across breakpoints is recommended before merge.

🤖 Generated with Claude Code

Preview domain

https://claude-quizzical-bose-994274.preview.app.daily.dev

Redesign the notifications page for better scannability and less scrolling:

- Add a filter bar that buckets the 51 notification types into 5 human
  categories (Mentions & replies, Reactions, Following, Squads, Updates).
  Chips only render for categories present in loaded data, and the bar
  hides when a single category is present. Filtering is client-side since
  the notifications API has no server-side type filter.
- Group notifications under Today / Yesterday / date headers, reusing the
  existing getReadHistoryDateFormat helper.
- Tighten NotificationItem density (py-4->py-3, avatar mb-4->mb-2,
  description mt-2->mt-1) so more fits on screen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
daily-webapp Ready Ready Preview Jun 21, 2026 6:54pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
storybook Ignored Ignored Jun 21, 2026 6:54pm

Request Review

Address feedback that the row layout wasn't actually compact and that the
date headers were redundant with the per-row timestamp.

- Rework NotificationItem into the social-feed row pattern (Instagram /
  TikTok / X / Facebook): a single avatar on the left with the type icon
  as an overlaid corner badge, a tight text block (title + context +
  inline relative timestamp) in the middle, and the post thumbnail on the
  right. Replaces the old icon-column + avatars-above-title + full-width
  attachment card, cutting row height substantially.
- Remove the Today/Yesterday date section headers — the inline per-row
  timestamp already conveys recency.
- Delete the now-unused NotificationItemAttachment component.

Uses our existing palette/design tokens throughout.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tsahimatsliah and others added 2 commits June 18, 2026 00:18
Long comment/description paragraphs could still blow up row height. Cap
every text line so only the relevant detail stays on screen, on mobile
and desktop alike:

- Title and description clamp to 2 lines, referenced post title to 1.
- Use the shared `multi-truncate` helper + zero inner `<p>` margins so the
  clamp actually holds for sanitized HTML content (nested paragraphs no
  longer inflate height or break the ellipsis).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address design feedback:

- Align every row: the lead avatar/icon now sits in a fixed-width column
  so titles start at the same x regardless of avatar vs icon-only rows.
- Move the timestamp back to the top-right (as before) and drop the inline
  date line, shrinking each row's height. Post thumbnail sits under it.
- Replace the broken-looking `border-y` in the page background color with a
  single subtle `border-b` divider.
- Rework filters to the requested set: All activity / Upvotes / Mentions /
  Comments / Followers / Squads / Updates.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address design feedback (settings-page vibe: flat, minimal borders):

- Remove the broken overlaid type-icon badge. The lead is now a single
  clean element — the avatar when present, otherwise the type icon — so
  rows no longer show clipped/overlapping bell badges.
- Drop the per-row border for a flat list; separation comes from spacing,
  hover and the unread tint (the outer page container keeps the only border).
- Make the filter bar sticky so it stays visible while scrolling (it was
  scrolling out of view, which is why the filters seemed missing).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Always render the sticky filter bar when there are notifications (it was
  hidden whenever the inbox mapped to a single category — the reason the
  filters appeared to be missing).
- Flatten the V2 layout: drop the left/right page borders on V2 for an
  edge-to-edge look.
- Replace the cluttered 3-level text (title + subtitle + article title +
  floating thumbnail) with a cleaner hierarchy: event title, optional
  comment, and the referenced article as a single compact card
  (thumbnail + title) — the one place a border is used.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The filter bar only rendered chips for categories that currently had
notifications loaded, so users mostly saw just "All activity" and
"Updates". Always render the full set (All activity / Upvotes / Mentions /
Comments / Followers / Squads / Updates) and show a friendly empty state
when a selected tab has no notifications yet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per feedback, the filters shouldn't live in a second bar. Render them as
page-header tabs using the same SquadDirectoryNavbar/NavbarItem treatment
(text + active underline) as the Squads directory and Explore headers:

- V2: the tabs fill the page-header strip (title shown only when there are
  no notifications to filter).
- Legacy: tabs sit directly under the page title.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tsahimatsliah and others added 3 commits June 18, 2026 21:53
Per feedback, the filters belong in the V2 sidebar panel (like the Settings
sub-nav), not in the page header:

- NotificationsRailPanel now lists every filter category (All activity,
  Upvotes, Mentions, Comments, Followers, Squads, Updates) as sidebar rows
  with icons, plus the existing Settings shortcut.
- Filtering is now driven by the `?type=` query param so the sidebar (a
  separate tree) controls the page; the active row highlights accordingly.
- V2 page header returns to a plain "Notifications" title.
- Legacy/mobile layout (no rail) keeps the in-page filter tabs, also
  query-param driven.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Researched notification-list best practices (two text levels max, whitespace
over per-row borders/cards, subtle timestamp, small thumbnail, gentle unread
tint) and applied them:

- Drop the bordered "article card". Its CardCover wrapped the image in a
  flex-1 box, which left a large gap between the cover and the title — the
  reported bug.
- Collapse to two text levels: the event title + a single muted secondary
  line (the comment when present, otherwise the referenced post title).
- The post cover rides on the right as a small fixed 48px thumbnail
  (shared Image with graceful fallback) next to a subtle timestamp.

Result: less busy, more scannable, properly aligned rows.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
SidebarItem marks an item active when `item.active || isSidebarItemActive`,
and the matcher strips the query string — so every `/notifications?type=...`
row matched the current `/notifications` route and all filters looked
selected at once.

Filters now navigate via `action` (button) instead of `path`, so the
explicit `active` flag is the only source of truth and exactly one row
highlights. Settings keeps its real `path`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…le text

Applied verified findings from a deep-research pass (Material 3, Polaris,
WCAG, Slack/Linear):

- Fix inconsistent row gaps: the trailing thumbnail was stacked under the
  timestamp, so only image rows grew taller. Now the row has a uniform
  `min-h-16`, is vertically centered, and the thumbnail is a fixed 40px that
  fits inside that height — image and text-only rows are the same height.
- Readability: secondary line moves from faint text-tertiary/quaternary to
  `text-secondary` (meets WCAG 4.5:1, M3 medium-emphasis), primary title is
  explicit `text-primary`. Two text levels max.
- Timestamp now trails the title line (X/Twitter style) instead of stacking
  in a right column; relative format retained.
- Secondary clamped to one line for consistent rhythm; rows stay flat
  (no per-row dividers, per Polaris).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address "too busy / no rhythm / headings look the same" feedback, modeled on
Instagram/TikTok/X activity feeds:

- Group the feed into coarse time sections (Today / This week / This month /
  Earlier) with light section headers, giving the list rhythm and breaks
  instead of one uniform wall.
- Make every notification title a consistent bold heading regardless of type
  (streak, upvote, achievement now share the same weight), with the lighter
  text-secondary snippet beneath — a clear heading-vs-body hierarchy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ierarchy

- The timestamp was at the right of the text column, so a trailing thumbnail
  shrank the column and shifted the timestamp left ("right side moves").
  Timestamp is now the only right-edge element in its own fixed slot — its
  position is constant across every row.
- Move the post image out of the right flow to the bottom of the content
  (small 48x80 preview), as suggested, so it never pushes the timestamp.
- Calmer hierarchy to reduce busyness: bold title (headline) stays, snippet
  drops to the more-muted text-tertiary, timestamp is the smallest/faintest.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reworked each item around the cross-platform (Instagram/Facebook/TikTok)
pattern after reviewing those social feeds:

- Eye-catching colored type badge overlaid on the avatar — a solid accent
  circle + white glyph per category (upvote/mention/comment/follow/squad/
  update) so the type reads at a glance. System rows keep the plain icon.
- Replace the space-hungry bottom image with a small 44px trailing
  thumbnail, vertically centered.
- Timestamp moves inline into the muted meta line (snippet · time) so
  nothing is pinned to the right edge and the layout no longer shifts when a
  thumbnail is present.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
For post-related notifications with no comment (e.g. "mentioned you in a
post"), surface the referenced post's title as the subtitle, alongside the
cover image on the right — matching comment-on-post rows. Still deduped
against the headline so source-post rows (whose title already is the post
title) don't repeat it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
For post-related notifications (mentions, comments, replies, etc.) the row now
shows BOTH the comment AND the referenced post's title, so it's clear which
article/post it happened on — plus the cover image on the right. Both lines
are deduped against the headline and each other so nothing repeats. The post
title is rendered more muted (one line) so it reads as context under the
comment. Storybook mention cases updated to include the post.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…om gap

- Move the timestamp inline below the title, leading the meta line with a
  "2h · …" dot separator before the comment/post context.
- Put the three-dots mute menu in the top-right (on hover) where the time
  used to be, with a small backdrop so it reads over a cover image.
- Drop min-h-20 back to min-h-16 so rows hug their content and lose the big
  empty bottom padding.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tsahimatsliah and others added 2 commits June 21, 2026 13:20
- Replace the overlapping avatar stack (which widened the lead and threw off
  alignment) with a 2x2 grid the size of one avatar: up to 3 faces plus the
  action icon in the bottom-right cell (or 4 faces / "+N" when there's no
  badge). The lead is now a consistent width, closing the gap to the title.
- Vertically center the lead and the cover image to the row so they read
  centered instead of sitting high.
- Tighten the lead column (w-10) now that nothing overflows it.
- Each grid face keeps its hover profile tooltip.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ttom-right

- Shrink the mute menu to an XSmall button and rotate the icon 90° (vertical
  kebab), sitting in the top-right of the title row.
- Move the post cover to the bottom-right (self-end), just left of the menu,
  so the image never pushes the menu down or inflates the title line height.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tsahimatsliah and others added 2 commits June 21, 2026 13:36
…ed cover

- Avatar grid is now four separate, individually-rounded boxes (with gaps,
  no connecting frame and no "+N" count) sized like a single avatar; the
  action cell is circular like the single-avatar badge. Each face keeps its
  hover profile tooltip.
- Mute menu uses the flat Float button (no backdrop/border/shadow), and shows
  by default on mobile (hover-reveal from tablet up).
- Cover image is vertically centered on the right with a gap before the menu.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Anchor the lead avatar/grid and the cover image to the top (same padding as
the title) instead of vertically centering. On a two-line row that reads as
centered, but on a tall multi-line row the image stays aligned with the
headline and never drifts down below it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…feed

The mute kebab is already visible-by-default below the 656px breakpoint and
hover-only above it. The side-by-side 356px container can't demonstrate that
because CSS breakpoints follow the browser viewport, not the box width. Add a
"Mobile viewport" story that narrows the canvas so the mobile behaviour
(kebab shown by default) is actually visible, and note this on the side-by-side.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a small top margin to the lead avatar/grid and the cover image so they
read as vertically centered on a two-line notification, while still staying
near the top (with the title) on taller rows.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The mute kebab was absolutely positioned in the top-right, sitting on top of
the cover image. Make it an in-flow element to the right of the cover so it
reserves its own space and the row gap keeps clear space between them — the
cover shifts left and nothing overlaps (on hover or on mobile).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Show the multi-image grid only when there are more than three actors
(e.g. >3 upvotes); one/two/three show a single avatar with the corner badge
instead. Point the Storybook AvatarStack story at a >3 case.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tsahimatsliah and others added 2 commits June 21, 2026 20:58
…isibility

Float maps to btn-tertiaryFloat which carries a faint surface-float
background; switch the mute kebab to the truly flat Tertiary variant (no
background or border). Visibility is unchanged and already correct: visible
by default below the 656px (mobile) breakpoint, hover-revealed at tablet+.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Covers were misaligned because the kebab only took space on muteable rows,
shifting those covers left vs covers on rows without a menu. Group the cover
and a fixed-width menu slot into one trailing block that's rendered whenever a
row has a cover and/or a menu — so the menu slot is always reserved and every
cover image lands at the same x down the feed (Gmail/Slack/Linear-style
reserved trailing actions). Menu still shows by default on mobile, hover on
desktop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@tsahimatsliah

Copy link
Copy Markdown
Member Author

Superseded by #6229 — a clean, engineering-ready port of this design rebased on main. All CI checks are green there (typecheck, lint, shared/webapp/extension tests, webapp build, Storybook deploy). Closing this mock-up branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant