Files
ThreadNet-Web/apps/web/src/utils/EventRenderingUtils.ts
T
R Midhun SureshandGitHub 2933b51fea 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
2026-05-11 21:12:51 +00:00

119 lines
4.5 KiB
TypeScript

/*
Copyright 2024 New Vector Ltd.
Copyright 2022 The Matrix.org Foundation C.I.C.
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,
type IContent,
type MatrixClient,
EventType,
MsgType,
M_POLL_END,
M_POLL_START,
M_BEACON_INFO,
} from "matrix-js-sdk/src/matrix";
import SettingsStore from "../settings/SettingsStore";
import { haveRendererForEvent, JitsiEventFactory, JSONEventFactory, pickFactory } from "../events/EventTileFactory";
import { getMessageModerationState, isLocationEvent, MessageModerationState } from "./EventUtils";
import { ElementCallEventType } from "../call-types";
const calcIsInfoMessage = (
eventType: EventType | string,
content: IContent,
isBubbleMessage: boolean,
isLeftAlignedBubbleMessage: boolean,
): boolean => {
return (
!isBubbleMessage &&
!isLeftAlignedBubbleMessage &&
eventType !== EventType.RoomMessage &&
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)
);
};
export function getEventDisplayInfo(
matrixClient: MatrixClient,
mxEvent: MatrixEvent,
showHiddenEvents: boolean,
hideEvent?: boolean,
): {
isInfoMessage: boolean;
hasRenderer: boolean;
isBubbleMessage: boolean;
isLeftAlignedBubbleMessage: boolean;
noBubbleEvent: boolean;
isSeeingThroughMessageHiddenForModeration: boolean;
} {
const content = mxEvent.getContent();
const msgtype = content.msgtype;
const eventType = mxEvent.getType();
let isSeeingThroughMessageHiddenForModeration = false;
if (SettingsStore.getValue("feature_msc3531_hide_messages_pending_moderation")) {
switch (getMessageModerationState(mxEvent, matrixClient)) {
case MessageModerationState.VISIBLE_FOR_ALL:
case MessageModerationState.HIDDEN_TO_CURRENT_USER:
// Nothing specific to do here
break;
case MessageModerationState.SEE_THROUGH_FOR_CURRENT_USER:
// Show message with a marker.
isSeeingThroughMessageHiddenForModeration = true;
break;
}
}
let factory = pickFactory(mxEvent, matrixClient, showHiddenEvents);
// 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 ||
eventType === EventType.RoomEncryption ||
factory === JitsiEventFactory;
const isLeftAlignedBubbleMessage =
!isBubbleMessage && (eventType === EventType.CallInvite || ElementCallEventType.matches(eventType));
let isInfoMessage = calcIsInfoMessage(eventType, content, isBubbleMessage, isLeftAlignedBubbleMessage);
// Some non-info messages want to be rendered in the appropriate bubble column but without the bubble background
const noBubbleEvent =
(eventType === EventType.RoomMessage && msgtype === MsgType.Emote) ||
M_POLL_START.matches(eventType) ||
M_BEACON_INFO.matches(eventType) ||
isLocationEvent(mxEvent);
// If we're showing hidden events in the timeline, we should use the
// source tile when there's no regular tile for an event and also for
// replace relations (which otherwise would display as a confusing
// duplicate of the thing they are replacing).
if (hideEvent || !haveRendererForEvent(mxEvent, matrixClient, showHiddenEvents)) {
// forcefully ask for a factory for a hidden event (hidden event setting is checked internally)
factory = pickFactory(mxEvent, matrixClient, showHiddenEvents, true);
if (factory === JSONEventFactory) {
isBubbleMessage = false;
// Reuse info message avatar and sender profile styling
isInfoMessage = true;
}
}
return {
hasRenderer: !!factory,
isInfoMessage,
isBubbleMessage,
isLeftAlignedBubbleMessage,
noBubbleEvent,
isSeeingThroughMessageHiddenForModeration,
};
}