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