From 1ef3d8e2998e661cbfae645f6bede5f94f3d74b3 Mon Sep 17 00:00:00 2001 From: freefire Date: Wed, 16 Sep 2026 00:53:54 +0800 Subject: [PATCH] =?UTF-8?q?fix(frontend):=20=E8=BF=9B=E6=88=BF=E5=90=8E?= =?UTF-8?q?=E4=BE=A7=E6=A0=8F=E6=9C=AA=E8=AF=BB=E8=A7=92=E6=A0=87=E4=B8=8D?= =?UTF-8?q?=E5=86=8D=E8=A2=AB=20refresh=20=E5=86=99=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 应用会话列表时强制清零当前房间未读,并在已读成功事件后再清一次。 Co-authored-by: Cursor --- frontend/app/chat/ChatShell.tsx | 67 +++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/frontend/app/chat/ChatShell.tsx b/frontend/app/chat/ChatShell.tsx index 89fed22..8b733b4 100644 --- a/frontend/app/chat/ChatShell.tsx +++ b/frontend/app/chat/ChatShell.tsx @@ -112,31 +112,45 @@ export default function ChatShell({ } | null>(null); const longPressTimer = useRef | 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 now = Date.now(); - if (!opts?.force) { - if (roomsInFlight.current) return; - // 切房/回前台可合并;建群、被邀请等走 force - if (now - lastRoomsFetchAt.current < 2_000) return; - } - roomsInFlight.current = true; - lastRoomsFetchAt.current = now; - try { - const res = await apiListChatRooms(1, 50, "", "joined"); - setRooms(sortRooms(res.rooms || [])); - } catch { - // 静默 - } finally { - roomsInFlight.current = false; - } - }, []); + const refreshRooms = useCallback( + async (opts?: { force?: boolean }) => { + const now = Date.now(); + if (!opts?.force) { + if (roomsInFlight.current) return; + // 切房/回前台可合并;建群、被邀请等走 force + if (now - lastRoomsFetchAt.current < 2_000) return; + } + roomsInFlight.current = true; + lastRoomsFetchAt.current = now; + try { + const res = await apiListChatRooms(1, 50, "", "joined"); + 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; - setRooms((prev) => - prev.map((r) => (r.id === activeRoomId ? { ...r, unread_count: 0 } : r)) - ); + 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]); // 搜索:会话本地过滤 + 用户远程搜索