90 lines
2.6 KiB
TypeScript
90 lines
2.6 KiB
TypeScript
// Copyright 2020-2021 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
import { createSelector } from 'reselect';
|
|
|
|
import { StateType } from '../reducer';
|
|
import {
|
|
CallingStateType,
|
|
CallsByConversationType,
|
|
DirectCallStateType,
|
|
GroupCallStateType,
|
|
isAnybodyElseInGroupCall,
|
|
} from '../ducks/calling';
|
|
import {
|
|
CallMode,
|
|
CallState,
|
|
GroupCallConnectionState,
|
|
} from '../../types/Calling';
|
|
import { getUserUuid } from './user';
|
|
import { getOwn } from '../../util/getOwn';
|
|
import { missingCaseError } from '../../util/missingCaseError';
|
|
|
|
export type CallStateType = DirectCallStateType | GroupCallStateType;
|
|
|
|
const getCalling = (state: StateType): CallingStateType => state.calling;
|
|
|
|
export const getActiveCallState = createSelector(
|
|
getCalling,
|
|
(state: CallingStateType) => state.activeCallState
|
|
);
|
|
|
|
export const getCallsByConversation = createSelector(
|
|
getCalling,
|
|
(state: CallingStateType): CallsByConversationType =>
|
|
state.callsByConversation
|
|
);
|
|
|
|
export type CallSelectorType = (
|
|
conversationId: string
|
|
) => CallStateType | undefined;
|
|
export const getCallSelector = createSelector(
|
|
getCallsByConversation,
|
|
(callsByConversation: CallsByConversationType): CallSelectorType => (
|
|
conversationId: string
|
|
) => getOwn(callsByConversation, conversationId)
|
|
);
|
|
|
|
export const getActiveCall = createSelector(
|
|
getActiveCallState,
|
|
getCallSelector,
|
|
(activeCallState, callSelector): undefined | CallStateType => {
|
|
if (activeCallState && activeCallState.conversationId) {
|
|
return callSelector(activeCallState.conversationId);
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
);
|
|
|
|
export const isInCall = createSelector(
|
|
getActiveCall,
|
|
(call: CallStateType | undefined): boolean => Boolean(call)
|
|
);
|
|
|
|
// In theory, there could be multiple incoming calls, or an incoming call while there's
|
|
// an active call. In practice, the UI is not ready for this, and RingRTC doesn't
|
|
// support it for direct calls.
|
|
export const getIncomingCall = createSelector(
|
|
getCallsByConversation,
|
|
getUserUuid,
|
|
(
|
|
callsByConversation: CallsByConversationType,
|
|
ourUuid: string
|
|
): undefined | DirectCallStateType | GroupCallStateType => {
|
|
return Object.values(callsByConversation).find(call => {
|
|
switch (call.callMode) {
|
|
case CallMode.Direct:
|
|
return call.isIncoming && call.callState === CallState.Ringing;
|
|
case CallMode.Group:
|
|
return (
|
|
call.ringerUuid &&
|
|
call.connectionState === GroupCallConnectionState.NotConnected &&
|
|
isAnybodyElseInGroupCall(call.peekInfo, ourUuid)
|
|
);
|
|
default:
|
|
throw missingCaseError(call);
|
|
}
|
|
});
|
|
}
|
|
);
|