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;
 |