From 00ccc97c79b384efa2095da773a119c51393d011 Mon Sep 17 00:00:00 2001 From: R Midhun Suresh Date: Tue, 19 May 2026 14:48:30 +0530 Subject: [PATCH] Call Tile - Improve tile alignment in modern and bubble layout (#33478) * Tile must have same indent as messages * Align the call tiles between the bubbles --- .../res/css/views/rooms/_EventBubbleTile.pcss | 18 +++++++++- .../src/components/views/rooms/EventTile.tsx | 2 ++ .../rooms/EventTile/eventTileDerivedState.ts | 4 +++ apps/web/src/utils/EventRenderingUtils.ts | 34 +++++++++++++++++-- 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/apps/web/res/css/views/rooms/_EventBubbleTile.pcss b/apps/web/res/css/views/rooms/_EventBubbleTile.pcss index 18dac9547a..493cb9b4df 100644 --- a/apps/web/res/css/views/rooms/_EventBubbleTile.pcss +++ b/apps/web/res/css/views/rooms/_EventBubbleTile.pcss @@ -355,7 +355,8 @@ Please see LICENSE files in the repository root for full details. } } - &:not(.mx_EventTile_noBubble) .mx_EventTile_line:not(.mx_EventTile_mediaLine) { + &:not(.mx_EventTile_noBubble):not(.mx_EventTile_alignedBetweenBubbles) + .mx_EventTile_line:not(.mx_EventTile_mediaLine) { /* make the top and bottom padding 1px smaller so that we can pad .mx_EventTile_content by 1px */ /* to avoid anti-zalgo cutting off our larger than text emojis. */ @@ -523,6 +524,21 @@ Please see LICENSE files in the repository root for full details. .mx_CallEvent_wrapper { justify-content: center; } + + &.mx_EventTile_alignedBetweenBubbles { + margin-inline-start: calc( + var(--EventTile_bubble-margin-inline-start) + var(--EventTile_bubble_line-margin-inline-start) + ); + margin-inline-end: calc( + var(--EventTile_bubble-margin-inline-end) + var(--EventTile_bubble_line-margin-inline-end) + ); + + .mx_EventTile_line { + max-width: 100%; + width: 100%; + margin: 0; + } + } } .mx_EventTile.mx_EventTile_noBubble[data-layout="bubble"] { diff --git a/apps/web/src/components/views/rooms/EventTile.tsx b/apps/web/src/components/views/rooms/EventTile.tsx index 0fc6370a90..80a5560f1e 100644 --- a/apps/web/src/components/views/rooms/EventTile.tsx +++ b/apps/web/src/components/views/rooms/EventTile.tsx @@ -1071,6 +1071,7 @@ export class UnwrappedEventTile extends React.Component isLeftAlignedBubbleMessage, noBubbleEvent, isSeeingThroughMessageHiddenForModeration, + isAlignedBetweenBubbles, } = getEventDisplayInfo( MatrixClientPeg.safeGet(), this.props.mxEvent, @@ -1118,6 +1119,7 @@ export class UnwrappedEventTile extends React.Component getEventTileClassState({ isBubbleMessage, isLeftAlignedBubbleMessage, + isAlignedBetweenBubbles, isEditing, isInfoMessage, isTwelveHour: this.props.isTwelveHour, diff --git a/apps/web/src/components/views/rooms/EventTile/eventTileDerivedState.ts b/apps/web/src/components/views/rooms/EventTile/eventTileDerivedState.ts index e728dba55b..e2529243b7 100644 --- a/apps/web/src/components/views/rooms/EventTile/eventTileDerivedState.ts +++ b/apps/web/src/components/views/rooms/EventTile/eventTileDerivedState.ts @@ -402,6 +402,8 @@ export interface EventTileClassState { isBubbleMessage: boolean; /** Whether the bubble tile is left-aligned. */ isLeftAlignedBubbleMessage: boolean; + /** Whether the event is aligned between the bubbles */ + isAlignedBetweenBubbles: boolean; /** Whether the event is currently being edited. */ isEditing: boolean; /** Whether the event renders as an informational timeline item. */ @@ -444,6 +446,7 @@ export interface EventTileClassState { export function getEventTileClassState({ isBubbleMessage, isLeftAlignedBubbleMessage, + isAlignedBetweenBubbles, isEditing, isInfoMessage, isTwelveHour, @@ -466,6 +469,7 @@ export function getEventTileClassState({ return { mx_EventTile_bubbleContainer: isBubbleMessage, mx_EventTile_leftAlignedBubble: isLeftAlignedBubbleMessage, + mx_EventTile_alignedBetweenBubbles: isAlignedBetweenBubbles, mx_EventTile: true, mx_EventTile_isEditing: isEditing, mx_EventTile_info: isInfoMessage, diff --git a/apps/web/src/utils/EventRenderingUtils.ts b/apps/web/src/utils/EventRenderingUtils.ts index 2295cfd144..6bc01d477a 100644 --- a/apps/web/src/utils/EventRenderingUtils.ts +++ b/apps/web/src/utils/EventRenderingUtils.ts @@ -54,6 +54,7 @@ export function getEventDisplayInfo( isLeftAlignedBubbleMessage: boolean; noBubbleEvent: boolean; isSeeingThroughMessageHiddenForModeration: boolean; + isAlignedBetweenBubbles: boolean; } { const content = mxEvent.getContent(); const msgtype = content.msgtype; @@ -77,14 +78,16 @@ 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 || eventType === EventType.RoomEncryption || factory === JitsiEventFactory; const isLeftAlignedBubbleMessage = - !isBubbleMessage && (eventType === EventType.CallInvite || ElementCallEventType.matches(eventType)); + !isBubbleMessage && + (eventType === EventType.RTCNotification || + 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 = @@ -107,6 +110,32 @@ export function getEventDisplayInfo( } } + /* + ┌──────────────────────────────────────────────────────────┐ + │ │ + │ TILE ALIGNED BETWEEN BUBBLES │ + │ │ + └──────────────────────────────────────────────────────────┘ + ▲ ▲ + │ │ + │ │ + │ │ +┌────┤ │ +│ ┌──┼───────────────────┐ │ +│ │ │ │ │ +└─┼──┘ Bubble │ │ + └──────────────────────┘ │ + │ + │ + │ + ├────┐ + ┌───────────────────┼──┐ │ + │ │ │ │ + │ Bubble └──┼─┘ + └──────────────────────┘ + */ + const isAlignedBetweenBubbles = eventType === EventType.RTCNotification; + return { hasRenderer: !!factory, isInfoMessage, @@ -114,5 +143,6 @@ export function getEventDisplayInfo( isLeftAlignedBubbleMessage, noBubbleEvent, isSeeingThroughMessageHiddenForModeration, + isAlignedBetweenBubbles, }; }