You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
4.4 KiB
TypeScript
136 lines
4.4 KiB
TypeScript
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
|
import { setIsRinging } from '../../session/utils/RingingManager';
|
|
|
|
export type CallStatusEnum = 'offering' | 'incoming' | 'connecting' | 'ongoing' | undefined;
|
|
|
|
export type CallStateType = {
|
|
ongoingWith?: string;
|
|
ongoingCallStatus?: CallStatusEnum;
|
|
callIsInFullScreen: boolean;
|
|
};
|
|
|
|
export const initialCallState: CallStateType = {
|
|
ongoingWith: undefined,
|
|
ongoingCallStatus: undefined,
|
|
callIsInFullScreen: false,
|
|
};
|
|
|
|
/**
|
|
* This slice is the one holding the default joinable rooms fetched once in a while from the default opengroup v2 server.
|
|
*/
|
|
const callSlice = createSlice({
|
|
name: 'call',
|
|
initialState: initialCallState,
|
|
reducers: {
|
|
incomingCall(state: CallStateType, action: PayloadAction<{ pubkey: string }>) {
|
|
const callerPubkey = action.payload.pubkey;
|
|
if (state.ongoingWith && state.ongoingWith !== callerPubkey) {
|
|
window.log.warn(
|
|
`Got an incoming call action for ${callerPubkey} but we are already in a call.`
|
|
);
|
|
return state;
|
|
}
|
|
state.ongoingWith = callerPubkey;
|
|
state.ongoingCallStatus = 'incoming';
|
|
setIsRinging(true);
|
|
return state;
|
|
},
|
|
endCall(state: CallStateType) {
|
|
state.ongoingCallStatus = undefined;
|
|
state.ongoingWith = undefined;
|
|
setIsRinging(false);
|
|
|
|
return state;
|
|
},
|
|
answerCall(state: CallStateType, action: PayloadAction<{ pubkey: string }>) {
|
|
const callerPubkey = action.payload.pubkey;
|
|
|
|
// to answer a call we need an incoming call form that specific pubkey
|
|
|
|
if (state.ongoingWith !== callerPubkey || state.ongoingCallStatus !== 'incoming') {
|
|
window.log.info('cannot answer a call we are not displaying a dialog with');
|
|
return state;
|
|
}
|
|
state.ongoingCallStatus = 'connecting';
|
|
state.callIsInFullScreen = false;
|
|
setIsRinging(false);
|
|
return state;
|
|
},
|
|
callConnected(state: CallStateType, action: PayloadAction<{ pubkey: string }>) {
|
|
const callerPubkey = action.payload.pubkey;
|
|
if (callerPubkey !== state.ongoingWith) {
|
|
window.log.info('cannot answer a call we did not start or receive first');
|
|
return state;
|
|
}
|
|
const existingCallState = state.ongoingCallStatus;
|
|
|
|
if (existingCallState !== 'connecting' && existingCallState !== 'offering') {
|
|
window.log.info(
|
|
'cannot answer a call we are not connecting (and so answered) to or offering a call'
|
|
);
|
|
return state;
|
|
}
|
|
setIsRinging(false);
|
|
|
|
state.ongoingCallStatus = 'ongoing';
|
|
state.callIsInFullScreen = false;
|
|
return state;
|
|
},
|
|
callReconnecting(state: CallStateType, action: PayloadAction<{ pubkey: string }>) {
|
|
const callerPubkey = action.payload.pubkey;
|
|
if (callerPubkey !== state.ongoingWith) {
|
|
window.log.info('cannot reconnect a call we did not start or receive first');
|
|
return state;
|
|
}
|
|
const existingCallState = state.ongoingCallStatus;
|
|
|
|
if (existingCallState !== 'ongoing') {
|
|
window.log.info('cannot reconnect a call we are not ongoing');
|
|
return state;
|
|
}
|
|
|
|
state.ongoingCallStatus = 'connecting';
|
|
return state;
|
|
},
|
|
startingCallWith(state: CallStateType, action: PayloadAction<{ pubkey: string }>) {
|
|
if (state.ongoingWith) {
|
|
window.log.warn('cannot start a call with an ongoing call already: ongoingWith');
|
|
return state;
|
|
}
|
|
if (state.ongoingCallStatus) {
|
|
window.log.warn('cannot start a call with an ongoing call already: ongoingCallStatus');
|
|
return state;
|
|
}
|
|
setIsRinging(true);
|
|
|
|
const callerPubkey = action.payload.pubkey;
|
|
state.ongoingWith = callerPubkey;
|
|
state.ongoingCallStatus = 'offering';
|
|
state.callIsInFullScreen = false;
|
|
|
|
return state;
|
|
},
|
|
setFullScreenCall(state: CallStateType, action: PayloadAction<boolean>) {
|
|
// only set in full screen if we have an ongoing call
|
|
if (state.ongoingWith && state.ongoingCallStatus === 'ongoing' && action.payload) {
|
|
state.callIsInFullScreen = true;
|
|
return state;
|
|
}
|
|
state.callIsInFullScreen = false;
|
|
return state;
|
|
},
|
|
},
|
|
});
|
|
|
|
const { actions, reducer } = callSlice;
|
|
export const {
|
|
incomingCall,
|
|
endCall,
|
|
answerCall,
|
|
callConnected,
|
|
callReconnecting,
|
|
startingCallWith,
|
|
setFullScreenCall,
|
|
} = actions;
|
|
export const callReducer = reducer;
|