fix(frontend): 进房后侧栏未读角标不再被 refresh 写回

应用会话列表时强制清零当前房间未读,并在已读成功事件后再清一次。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-16 00:53:54 +08:00
parent e6f8fadbe5
commit 1ef3d8e299

View File

@@ -112,14 +112,26 @@ export default function ChatShell({
} | null>(null);
const longPressTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
/** 拉列表/SSR 回填时,当前打开的会话未读一律置 0(已读请求可能尚未落库) */
const applyRooms = useCallback(
(list: ChatRoomView[]) => {
const next = (list || []).map((r) =>
activeRoomId && r.id === activeRoomId ? { ...r, unread_count: 0 } : r
);
setRooms(sortRooms(next));
},
[activeRoomId]
);
useEffect(() => {
setRooms(sortRooms(initialRooms));
}, [initialRooms]);
applyRooms(initialRooms);
}, [initialRooms, applyRooms]);
const roomsInFlight = useRef(false);
const lastRoomsFetchAt = useRef(0);
const refreshRooms = useCallback(async (opts?: { force?: boolean }) => {
const refreshRooms = useCallback(
async (opts?: { force?: boolean }) => {
const now = Date.now();
if (!opts?.force) {
if (roomsInFlight.current) return;
@@ -130,13 +142,15 @@ export default function ChatShell({
lastRoomsFetchAt.current = now;
try {
const res = await apiListChatRooms(1, 50, "", "joined");
setRooms(sortRooms(res.rooms || []));
applyRooms(res.rooms || []);
} catch {
// 静默
} finally {
roomsInFlight.current = false;
}
}, []);
},
[applyRooms]
);
// 进入消息壳 / 切会话:HTTP 拉最新排序(避开预取缓存)
useEffect(() => {
@@ -194,12 +208,17 @@ export default function ChatShell({
return off;
}, [refreshRooms]);
// 进入会话后清零该会话未读
// 进房即清角标;MarkRead 成功后再清一次(防 refresh 抢在已读落库前写回旧未读)
useEffect(() => {
if (!activeRoomId) return;
const clearActiveUnread = () => {
setRooms((prev) =>
prev.map((r) => (r.id === activeRoomId ? { ...r, unread_count: 0 } : r))
);
};
clearActiveUnread();
window.addEventListener("j13-chat-unread-sync", clearActiveUnread);
return () => window.removeEventListener("j13-chat-unread-sync", clearActiveUnread);
}, [activeRoomId]);
// 搜索:会话本地过滤 + 用户远程搜索