Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package io.element.android.features.messages.impl

import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
import io.element.android.libraries.matrix.api.user.MatrixUser

Expand All @@ -18,6 +19,7 @@ sealed interface MessagesEvent {
data class ToggleReaction(val emoji: String, val eventOrTransactionId: EventOrTransactionId) : MessagesEvent
data class InviteDialogDismissed(val action: InviteDialogAction) : MessagesEvent
data class OnUserClicked(val user: MatrixUser) : MessagesEvent
data class OnMemberClicked(val userId: UserId) : MessagesEvent
data object MarkAsFullyReadAndExit : MessagesEvent
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,10 @@ class MessagesNode(
}
},
onUserDataClick = callback::navigateToRoomMemberDetails,
onMemberClick = { userId ->
state.eventSink(MessagesEvent.OnMemberClicked(userId))
},
onRoomStateClick = callback::navigateToRoomDetails,
onLinkClick = { url, customTab ->
onLinkClick(
activity = activity,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ import io.element.android.libraries.matrix.api.room.RoomMembersState
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
import io.element.android.libraries.matrix.api.room.isDm
import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState
import io.element.android.libraries.matrix.api.room.roomMembers
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.ui.messages.reply.map
import io.element.android.libraries.matrix.ui.model.getAvatarData
import io.element.android.libraries.matrix.ui.room.getDirectRoomMember
Expand Down Expand Up @@ -262,6 +264,14 @@ class MessagesPresenter(
is MessagesEvent.OnUserClicked -> {
roomMemberModerationState.eventSink(RoomMemberModerationEvents.ShowActionsForUser(event.user))
}
is MessagesEvent.OnMemberClicked -> {
val userId = event.userId
val member = membersState.roomMembers()?.firstOrNull { it.userId == userId }
val matrixUser = member?.let {
MatrixUser(userId = it.userId, displayName = it.displayName, avatarUrl = it.avatarUrl)
} ?: MatrixUser(userId = userId)
roomMemberModerationState.eventSink(RoomMemberModerationEvents.ShowActionsForUser(matrixUser))
}
is MessagesEvent.MarkAsFullyReadAndExit -> if (!markingAsReadAndExiting.getAndSet(true)) {
coroutineScope.launch {
val latestEventId = room.liveTimeline.getLatestEventId().getOrElse {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ fun MessagesView(
onRoomDetailsClick: () -> Unit,
onEventContentClick: (isLive: Boolean, event: TimelineItem.Event) -> Boolean,
onUserDataClick: (UserId) -> Unit,
@Suppress("UNUSED_PARAMETER") onMemberClick: (UserId) -> Unit,
onRoomStateClick: () -> Unit,
onLinkClick: (String, Boolean) -> Unit,
onSendLocationClick: () -> Unit,
onCreatePollClick: () -> Unit,
Expand Down Expand Up @@ -284,6 +286,12 @@ fun MessagesView(
forceJumpToBottomVisibility = forceJumpToBottomVisibility,
onJoinCallClick = onJoinCallClick,
onViewAllPinnedMessagesClick = onViewAllPinnedMessagesClick,
onMemberClick = { userId ->
hidingKeyboard {
state.eventSink(MessagesEvent.OnMemberClicked(userId))
}
},
onRoomStateClick = onRoomStateClick,
knockRequestsBannerView = knockRequestsBannerView,
)

Expand Down Expand Up @@ -464,6 +472,8 @@ private fun MessagesViewContent(
onViewAllPinnedMessagesClick: () -> Unit,
forceJumpToBottomVisibility: Boolean,
onSwipeToReply: (TimelineItem.Event) -> Unit,
onMemberClick: (UserId) -> Unit,
onRoomStateClick: () -> Unit,
modifier: Modifier = Modifier,
knockRequestsBannerView: @Composable () -> Unit,
) {
Expand Down Expand Up @@ -518,6 +528,8 @@ private fun MessagesViewContent(
onReadReceiptClick = onReadReceiptClick,
forceJumpToBottomVisibility = forceJumpToBottomVisibility,
onJoinCallClick = onJoinCallClick,
onMemberClick = onMemberClick,
onRoomStateClick = onRoomStateClick,
nestedScrollConnection = scrollBehavior.nestedScrollConnection,
floatingDateTopOffset = pinnedBannerHeightDp,
)
Expand Down Expand Up @@ -630,6 +642,8 @@ internal fun MessagesViewPreview(@PreviewParameter(MessagesStateProvider::class)
onRoomDetailsClick = {},
onEventContentClick = { _, _ -> false },
onUserDataClick = {},
onMemberClick = {},
onRoomStateClick = {},
onLinkClick = { _, _ -> },
onSendLocationClick = {},
onCreatePollClick = {},
Expand Down Expand Up @@ -685,6 +699,8 @@ internal fun MessagesViewA11yPreview() = ElementPreview {
onRoomDetailsClick = {},
onEventContentClick = { _, _ -> false },
onUserDataClick = {},
onMemberClick = {},
onRoomStateClick = {},
onLinkClick = { _, _ -> },
onSendLocationClick = {},
onCreatePollClick = {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,7 @@ internal fun MessagesViewWithIdentityChangePreview(
onViewAllPinnedMessagesClick = {},
knockRequestsBannerView = {},
onThreadsListClick = {},
onMemberClick = {},
onRoomStateClick = {},
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ class PinnedMessagesListNode(
onBackClick = ::navigateUp,
onEventClick = callback::handleEventClick,
onUserDataClick = { callback.navigateToRoomMemberDetails(it.userId) },
onMemberClick = {},
onLinkClick = { link -> onLinkClick(context, link.url) },
onLinkLongClick = {
view.performHapticFeedback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.ui.strings.CommonStrings
Expand All @@ -61,6 +62,7 @@ fun PinnedMessagesListView(
onBackClick: () -> Unit,
onEventClick: (event: TimelineItem.Event) -> Unit,
onUserDataClick: (MatrixUser) -> Unit,
onMemberClick: (UserId) -> Unit,
onLinkClick: (Link) -> Unit,
onLinkLongClick: (Link) -> Unit,
modifier: Modifier = Modifier,
Expand All @@ -82,6 +84,7 @@ fun PinnedMessagesListView(
state = state,
onEventClick = onEventClick,
onUserDataClick = onUserDataClick,
onMemberClick = onMemberClick,
onLinkClick = onLinkClick,
onLinkLongClick = onLinkLongClick,
onErrorDismiss = onBackClick,
Expand Down Expand Up @@ -112,6 +115,7 @@ private fun PinnedMessagesListContent(
state: PinnedMessagesListState,
onEventClick: (event: TimelineItem.Event) -> Unit,
onUserDataClick: (MatrixUser) -> Unit,
onMemberClick: (UserId) -> Unit,
onLinkClick: (Link) -> Unit,
onLinkLongClick: (Link) -> Unit,
onErrorDismiss: () -> Unit,
Expand All @@ -134,6 +138,7 @@ private fun PinnedMessagesListContent(
onUserDataClick = onUserDataClick,
onLinkClick = onLinkClick,
onLinkLongClick = onLinkLongClick,
onMemberClick = onMemberClick,
)
PinnedMessagesListState.Loading -> {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Expand Down Expand Up @@ -172,6 +177,7 @@ private fun PinnedMessagesListLoaded(
onUserDataClick: (MatrixUser) -> Unit,
onLinkClick: (Link) -> Unit,
onLinkLongClick: (Link) -> Unit,
onMemberClick: (UserId) -> Unit,
modifier: Modifier = Modifier,
) {
fun onActionSelected(timelineItemAction: TimelineItemAction, event: TimelineItem.Event) {
Expand Down Expand Up @@ -236,6 +242,8 @@ private fun PinnedMessagesListLoaded(
onReadReceiptClick = {},
onSwipeToReply = {},
onJoinCallClick = {},
onMemberClick = onMemberClick,
onRoomStateClick = {},
eventSink = { timelineItemEvent ->
when (timelineItemEvent) {
is TimelineEvent.OpenThread -> state.eventSink(PinnedMessagesListEvent.OpenThread(timelineItemEvent.threadRootEventId))
Expand Down Expand Up @@ -307,6 +315,7 @@ internal fun PinnedMessagesListViewPreview(@PreviewParameter(PinnedMessagesListS
onBackClick = {},
onEventClick = { },
onUserDataClick = {},
onMemberClick = {},
onLinkClick = {},
onLinkLongClick = {},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ import io.element.android.libraries.designsystem.theme.components.FloatingAction
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.utils.animateScrollToItemCenter
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.testtags.TestTags
Expand Down Expand Up @@ -104,6 +105,8 @@ fun TimelineView(
onMoreReactionsClick: (TimelineItem.Event) -> Unit,
onReadReceiptClick: (TimelineItem.Event) -> Unit,
onJoinCallClick: (isAudioCall: Boolean) -> Unit,
onMemberClick: (UserId) -> Unit = {},
onRoomStateClick: () -> Unit = {},
modifier: Modifier = Modifier,
lazyListState: LazyListState = rememberLazyListState(),
forceJumpToBottomVisibility: Boolean = false,
Expand Down Expand Up @@ -188,6 +191,8 @@ fun TimelineView(
onReadReceiptClick = onReadReceiptClick,
onSwipeToReply = onSwipeToReply,
onJoinCallClick = onJoinCallClick,
onMemberClick = onMemberClick,
onRoomStateClick = onRoomStateClick,
eventSink = state.eventSink,
)
}
Expand Down Expand Up @@ -432,6 +437,8 @@ internal fun TimelineViewPreview(
onMoreReactionsClick = {},
onReadReceiptClick = {},
onJoinCallClick = {},
onMemberClick = {},
onRoomStateClick = {},
forceJumpToBottomVisibility = true,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import io.element.android.features.messages.impl.timeline.protection.aTimelinePr
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.ui.utils.time.isTalkbackActive
Expand All @@ -57,6 +58,8 @@ fun TimelineItemGroupedEventsRow(
onReactionLongClick: (key: String, TimelineItem.Event) -> Unit,
onMoreReactionsClick: (TimelineItem.Event) -> Unit,
onReadReceiptClick: (TimelineItem.Event) -> Unit,
onMemberClick: (UserId) -> Unit,
onRoomStateClick: () -> Unit,
eventSink: (TimelineEvent.TimelineItemEvent) -> Unit,
modifier: Modifier = Modifier,
eventContentView: @Composable (TimelineItem.Event, Modifier, (ContentAvoidingLayoutData) -> Unit) -> Unit =
Expand Down Expand Up @@ -102,6 +105,8 @@ fun TimelineItemGroupedEventsRow(
onReactionLongClick = onReactionLongClick,
onMoreReactionsClick = onMoreReactionsClick,
onReadReceiptClick = onReadReceiptClick,
onMemberClick = onMemberClick,
onRoomStateClick = onRoomStateClick,
eventSink = eventSink,
modifier = modifier,
eventContentView = eventContentView,
Expand Down Expand Up @@ -130,6 +135,8 @@ private fun TimelineItemGroupedEventsRowContent(
onReactionLongClick: (key: String, TimelineItem.Event) -> Unit,
onMoreReactionsClick: (TimelineItem.Event) -> Unit,
onReadReceiptClick: (TimelineItem.Event) -> Unit,
onMemberClick: (UserId) -> Unit,
onRoomStateClick: () -> Unit,
eventSink: (TimelineEvent.TimelineItemEvent) -> Unit,
modifier: Modifier = Modifier,
eventContentView: @Composable (TimelineItem.Event, Modifier, (ContentAvoidingLayoutData) -> Unit) -> Unit =
Expand Down Expand Up @@ -189,6 +196,8 @@ private fun TimelineItemGroupedEventsRowContent(
onReadReceiptClick = onReadReceiptClick,
onSwipeToReply = {},
onJoinCallClick = {},
onMemberClick = onMemberClick,
onRoomStateClick = onRoomStateClick,
eventSink = eventSink,
eventContentView = eventContentView,
)
Expand Down Expand Up @@ -233,6 +242,8 @@ internal fun TimelineItemGroupedEventsRowContentExpandedPreview() = ElementPrevi
onReactionLongClick = { _, _ -> },
onMoreReactionsClick = {},
onReadReceiptClick = {},
onMemberClick = {},
onRoomStateClick = {},
eventSink = {},
)
}
Expand Down Expand Up @@ -261,6 +272,8 @@ internal fun TimelineItemGroupedEventsRowContentCollapsePreview() = ElementPrevi
onReactionLongClick = { _, _ -> },
onMoreReactionsClick = {},
onReadReceiptClick = {},
onMemberClick = {},
onRoomStateClick = {},
eventSink = {},
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import io.element.android.features.messages.impl.timeline.components.layout.Cont
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLegacyCallInviteContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemPollContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemProfileChangeContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRoomMembershipContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRtcNotificationContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContent
Expand All @@ -44,6 +46,7 @@ import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.text.toPx
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.ui.strings.CommonStrings
Expand Down Expand Up @@ -73,6 +76,8 @@ internal fun TimelineItemRow(
onReadReceiptClick: (TimelineItem.Event) -> Unit,
onSwipeToReply: (TimelineItem.Event) -> Unit,
onJoinCallClick: (isAudioCall: Boolean) -> Unit,
onMemberClick: (UserId) -> Unit = {},
onRoomStateClick: () -> Unit = {},
eventSink: (TimelineEvent.TimelineItemEvent) -> Unit,
modifier: Modifier = Modifier,
eventContentView: @Composable (TimelineItem.Event, Modifier, (ContentAvoidingLayoutData) -> Unit) -> Unit =
Expand Down Expand Up @@ -111,13 +116,29 @@ internal fun TimelineItemRow(
)
}
is TimelineItem.Event -> {
val onStateEventClick: () -> Unit = when {
timelineItem.content is TimelineItemRoomMembershipContent -> {
val targetUserId = timelineItem.content.targetUserId
{ onMemberClick(targetUserId ?: timelineItem.senderId) }
}
timelineItem.content is TimelineItemProfileChangeContent -> {
{ onMemberClick(timelineItem.senderId) }
}
timelineItem.content is TimelineItemStateContent ||
timelineItem.content is TimelineItemLegacyCallInviteContent -> {
{ onRoomStateClick() }
}
else -> {
{ onContentClick(timelineItem) }
}
}
when (timelineItem.content) {
is TimelineItemStateContent, is TimelineItemLegacyCallInviteContent -> {
TimelineItemStateEventRow(
event = timelineItem,
renderReadReceipts = renderReadReceipts,
isLastOutgoingMessage = isLastOutgoingMessage,
onClick = { onContentClick(timelineItem) },
onClick = onStateEventClick,
onReadReceiptsClick = onReadReceiptClick,
onLongClick = { onLongClick(timelineItem) },
eventSink = eventSink,
Expand Down Expand Up @@ -209,6 +230,8 @@ internal fun TimelineItemRow(
onReactionLongClick = onReactionLongClick,
onMoreReactionsClick = onMoreReactionsClick,
onReadReceiptClick = onReadReceiptClick,
onMemberClick = onMemberClick,
onRoomStateClick = onRoomStateClick,
eventSink = eventSink,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
import io.element.android.libraries.core.extensions.orEmpty
import io.element.android.libraries.eventformatter.api.TimelineEventFormatter
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.timeline.item.event.EventContent
import io.element.android.libraries.matrix.api.timeline.item.event.RoomMembershipContent

@Inject
class TimelineItemContentRoomMembershipFactory(
private val timelineEventFormatter: TimelineEventFormatter,
) {
fun create(eventContent: EventContent, isOutgoing: Boolean, sender: UserId, senderDisambiguatedDisplayName: String): TimelineItemEventContent {
fun create(eventContent: RoomMembershipContent, isOutgoing: Boolean, sender: UserId, senderDisambiguatedDisplayName: String): TimelineItemEventContent {
val text = timelineEventFormatter.format(eventContent, isOutgoing, sender, senderDisambiguatedDisplayName)
return TimelineItemRoomMembershipContent(text.orEmpty().toString())
return TimelineItemRoomMembershipContent(
body = text.orEmpty().toString(),
targetUserId = eventContent.userId,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@

package io.element.android.features.messages.impl.timeline.model.event

import io.element.android.libraries.matrix.api.core.UserId

data class TimelineItemRoomMembershipContent(
override val body: String,
val targetUserId: UserId? = null,
) : TimelineItemStateContent {
override val type: String = "TimelineItemRoomMembershipContent"
}
Loading