diff --git a/jam-ui/src/helpers/chatStorage.js b/jam-ui/src/helpers/chatStorage.js new file mode 100644 index 000000000..286196e2d --- /dev/null +++ b/jam-ui/src/helpers/chatStorage.js @@ -0,0 +1,71 @@ +/** + * localStorage utilities for chat lastReadAt persistence + * + * Stores lastReadAt timestamps for each chat channel to track unread status + * across browser sessions. Data is stored as JSON object keyed by channel ID. + */ + +const STORAGE_KEY = 'jk_chat_lastReadAt'; + +/** + * Save lastReadAt timestamp for a channel + * + * Merges with existing data to preserve timestamps for other channels. + * Handles localStorage quota errors gracefully. + * + * @param {string} channel - Channel ID (session ID, lesson ID, or 'global') + * @param {string} timestamp - ISO timestamp (e.g., '2026-01-26T12:00:00Z') + */ +export const saveLastReadAt = (channel, timestamp) => { + try { + const existing = loadLastReadAt(); + existing[channel] = timestamp; + localStorage.setItem(STORAGE_KEY, JSON.stringify(existing)); + } catch (error) { + console.error('Failed to save lastReadAt:', error); + } +}; + +/** + * Load all lastReadAt timestamps from localStorage + * + * Returns empty object if no data exists or if JSON parsing fails. + * + * @returns {Object} Map of channel IDs to ISO timestamp strings + */ +export const loadLastReadAt = () => { + try { + const stored = localStorage.getItem(STORAGE_KEY); + if (!stored) return {}; + return JSON.parse(stored); + } catch (error) { + console.error('Failed to load lastReadAt:', error); + return {}; + } +}; + +/** + * Clear lastReadAt timestamp for a channel, or all channels + * + * If channel is specified, removes only that channel's timestamp. + * If no channel is specified, removes entire storage key. + * + * @param {string} [channel] - Channel ID to clear, or undefined to clear all + */ +export const clearLastReadAt = (channel) => { + try { + if (channel) { + const existing = loadLastReadAt(); + delete existing[channel]; + if (Object.keys(existing).length === 0) { + localStorage.removeItem(STORAGE_KEY); + } else { + localStorage.setItem(STORAGE_KEY, JSON.stringify(existing)); + } + } else { + localStorage.removeItem(STORAGE_KEY); + } + } catch (error) { + console.error('Failed to clear lastReadAt:', error); + } +};