feat(07-01): implement sessionChatSlice with initial state structure
GREEN phase of TDD: - Create sessionChatSlice.js with complete initial state - All 12 state fields match CHAT_REDUX_DESIGN.md specification - Multi-channel architecture: messagesByChannel keyed by channel ID - Unread tracking: unreadCounts, lastReadAt per channel - State machines: fetchStatus/error per channel, sendStatus/error global - Pagination support: nextCursors per channel - UI state: isWindowOpen, windowPosition - Register slice in store.js as sessionChat reducer All 13 tests pass. Ready for reducers in Task 2. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
fd44d1255f
commit
e98504ebad
|
|
@ -0,0 +1,43 @@
|
|||
import { createSlice } from '@reduxjs/toolkit';
|
||||
|
||||
/**
|
||||
* Initial state for session chat
|
||||
* @type {Object}
|
||||
* @property {Object.<string, Array>} messagesByChannel - Messages organized by channel ID
|
||||
* @property {string|null} activeChannel - Currently active channel ID
|
||||
* @property {string|null} channelType - Type of active channel ('global', 'session', 'lesson')
|
||||
* @property {Object.<string, number>} unreadCounts - Unread message count per channel
|
||||
* @property {Object.<string, string|null>} lastReadAt - ISO timestamp of last read per channel
|
||||
* @property {Object.<string, string>} fetchStatus - Fetch status per channel ('idle', 'loading', 'succeeded', 'failed')
|
||||
* @property {Object.<string, string|null>} fetchError - Fetch error message per channel
|
||||
* @property {string} sendStatus - Send status ('idle', 'loading', 'succeeded', 'failed')
|
||||
* @property {string|null} sendError - Send error message
|
||||
* @property {Object.<string, number|null>} nextCursors - Pagination cursors per channel
|
||||
* @property {boolean} isWindowOpen - Whether chat window is open
|
||||
* @property {Object|null} windowPosition - Window position {x, y}
|
||||
*/
|
||||
const initialState = {
|
||||
messagesByChannel: {},
|
||||
activeChannel: null,
|
||||
channelType: null,
|
||||
unreadCounts: {},
|
||||
lastReadAt: {},
|
||||
fetchStatus: {},
|
||||
fetchError: {},
|
||||
sendStatus: 'idle',
|
||||
sendError: null,
|
||||
nextCursors: {},
|
||||
isWindowOpen: false,
|
||||
windowPosition: null
|
||||
};
|
||||
|
||||
const sessionChatSlice = createSlice({
|
||||
name: 'sessionChat',
|
||||
initialState,
|
||||
reducers: {
|
||||
// Reducers will be added in Tasks 2-3
|
||||
}
|
||||
});
|
||||
|
||||
export const {} = sessionChatSlice.actions;
|
||||
export default sessionChatSlice.reducer;
|
||||
|
|
@ -15,6 +15,7 @@ import activeSessionReducer from "./features/activeSessionSlice"
|
|||
import sessionUIReducer from "./features/sessionUISlice"
|
||||
import mixersReducer from "./features/mixersSlice"
|
||||
import mediaReducer from "./features/mediaSlice"
|
||||
import sessionChatReducer from "./features/sessionChatSlice"
|
||||
|
||||
export default configureStore({
|
||||
reducer: {
|
||||
|
|
@ -25,6 +26,7 @@ export default configureStore({
|
|||
session: sessionReducer, // this is the slice that holds the session lists
|
||||
activeSession: activeSessionReducer, // this is the slice that holds the currently active session
|
||||
sessionUI: sessionUIReducer, // this is the slice that holds the session UI state (modals, panels)
|
||||
sessionChat: sessionChatReducer, // Phase 7: session chat state (messages, channels, unread tracking)
|
||||
mixers: mixersReducer, // Phase 5: mixer state (chat, broadcast, track mixers, metronome, media summary)
|
||||
media: mediaReducer, // Phase 5: media data (backing tracks, jam tracks, recorded tracks)
|
||||
latency: latencyReducer,
|
||||
|
|
|
|||
Loading…
Reference in New Issue