2023-01-03 19:55:46 +00:00
|
|
|
// Copyright 2020 Signal Messenger, LLC
|
2020-12-07 20:43:19 +00:00
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
2021-10-26 19:15:33 +00:00
|
|
|
import type { LocalizerType } from '../types/Util';
|
2020-12-07 20:43:19 +00:00
|
|
|
import { CallMode } from '../types/Calling';
|
|
|
|
import { missingCaseError } from './missingCaseError';
|
2023-08-09 00:53:06 +00:00
|
|
|
import type { CallStatus } from '../types/CallDisposition';
|
|
|
|
import {
|
|
|
|
CallDirection,
|
|
|
|
DirectCallStatus,
|
|
|
|
type CallHistoryDetails,
|
|
|
|
CallType,
|
|
|
|
} from '../types/CallDisposition';
|
2023-01-12 23:29:07 +00:00
|
|
|
import type { ConversationType } from '../state/ducks/conversations';
|
2023-08-21 17:09:54 +00:00
|
|
|
import { strictAssert } from './assert';
|
2020-12-07 20:43:19 +00:00
|
|
|
|
2023-08-09 00:53:06 +00:00
|
|
|
export type CallingNotificationType = Readonly<{
|
2023-08-17 00:11:09 +00:00
|
|
|
// In some older calls, we don't have a call id, this hardens against that.
|
|
|
|
callHistory: CallHistoryDetails | null;
|
2023-08-09 00:53:06 +00:00
|
|
|
callCreator: ConversationType | null;
|
2023-08-21 17:09:54 +00:00
|
|
|
activeConversationId: string | null;
|
|
|
|
groupCallEnded: boolean | null;
|
2020-12-07 20:43:19 +00:00
|
|
|
deviceCount: number;
|
|
|
|
maxDevices: number;
|
2023-08-09 00:53:06 +00:00
|
|
|
}>;
|
2020-12-07 20:43:19 +00:00
|
|
|
|
|
|
|
function getDirectCallNotificationText(
|
2023-08-09 00:53:06 +00:00
|
|
|
callDirection: CallDirection,
|
|
|
|
callType: CallType,
|
|
|
|
callStatus: DirectCallStatus,
|
2020-12-07 20:43:19 +00:00
|
|
|
i18n: LocalizerType
|
|
|
|
): string {
|
2023-08-09 00:53:06 +00:00
|
|
|
if (callStatus === DirectCallStatus.Pending) {
|
|
|
|
if (callDirection === CallDirection.Incoming) {
|
|
|
|
return callType === CallType.Video
|
|
|
|
? i18n('icu:incomingVideoCall')
|
|
|
|
: i18n('icu:incomingAudioCall');
|
2020-12-07 20:43:19 +00:00
|
|
|
}
|
2023-08-09 00:53:06 +00:00
|
|
|
return callType === CallType.Video
|
|
|
|
? i18n('icu:outgoingVideoCall')
|
|
|
|
: i18n('icu:outgoingAudioCall');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (callStatus === DirectCallStatus.Accepted) {
|
|
|
|
if (callDirection === CallDirection.Incoming) {
|
|
|
|
return callType === CallType.Video
|
|
|
|
? i18n('icu:acceptedIncomingVideoCall')
|
|
|
|
: i18n('icu:acceptedIncomingAudioCall');
|
2020-12-07 20:43:19 +00:00
|
|
|
}
|
2023-08-09 00:53:06 +00:00
|
|
|
return callType === CallType.Video
|
|
|
|
? i18n('icu:acceptedOutgoingVideoCall')
|
|
|
|
: i18n('icu:acceptedOutgoingAudioCall');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (callStatus === DirectCallStatus.Declined) {
|
|
|
|
if (callDirection === CallDirection.Incoming) {
|
|
|
|
return callType === CallType.Video
|
|
|
|
? i18n('icu:declinedIncomingVideoCall')
|
|
|
|
: i18n('icu:declinedIncomingAudioCall');
|
2020-12-07 20:43:19 +00:00
|
|
|
}
|
2023-08-09 00:53:06 +00:00
|
|
|
return callType === CallType.Video
|
|
|
|
? i18n('icu:missedOrDeclinedOutgoingVideoCall')
|
|
|
|
: i18n('icu:missedOrDeclinedOutgoingAudioCall');
|
2020-12-07 20:43:19 +00:00
|
|
|
}
|
2023-08-09 00:53:06 +00:00
|
|
|
|
|
|
|
if (callStatus === DirectCallStatus.Missed) {
|
|
|
|
if (callDirection === CallDirection.Incoming) {
|
|
|
|
return callType === CallType.Video
|
|
|
|
? i18n('icu:missedIncomingVideoCall')
|
|
|
|
: i18n('icu:missedIncomingAudioCall');
|
2020-12-07 20:43:19 +00:00
|
|
|
}
|
2023-08-09 00:53:06 +00:00
|
|
|
return callType === CallType.Video
|
|
|
|
? i18n('icu:missedOrDeclinedOutgoingVideoCall')
|
|
|
|
: i18n('icu:missedOrDeclinedOutgoingAudioCall');
|
2020-12-07 20:43:19 +00:00
|
|
|
}
|
2023-08-09 00:53:06 +00:00
|
|
|
|
|
|
|
if (callStatus === DirectCallStatus.Deleted) {
|
|
|
|
throw new Error(
|
|
|
|
'getDirectCallNotificationText: Cannot render deleted call'
|
|
|
|
);
|
2020-12-07 20:43:19 +00:00
|
|
|
}
|
2023-08-09 00:53:06 +00:00
|
|
|
|
|
|
|
throw missingCaseError(callStatus);
|
2020-12-07 20:43:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function getGroupCallNotificationText(
|
2023-08-21 17:09:54 +00:00
|
|
|
groupCallEnded: boolean,
|
2023-08-09 00:53:06 +00:00
|
|
|
creator: ConversationType | null,
|
2020-12-07 20:43:19 +00:00
|
|
|
i18n: LocalizerType
|
|
|
|
): string {
|
2023-08-21 17:09:54 +00:00
|
|
|
if (groupCallEnded) {
|
2023-03-30 00:03:25 +00:00
|
|
|
return i18n('icu:calling__call-notification__ended');
|
2020-12-07 20:43:19 +00:00
|
|
|
}
|
2023-08-09 00:53:06 +00:00
|
|
|
if (creator == null) {
|
2023-03-30 00:03:25 +00:00
|
|
|
return i18n('icu:calling__call-notification__started-by-someone');
|
2020-12-07 20:43:19 +00:00
|
|
|
}
|
2023-08-09 00:53:06 +00:00
|
|
|
if (creator.isMe) {
|
2023-03-30 00:03:25 +00:00
|
|
|
return i18n('icu:calling__call-notification__started-by-you');
|
2020-12-07 20:43:19 +00:00
|
|
|
}
|
2023-03-30 00:03:25 +00:00
|
|
|
return i18n('icu:calling__call-notification__started', {
|
2023-08-09 00:53:06 +00:00
|
|
|
name: creator.systemGivenName ?? creator.title,
|
2023-03-27 23:37:39 +00:00
|
|
|
});
|
2020-12-07 20:43:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export function getCallingNotificationText(
|
2023-08-09 00:53:06 +00:00
|
|
|
callingNotification: CallingNotificationType,
|
2020-12-07 20:43:19 +00:00
|
|
|
i18n: LocalizerType
|
2023-08-17 00:11:09 +00:00
|
|
|
): string | null {
|
2023-08-21 17:09:54 +00:00
|
|
|
const { callHistory, callCreator, groupCallEnded } = callingNotification;
|
2023-08-17 00:11:09 +00:00
|
|
|
if (callHistory == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2023-08-09 00:53:06 +00:00
|
|
|
if (callHistory.mode === CallMode.Direct) {
|
|
|
|
return getDirectCallNotificationText(
|
|
|
|
callHistory.direction,
|
|
|
|
callHistory.type,
|
|
|
|
callHistory.status as DirectCallStatus,
|
|
|
|
i18n
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (callHistory.mode === CallMode.Group) {
|
2023-08-21 17:09:54 +00:00
|
|
|
strictAssert(
|
|
|
|
groupCallEnded != null,
|
|
|
|
'getCallingNotificationText: groupCallEnded shouldnt be null for a group call'
|
|
|
|
);
|
|
|
|
return getGroupCallNotificationText(groupCallEnded, callCreator, i18n);
|
2023-08-09 00:53:06 +00:00
|
|
|
}
|
|
|
|
throw missingCaseError(callHistory.mode);
|
2020-12-07 20:43:19 +00:00
|
|
|
}
|
2021-08-26 20:51:55 +00:00
|
|
|
|
|
|
|
type CallingIconType =
|
|
|
|
| 'audio-incoming'
|
|
|
|
| 'audio-missed'
|
|
|
|
| 'audio-outgoing'
|
|
|
|
| 'phone'
|
|
|
|
| 'video'
|
|
|
|
| 'video-incoming'
|
|
|
|
| 'video-missed'
|
|
|
|
| 'video-outgoing';
|
|
|
|
|
2023-08-09 00:53:06 +00:00
|
|
|
export function getCallingIcon(
|
|
|
|
callType: CallType,
|
|
|
|
callDirection: CallDirection,
|
|
|
|
callStatus: CallStatus
|
|
|
|
): CallingIconType {
|
|
|
|
if (callType === CallType.Audio) {
|
|
|
|
if (callStatus === DirectCallStatus.Accepted) {
|
|
|
|
return callDirection === CallDirection.Incoming
|
|
|
|
? 'audio-incoming'
|
|
|
|
: 'audio-outgoing';
|
2021-08-26 20:51:55 +00:00
|
|
|
}
|
2023-08-09 00:53:06 +00:00
|
|
|
if (
|
|
|
|
callStatus === DirectCallStatus.Missed ||
|
|
|
|
callStatus === DirectCallStatus.Declined
|
|
|
|
) {
|
|
|
|
return 'audio-missed';
|
|
|
|
}
|
|
|
|
return 'phone';
|
2021-08-26 20:51:55 +00:00
|
|
|
}
|
2023-08-09 00:53:06 +00:00
|
|
|
if (callType === CallType.Video) {
|
|
|
|
if (callStatus === DirectCallStatus.Accepted) {
|
|
|
|
return callDirection === CallDirection.Incoming
|
|
|
|
? 'video-incoming'
|
|
|
|
: 'video-outgoing';
|
|
|
|
}
|
|
|
|
if (
|
|
|
|
callStatus === DirectCallStatus.Missed ||
|
|
|
|
callStatus === DirectCallStatus.Declined
|
|
|
|
) {
|
|
|
|
return 'video-missed';
|
|
|
|
}
|
|
|
|
return 'video';
|
2021-08-26 20:51:55 +00:00
|
|
|
}
|
2023-08-09 00:53:06 +00:00
|
|
|
if (callType === CallType.Group) {
|
|
|
|
return 'video';
|
2021-08-26 20:51:55 +00:00
|
|
|
}
|
2023-08-09 00:53:06 +00:00
|
|
|
throw missingCaseError(callType);
|
2021-08-26 20:51:55 +00:00
|
|
|
}
|