232 lines
6.4 KiB
TypeScript
232 lines
6.4 KiB
TypeScript
// Copyright 2020 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
import type { LocalizerType } from '../types/Util';
|
|
import {
|
|
CallMode,
|
|
CallDirection,
|
|
DirectCallStatus,
|
|
type CallHistoryDetails,
|
|
CallType,
|
|
GroupCallStatus,
|
|
} from '../types/CallDisposition';
|
|
import { missingCaseError } from './missingCaseError';
|
|
import type { CallStatus } from '../types/CallDisposition';
|
|
import type { ConversationType } from '../state/ducks/conversations';
|
|
import { strictAssert } from './assert';
|
|
import { isMoreRecentThan } from './timestamp';
|
|
import { MINUTE } from './durations';
|
|
|
|
export type CallingNotificationType = Readonly<{
|
|
// In some older calls, we don't have a call id, this hardens against that.
|
|
callHistory: CallHistoryDetails | null;
|
|
callCreator: ConversationType | null;
|
|
activeConversationId: string | null;
|
|
groupCallEnded: boolean | null;
|
|
deviceCount: number;
|
|
maxDevices: number;
|
|
isSelectMode: boolean;
|
|
isTargeted: boolean;
|
|
}>;
|
|
|
|
export function getDirectCallNotificationText(
|
|
callDirection: CallDirection,
|
|
callType: CallType,
|
|
callStatus: DirectCallStatus,
|
|
i18n: LocalizerType
|
|
): string {
|
|
if (
|
|
callStatus === DirectCallStatus.Pending ||
|
|
callStatus === DirectCallStatus.Unknown
|
|
) {
|
|
if (callDirection === CallDirection.Incoming) {
|
|
return callType === CallType.Video
|
|
? i18n('icu:incomingVideoCall')
|
|
: i18n('icu:incomingAudioCall');
|
|
}
|
|
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');
|
|
}
|
|
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');
|
|
}
|
|
return callType === CallType.Video
|
|
? i18n('icu:missedOrDeclinedOutgoingVideoCall')
|
|
: i18n('icu:missedOrDeclinedOutgoingAudioCall');
|
|
}
|
|
|
|
if (
|
|
callStatus === DirectCallStatus.Missed ||
|
|
callStatus === DirectCallStatus.MissedNotificationProfile
|
|
) {
|
|
if (callDirection === CallDirection.Incoming) {
|
|
return callType === CallType.Video
|
|
? i18n('icu:missedIncomingVideoCall')
|
|
: i18n('icu:missedIncomingAudioCall');
|
|
}
|
|
return callType === CallType.Video
|
|
? i18n('icu:missedOrDeclinedOutgoingVideoCall')
|
|
: i18n('icu:missedOrDeclinedOutgoingAudioCall');
|
|
}
|
|
|
|
if (callStatus === DirectCallStatus.Deleted) {
|
|
throw new Error(
|
|
'getDirectCallNotificationText: Cannot render deleted call'
|
|
);
|
|
}
|
|
|
|
throw missingCaseError(callStatus);
|
|
}
|
|
|
|
function getGroupCallNotificationText({
|
|
groupCallEnded,
|
|
creator,
|
|
callHistory,
|
|
i18n,
|
|
}: {
|
|
groupCallEnded: boolean;
|
|
creator: ConversationType | null;
|
|
callHistory: CallHistoryDetails;
|
|
i18n: LocalizerType;
|
|
}): string {
|
|
if (groupCallEnded) {
|
|
const { direction, status, timestamp } = callHistory;
|
|
if (direction === CallDirection.Incoming) {
|
|
if (status === GroupCallStatus.Declined) {
|
|
return i18n('icu:CallHistory__DescriptionVideoCall--Declined');
|
|
}
|
|
if (status === GroupCallStatus.Missed) {
|
|
return i18n('icu:CallHistory__DescriptionVideoCall--Missed');
|
|
}
|
|
if (isMoreRecentThan(timestamp, 5 * MINUTE)) {
|
|
return i18n('icu:calling__call-notification__ended');
|
|
}
|
|
return i18n('icu:acceptedIncomingVideoCall');
|
|
}
|
|
|
|
// Outgoing ended group calls
|
|
if (isMoreRecentThan(timestamp, 5 * MINUTE)) {
|
|
return i18n('icu:calling__call-notification__ended');
|
|
}
|
|
return i18n('icu:acceptedOutgoingVideoCall');
|
|
}
|
|
|
|
// TODO: Active call with participants DESKTOP-7439
|
|
|
|
if (creator == null) {
|
|
return i18n('icu:calling__call-notification__started-by-someone');
|
|
}
|
|
if (creator.isMe) {
|
|
return i18n('icu:calling__call-notification__started-by-you');
|
|
}
|
|
return i18n('icu:calling__call-notification__started', {
|
|
name: creator.systemGivenName ?? creator.title,
|
|
});
|
|
}
|
|
|
|
export function getCallingNotificationText(
|
|
callingNotification: CallingNotificationType,
|
|
i18n: LocalizerType
|
|
): string | null {
|
|
const {
|
|
callHistory,
|
|
callCreator: creator,
|
|
groupCallEnded,
|
|
} = callingNotification;
|
|
if (callHistory == null) {
|
|
return null;
|
|
}
|
|
|
|
if (callHistory.mode === CallMode.Direct) {
|
|
return getDirectCallNotificationText(
|
|
callHistory.direction,
|
|
callHistory.type,
|
|
callHistory.status as DirectCallStatus,
|
|
i18n
|
|
);
|
|
}
|
|
if (callHistory.mode === CallMode.Group) {
|
|
strictAssert(
|
|
groupCallEnded != null,
|
|
'getCallingNotificationText: groupCallEnded shouldnt be null for a group call'
|
|
);
|
|
return getGroupCallNotificationText({
|
|
groupCallEnded,
|
|
creator,
|
|
callHistory,
|
|
i18n,
|
|
});
|
|
}
|
|
if (callHistory.mode === CallMode.Adhoc) {
|
|
return null;
|
|
}
|
|
throw missingCaseError(callHistory.mode);
|
|
}
|
|
|
|
type CallingIconType =
|
|
| 'audio-incoming'
|
|
| 'audio-missed'
|
|
| 'audio-outgoing'
|
|
| 'phone'
|
|
| 'video'
|
|
| 'video-incoming'
|
|
| 'video-missed'
|
|
| 'video-outgoing';
|
|
|
|
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';
|
|
}
|
|
if (
|
|
callStatus === DirectCallStatus.Missed ||
|
|
callStatus === DirectCallStatus.Declined
|
|
) {
|
|
return 'audio-missed';
|
|
}
|
|
return 'phone';
|
|
}
|
|
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';
|
|
}
|
|
if (callType === CallType.Group || callType === CallType.Adhoc) {
|
|
return 'video';
|
|
}
|
|
if (callType === CallType.Unknown) {
|
|
return 'video';
|
|
}
|
|
throw missingCaseError(callType);
|
|
}
|