Files
sow-nodebb-theme/docs/superpowers/specs/2026-07-17-topbar-unread-drawer-design.md
T
archvillainette 004be9b038 Topbar unread drawer (#28)
Adds an Unread dropdown to the topbar utilities (before notifications), per docs/superpowers/plans/2026-07-17-topbar-unread-drawer.md.

- New partial `templates/partials/header/unread-drawer.tpl`: toggle with live `component="unread/count"` badge (core socket updates), server-rendered empty/footer rows.
- `public/client.js`: on dropdown open, fetches `GET /api/unread` and injects up to 10 topic rows (titles/categories via textContent only); fetch failure falls back to the empty state.
- Mobile burger drawer gets an Unread row with the same badge.
- SCSS: unread dropdown joins the shared dropdown width rule; flex row styles for topic items.

Deviations from the plan's example code, found by live verification against the dev forum:
- Plan's `api.get('/unread')` hits the v3 write API and 404s → replaced with a fetch of the `/api/unread` read route.
- NodeBB 4 has no global `window.require`, so runtime translation of the static `[[unread:...]]` strings never ran → those strings are now server-rendered in the template (also removes the plan's translate-over-innerHTML step, which would have re-parsed untrusted titles as HTML).

Verified: full plain-node test suite passes; Playwright against the dev container passed all checks (badge count, item ordering before notifications, dropdown topic links + navigation, /unread footer link, mobile drawer badge at 390px).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: #28
Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
Co-committed-by: vickydotbat <vickydotbat@tutamail.com>
2026-07-17 16:43:12 +00:00

2.9 KiB

Topbar Unread Drawer — Design

Date: 2026-07-17

Goal

Add an "Unread" item to the topbar utilities, next to notifications. It shows a live badge with the number of unread topics. Clicking it opens a dropdown that lists recent unread topics.

Template

New partial templates/partials/header/unread-drawer.tpl, imported in templates/partials/header/topbar.tpl just before the notifications <li> (logged-in menu only). It follows the structure of the neighboring utility dropdowns:

  • Toggle button: fa-inbox icon, title="[[unread:title]]", badge <span component="unread/count" class="badge ... {{{ if !unreadCount.topic }}}hidden{{{ end }}}">{unreadCount.topic}</span>. NodeBB core sends unreadCount.topic in header data and live-updates any component="unread/count" badge over sockets, so the count needs no theme JS.
  • Dropdown body: an empty <ul class="dropdown-menu wg-topbar__dropdown"> shell with a loading placeholder item.

Client JS

Small addition to public/client.js (inside the existing topbar init):

  • On show.bs.dropdown for the unread item, call api.get('/unread', ...) (same data the /unread page uses).
  • Render up to 10 topics as plain links: topic title, category name, unread-post count. Footer link "See all unread" → /unread.
  • Re-fetch on every open (always fresh, no caching). Errors show a short "could not load" item — never a blank menu.

Skipped: mark-all-read, pagination, watched-filter tabs — the /unread page already has all of those.

SCSS

Reuse the existing .wg-topbar__dropdown styles. Only a few lines for the topic rows (truncation, spacing).

Mobile drawer

Add a plain "Unread" link with the same component="unread/count" badge to the burger-drawer actions block in topbar.tpl, matching the existing notifications/chats rows.

Accessibility

  • Toggle is a real <a role="button">/dropdown like the other utility items, with aria-label and Bootstrap's dropdown keyboard handling.
  • Badge count also appears in the accessible name (matching how the notifications item does it).

Verification

Manual + Playwright checks run against the sow-nodebb dev container (../sow-nodebb):

  1. In ../sow-nodebb, set .env for theme work (PLUGIN_PATH=../sow-nodebb-theme, PLUGIN_ID=nodebb-theme-westgate, EXTRA_PLUGINS=nodebb-plugin-westgate-wiki), then make dev → forum at http://localhost:4567.
  2. After template/JS/SCSS edits: make dev-build in ../sow-nodebb, then reload the browser.
  3. Playwright (playwright-skill / MCP browser tools) against http://localhost:4567: log in, confirm the Unread button exists next to notifications, badge shows the unread count, opening the dropdown lists unread topics with working links, and the footer link lands on /unread. Also check the mobile burger drawer shows the Unread row.

Existing template contract test tests/global-topbar-contract.test.js is updated if it asserts the utility-list structure.