mirror of
https://github.com/block/buzz.git
synced 2026-10-28 13:01:10 +00:00
**Category:** fix **User Impact:** Sidebar mention numerals now match the user's theme/accent color and appear for mentions inside threads, not just top-level channel messages. Hover-to-preview on channel rows is unchanged. **Problem:** Follow-ups to #6696: 1. The mention numeral used a fixed red `--notification` token that ignored the user's theme and accent selection. 2. The numeral read `appBadgeCount`, which deliberately excludes threaded replies (Home's badge subtotal counts those toward the Dock badge). Mentions inside threads therefore never surfaced a numeral on the channel row — only the generic thread-activity dot. **Solution:** 1. The badge now reuses the primary accent pair (`bg-primary` / `text-primary-foreground`), the same treatment as the DM count badge, so it follows whatever accent the user applies — including the pinned neutral accent of the Buzz themes. The now-unused `--notification` tokens and Tailwind utilities are removed. 2. Non-DM rows now count every unread mention/broadcast — threaded or top-level — via a new `highPriorityCount` channel projection, replacing the boolean `highPriorityUnread` across the TS contract, the Tauri SQLite store, the e2e mock bridge, and the native test rig. The Dock/app badge projection (`appBadgeCount`) is unchanged, so Dock totals do not double-count thread activity that Home already counts. The hover-to-preview channel activity popover is untouched; e2e coverage now pins the combination (thread mention → numeral, no dot, popover still opens and lists the mentioning reply). <details> <summary>File changes</summary> **desktop/src/features/channels/useUnreadChannels.ts** Non-DM sidebar counts switch from `appBadgeCount` to the mention/broadcast-inclusive `highPriorityCount`; the high-priority channel set derives from the same count. **desktop/src/features/sidebar/ui/SidebarSection.tsx** Badge drops the fixed notification classes and inherits the accent-following default. **desktop/src/shared/styles/globals/theme.css / desktop/tailwind.config.js** Remove the unused fixed `--notification` tokens and semantic utilities. **desktop/src/shared/api/tauriObservedUnread.ts / desktop/src-tauri/src/observed_unread.rs** Projection contract: `highPriorityUnread: bool` → `highPriorityCount: u64`, aggregated per unread high-priority event. **desktop/src/testing/e2eBridge.ts / desktop/src/features/channels/observedUnreadNativeRig.mjs** Mock/native-rig projections mirror the new count field. **desktop/src/features/channels/observedUnreadNative.test.mjs** Native badge-lane test seeds a high-priority event to match the numeral's new semantics. **desktop/tests/e2e/badge.spec.ts** Top-level mention test now asserts the badge equals the applied accent (seeded `#22c55e` under an adversarial theme). New test: in-thread mention shows the numeral, no dot, and the hover preview popover still lists the mentioning reply. **desktop/tests/e2e/channel-activity-popover.spec.ts / desktop/tests/e2e/thread-unread.spec.ts** Seeded fixtures that mention the user now expect the numeral (which subsumes the dot). </details> ## Reproduction steps 1. Pick any theme + accent color in Settings → Appearance. 2. Receive a top-level message mentioning you in an inactive channel → the row shows a numeral pill in your accent color. 3. Receive a reply **inside a thread** that mentions you in an inactive channel → the row shows the numeral (previously only a dot). 4. Hover the row → the channel activity preview still opens and lists the mentioning reply. 5. Switch accents/themes → the pill re-colors accordingly; the Dock badge count is unchanged from before. ## Verification - `tsc --noEmit`, Biome, `check:px-text` — clean - Desktop unit tests: 179/179 channel-suite; full suite has one pre-existing failure from #6590 (`useRetainedProjectGitViews.test.mjs` loader error, fails on clean `main`) - Tauri Rust: `observed_unread` tests + clippy + fmt — clean - Playwright smoke: badge (19), channel-activity-popover (10), thread-unread (13), plus channels/inbox/stream/messaging/mentions suites — all green ## Screenshots Screenshots are posted in the PR discussion using immutable repository-hosted image URLs. Signed-off-by: tulsi <tulsi@block.xyz>
75 lines
2.2 KiB
TypeScript
75 lines
2.2 KiB
TypeScript
import { invokeTauri } from "@/shared/api/tauri";
|
|
import type { ObservedUnreadEvent } from "@/features/channels/unreadChannelCounts";
|
|
|
|
export type ObservedUnreadScope = { pubkey: string; relayUrl: string };
|
|
export type ObservedUnreadProjection = {
|
|
channelId: string;
|
|
latest: number;
|
|
count: number;
|
|
badgeCount: number;
|
|
appBadgeCount: number;
|
|
topLevelUnread: boolean;
|
|
highPriorityCount: number;
|
|
};
|
|
export type ObservedUnreadMembershipSeed = {
|
|
participatedRootIds: string[];
|
|
authoredRootIds: string[];
|
|
mentionedRootIds: string[];
|
|
followedRootIds: string[];
|
|
mutedRootIds: string[];
|
|
mutedChannelIds: string[];
|
|
};
|
|
export type ObservedUnreadWireEvent = ObservedUnreadEvent & {
|
|
channelId: string;
|
|
};
|
|
export type ObservedUnreadResponse =
|
|
| {
|
|
kind: "snapshot";
|
|
scope: ObservedUnreadScope;
|
|
generation: string;
|
|
revision: number;
|
|
lastAckedSequence: number;
|
|
migrationComplete: boolean;
|
|
membershipSeeded: boolean;
|
|
channels: ObservedUnreadProjection[];
|
|
}
|
|
| {
|
|
kind: "delta";
|
|
scope: ObservedUnreadScope;
|
|
generation: string;
|
|
baseRevision: number;
|
|
revision: number;
|
|
ackedSequence: number;
|
|
upserts: ObservedUnreadProjection[];
|
|
removed: string[];
|
|
}
|
|
| {
|
|
kind: "snapshotRequired";
|
|
scope: ObservedUnreadScope;
|
|
generation: string;
|
|
revision: number;
|
|
lastAckedSequence: number;
|
|
};
|
|
|
|
export function openObservedUnreadScope(request: {
|
|
scope: ObservedUnreadScope;
|
|
legacyPayload: unknown | null;
|
|
membershipSeed: ObservedUnreadMembershipSeed | null;
|
|
}): Promise<ObservedUnreadResponse> {
|
|
return invokeTauri("observed_unread_open_scope", { request });
|
|
}
|
|
|
|
export function ingestObservedUnread(request: {
|
|
scope: ObservedUnreadScope;
|
|
sequence: number;
|
|
baseRevision: number;
|
|
events: ObservedUnreadWireEvent[];
|
|
channelLatest: Array<{ channelId: string; createdAt: number }>;
|
|
markers: Array<{ contextId: string; readAt: number | null }>;
|
|
membership: Array<{ kind: string; value: string; present: boolean }>;
|
|
clearChannels: string[];
|
|
clearAll: boolean;
|
|
}): Promise<ObservedUnreadResponse> {
|
|
return invokeTauri("observed_unread_ingest", { request });
|
|
}
|