From 3f9b8b822e8115193eedc48dc72ce6ae43fe6142 Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 16 Apr 2026 16:35:28 +0200 Subject: [PATCH 1/7] cleaning: Remove join button from call notify timelineItemView --- .../features/messages/impl/MessagesView.kt | 3 -- .../pinned/list/PinnedMessagesListView.kt | 1 - .../messages/impl/timeline/TimelineView.kt | 3 -- .../TimelineViewMessageShieldPreview.kt | 1 - .../components/TimelineItemCallNotifyView.kt | 51 ++++++++----------- .../TimelineItemGroupedEventsRow.kt | 1 - .../timeline/components/TimelineItemRow.kt | 3 -- .../event/TimelineItemContentFactory.kt | 4 +- .../impl/timeline/groups/Groupability.kt | 2 +- .../TimelineItemRtcNotificationContent.kt | 4 +- .../api/timeline/item/event/EventContent.kt | 5 +- .../item/event/TimelineEventContentMapper.kt | 11 +++- .../impl/datasource/EventItemFactory.kt | 2 +- 13 files changed, 43 insertions(+), 48 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt index bf20c8dc6b..5a0b14b820 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt @@ -282,7 +282,6 @@ fun MessagesView( state.eventSink(MessagesEvent.HandleAction(TimelineItemAction.Reply, targetEvent)) }, forceJumpToBottomVisibility = forceJumpToBottomVisibility, - onJoinCallClick = onJoinCallClick, onViewAllPinnedMessagesClick = onViewAllPinnedMessagesClick, knockRequestsBannerView = knockRequestsBannerView, ) @@ -460,7 +459,6 @@ private fun MessagesViewContent( onMessageLongClick: (TimelineItem.Event) -> Unit, onSendLocationClick: () -> Unit, onCreatePollClick: () -> Unit, - onJoinCallClick: (isAudioCall: Boolean) -> Unit, onViewAllPinnedMessagesClick: () -> Unit, forceJumpToBottomVisibility: Boolean, onSwipeToReply: (TimelineItem.Event) -> Unit, @@ -517,7 +515,6 @@ private fun MessagesViewContent( onMoreReactionsClick = onMoreReactionsClick, onReadReceiptClick = onReadReceiptClick, forceJumpToBottomVisibility = forceJumpToBottomVisibility, - onJoinCallClick = onJoinCallClick, nestedScrollConnection = scrollBehavior.nestedScrollConnection, floatingDateTopOffset = pinnedBannerHeightDp, ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListView.kt index b212549a22..7190aa174f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListView.kt @@ -235,7 +235,6 @@ private fun PinnedMessagesListLoaded( onMoreReactionsClick = {}, onReadReceiptClick = {}, onSwipeToReply = {}, - onJoinCallClick = {}, eventSink = { timelineItemEvent -> when (timelineItemEvent) { is TimelineEvent.OpenThread -> state.eventSink(PinnedMessagesListEvent.OpenThread(timelineItemEvent.threadRootEventId)) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt index 0137b1736d..afe1f25d24 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt @@ -102,7 +102,6 @@ fun TimelineView( onReactionLongClick: (emoji: String, TimelineItem.Event) -> Unit, onMoreReactionsClick: (TimelineItem.Event) -> Unit, onReadReceiptClick: (TimelineItem.Event) -> Unit, - onJoinCallClick: (isAudioCall: Boolean) -> Unit, modifier: Modifier = Modifier, lazyListState: LazyListState = rememberLazyListState(), forceJumpToBottomVisibility: Boolean = false, @@ -186,7 +185,6 @@ fun TimelineView( onMoreReactionsClick = onMoreReactionsClick, onReadReceiptClick = onReadReceiptClick, onSwipeToReply = onSwipeToReply, - onJoinCallClick = onJoinCallClick, eventSink = state.eventSink, ) } @@ -425,7 +423,6 @@ internal fun TimelineViewPreview( onReactionLongClick = { _, _ -> }, onMoreReactionsClick = {}, onReadReceiptClick = {}, - onJoinCallClick = {}, forceJumpToBottomVisibility = true, ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewMessageShieldPreview.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewMessageShieldPreview.kt index 5f9c3d0364..f0a11081e1 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewMessageShieldPreview.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewMessageShieldPreview.kt @@ -49,7 +49,6 @@ internal fun TimelineViewMessageShieldPreview() = ElementPreview { onReactionLongClick = { _, _ -> }, onMoreReactionsClick = {}, onReadReceiptClick = {}, - onJoinCallClick = {}, forceJumpToBottomVisibility = true, ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt index a6ae2d9ee5..bf55503665 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt @@ -31,24 +31,22 @@ import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.messages.impl.timeline.aTimelineItemEvent import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRtcNotificationContent -import io.element.android.features.roomcall.api.RoomCallState -import io.element.android.features.roomcall.api.RoomCallStateProvider import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.modifiers.onKeyboardContextMenuAction import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.text.toDp +import io.element.android.libraries.matrix.api.notification.CallIntent import io.element.android.libraries.ui.strings.CommonStrings @Composable internal fun TimelineItemCallNotifyView( event: TimelineItem.Event, - roomCallState: RoomCallState, onLongClick: (TimelineItem.Event) -> Unit, - onJoinCallClick: (isAudioCall: Boolean) -> Unit, modifier: Modifier = Modifier ) { + val intent = (event.content as? TimelineItemRtcNotificationContent)?.callIntent Row( modifier = modifier .fillMaxWidth() @@ -81,7 +79,8 @@ internal fun TimelineItemCallNotifyView( ) { Icon( modifier = Modifier.size(20.sp.toDp()), - imageVector = CompoundIcons.VideoCallSolid(), + imageVector = + if (intent == CallIntent.AUDIO) CompoundIcons.VoiceCallSolid() else CompoundIcons.VideoCallSolid(), contentDescription = null, tint = ElementTheme.colors.iconSecondary, ) @@ -94,20 +93,13 @@ internal fun TimelineItemCallNotifyView( ) } } - if (roomCallState is RoomCallState.OnGoing) { - CallMenuItem( - roomCallState = roomCallState, - onJoinCallClick = onJoinCallClick, - ) - } else { - Text( - text = event.sentTime, - style = ElementTheme.typography.fontBodyMdRegular, - color = ElementTheme.colors.textSecondary, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - } + Text( + text = event.sentTime, + style = ElementTheme.typography.fontBodyMdRegular, + color = ElementTheme.colors.textSecondary, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) } } @@ -115,16 +107,15 @@ internal fun TimelineItemCallNotifyView( @Composable internal fun TimelineItemCallNotifyViewPreview() = ElementPreview { Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) { - RoomCallStateProvider() - .values - .filter { it !is RoomCallState.Unavailable } - .forEach { roomCallState -> - TimelineItemCallNotifyView( - event = aTimelineItemEvent(content = TimelineItemRtcNotificationContent()), - roomCallState = roomCallState, - onLongClick = {}, - onJoinCallClick = {}, - ) - } + listOf( + aTimelineItemEvent(content = TimelineItemRtcNotificationContent(null)), + aTimelineItemEvent(content = TimelineItemRtcNotificationContent(CallIntent.AUDIO)), + aTimelineItemEvent(content = TimelineItemRtcNotificationContent(CallIntent.VIDEO)), + ).forEach { event -> + TimelineItemCallNotifyView( + event = event, + onLongClick = {}, + ) + } } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt index 505d76b24b..8316911843 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt @@ -188,7 +188,6 @@ private fun TimelineItemGroupedEventsRowContent( onMoreReactionsClick = onMoreReactionsClick, onReadReceiptClick = onReadReceiptClick, onSwipeToReply = {}, - onJoinCallClick = {}, eventSink = eventSink, eventContentView = eventContentView, ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt index 469afe494e..28b05c29fb 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt @@ -72,7 +72,6 @@ internal fun TimelineItemRow( onMoreReactionsClick: (TimelineItem.Event) -> Unit, onReadReceiptClick: (TimelineItem.Event) -> Unit, onSwipeToReply: (TimelineItem.Event) -> Unit, - onJoinCallClick: (isAudioCall: Boolean) -> Unit, eventSink: (TimelineEvent.TimelineItemEvent) -> Unit, modifier: Modifier = Modifier, eventContentView: @Composable (TimelineItem.Event, Modifier, (ContentAvoidingLayoutData) -> Unit) -> Unit = @@ -127,9 +126,7 @@ internal fun TimelineItemRow( TimelineItemCallNotifyView( modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 16.dp), event = timelineItem, - roomCallState = timelineRoomInfo.roomCallState, onLongClick = onLongClick, - onJoinCallClick = onJoinCallClick, ) } else -> { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentFactory.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentFactory.kt index 2b5c0fa98a..d228a45371 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentFactory.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentFactory.kt @@ -97,7 +97,9 @@ class TimelineItemContentFactory( is StickerContent -> stickerFactory.create(itemContent) is PollContent -> pollFactory.create(eventId, isEditable, isOutgoing, itemContent) is UnableToDecryptContent -> utdFactory.create(itemContent) - is CallNotifyContent -> TimelineItemRtcNotificationContent() + is CallNotifyContent -> TimelineItemRtcNotificationContent( + itemContent.callIntent + ) is UnknownContent -> TimelineItemUnknownContent is LiveLocationContent -> { val lastKnownLocation = itemContent.locations.mapNotNull { beacon -> diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/Groupability.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/Groupability.kt index 6f369417dd..837692ae6f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/Groupability.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/Groupability.kt @@ -90,7 +90,7 @@ internal fun MatrixTimelineItem.Event.canBeDisplayedInBubbleBlock(): Boolean { is RoomMembershipContent, UnknownContent, is LegacyCallInviteContent, - CallNotifyContent, + is CallNotifyContent, is StateContent -> false } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemRtcNotificationContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemRtcNotificationContent.kt index 00ad32ba5f..168d11af16 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemRtcNotificationContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemRtcNotificationContent.kt @@ -8,6 +8,8 @@ package io.element.android.features.messages.impl.timeline.model.event -class TimelineItemRtcNotificationContent : TimelineItemEventContent { +import io.element.android.libraries.matrix.api.notification.CallIntent + +class TimelineItemRtcNotificationContent(val callIntent: CallIntent?) : TimelineItemEventContent { override val type: String = "org.matrix.msc4075.rtc.notification" } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt index 95d4327c07..12fb0b5f81 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt @@ -12,6 +12,7 @@ import androidx.compose.runtime.Immutable import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.media.ImageInfo import io.element.android.libraries.matrix.api.media.MediaSource +import io.element.android.libraries.matrix.api.notification.CallIntent import io.element.android.libraries.matrix.api.poll.PollAnswer import io.element.android.libraries.matrix.api.poll.PollKind import io.element.android.libraries.matrix.api.room.location.AssetType @@ -115,6 +116,8 @@ data class LiveLocationContent( data object LegacyCallInviteContent : EventContent -data object CallNotifyContent : EventContent +data class CallNotifyContent( + val callIntent: CallIntent? +) : EventContent data object UnknownContent : EventContent diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt index d617df60db..d9e47b00c7 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt @@ -11,6 +11,7 @@ package io.element.android.libraries.matrix.impl.timeline.item.event import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.notification.CallIntent import io.element.android.libraries.matrix.api.timeline.item.EmbeddedEventInfo import io.element.android.libraries.matrix.api.timeline.item.EventThreadInfo import io.element.android.libraries.matrix.api.timeline.item.ThreadSummary @@ -137,7 +138,15 @@ class TimelineEventContentMapper( ) } is TimelineItemContent.CallInvite -> LegacyCallInviteContent - is TimelineItemContent.RtcNotification -> CallNotifyContent + is TimelineItemContent.RtcNotification -> CallNotifyContent( + it.callIntent?.let { intentString -> + if (intentString == "audio") { + CallIntent.AUDIO + } else { + CallIntent.VIDEO + } + } + ) } } } diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/datasource/EventItemFactory.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/datasource/EventItemFactory.kt index 67b73d616d..379c70f960 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/datasource/EventItemFactory.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/datasource/EventItemFactory.kt @@ -65,7 +65,7 @@ class EventItemFactory( mode = DateFormatterMode.Full, ) return when (val content = event.content) { - CallNotifyContent, + is CallNotifyContent, is FailedToParseMessageLikeContent, is FailedToParseStateContent, LegacyCallInviteContent, From 2966ccc96d4fc5660abaa07c128ee568b08cda4d Mon Sep 17 00:00:00 2001 From: ElementBot Date: Thu, 16 Apr 2026 15:25:42 +0000 Subject: [PATCH 2/7] Update screenshots --- ...imeline.components_TimelineItemCallNotifyView_Day_0_en.png | 4 ++-- ...eline.components_TimelineItemCallNotifyView_Night_0_en.png | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en.png index 2a713b1b39..3ded87a38d 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:155ad78cfadaab78089293eca38ab8c404f227e38c451dddbbe3c59cccb82bc5 -size 51391 +oid sha256:53068e2713cc73cf8492f960ff36aad79ae2a964d08e72ae35815b6614c7b061 +size 23873 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en.png index 77fd3bfa80..24e62daad5 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8b54d16054565d3ba0280ff704c350227a03db0fad93750ad6d41f6e67f605f3 -size 51582 +oid sha256:fb140f4fb625affba7ca229b2e596476b37c5787431215b3f9ecc5c93001b328 +size 23789 From 6d134375f6a81f52a6db8f5797207ec23efbd55a Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 17 Apr 2026 10:07:22 +0200 Subject: [PATCH 3/7] review: pass the RtcNotificationContent in the view to avoid casting --- .../components/TimelineItemCallNotifyView.kt | 17 +++++++++-------- .../impl/timeline/components/TimelineItemRow.kt | 1 + 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt index bf55503665..063a84dbeb 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt @@ -43,10 +43,10 @@ import io.element.android.libraries.ui.strings.CommonStrings @Composable internal fun TimelineItemCallNotifyView( event: TimelineItem.Event, + content: TimelineItemRtcNotificationContent, onLongClick: (TimelineItem.Event) -> Unit, modifier: Modifier = Modifier ) { - val intent = (event.content as? TimelineItemRtcNotificationContent)?.callIntent Row( modifier = modifier .fillMaxWidth() @@ -54,7 +54,7 @@ internal fun TimelineItemCallNotifyView( .combinedClickable( enabled = true, onClick = {}, - onLongClick = { onLongClick(event) }, + onLongClick = { onLongClick() }, onLongClickLabel = stringResource(CommonStrings.action_open_context_menu), ) .onKeyboardContextMenuAction { onLongClick(event) } @@ -80,7 +80,7 @@ internal fun TimelineItemCallNotifyView( Icon( modifier = Modifier.size(20.sp.toDp()), imageVector = - if (intent == CallIntent.AUDIO) CompoundIcons.VoiceCallSolid() else CompoundIcons.VideoCallSolid(), + if (content.callIntent == CallIntent.AUDIO) CompoundIcons.VoiceCallSolid() else CompoundIcons.VideoCallSolid(), contentDescription = null, tint = ElementTheme.colors.iconSecondary, ) @@ -108,12 +108,13 @@ internal fun TimelineItemCallNotifyView( internal fun TimelineItemCallNotifyViewPreview() = ElementPreview { Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) { listOf( - aTimelineItemEvent(content = TimelineItemRtcNotificationContent(null)), - aTimelineItemEvent(content = TimelineItemRtcNotificationContent(CallIntent.AUDIO)), - aTimelineItemEvent(content = TimelineItemRtcNotificationContent(CallIntent.VIDEO)), - ).forEach { event -> + TimelineItemRtcNotificationContent(null), + TimelineItemRtcNotificationContent(CallIntent.AUDIO), + TimelineItemRtcNotificationContent(CallIntent.VIDEO), + ).forEach { content -> TimelineItemCallNotifyView( - event = event, + event = aTimelineItemEvent(content = content), + content = content, onLongClick = {}, ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt index 28b05c29fb..e75df2f89f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt @@ -126,6 +126,7 @@ internal fun TimelineItemRow( TimelineItemCallNotifyView( modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 16.dp), event = timelineItem, + content = timelineItem.content, onLongClick = onLongClick, ) } From d7963ddb5a1b9aaa87037e216a345207706cce75 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 17 Apr 2026 12:52:25 +0200 Subject: [PATCH 4/7] fixup: missing param --- .../impl/timeline/components/TimelineItemCallNotifyView.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt index 063a84dbeb..0ba3c9b7d9 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt @@ -54,7 +54,7 @@ internal fun TimelineItemCallNotifyView( .combinedClickable( enabled = true, onClick = {}, - onLongClick = { onLongClick() }, + onLongClick = { onLongClick(event) }, onLongClickLabel = stringResource(CommonStrings.action_open_context_menu), ) .onKeyboardContextMenuAction { onLongClick(event) } From b0e9073efbdcb1f1965a9397cb6d0ff9405d7a0b Mon Sep 17 00:00:00 2001 From: Valere Date: Tue, 21 Apr 2026 10:49:08 +0200 Subject: [PATCH 5/7] fix test compilation --- .../messages/impl/actionlist/ActionListPresenterTest.kt | 3 ++- .../features/messages/impl/timeline/TimelineViewTest.kt | 2 -- .../mediaviewer/impl/datasource/DefaultEventItemFactoryTest.kt | 3 ++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt index 7a99ad39aa..8c7f290441 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt @@ -28,6 +28,7 @@ import io.element.android.features.poll.api.pollcontent.aPollAnswerItemList import io.element.android.libraries.dateformatter.test.FakeDateFormatter import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.test.FakeFeatureFlagService +import io.element.android.libraries.matrix.api.notification.CallIntent import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState @@ -1168,7 +1169,7 @@ class ActionListPresenterTest { val initialState = awaitItem() val messageEvent = aMessageEvent( isMine = true, - content = TimelineItemRtcNotificationContent(), + content = TimelineItemRtcNotificationContent(callIntent = CallIntent.VIDEO), ) initialState.eventSink.invoke( ActionListEvent.ComputeForMessage( diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewTest.kt index c05625e2d3..3a0b0e1224 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewTest.kt @@ -219,7 +219,6 @@ private fun AndroidComposeTestRule.setTimel onReactionLongClick: (emoji: String, TimelineItem.Event) -> Unit = EnsureNeverCalledWithTwoParams(), onMoreReactionsClick: (TimelineItem.Event) -> Unit = EnsureNeverCalledWithParam(), onReadReceiptClick: (TimelineItem.Event) -> Unit = EnsureNeverCalledWithParam(), - onJoinCallClick: (Boolean) -> Unit = EnsureNeverCalledWithParam(), forceJumpToBottomVisibility: Boolean = false, ) { setSafeContent(clearAndroidUiDispatcher = true) { @@ -235,7 +234,6 @@ private fun AndroidComposeTestRule.setTimel onReactionLongClick = onReactionLongClick, onMoreReactionsClick = onMoreReactionsClick, onReadReceiptClick = onReadReceiptClick, - onJoinCallClick = onJoinCallClick, forceJumpToBottomVisibility = forceJumpToBottomVisibility, ) } diff --git a/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/datasource/DefaultEventItemFactoryTest.kt b/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/datasource/DefaultEventItemFactoryTest.kt index 6c88f1c33f..6602f475eb 100644 --- a/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/datasource/DefaultEventItemFactoryTest.kt +++ b/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/datasource/DefaultEventItemFactoryTest.kt @@ -18,6 +18,7 @@ import io.element.android.libraries.matrix.api.media.FileInfo import io.element.android.libraries.matrix.api.media.ImageInfo import io.element.android.libraries.matrix.api.media.MediaSource import io.element.android.libraries.matrix.api.media.VideoInfo +import io.element.android.libraries.matrix.api.notification.CallIntent import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem import io.element.android.libraries.matrix.api.timeline.item.event.AudioMessageType import io.element.android.libraries.matrix.api.timeline.item.event.CallNotifyContent @@ -61,7 +62,7 @@ class DefaultEventItemFactoryTest { fun `create check all null cases`() { val factory = createEventItemFactory() val contents = listOf( - CallNotifyContent, + CallNotifyContent(callIntent = CallIntent.VIDEO), FailedToParseMessageLikeContent("", ""), FailedToParseStateContent("", "", ""), LegacyCallInviteContent, From e158be86aa14c487ec3204bf58c613d859395537 Mon Sep 17 00:00:00 2001 From: Valere Date: Tue, 21 Apr 2026 11:03:48 +0200 Subject: [PATCH 6/7] review: Make call intent not optional in content --- .../components/TimelineItemCallNotifyView.kt | 1 - .../event/TimelineItemRtcNotificationContent.kt | 2 +- .../matrix/api/timeline/item/event/EventContent.kt | 2 +- .../item/event/TimelineEventContentMapper.kt | 12 +++++------- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt index 0ba3c9b7d9..dfd1b2ed0e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt @@ -108,7 +108,6 @@ internal fun TimelineItemCallNotifyView( internal fun TimelineItemCallNotifyViewPreview() = ElementPreview { Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) { listOf( - TimelineItemRtcNotificationContent(null), TimelineItemRtcNotificationContent(CallIntent.AUDIO), TimelineItemRtcNotificationContent(CallIntent.VIDEO), ).forEach { content -> diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemRtcNotificationContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemRtcNotificationContent.kt index 168d11af16..53facfc675 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemRtcNotificationContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemRtcNotificationContent.kt @@ -10,6 +10,6 @@ package io.element.android.features.messages.impl.timeline.model.event import io.element.android.libraries.matrix.api.notification.CallIntent -class TimelineItemRtcNotificationContent(val callIntent: CallIntent?) : TimelineItemEventContent { +class TimelineItemRtcNotificationContent(val callIntent: CallIntent) : TimelineItemEventContent { override val type: String = "org.matrix.msc4075.rtc.notification" } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt index 12fb0b5f81..9cecb57800 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt @@ -117,7 +117,7 @@ data class LiveLocationContent( data object LegacyCallInviteContent : EventContent data class CallNotifyContent( - val callIntent: CallIntent? + val callIntent: CallIntent ) : EventContent data object UnknownContent : EventContent diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt index d9e47b00c7..11514d73c6 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt @@ -110,7 +110,7 @@ class TimelineEventContentMapper( } is MsgLikeKind.LiveLocation -> { // Live location messages are a special kind of message that we want to treat as unknown content for now - UnknownContent + UnknownContent } is MsgLikeKind.Other -> UnknownContent } @@ -139,12 +139,10 @@ class TimelineEventContentMapper( } is TimelineItemContent.CallInvite -> LegacyCallInviteContent is TimelineItemContent.RtcNotification -> CallNotifyContent( - it.callIntent?.let { intentString -> - if (intentString == "audio") { - CallIntent.AUDIO - } else { - CallIntent.VIDEO - } + callIntent = if (it.callIntent == "audio") { + CallIntent.AUDIO + } else { + CallIntent.VIDEO } ) } From 3c06e0a260bca34a8ab25e045ade58db8e31f870 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 21 Apr 2026 09:26:51 +0000 Subject: [PATCH 7/7] Update screenshots --- ...imeline.components_TimelineItemCallNotifyView_Day_0_en.png | 4 ++-- ...eline.components_TimelineItemCallNotifyView_Night_0_en.png | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en.png index 3ded87a38d..afec980e10 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:53068e2713cc73cf8492f960ff36aad79ae2a964d08e72ae35815b6614c7b061 -size 23873 +oid sha256:3624fe8448ae4af2481e2023a978ffab2d69f2784b7cef41e5ae2e2dbe8fdbd5 +size 17804 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en.png index 24e62daad5..8f7f14e64a 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fb140f4fb625affba7ca229b2e596476b37c5787431215b3f9ecc5c93001b328 -size 23789 +oid sha256:6bd02d39619efbcaa6d96f1e75a0d14a572c43e60bad0c3f84d6a5a48b6fbda1 +size 17395