/** * Calls State Slice * Manages voice and video calls */ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; export interface Call { id: string; type: 'voice' | 'video'; participants: string[]; initiatorId: string; status: 'ringing' | 'active' | 'ended' | 'declined' | 'missed'; startedAt?: string; endedAt?: string; } export interface VoiceState { muted: boolean; deafened: boolean; speaking: boolean; volume: number; } interface CallsState { activeCall: Call | null; incomingCall: Call | null; callHistory: Call[]; voiceState: VoiceState; error: string | null; } const initialState: CallsState = { activeCall: null, incomingCall: null, callHistory: [], voiceState: { muted: false, deafened: false, speaking: false, volume: 100, }, error: null, }; const callsSlice = createSlice({ name: 'calls', initialState, reducers: { setActiveCall: (state, action: PayloadAction) => { state.activeCall = action.payload; state.incomingCall = null; }, setIncomingCall: (state, action: PayloadAction) => { state.incomingCall = action.payload; }, endCall: (state) => { if (state.activeCall) { const endedCall = { ...state.activeCall, status: 'ended' as const, endedAt: new Date().toISOString(), }; state.callHistory.unshift(endedCall); state.activeCall = null; } }, declineCall: (state) => { if (state.incomingCall) { const declinedCall = { ...state.incomingCall, status: 'declined' as const, endedAt: new Date().toISOString(), }; state.callHistory.unshift(declinedCall); state.incomingCall = null; } }, setMuted: (state, action: PayloadAction) => { state.voiceState.muted = action.payload; }, setDeafened: (state, action: PayloadAction) => { state.voiceState.deafened = action.payload; // Deafening also mutes if (action.payload) { state.voiceState.muted = true; } }, setSpeaking: (state, action: PayloadAction) => { state.voiceState.speaking = action.payload; }, setVolume: (state, action: PayloadAction) => { state.voiceState.volume = Math.max(0, Math.min(100, action.payload)); }, clearError: (state) => { state.error = null; }, }, }); export const { setActiveCall, setIncomingCall, endCall, declineCall, setMuted, setDeafened, setSpeaking, setVolume, clearError, } = callsSlice.actions; export default callsSlice.reducer;