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
This commit is contained in:
R Midhun Suresh
2026-05-19 14:48:30 +05:30
committed by GitHub
parent 02b6520f09
commit 00ccc97c79
4 changed files with 55 additions and 3 deletions
@@ -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"] {
@@ -1071,6 +1071,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
isLeftAlignedBubbleMessage,
noBubbleEvent,
isSeeingThroughMessageHiddenForModeration,
isAlignedBetweenBubbles,
} = getEventDisplayInfo(
MatrixClientPeg.safeGet(),
this.props.mxEvent,
@@ -1118,6 +1119,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
getEventTileClassState({
isBubbleMessage,
isLeftAlignedBubbleMessage,
isAlignedBetweenBubbles,
isEditing,
isInfoMessage,
isTwelveHour: this.props.isTwelveHour,
@@ -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,
+32 -2
View File
@@ -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,
};
}