From 3cdeae691ff7add762af6c3784e95f4c119cec07 Mon Sep 17 00:00:00 2001 From: Nuwan Date: Tue, 27 Jan 2026 12:45:33 +0530 Subject: [PATCH] feat(07-03): integrate localStorage with Redux slice - Import saveLastReadAt and loadLastReadAt utilities - Load lastReadAt from localStorage on Redux store initialization - Save to localStorage when openChatWindow action is dispatched - Save to localStorage when markAsRead action is dispatched - All 68 Redux tests still passing after integration - All 8 localStorage tests passing Part of Phase 7 Plan 3 (WebSocket Integration & Selectors) Co-Authored-By: Claude Sonnet 4.5 --- jam-ui/src/store/features/sessionChatSlice.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/jam-ui/src/store/features/sessionChatSlice.js b/jam-ui/src/store/features/sessionChatSlice.js index cde27677d..3586f8c44 100644 --- a/jam-ui/src/store/features/sessionChatSlice.js +++ b/jam-ui/src/store/features/sessionChatSlice.js @@ -1,5 +1,6 @@ import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; import { getChatMessages, sendChatMessage } from '../../helpers/rest'; +import { saveLastReadAt, loadLastReadAt } from '../../helpers/chatStorage'; /** * Async thunk to fetch chat history for a channel @@ -63,7 +64,7 @@ const initialState = { activeChannel: null, channelType: null, unreadCounts: {}, - lastReadAt: {}, + lastReadAt: loadLastReadAt(), // Load from localStorage on init fetchStatus: {}, fetchError: {}, sendStatus: 'idle', @@ -150,15 +151,17 @@ const sessionChatSlice = createSlice({ /** * Open chat window - * Resets unread count for active channel + * Resets unread count for active channel and persists to localStorage */ openChatWindow: (state) => { state.isWindowOpen = true; // Reset unread count for active channel if (state.activeChannel) { + const now = new Date().toISOString(); state.unreadCounts[state.activeChannel] = 0; - state.lastReadAt[state.activeChannel] = new Date().toISOString(); + state.lastReadAt[state.activeChannel] = now; + saveLastReadAt(state.activeChannel, now); // Persist to localStorage } }, @@ -172,12 +175,14 @@ const sessionChatSlice = createSlice({ /** * Mark channel as read - * Resets unread count and updates lastReadAt timestamp + * Resets unread count, updates lastReadAt timestamp, and persists to localStorage */ markAsRead: (state, action) => { const { channel } = action.payload; + const now = new Date().toISOString(); state.unreadCounts[channel] = 0; - state.lastReadAt[channel] = new Date().toISOString(); + state.lastReadAt[channel] = now; + saveLastReadAt(channel, now); // Persist to localStorage }, /**