From 173a7b729a519afc4d3ad2563a5c352064228ef8 Mon Sep 17 00:00:00 2001 From: automated-signal <37887102+automated-signal@users.noreply.github.com> Date: Wed, 16 Oct 2024 12:36:32 -0500 Subject: [PATCH] Fix sync CallEvent peerId for call link roomIds Co-authored-by: ayumi-signal <143036029+ayumi-signal@users.noreply.github.com> --- ts/components/CallLinkDetails.stories.tsx | 4 +++ ts/components/CallLinkDetails.tsx | 39 ++++++++++++++++++++++- ts/state/smart/CallLinkDetails.tsx | 6 ---- ts/types/CallDisposition.ts | 37 +++++++++++++++------ ts/util/callDisposition.ts | 5 ++- 5 files changed, 74 insertions(+), 17 deletions(-) diff --git a/ts/components/CallLinkDetails.stories.tsx b/ts/components/CallLinkDetails.stories.tsx index 38797634ca1..540120e9874 100644 --- a/ts/components/CallLinkDetails.stories.tsx +++ b/ts/components/CallLinkDetails.stories.tsx @@ -74,3 +74,7 @@ export function InAnotherCallAndCallActive( /> ); } + +export function MissingCallLink(args: CallLinkDetailsProps): JSX.Element { + return ; +} diff --git a/ts/components/CallLinkDetails.tsx b/ts/components/CallLinkDetails.tsx index fa32a965532..8ff7b79af87 100644 --- a/ts/components/CallLinkDetails.tsx +++ b/ts/components/CallLinkDetails.tsx @@ -31,7 +31,7 @@ function toUrlWithoutProtocol(url: URL): string { export type CallLinkDetailsProps = Readonly<{ callHistoryGroup: CallHistoryGroup; - callLink: CallLinkType; + callLink: CallLinkType | undefined; isAnybodyInCall: boolean; isInCall: boolean; isInAnotherCall: boolean; @@ -58,6 +58,11 @@ export function CallLinkDetails({ }: CallLinkDetailsProps): JSX.Element { const [isDeleteCallLinkModalOpen, setIsDeleteCallLinkModalOpen] = useState(false); + + if (!callLink) { + return renderMissingCallLink({ callHistoryGroup, i18n }); + } + const webUrl = linkCallRoute.toWebUrl({ key: callLink.rootKey, }); @@ -256,3 +261,35 @@ export function CallLinkDetails({ ); } + +function renderMissingCallLink({ + callHistoryGroup, + i18n, +}: Pick): JSX.Element { + return ( +
+
+ +
+

+ {i18n('icu:calling__call-link-default-title')} +

+
+
+ +
+ ); +} diff --git a/ts/state/smart/CallLinkDetails.tsx b/ts/state/smart/CallLinkDetails.tsx index 4884292f35c..d615d35f1ab 100644 --- a/ts/state/smart/CallLinkDetails.tsx +++ b/ts/state/smart/CallLinkDetails.tsx @@ -12,7 +12,6 @@ import { } from '../selectors/calling'; import { useGlobalModalActions } from '../ducks/globalModals'; import { useCallingActions } from '../ducks/calling'; -import * as log from '../../logging/log'; import { strictAssert } from '../../util/assert'; import type { CallLinkRestrictions } from '../../types/CallLink'; import { isAnybodyInGroupCall } from '../ducks/callingHelpers'; @@ -77,11 +76,6 @@ export const SmartCallLinkDetails = memo(function SmartCallLinkDetails({ activeCall && callLink && activeCall.conversationId === callLink.roomId ); - if (callLink == null) { - log.error(`SmartCallLinkDetails: callLink not found for room ${roomId}`); - return null; - } - return ( { } } - // groupId or call link roomId + // groupId return Bytes.toBase64(value); }); +const roomIdInBytesSchema = z + .instanceof(Uint8Array) + .transform(value => Bytes.toHex(value)); + const longToStringSchema = z .instanceof(Long) .transform(long => long.toString()); @@ -264,14 +268,29 @@ const longToNumberSchema = z .instanceof(Long) .transform(long => long.toNumber()); -export const callEventNormalizeSchema = z.object({ - peerId: peerIdInBytesSchema, - callId: longToStringSchema, - timestamp: longToNumberSchema, - type: z.nativeEnum(Proto.SyncMessage.CallEvent.Type), - direction: z.nativeEnum(Proto.SyncMessage.CallEvent.Direction), - event: z.nativeEnum(Proto.SyncMessage.CallEvent.Event), -}); +export const callEventNormalizeSchema = z + .object({ + callId: longToStringSchema, + timestamp: longToNumberSchema, + direction: z.nativeEnum(Proto.SyncMessage.CallEvent.Direction), + event: z.nativeEnum(Proto.SyncMessage.CallEvent.Event), + }) + .and( + z.union([ + z.object({ + type: z + .nativeEnum(Proto.SyncMessage.CallEvent.Type) + .refine(val => val === Proto.SyncMessage.CallEvent.Type.AD_HOC_CALL), + peerId: roomIdInBytesSchema, + }), + z.object({ + type: z + .nativeEnum(Proto.SyncMessage.CallEvent.Type) + .refine(val => val !== Proto.SyncMessage.CallEvent.Type.AD_HOC_CALL), + peerId: peerIdInBytesSchema, + }), + ]) + ); export const callLogEventNormalizeSchema = z.object({ type: z.nativeEnum(Proto.SyncMessage.CallLogEvent.Type), diff --git a/ts/util/callDisposition.ts b/ts/util/callDisposition.ts index 51fc4354130..a80683ecffc 100644 --- a/ts/util/callDisposition.ts +++ b/ts/util/callDisposition.ts @@ -338,10 +338,13 @@ function shouldSyncStatus(callStatus: CallStatus) { return statusToProto[callStatus] != null; } +// For outgoing sync messages. peerId contains direct or group conversationId or +// call link peerId. Locally conversationId is Base64 encoded but roomIds +// are hex encoded. export function getBytesForPeerId(callHistory: CallHistoryDetails): Uint8Array { let peerId = callHistory.mode === CallMode.Adhoc - ? Bytes.fromBase64(callHistory.peerId) + ? Bytes.fromHex(callHistory.peerId) : uuidToBytes(callHistory.peerId); if (peerId.length === 0) { peerId = Bytes.fromBase64(callHistory.peerId);