fix(16): persist unread count across page reloads

Problem: After page reload, the unread badge on chat button disappeared
even though there were unread messages.

Root cause:
1. unreadCounts was reset to {} on page reload
2. fetchChatHistory was only called when chat window opened
3. By that time, openChatWindow already reset the count to 0

Fix:
1. Fetch chat history when session joins (not just when chat opens)
2. In fetchChatHistory.fulfilled, calculate unread count based on
   lastReadAt timestamp from localStorage
3. Only calculate unread if chat window is NOT open for that channel

This ensures the badge shows correct unread count after page reload.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Nuwan 2026-02-07 02:07:01 +05:30
parent 20d0259433
commit 7110e7cdf9
2 changed files with 32 additions and 1 deletions

View File

@ -55,7 +55,7 @@ import {
selectBackingTrackData,
selectJamTrackData
} from '../../store/features/activeSessionSlice';
import { addMessageFromWebSocket, uploadAttachment, selectIsUploading, selectUploadError, selectUploadFileName, selectUploadStatus, clearUploadError } from '../../store/features/sessionChatSlice';
import { addMessageFromWebSocket, uploadAttachment, selectIsUploading, selectUploadError, selectUploadFileName, selectUploadStatus, clearUploadError, fetchChatHistory } from '../../store/features/sessionChatSlice';
import { validateFile } from '../../services/attachmentValidation';
import { CLIENT_ROLE, RECORD_TYPE_AUDIO, RECORD_TYPE_BOTH } from '../../helpers/globals';
@ -471,6 +471,19 @@ const JKSessionScreen = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [hasJoined, sessionId, mixersReady, dispatch])
// Fetch chat history when session joins to populate unread badge
// This ensures unread count persists across page reloads
useEffect(() => {
if (!hasJoined || !sessionId) {
return;
}
dispatch(fetchChatHistory({
channel: sessionId,
sessionId: sessionId
}));
}, [hasJoined, sessionId, dispatch]);
const joinSession = async () => {
await jamClient.SetVURefreshRate(150);

View File

@ -372,6 +372,24 @@ const sessionChatSlice = createSlice({
state.fetchStatus[channel] = 'succeeded';
state.nextCursors[channel] = next;
// Calculate unread count based on lastReadAt (for page reload persistence)
// Only set unread count if chat window is NOT open for this channel
// (if window is open, user is viewing messages so they're not "unread")
if (!state.isWindowOpen || state.activeChannel !== channel) {
const lastRead = state.lastReadAt[channel];
if (lastRead) {
// Count messages newer than lastReadAt
const lastReadDate = new Date(lastRead);
const unreadCount = state.messagesByChannel[channel].filter(
m => new Date(m.createdAt) > lastReadDate
).length;
state.unreadCounts[channel] = unreadCount;
} else {
// No lastReadAt means user never opened chat - all messages are unread
state.unreadCounts[channel] = state.messagesByChannel[channel].length;
}
}
})
// fetchChatHistory rejected
.addCase(fetchChatHistory.rejected, (state, action) => {