From 2933b51fea276d4eca053d801572ecf2a8505fd9 Mon Sep 17 00:00:00 2001 From: R Midhun Suresh Date: Tue, 12 May 2026 02:42:51 +0530 Subject: [PATCH] Call Tile - Render a tile showing that a call was started (#32988) * Ignore specific directories Otherwise newly generated screenshots will be ignored. * Create a CallStartedTileView This view will render a tile that shows when an EC call was started in the timeline. * Add storybook tests * Add vite tests * Export the view from shared-components package * Add a viewmodel for driving the view * Support rendering the tile in the tile factory * Fix tile rendering * Add comment to explain css height * Use semantic token for gap * Update snapshot * Use min-height over height This will scale the element if the user sets a custom font size. * Don't show timestamp for call started tile Timestamp is already shown as a part of the tile content. * Fix broken tile on bubble layout The tile should be full-width and not shown within a bubble. * Fix tests * Update storybook title --- .../src/components/views/rooms/EventTile.tsx | 9 +- apps/web/src/events/EventTileFactory.tsx | 12 +++ apps/web/src/utils/EventRenderingUtils.ts | 2 + .../call/CallStartedTileViewModel.ts | 79 ++++++++++++++++++ .../CallStartedTileViewModel-test.ts | 71 ++++++++++++++++ .../default-auto.png | Bin 0 -> 19644 bytes .../video-call-auto.png | Bin 0 -> 19595 bytes .../voice-call-auto.png | Bin 0 -> 19647 bytes .../src/i18n/strings/en_EN.json | 4 + packages/shared-components/src/index.ts | 1 + .../CallStartedTileView.module.css | 30 +++++++ .../CallStartedTileView.stories.tsx | 62 ++++++++++++++ .../CallStartedTileView.test.tsx | 29 +++++++ .../CallStartedTile/CallStartedTileView.tsx | 77 +++++++++++++++++ .../CallStartedTileView.test.tsx.snap | 65 ++++++++++++++ .../room/timeline/event-tile/call/index.ts | 8 ++ 16 files changed, 448 insertions(+), 1 deletion(-) create mode 100644 apps/web/src/viewmodels/room/timeline/event-tile/call/CallStartedTileViewModel.ts create mode 100644 apps/web/test/viewmodels/event-tiles/CallStartedTileViewModel-test.ts create mode 100644 packages/shared-components/__vis__/linux/__baselines__/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.stories.tsx/default-auto.png create mode 100644 packages/shared-components/__vis__/linux/__baselines__/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.stories.tsx/video-call-auto.png create mode 100644 packages/shared-components/__vis__/linux/__baselines__/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.stories.tsx/voice-call-auto.png create mode 100644 packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.module.css create mode 100644 packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.stories.tsx create mode 100644 packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.test.tsx create mode 100644 packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.tsx create mode 100644 packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/__snapshots__/CallStartedTileView.test.tsx.snap create mode 100644 packages/shared-components/src/room/timeline/event-tile/call/index.ts diff --git a/apps/web/src/components/views/rooms/EventTile.tsx b/apps/web/src/components/views/rooms/EventTile.tsx index 0590c06887..171cc38c0c 100644 --- a/apps/web/src/components/views/rooms/EventTile.tsx +++ b/apps/web/src/components/views/rooms/EventTile.tsx @@ -717,6 +717,9 @@ export class UnwrappedEventTile extends React.Component if (this.props.isRedacted) return false; + // This event is a room mention but we don't want the call tile to have a highlight. + if (this.props.mxEvent.getType() === EventType.RTCNotification) return false; + const cli = MatrixClientPeg.safeGet(); const actions = cli.getPushActionsForEvent(this.props.mxEvent.replacingEvent() || this.props.mxEvent); // get the actions for the previous version of the event too if it is an edit @@ -1119,7 +1122,8 @@ export class UnwrappedEventTile extends React.Component } else if ( (this.props.continuation && this.context.timelineRenderingType !== TimelineRenderingType.File) || eventType === EventType.CallInvite || - ElementCallEventType.matches(eventType) + ElementCallEventType.matches(eventType) || + eventType === EventType.RTCNotification ) { // no avatar or sender profile for continuation messages and call tiles avatarSize = null; @@ -1197,6 +1201,9 @@ export class UnwrappedEventTile extends React.Component const showTimestamp = this.props.mxEvent.getTs() && + // Don't show timestamp for the CallStarted tile because + // the tile content already renders a timestamp. + this.props.mxEvent.getType() !== EventType.RTCNotification && !this.props.hideTimestamp && (this.props.alwaysShowTimestamps || this.props.last || diff --git a/apps/web/src/events/EventTileFactory.tsx b/apps/web/src/events/EventTileFactory.tsx index 152a69c1ec..6ac6adf9cb 100644 --- a/apps/web/src/events/EventTileFactory.tsx +++ b/apps/web/src/events/EventTileFactory.tsx @@ -18,6 +18,7 @@ import { M_POLL_START, } from "matrix-js-sdk/src/matrix"; import { + CallStartedTileView, EncryptionEventView, HiddenBodyView, MKeyVerificationRequestView, @@ -51,6 +52,7 @@ import { MKeyVerificationRequestViewModel } from "../viewmodels/room/timeline/ev import { TextualEventViewModel } from "../viewmodels/room/timeline/event-tile/TextualEventViewModel"; import { HiddenBodyViewModel } from "../viewmodels/room/timeline/event-tile/body/HiddenBodyViewModel"; import { ElementCallEventType } from "../call-types"; +import { CallStartedTileViewModel } from "../viewmodels/room/timeline/event-tile/call/CallStartedTileViewModel"; // Subset of EventTile's IProps plus some mixins export interface EventTileTypeProps extends Pick< @@ -122,6 +124,15 @@ function HiddenBodyWrappedView({ mxEvent, ref }: IBodyProps): JSX.Element { } const HiddenEventFactory: Factory = (ref, props) => ; +function CallStartedTileViewWrapped({ mxEvent }: IBodyProps): JSX.Element { + const vm = useCreateAutoDisposedViewModel(() => new CallStartedTileViewModel({ mxEvent })); + return ; +} + +export const CallStartedEventFactory: Factory = (ref, props) => { + return ; +}; + // These factories are exported for reference comparison against pickFactory() export const JitsiEventFactory: Factory = (ref, props) => ; export const JSONEventFactory: Factory = (ref, props) => ; @@ -135,6 +146,7 @@ const EVENT_TILE_TYPES = new Map([ [M_POLL_END.name, MessageEventFactory], [M_POLL_END.altName, MessageEventFactory], [EventType.CallInvite, LegacyCallEventFactory as Factory], // note that this requires a special factory type + [EventType.RTCNotification, CallStartedEventFactory], ]); const STATE_EVENT_TILE_TYPES = new Map([ diff --git a/apps/web/src/utils/EventRenderingUtils.ts b/apps/web/src/utils/EventRenderingUtils.ts index b99e01a07b..2295cfd144 100644 --- a/apps/web/src/utils/EventRenderingUtils.ts +++ b/apps/web/src/utils/EventRenderingUtils.ts @@ -35,6 +35,7 @@ const calcIsInfoMessage = ( eventType !== EventType.RoomMessageEncrypted && eventType !== EventType.Sticker && eventType !== EventType.RoomCreate && + eventType !== EventType.RTCNotification && !M_POLL_START.matches(eventType) && !M_POLL_END.matches(eventType) && !M_BEACON_INFO.matches(eventType) @@ -76,6 +77,7 @@ export function getEventDisplayInfo( // Info messages are basically information about commands processed on a room let isBubbleMessage = + eventType === EventType.RTCNotification || eventType.startsWith("m.key.verification") || (eventType === EventType.RoomMessage && msgtype?.startsWith("m.key.verification")) || eventType === EventType.RoomCreate || diff --git a/apps/web/src/viewmodels/room/timeline/event-tile/call/CallStartedTileViewModel.ts b/apps/web/src/viewmodels/room/timeline/event-tile/call/CallStartedTileViewModel.ts new file mode 100644 index 0000000000..514c7c7c89 --- /dev/null +++ b/apps/web/src/viewmodels/room/timeline/event-tile/call/CallStartedTileViewModel.ts @@ -0,0 +1,79 @@ +/* + * Copyright 2026 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +import { BaseViewModel, CallType, type CallStartedTileViewSnapshot } from "@element-hq/web-shared-components"; + +import type { MatrixEvent } from "matrix-js-sdk/src/matrix"; +import type { IRTCNotificationContent } from "matrix-js-sdk/src/matrixrtc"; +import SettingsStore from "../../../../../settings/SettingsStore"; +import { formatTime } from "../../../../../DateUtils"; +import defaultDispatcher from "../../../../../dispatcher/dispatcher"; +import type { SettingUpdatedPayload } from "../../../../../dispatcher/payloads/SettingUpdatedPayload"; +import type { ActionPayload } from "../../../../../dispatcher/payloads"; +import { Action } from "../../../../../dispatcher/actions"; + +export interface CallStartedTileViewModelProps { + mxEvent: MatrixEvent; +} + +function getIntentFromEvent(event: MatrixEvent): CallStartedTileViewSnapshot["type"] { + const content = event.getContent(); + const intentInContent = content["m.call.intent"]; + switch (intentInContent) { + case "audio": + return CallType.Voice; + case "video": + default: + return CallType.Video; + } +} + +function getTimeFromEvent(event: MatrixEvent, showTwelveHour: boolean): CallStartedTileViewSnapshot["timestamp"] { + const content = event.getContent(); + const senderTs = content["sender_ts"]; + const originServerTs = event.getTs(); + const ts = Math.abs(senderTs - originServerTs) > 20000 ? originServerTs : senderTs; + + const date = new Date(ts); + const timestamp = formatTime(date, showTwelveHour); + return timestamp; +} + +function getInitialSnapshot(event: MatrixEvent): CallStartedTileViewSnapshot { + const type = getIntentFromEvent(event); + const showTwelveHour = SettingsStore.getValue("showTwelveHourTimestamps"); + const timestamp = getTimeFromEvent(event, showTwelveHour); + return { type, timestamp }; +} + +function isSettingsChangedPayload(payload: ActionPayload): payload is SettingUpdatedPayload { + return payload.action === Action.SettingUpdated; +} + +/** + * ViewModel for a timeline tile that indicates the start of an element call. + */ +export class CallStartedTileViewModel extends BaseViewModel< + CallStartedTileViewSnapshot, + CallStartedTileViewModelProps +> { + public constructor(props: CallStartedTileViewModelProps) { + super(props, getInitialSnapshot(props.mxEvent)); + SettingsStore.monitorSetting("showTwelveHourTimestamps", null); + const token = defaultDispatcher.register(this.onAction); + this.disposables.track(() => { + defaultDispatcher.unregister(token); + }); + } + + private onAction = (payload: ActionPayload): void => { + if (!isSettingsChangedPayload(payload) || payload.settingName !== "showTwelveHourTimestamps") return; + const showTwelveHour = (payload.newValue as boolean) ?? false; + const timestamp = getTimeFromEvent(this.props.mxEvent, showTwelveHour); + this.snapshot.merge({ timestamp }); + }; +} diff --git a/apps/web/test/viewmodels/event-tiles/CallStartedTileViewModel-test.ts b/apps/web/test/viewmodels/event-tiles/CallStartedTileViewModel-test.ts new file mode 100644 index 0000000000..166407da2b --- /dev/null +++ b/apps/web/test/viewmodels/event-tiles/CallStartedTileViewModel-test.ts @@ -0,0 +1,71 @@ +/* + * Copyright 2026 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +import { type MatrixEvent, EventType } from "matrix-js-sdk/src/matrix"; +import { CallType } from "@element-hq/web-shared-components"; +import { waitFor } from "jest-matrix-react"; + +import { mkEvent } from "../../test-utils"; +import { CallStartedTileViewModel } from "../../../src/viewmodels/room/timeline/event-tile/call/CallStartedTileViewModel"; +import SettingsStore from "../../../src/settings/SettingsStore"; +import { SettingLevel } from "../../../src/settings/SettingLevel"; + +function getMockedRtcNotificationEvent(intent: string, senderTs: number, serverTs: number): MatrixEvent { + const mockEvent = mkEvent({ + type: EventType.RTCNotification, + user: "@foo:m.org", + content: { + "m.call.intent": intent, + "sender_ts": senderTs, + }, + ts: serverTs, + event: true, + }); + return mockEvent; +} + +describe("CallStartedTileViewModel", () => { + it("should set voice intent in state", () => { + const mxEvent = getMockedRtcNotificationEvent("audio", 1752583130365, 1752583130365); + const vm = new CallStartedTileViewModel({ mxEvent }); + const { type } = vm.getSnapshot(); + expect(type).toStrictEqual(CallType.Voice); + }); + + it("should set video intent in state", () => { + const mxEvent = getMockedRtcNotificationEvent("video", 1752583130365, 1752583130365); + const vm = new CallStartedTileViewModel({ mxEvent }); + const { type } = vm.getSnapshot(); + expect(type).toStrictEqual(CallType.Video); + }); + + it("should calculate time string correctly", () => { + const mxEvent = getMockedRtcNotificationEvent("video", 924285348000, 924285348000); + const vm = new CallStartedTileViewModel({ mxEvent }); + const { timestamp } = vm.getSnapshot(); + expect(timestamp).toStrictEqual("17:55"); + }); + + it("should calculate time string correctly when configured to use 12 hour format", async () => { + const mxEvent = getMockedRtcNotificationEvent("video", 924285348000, 924285348000); + await SettingsStore.setValue("showTwelveHourTimestamps", null, SettingLevel.DEVICE, true); + const vm = new CallStartedTileViewModel({ mxEvent }); + const { timestamp } = vm.getSnapshot(); + expect(timestamp).toStrictEqual("5:55 PM"); + SettingsStore.reset(); + }); + + it("should change timestamp format when setting is modified", async () => { + const mxEvent = getMockedRtcNotificationEvent("video", 924285348000, 924285348000); + const vm = new CallStartedTileViewModel({ mxEvent }); + expect(vm.getSnapshot().timestamp).toStrictEqual("17:55"); + await SettingsStore.setValue("showTwelveHourTimestamps", null, SettingLevel.DEVICE, true); + await waitFor(() => { + expect(vm.getSnapshot().timestamp).toStrictEqual("5:55 PM"); + }); + }); +}); diff --git a/packages/shared-components/__vis__/linux/__baselines__/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.stories.tsx/default-auto.png b/packages/shared-components/__vis__/linux/__baselines__/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.stories.tsx/default-auto.png new file mode 100644 index 0000000000000000000000000000000000000000..ca64e3659e867830d9130bf8bb37f1567d2d5279 GIT binary patch literal 19644 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 hvRJHbW* literal 0 HcmV?d00001 diff --git a/packages/shared-components/__vis__/linux/__baselines__/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.stories.tsx/video-call-auto.png b/packages/shared-components/__vis__/linux/__baselines__/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.stories.tsx/video-call-auto.png new file mode 100644 index 0000000000000000000000000000000000000000..c1d96b394d958f72ebf6ab2a347ad7410d1d258c GIT binary patch literal 19595 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 AZ2$lO literal 0 HcmV?d00001 diff --git a/packages/shared-components/__vis__/linux/__baselines__/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.stories.tsx/voice-call-auto.png b/packages/shared-components/__vis__/linux/__baselines__/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.stories.tsx/voice-call-auto.png new file mode 100644 index 0000000000000000000000000000000000000000..775a3b94cdbeb53da5c750b6a4663d96a886d7eb GIT binary patch literal 19647 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 rJ!rvTFouS7!#|vb4Z9D;6d$;2r#bmyc7@ literal 0 HcmV?d00001 diff --git a/packages/shared-components/src/i18n/strings/en_EN.json b/packages/shared-components/src/i18n/strings/en_EN.json index 3bb8915e14..bf2775e354 100644 --- a/packages/shared-components/src/i18n/strings/en_EN.json +++ b/packages/shared-components/src/i18n/strings/en_EN.json @@ -199,6 +199,10 @@ "n_minutes_ago": "%(num)s minutes ago" }, "timeline": { + "call_tile": { + "video_call_title": "Video call", + "voice_call_title": "Voice call" + }, "decryption_failure": { "blocked": "The sender has blocked you from receiving this message because your device is unverified", "historical_event_no_key_backup": "Historical messages are not available on this device", diff --git a/packages/shared-components/src/index.ts b/packages/shared-components/src/index.ts index 23bc9d4758..fa52da1a02 100644 --- a/packages/shared-components/src/index.ts +++ b/packages/shared-components/src/index.ts @@ -39,6 +39,7 @@ export * from "./room/timeline/TimelineSeparator"; export * from "./room/timeline/event-tile/actions/ActionBarView"; export * from "./room/timeline/event-tile/EventTileView/DisambiguatedProfile"; export * from "./room/timeline/event-tile/EventTileView/EncryptionEventView"; +export * from "./room/timeline/event-tile/call"; export * from "./room/timeline/event-tile/EventTileView/EventTileBubble"; export * from "./room/timeline/event-tile/EventTileView/MKeyVerificationRequestView"; export * from "./room/timeline/event-tile/EventTileView/PinnedMessageBadge"; diff --git a/packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.module.css b/packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.module.css new file mode 100644 index 0000000000..c7b03256f1 --- /dev/null +++ b/packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.module.css @@ -0,0 +1,30 @@ +/* + * Copyright 2026 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +.container { + /* This is the height of the tile as per design */ + min-height: 39px; + width: 100%; + border: 1px solid var(--cpd-color-border-interactive-secondary); + border-radius: var(--cpd-space-2x); + padding: var(--cpd-space-2x) var(--cpd-space-3x); + box-sizing: border-box; +} + +.title { + font: var(--cpd-font-body-md-semibold); + flex: 1; +} + +.time { + font: var(--cpd-font-body-xs-regular); + color: var(--cpd-color-text-secondary); +} + +.icon { + color: var(--cpd-color-icon-secondary); +} diff --git a/packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.stories.tsx b/packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.stories.tsx new file mode 100644 index 0000000000..89212b0071 --- /dev/null +++ b/packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.stories.tsx @@ -0,0 +1,62 @@ +/* + * Copyright 2026 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +import React from "react"; + +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { CallStartedTileView, type CallStartedTileViewSnapshot, CallType } from "./CallStartedTileView"; +import { useMockedViewModel } from "../../../../../core/viewmodel"; +import { withViewDocs } from "../../../../../../.storybook/withViewDocs"; + +const CallStartedTileViewWrapperImpl = ({ ...rest }: CallStartedTileViewSnapshot): React.ReactNode => { + const vm = useMockedViewModel(rest, {}); + return ; +}; + +const CallStartedTileViewWrapper = withViewDocs(CallStartedTileViewWrapperImpl, CallStartedTileView); + +const meta = { + title: "Timeline/Timeline Event/Call/CallStartedTileView", + component: CallStartedTileViewWrapper, + tags: ["autodocs"], + argTypes: { + type: { + options: [CallType.Video, CallType.Voice], + control: { type: "select" }, + }, + timestamp: { + control: { type: "text" }, + }, + }, + args: { + type: CallType.Voice, + timestamp: "12:36", + }, + parameters: { + design: { + type: "figma", + url: "https://www.figma.com/design/rTaQE2nIUSLav4Tg3nozq7/Compound-Web-Components?node-id=11217-3901&t=OvT1LOc5wH4kXt0a-4", + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = {}; + +export const VoiceCall: Story = { + args: { + type: CallType.Voice, + }, +}; + +export const VideoCall: Story = { + args: { + type: CallType.Video, + }, +}; diff --git a/packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.test.tsx b/packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.test.tsx new file mode 100644 index 0000000000..f885b7aa18 --- /dev/null +++ b/packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.test.tsx @@ -0,0 +1,29 @@ +/* + * Copyright 2026 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +import { composeStories } from "@storybook/react-vite"; +import { describe, expect, it } from "vitest"; +import React from "react"; +import { render } from "@test-utils"; + +import * as Stories from "./CallStartedTileView.stories"; + +const { VideoCall, VoiceCall } = composeStories(Stories); + +describe("CallStartedTileView", () => { + describe("renders the tile", () => { + it("voice call", () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + + it("video call", () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + }); +}); diff --git a/packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.tsx b/packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.tsx new file mode 100644 index 0000000000..53e4619aee --- /dev/null +++ b/packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/CallStartedTileView.tsx @@ -0,0 +1,77 @@ +/* + * Copyright 2026 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +import React from "react"; +import { VideoCallSolidIcon, VoiceCallSolidIcon } from "@vector-im/compound-design-tokens/assets/web/icons"; +import classnames from "classnames"; + +import { useViewModel, type ViewModel } from "../../../../../core/viewmodel"; +import { Flex } from "../../../../../core/utils/Flex"; +import styles from "./CallStartedTileView.module.css"; +import { useI18n } from "../../../../../core/i18n/i18nContext"; + +/** + * Represents whether a call is a voice call or video call. + */ +export const enum CallType { + /** + * This is a voice call. + */ + Voice = "voice", + /** + * This is a video call. + */ + Video = "video", +} + +export type CallStartedTileViewSnapshot = { + /** + * What type of call this tile needs to render for. + */ + type: CallType; + /** + * Time when this call was started. + */ + timestamp: string; +}; + +export type CallStartedTileViewModel = ViewModel; + +export interface CallStartedTileViewProps { + vm: CallStartedTileViewModel; + className?: string; +} + +function getIconForCallType(type: CallType): React.ReactNode { + switch (type) { + case CallType.Video: + return ; + case CallType.Voice: + return ; + } +} + +/** + * View for a timeline tile that indicates the start of an element call. + */ +export function CallStartedTileView({ vm, className }: CallStartedTileViewProps): React.ReactNode { + const { translate: _t } = useI18n(); + const { type, timestamp } = useViewModel(vm); + const classNames = classnames(className, styles.container); + return ( + + {getIconForCallType(type)} +

+ {type === CallType.Voice + ? _t("timeline|call_tile|voice_call_title") + : _t("timeline|call_tile|video_call_title")} +
+ +
{timestamp}
+ + ); +} diff --git a/packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/__snapshots__/CallStartedTileView.test.tsx.snap b/packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/__snapshots__/CallStartedTileView.test.tsx.snap new file mode 100644 index 0000000000..eb67bd154a --- /dev/null +++ b/packages/shared-components/src/room/timeline/event-tile/call/CallStartedTile/__snapshots__/CallStartedTileView.test.tsx.snap @@ -0,0 +1,65 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`CallStartedTileView > renders the tile > video call 1`] = ` +
+
+ + + +
+ Video call +
+
+ 12:36 +
+
+
+`; + +exports[`CallStartedTileView > renders the tile > voice call 1`] = ` +
+
+ + + +
+ Voice call +
+
+ 12:36 +
+
+
+`; diff --git a/packages/shared-components/src/room/timeline/event-tile/call/index.ts b/packages/shared-components/src/room/timeline/event-tile/call/index.ts new file mode 100644 index 0000000000..fc4fb78c6f --- /dev/null +++ b/packages/shared-components/src/room/timeline/event-tile/call/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright 2026 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +export * from "./CallStartedTile/CallStartedTileView";