Skip to content

feat(tabs): mark an off-screen pending_review tab unread - #942

Open
Today-ddr wants to merge 1 commit into
spacering-net:mainfrom
Today-ddr:feat/topbar-status-light
Open

Today-ddr wants to merge 1 commit into
spacering-net:mainfrom
Today-ddr:feat/topbar-status-light

Conversation

@Today-ddr

Copy link
Copy Markdown
image

A turn that finishes while you're on another tab now shows purple instead of the plain pending_review blue, and clears the moment that tab is focused.
Sequence: 🟡 in_progress → 🟣 unread → 🔵 pending_review → 🟢 completed

Why an overlay rather than a fifth status

"Unread" is cleared by looking at it, which doesn't fit a persisted ConversationStatus — those are CAS-guarded DB transitions. So the flag lives in memory in the tab store; the backend, the DB and the enum are untouched. A restart degrades purple back to blue: the "needs attention" information survives, only the "not looked at yet" tint is lost.

Tests

12 new vitest cases — mark / don't-mark-when-visible / clear-on-focus / hydration-doesn't-paint-history / survives-recompute, plus the dot's colour contract.

A turn that finishes while the user is looking at another tab now shows
purple instead of the plain `pending_review` blue, and clears the moment
that tab is focused. Focusing is the "I have seen it" signal, so the
sequence reads purple -> blue, never the reverse.

The flag is a view-only overlay, not a fifth `ConversationStatus`: the
backend and the DB are untouched, the conversation stays `pending_review`
underneath, and the set of unread ids lives in memory only. A restart
degrades a purple dot back to blue — the "needs attention" information
survives, only the "not looked at yet" tint is lost.

Two details worth calling out:

- The flag is derived in `recomputeTabs` from the store's own set rather
  than carried on the raw tab. `tab.status` is re-derived from the
  conversation list on every tick, so a flag stored beside it would be
  wiped by the next title or status change.
- Clearing hooks the store's `activeTabId` subscription instead of
  `focusTab`, because `closeTab` advances the active tab with a direct
  `setState` that bypasses `focusTab`. Every other route to a tab
  becoming active — switchTab, remote snapshot apply, hydration — is
  covered by the same subscription.

Visibility is per split group rather than per active tab: a reply landing
in a neighbouring group is already on screen, so it must not turn unread.
A status transition is required too, which keeps the first hydration from
painting every historical `pending_review` row purple.
@xintaofei

Copy link
Copy Markdown
Collaborator

感谢PR,虽然这是一个小功能,但是它涉及到了会话的生命周期,所以也很重视这块的改动,目前还没有想好方案。

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.

2 participants