Merge pull request #5824 from element-hq/feature/bma/roomListIndicators

Add room list indicators about last message
This commit is contained in:
Benoit Marty 2025-12-02 17:42:46 +01:00 committed by GitHub
commit 39e580284d
18 changed files with 205 additions and 67 deletions

View file

@ -40,6 +40,7 @@ import androidx.compose.ui.zIndex
import io.element.android.compound.theme.ElementTheme import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.features.home.impl.R import io.element.android.features.home.impl.R
import io.element.android.features.home.impl.model.LatestEvent
import io.element.android.features.home.impl.model.RoomListRoomSummary import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.features.home.impl.model.RoomListRoomSummaryProvider import io.element.android.features.home.impl.model.RoomListRoomSummaryProvider
import io.element.android.features.home.impl.model.RoomSummaryDisplayType import io.element.android.features.home.impl.model.RoomSummaryDisplayType
@ -120,6 +121,7 @@ internal fun RoomSummaryRow(
) { ) {
NameAndTimestampRow( NameAndTimestampRow(
name = room.name, name = room.name,
latestEvent = room.latestEvent,
timestamp = room.timestamp, timestamp = room.timestamp,
isHighlighted = room.isHighlighted isHighlighted = room.isHighlighted
) )
@ -136,6 +138,7 @@ internal fun RoomSummaryRow(
) { ) {
NameAndTimestampRow( NameAndTimestampRow(
name = room.name, name = room.name,
latestEvent = room.latestEvent,
timestamp = null, timestamp = null,
isHighlighted = room.isHighlighted isHighlighted = room.isHighlighted
) )
@ -211,6 +214,7 @@ private fun RoomSummaryScaffoldRow(
@Composable @Composable
private fun NameAndTimestampRow( private fun NameAndTimestampRow(
name: String?, name: String?,
latestEvent: LatestEvent,
timestamp: String?, timestamp: String?,
isHighlighted: Boolean, isHighlighted: Boolean,
modifier: Modifier = Modifier modifier: Modifier = Modifier
@ -218,10 +222,13 @@ private fun NameAndTimestampRow(
Row( Row(
modifier = modifier.fillMaxWidth(), modifier = modifier.fillMaxWidth(),
horizontalArrangement = spacedBy(16.dp) horizontalArrangement = spacedBy(16.dp)
) {
Row(
modifier = Modifier.weight(1f),
verticalAlignment = Alignment.CenterVertically,
) { ) {
// Name // Name
Text( Text(
modifier = Modifier.weight(1f),
style = ElementTheme.typography.fontBodyLgMedium, style = ElementTheme.typography.fontBodyLgMedium,
text = name ?: stringResource(id = CommonStrings.common_no_room_name), text = name ?: stringResource(id = CommonStrings.common_no_room_name),
fontStyle = FontStyle.Italic.takeIf { name == null }, fontStyle = FontStyle.Italic.takeIf { name == null },
@ -229,6 +236,29 @@ private fun NameAndTimestampRow(
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
// Picto
when (latestEvent) {
is LatestEvent.Sending -> {
Spacer(modifier = Modifier.width(4.dp))
Icon(
modifier = Modifier.size(16.dp),
imageVector = CompoundIcons.Time(),
contentDescription = null,
tint = ElementTheme.colors.iconTertiary,
)
}
is LatestEvent.Error -> {
Spacer(modifier = Modifier.width(4.dp))
Icon(
modifier = Modifier.size(16.dp),
imageVector = CompoundIcons.ErrorSolid(),
contentDescription = null,
tint = ElementTheme.colors.iconCriticalPrimary,
)
}
else -> Unit
}
}
// Timestamp // Timestamp
Text( Text(
text = timestamp ?: "", text = timestamp ?: "",
@ -274,12 +304,30 @@ private fun MessagePreviewAndIndicatorRow(
modifier = modifier.fillMaxWidth(), modifier = modifier.fillMaxWidth(),
horizontalArrangement = spacedBy(28.dp) horizontalArrangement = spacedBy(28.dp)
) { ) {
val messagePreview = if (room.isTombstoned) { if (room.isTombstoned) {
stringResource(R.string.screen_roomlist_tombstoned_room_description) Text(
modifier = Modifier.weight(1f),
text = stringResource(R.string.screen_roomlist_tombstoned_room_description),
color = ElementTheme.colors.roomListRoomMessage,
style = ElementTheme.typography.fontBodyMdRegular,
minLines = 2,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
)
} else { } else {
room.latestEvent.orEmpty() if (room.latestEvent is LatestEvent.Error) {
} Text(
val annotatedMessagePreview = messagePreview as? AnnotatedString ?: AnnotatedString(text = messagePreview.toString()) modifier = Modifier.weight(1f),
text = stringResource(CommonStrings.common_message_failed_to_send),
color = ElementTheme.colors.textCriticalPrimary,
style = ElementTheme.typography.fontBodyMdRegular,
minLines = 2,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
)
} else {
val messagePreview = room.latestEvent.content()
val annotatedMessagePreview = messagePreview as? AnnotatedString ?: AnnotatedString(text = messagePreview.orEmpty().toString())
Text( Text(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
text = annotatedMessagePreview, text = annotatedMessagePreview,
@ -287,8 +335,10 @@ private fun MessagePreviewAndIndicatorRow(
style = ElementTheme.typography.fontBodyMdRegular, style = ElementTheme.typography.fontBodyMdRegular,
minLines = 2, minLines = 2,
maxLines = 2, maxLines = 2,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis,
) )
}
}
// Call and unread // Call and unread
Row( Row(

View file

@ -9,6 +9,7 @@
package io.element.android.features.home.impl.datasource package io.element.android.features.home.impl.datasource
import dev.zacsweers.metro.Inject import dev.zacsweers.metro.Inject
import io.element.android.features.home.impl.model.LatestEvent
import io.element.android.features.home.impl.model.RoomListRoomSummary import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.features.home.impl.model.RoomSummaryDisplayType import io.element.android.features.home.impl.model.RoomSummaryDisplayType
import io.element.android.libraries.core.extensions.orEmpty import io.element.android.libraries.core.extensions.orEmpty
@ -18,6 +19,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.eventformatter.api.RoomLatestEventFormatter import io.element.android.libraries.eventformatter.api.RoomLatestEventFormatter
import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.CurrentUserMembership
import io.element.android.libraries.matrix.api.room.isDm import io.element.android.libraries.matrix.api.room.isDm
import io.element.android.libraries.matrix.api.roomlist.LatestEventValue
import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.api.roomlist.RoomSummary
import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.matrix.ui.model.getAvatarData
import io.element.android.libraries.matrix.ui.model.toInviteSender import io.element.android.libraries.matrix.ui.model.toInviteSender
@ -44,7 +46,7 @@ class RoomListRoomSummaryFactory(
mode = DateFormatterMode.TimeOrDate, mode = DateFormatterMode.TimeOrDate,
useRelative = true, useRelative = true,
), ),
latestEvent = roomLatestEventFormatter.format(roomSummary.latestEvent, roomInfo.isDm).orEmpty(), latestEvent = computeLatestEvent(roomSummary.latestEvent, roomInfo.isDm),
avatarData = avatarData, avatarData = avatarData,
userDefinedNotificationMode = roomInfo.userDefinedNotificationMode, userDefinedNotificationMode = roomInfo.userDefinedNotificationMode,
hasRoomCall = roomInfo.hasRoomCall, hasRoomCall = roomInfo.hasRoomCall,
@ -71,4 +73,28 @@ class RoomListRoomSummaryFactory(
isSpace = roomInfo.isSpace, isSpace = roomInfo.isSpace,
) )
} }
private fun computeLatestEvent(latestEvent: LatestEventValue, dm: Boolean): LatestEvent {
return when (latestEvent) {
is LatestEventValue.None -> {
LatestEvent.None
}
is LatestEventValue.Local -> {
if (latestEvent.isSending) {
val content = roomLatestEventFormatter.format(latestEvent, dm).orEmpty()
LatestEvent.Sending(
content = content,
)
} else {
LatestEvent.Error
}
}
is LatestEventValue.Remote -> {
val content = roomLatestEventFormatter.format(latestEvent, dm).orEmpty()
LatestEvent.Synced(
content = content,
)
}
}
}
} }

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.home.impl.model
import androidx.compose.runtime.Immutable
@Immutable
sealed interface LatestEvent {
data object None : LatestEvent
data class Synced(
val content: CharSequence?,
) : LatestEvent
data class Sending(
val content: CharSequence?,
) : LatestEvent
data object Error : LatestEvent
fun content(): CharSequence? {
return when (this) {
is None -> null
is Synced -> content
is Sending -> content
is Error -> null
}
}
}

View file

@ -29,7 +29,7 @@ data class RoomListRoomSummary(
val numberOfUnreadNotifications: Long, val numberOfUnreadNotifications: Long,
val isMarkedUnread: Boolean, val isMarkedUnread: Boolean,
val timestamp: String?, val timestamp: String?,
val latestEvent: CharSequence?, val latestEvent: LatestEvent,
val avatarData: AvatarData, val avatarData: AvatarData,
val userDefinedNotificationMode: RoomNotificationMode?, val userDefinedNotificationMode: RoomNotificationMode?,
val hasRoomCall: Boolean, val hasRoomCall: Boolean,

View file

@ -25,12 +25,14 @@ open class RoomListRoomSummaryProvider : PreviewParameterProvider<RoomListRoomSu
aRoomListRoomSummary(displayType = RoomSummaryDisplayType.PLACEHOLDER), aRoomListRoomSummary(displayType = RoomSummaryDisplayType.PLACEHOLDER),
aRoomListRoomSummary(), aRoomListRoomSummary(),
aRoomListRoomSummary(name = null), aRoomListRoomSummary(name = null),
aRoomListRoomSummary(lastMessage = null), aRoomListRoomSummary(latestEvent = LatestEvent.None),
aRoomListRoomSummary( aRoomListRoomSummary(
name = "A very long room name that should be truncated", name = "A very long room name that should be truncated",
lastMessage = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt" + latestEvent = LatestEvent.Synced(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt" +
" ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea com" + " ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea com" +
"modo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.", "modo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
),
timestamp = "yesterday", timestamp = "yesterday",
numberOfUnreadMessages = 1, numberOfUnreadMessages = 1,
), ),
@ -44,7 +46,7 @@ open class RoomListRoomSummaryProvider : PreviewParameterProvider<RoomListRoomSu
listOf( listOf(
aRoomListRoomSummary( aRoomListRoomSummary(
name = roomNotificationMode.name, name = roomNotificationMode.name,
lastMessage = "No activity" + if (hasCall) ", call" else "", latestEvent = LatestEvent.Synced("No activity" + if (hasCall) ", call" else ""),
notificationMode = roomNotificationMode, notificationMode = roomNotificationMode,
numberOfUnreadMessages = 0, numberOfUnreadMessages = 0,
numberOfUnreadMentions = 0, numberOfUnreadMentions = 0,
@ -52,7 +54,7 @@ open class RoomListRoomSummaryProvider : PreviewParameterProvider<RoomListRoomSu
), ),
aRoomListRoomSummary( aRoomListRoomSummary(
name = roomNotificationMode.name, name = roomNotificationMode.name,
lastMessage = "New messages" + if (hasCall) ", call" else "", latestEvent = LatestEvent.Synced("New messages" + if (hasCall) ", call" else ""),
notificationMode = roomNotificationMode, notificationMode = roomNotificationMode,
numberOfUnreadMessages = 1, numberOfUnreadMessages = 1,
numberOfUnreadMentions = 0, numberOfUnreadMentions = 0,
@ -60,7 +62,7 @@ open class RoomListRoomSummaryProvider : PreviewParameterProvider<RoomListRoomSu
), ),
aRoomListRoomSummary( aRoomListRoomSummary(
name = roomNotificationMode.name, name = roomNotificationMode.name,
lastMessage = "New messages, mentions" + if (hasCall) ", call" else "", latestEvent = LatestEvent.Synced("New messages, mentions" + if (hasCall) ", call" else ""),
notificationMode = roomNotificationMode, notificationMode = roomNotificationMode,
numberOfUnreadMessages = 1, numberOfUnreadMessages = 1,
numberOfUnreadMentions = 1, numberOfUnreadMentions = 1,
@ -68,7 +70,7 @@ open class RoomListRoomSummaryProvider : PreviewParameterProvider<RoomListRoomSu
), ),
aRoomListRoomSummary( aRoomListRoomSummary(
name = roomNotificationMode.name, name = roomNotificationMode.name,
lastMessage = "New mentions" + if (hasCall) ", call" else "", latestEvent = LatestEvent.Synced("New mentions" + if (hasCall) ", call" else ""),
notificationMode = roomNotificationMode, notificationMode = roomNotificationMode,
numberOfUnreadMessages = 0, numberOfUnreadMessages = 0,
numberOfUnreadMentions = 1, numberOfUnreadMentions = 1,
@ -127,6 +129,10 @@ open class RoomListRoomSummaryProvider : PreviewParameterProvider<RoomListRoomSu
isTombstoned = true, isTombstoned = true,
) )
), ),
listOf(
aRoomListRoomSummary(latestEvent = LatestEvent.Sending("A sending message")),
aRoomListRoomSummary(latestEvent = LatestEvent.Error),
)
).flatten() ).flatten()
} }
@ -148,8 +154,8 @@ internal fun aRoomListRoomSummary(
numberOfUnreadMentions: Long = 0, numberOfUnreadMentions: Long = 0,
numberOfUnreadNotifications: Long = 0, numberOfUnreadNotifications: Long = 0,
isMarkedUnread: Boolean = false, isMarkedUnread: Boolean = false,
lastMessage: String? = "Last message", latestEvent: LatestEvent = LatestEvent.Synced("Last message"),
timestamp: String? = lastMessage?.let { "88:88" }, timestamp: String? = latestEvent.takeIf { it !is LatestEvent.None }?.let { "88:88" },
notificationMode: RoomNotificationMode? = null, notificationMode: RoomNotificationMode? = null,
hasRoomCall: Boolean = false, hasRoomCall: Boolean = false,
avatarData: AvatarData = AvatarData(id, name, size = AvatarSize.RoomListItem), avatarData: AvatarData = AvatarData(id, name, size = AvatarSize.RoomListItem),
@ -171,7 +177,7 @@ internal fun aRoomListRoomSummary(
numberOfUnreadNotifications = numberOfUnreadNotifications, numberOfUnreadNotifications = numberOfUnreadNotifications,
isMarkedUnread = isMarkedUnread, isMarkedUnread = isMarkedUnread,
timestamp = timestamp, timestamp = timestamp,
latestEvent = lastMessage, latestEvent = latestEvent,
avatarData = avatarData, avatarData = avatarData,
userDefinedNotificationMode = notificationMode, userDefinedNotificationMode = notificationMode,
hasRoomCall = hasRoomCall, hasRoomCall = hasRoomCall,

View file

@ -11,6 +11,7 @@ package io.element.android.features.home.impl.roomlist
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.home.impl.filters.RoomListFiltersState import io.element.android.features.home.impl.filters.RoomListFiltersState
import io.element.android.features.home.impl.filters.aRoomListFiltersState import io.element.android.features.home.impl.filters.aRoomListFiltersState
import io.element.android.features.home.impl.model.LatestEvent
import io.element.android.features.home.impl.model.RoomListRoomSummary import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.features.home.impl.model.RoomSummaryDisplayType import io.element.android.features.home.impl.model.RoomSummaryDisplayType
import io.element.android.features.home.impl.model.aRoomListRoomSummary import io.element.android.features.home.impl.model.aRoomListRoomSummary
@ -88,7 +89,7 @@ internal fun aRoomListRoomSummaryList(): ImmutableList<RoomListRoomSummary> {
name = "Room", name = "Room",
numberOfUnreadMessages = 1, numberOfUnreadMessages = 1,
timestamp = "14:18", timestamp = "14:18",
lastMessage = "A very very very very long message which suites on two lines", latestEvent = LatestEvent.Synced("A very very very very long message which suites on two lines"),
avatarData = AvatarData("!id", "R", size = AvatarSize.RoomListItem), avatarData = AvatarData("!id", "R", size = AvatarSize.RoomListItem),
id = "!roomId:domain", id = "!roomId:domain",
), ),
@ -96,7 +97,7 @@ internal fun aRoomListRoomSummaryList(): ImmutableList<RoomListRoomSummary> {
name = "Room#2", name = "Room#2",
numberOfUnreadMessages = 0, numberOfUnreadMessages = 0,
timestamp = "14:16", timestamp = "14:16",
lastMessage = "A short message", latestEvent = LatestEvent.Synced("A short message"),
avatarData = AvatarData("!id", "Z", size = AvatarSize.RoomListItem), avatarData = AvatarData("!id", "Z", size = AvatarSize.RoomListItem),
id = "!roomId2:domain", id = "!roomId2:domain",
), ),
@ -119,7 +120,7 @@ internal fun generateRoomListRoomSummaryList(
name = "Room#$index", name = "Room#$index",
numberOfUnreadMessages = 0, numberOfUnreadMessages = 0,
timestamp = "14:16", timestamp = "14:16",
lastMessage = "A message", latestEvent = LatestEvent.Synced("A message"),
avatarData = AvatarData("!id$index", "${(65 + index % 26).toChar()}", size = AvatarSize.RoomListItem), avatarData = AvatarData("!id$index", "${(65 + index % 26).toChar()}", size = AvatarSize.RoomListItem),
id = "!roomId$index:domain", id = "!roomId$index:domain",
) )

View file

@ -11,11 +11,12 @@ package io.element.android.features.home.impl.datasource
import io.element.android.libraries.dateformatter.api.DateFormatter import io.element.android.libraries.dateformatter.api.DateFormatter
import io.element.android.libraries.dateformatter.test.FakeDateFormatter import io.element.android.libraries.dateformatter.test.FakeDateFormatter
import io.element.android.libraries.eventformatter.api.RoomLatestEventFormatter import io.element.android.libraries.eventformatter.api.RoomLatestEventFormatter
import io.element.android.libraries.eventformatter.test.FakeRoomLatestEventFormatter
fun aRoomListRoomSummaryFactory( fun aRoomListRoomSummaryFactory(
dateFormatter: DateFormatter = FakeDateFormatter { _, _, _ -> "Today" }, dateFormatter: DateFormatter = FakeDateFormatter { _, _, _ -> "Today" },
roomLatestEventFormatter: RoomLatestEventFormatter = RoomLatestEventFormatter { _, _ -> "Hey" } roomLatestEventFormatter: RoomLatestEventFormatter = FakeRoomLatestEventFormatter(),
) = RoomListRoomSummaryFactory( ) = RoomListRoomSummaryFactory(
dateFormatter = dateFormatter, dateFormatter = dateFormatter,
roomLatestEventFormatter = roomLatestEventFormatter roomLatestEventFormatter = roomLatestEventFormatter,
) )

View file

@ -96,7 +96,7 @@ internal fun createRoomListRoomSummary(
numberOfUnreadNotifications = numberOfUnreadNotifications, numberOfUnreadNotifications = numberOfUnreadNotifications,
isMarkedUnread = isMarkedUnread, isMarkedUnread = isMarkedUnread,
timestamp = timestamp, timestamp = timestamp,
latestEvent = "", latestEvent = LatestEvent.Synced(""),
avatarData = AvatarData(id = A_ROOM_ID.value, name = A_ROOM_NAME, size = AvatarSize.RoomListItem), avatarData = AvatarData(id = A_ROOM_ID.value, name = A_ROOM_NAME, size = AvatarSize.RoomListItem),
displayType = displayType, displayType = displayType,
userDefinedNotificationMode = userDefinedNotificationMode, userDefinedNotificationMode = userDefinedNotificationMode,

View file

@ -170,7 +170,7 @@ class RoomListViewTest {
// Remove automatic initial events // Remove automatic initial events
eventsRecorder.clear() eventsRecorder.clear()
rule.onNodeWithText(room0.latestEvent!!.toString()).performClick() rule.onNodeWithText(room0.latestEvent.content().toString()).performClick()
} }
eventsRecorder.assertEmpty() eventsRecorder.assertEmpty()
@ -192,7 +192,7 @@ class RoomListViewTest {
) )
// Remove automatic initial events // Remove automatic initial events
eventsRecorder.clear() eventsRecorder.clear()
rule.onNodeWithText(room0.latestEvent!!.toString()) rule.onNodeWithText(room0.latestEvent.content().toString())
.performClick() .performClick()
.performClick() .performClick()
} }
@ -214,7 +214,7 @@ class RoomListViewTest {
// Remove automatic initial events // Remove automatic initial events
eventsRecorder.clear() eventsRecorder.clear()
rule.onNodeWithText(room0.latestEvent!!.toString()).performTouchInput { longClick() } rule.onNodeWithText(room0.latestEvent.content().toString()).performTouchInput { longClick() }
eventsRecorder.assertSingle(RoomListEvents.ShowContextMenu(room0)) eventsRecorder.assertSingle(RoomListEvents.ShowContextMenu(room0))
} }

View file

@ -10,6 +10,7 @@ package io.element.android.libraries.eventformatter.api
import io.element.android.libraries.matrix.api.roomlist.LatestEventValue import io.element.android.libraries.matrix.api.roomlist.LatestEventValue
fun interface RoomLatestEventFormatter { interface RoomLatestEventFormatter {
fun format(latestEvent: LatestEventValue, isDmRoom: Boolean): CharSequence? fun format(latestEvent: LatestEventValue.Local, isDmRoom: Boolean): CharSequence?
fun format(latestEvent: LatestEventValue.Remote, isDmRoom: Boolean): CharSequence?
} }

View file

@ -59,25 +59,27 @@ class DefaultRoomLatestEventFormatter(
private const val MAX_SAFE_LENGTH = 500 private const val MAX_SAFE_LENGTH = 500
} }
override fun format(latestEvent: LatestEventValue, isDmRoom: Boolean): CharSequence? { override fun format(
return when (latestEvent) { latestEvent: LatestEventValue.Local,
LatestEventValue.None -> null isDmRoom: Boolean,
is LatestEventValue.Local -> formatContent( ): CharSequence? = formatContent(
content = latestEvent.content, content = latestEvent.content,
isDmRoom = isDmRoom, isDmRoom = isDmRoom,
isOutgoing = true, isOutgoing = true,
senderId = latestEvent.senderId, senderId = latestEvent.senderId,
senderDisambiguatedDisplayName = latestEvent.senderProfile.getDisambiguatedDisplayName(latestEvent.senderId) senderDisambiguatedDisplayName = latestEvent.senderProfile.getDisambiguatedDisplayName(latestEvent.senderId)
) )
is LatestEventValue.Remote -> formatContent(
override fun format(
latestEvent: LatestEventValue.Remote,
isDmRoom: Boolean,
): CharSequence? = formatContent(
content = latestEvent.content, content = latestEvent.content,
isDmRoom = isDmRoom, isDmRoom = isDmRoom,
isOutgoing = latestEvent.isOwn, isOutgoing = latestEvent.isOwn,
senderId = latestEvent.senderId, senderId = latestEvent.senderId,
senderDisambiguatedDisplayName = latestEvent.senderProfile.getDisambiguatedDisplayName(latestEvent.senderId) senderDisambiguatedDisplayName = latestEvent.senderProfile.getDisambiguatedDisplayName(latestEvent.senderId)
) )
}
}
private fun formatContent( private fun formatContent(
content: EventContent, content: EventContent,

View file

@ -929,7 +929,7 @@ class DefaultRoomLatestEventFormatterTest {
sentByYou: Boolean, sentByYou: Boolean,
senderDisplayName: String?, senderDisplayName: String?,
content: EventContent, content: EventContent,
): LatestEventValue { ): LatestEventValue.Remote {
val sender = if (sentByYou) A_USER_ID else someoneElseId val sender = if (sentByYou) A_USER_ID else someoneElseId
val profile = aProfileDetails(senderDisplayName) val profile = aProfileDetails(senderDisplayName)
return aRemoteLatestEvent( return aRemoteLatestEvent(

View file

@ -14,7 +14,11 @@ import io.element.android.libraries.matrix.api.roomlist.LatestEventValue
class FakeRoomLatestEventFormatter : RoomLatestEventFormatter { class FakeRoomLatestEventFormatter : RoomLatestEventFormatter {
private var result: CharSequence? = null private var result: CharSequence? = null
override fun format(latestEvent: LatestEventValue, isDmRoom: Boolean): CharSequence? { override fun format(latestEvent: LatestEventValue.Local, isDmRoom: Boolean): CharSequence? {
return result
}
override fun format(latestEvent: LatestEventValue.Remote, isDmRoom: Boolean): CharSequence? {
return result return result
} }

View file

@ -246,6 +246,7 @@ Reason: %1$s."</string>
</plurals> </plurals>
<string name="common_message">"Message"</string> <string name="common_message">"Message"</string>
<string name="common_message_actions">"Message actions"</string> <string name="common_message_actions">"Message actions"</string>
<string name="common_message_failed_to_send">"Message failed to send"</string>
<string name="common_message_layout">"Message layout"</string> <string name="common_message_layout">"Message layout"</string>
<string name="common_message_removed">"Message removed"</string> <string name="common_message_removed">"Message removed"</string>
<string name="common_modern">"Modern"</string> <string name="common_modern">"Modern"</string>

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:761e963499f97f21b5c5b8b80e5d75092fbc4305371bcc413f595b503890d511
size 13085

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:de31aa3dbb9c9427189621d35022211220197de8ed8584f36801eb99d613f0b1
size 13728

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1f7327f29c9236b549d7f5037e3483e487a23902c5c30bd20a7a4bc0e6c13bec
size 13009

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f92a70303d515a135eb87eac344dc4a974183da8773524a48f790b31a70338e8
size 13528