fix: eliminate phantom notifications across the entire read-state pipeline
Root cause: own messages echoed by the server marked channels unread when the user had already navigated away. Seven related bugs compounded the problem — stale read states, missing cleanup on space/DM removal, REST broadcast ignoring VIEW_CHANNEL, and no validation on channel_ack writes. Frontend: - Skip markChannelUnread for the user's own messages (federation-aware) - Walk backward past temp_ IDs in ackChannel instead of bailing - Re-fire ack timer when temp message is replaced by server-confirmed ID - Add removeChannelStates to clean up unread/read/message caches - Clean up chatStore on removeSpace, removeDmChannel, removeInstanceSpaces Server: - Use sendToChannel instead of sendToSpace for REST message creation - Clean up read_states on space deletion, member kick/leave, and ban - Validate channel membership before accepting channel_ack writes - Clean up read_states on DM leave and DM channel deletion
This commit is contained in:
@@ -69,6 +69,9 @@ export function MessageList({ channelId, jumpToMessageId, onJumpComplete }: Mess
|
||||
}
|
||||
}, [channelId, loadMessages, canReadHistory]);
|
||||
|
||||
// Track the last message ID so the ack re-fires when a temp message is replaced by its server-confirmed ID
|
||||
const lastMessageId = messages.length > 0 ? messages[messages.length - 1]?.id ?? '' : '';
|
||||
|
||||
// Ack channel when messages load or when new messages arrive while near bottom
|
||||
useEffect(() => {
|
||||
if (messages.length > 0 && isNearBottom) {
|
||||
@@ -76,7 +79,7 @@ export function MessageList({ channelId, jumpToMessageId, onJumpComplete }: Mess
|
||||
ackTimerRef.current = setTimeout(() => ackChannel(channelId), 200);
|
||||
}
|
||||
return () => clearTimeout(ackTimerRef.current);
|
||||
}, [channelId, messages.length, isNearBottom, ackChannel]);
|
||||
}, [channelId, messages.length, lastMessageId, isNearBottom, ackChannel]);
|
||||
|
||||
// Reset scroll tracking on channel switch so initial-load scroll fires
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user