fix(desktop): preserve read state in activity windows

Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
This commit is contained in:
Taylor Ho
2026-08-23 20:52:06 -07:00
committed by Rizz
parent ad9da72423
commit bd49723afc
3 changed files with 39 additions and 2 deletions

View File

@@ -217,6 +217,7 @@ export function ChannelScreen({
activeChannelId,
activeChannel?.isMember,
activeReadAt,
!isDedicatedActivityWindow,
);
React.useEffect(() => {
if (!activeChannelId) {

View File

@@ -1,7 +1,10 @@
import assert from "node:assert/strict";
import test from "node:test";
import { getTopLevelInboxUnreadOverrideIds } from "./useChannelOpenReadState.ts";
import {
getTopLevelInboxUnreadOverrideIds,
shouldAdvanceChannelReadState,
} from "./useChannelOpenReadState.ts";
test("opening a channel clears only its top-level Inbox overrides", () => {
assert.deepEqual(
@@ -23,3 +26,22 @@ test("opening a channel clears only its top-level Inbox overrides", () => {
["top-level"],
);
});
test("passive activity companions never advance synced read state", () => {
assert.equal(
shouldAdvanceChannelReadState({
activeChannelId: "general",
enabled: false,
isChannelMember: true,
}),
false,
);
assert.equal(
shouldAdvanceChannelReadState({
activeChannelId: "general",
enabled: true,
isChannelMember: true,
}),
true,
);
});

View File

@@ -17,16 +17,29 @@ export function getTopLevelInboxUnreadOverrideIds(
);
}
export function shouldAdvanceChannelReadState({
activeChannelId,
enabled,
isChannelMember,
}: {
activeChannelId: string | null;
enabled: boolean;
isChannelMember: boolean | undefined;
}): boolean {
return enabled && activeChannelId !== null && isChannelMember !== false;
}
export function useChannelOpenReadState(
activeChannelId: string | null,
isChannelMember: boolean | undefined,
activeReadAt: string | null,
enabled = true,
) {
const { feedItemState, locallyUnreadFeedItems, markChannelRead } =
useAppShell();
React.useEffect(() => {
if (!activeChannelId || isChannelMember === false) return;
if (!activeChannelId || !enabled || isChannelMember === false) return;
for (const itemId of getTopLevelInboxUnreadOverrideIds(
locallyUnreadFeedItems,
activeChannelId,
@@ -37,6 +50,7 @@ export function useChannelOpenReadState(
}, [
activeChannelId,
activeReadAt,
enabled,
feedItemState.undoUnread,
isChannelMember,
locallyUnreadFeedItems,