Browse Source

Revert "Room list badges"

pull/2095/head
Jorge Martin Espinosa 9 months ago committed by GitHub
parent
commit
cbf34929af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      .idea/dictionaries/shared.xml
  2. 2
      features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListPresenter.kt
  3. 20
      features/invitelist/impl/src/test/kotlin/io/element/android/features/invitelist/impl/InviteListPresenterTests.kt
  4. 30
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesStateProvider.kt
  5. 6
      features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesPresenterTests.kt
  6. 13
      features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingStateProvider.kt
  7. 4
      features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt
  8. 8
      features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/notifications/EditDefaultNotificationSettingsPresenterTests.kt
  9. 4
      features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListStateProvider.kt
  10. 68
      features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt
  11. 9
      features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListDataSource.kt
  12. 17
      features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummary.kt
  13. 83
      features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryProvider.kt
  14. 9
      features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTests.kt
  15. 2
      libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt
  16. 18
      libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomSummary.kt
  17. 4
      libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/user/CurrentUser.kt
  18. 2
      libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt
  19. 10
      libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt
  20. 6
      libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt
  21. 37
      libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt
  22. 43
      libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedRoom.kt
  23. 2
      libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotificationDrawerManager.kt
  24. 31
      libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectStateProvider.kt
  25. 2
      libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectView.kt
  26. 8
      libraries/roomselect/impl/src/test/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenterTests.kt
  27. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_0,NEXUS_5,1.0,en].png
  28. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_10,NEXUS_5,1.0,en].png
  29. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_11,NEXUS_5,1.0,en].png
  30. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_12,NEXUS_5,1.0,en].png
  31. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_13,NEXUS_5,1.0,en].png
  32. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_14,NEXUS_5,1.0,en].png
  33. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_15,NEXUS_5,1.0,en].png
  34. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_16,NEXUS_5,1.0,en].png
  35. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_17,NEXUS_5,1.0,en].png
  36. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_18,NEXUS_5,1.0,en].png
  37. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_19,NEXUS_5,1.0,en].png
  38. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_2,NEXUS_5,1.0,en].png
  39. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_20,NEXUS_5,1.0,en].png
  40. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_21,NEXUS_5,1.0,en].png
  41. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_3,NEXUS_5,1.0,en].png
  42. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_4,NEXUS_5,1.0,en].png
  43. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_5,NEXUS_5,1.0,en].png
  44. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_6,NEXUS_5,1.0,en].png
  45. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_7,NEXUS_5,1.0,en].png
  46. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_8,NEXUS_5,1.0,en].png
  47. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_9,NEXUS_5,1.0,en].png
  48. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_0,NEXUS_5,1.0,en].png
  49. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_10,NEXUS_5,1.0,en].png
  50. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_11,NEXUS_5,1.0,en].png
  51. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_12,NEXUS_5,1.0,en].png
  52. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_13,NEXUS_5,1.0,en].png
  53. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_14,NEXUS_5,1.0,en].png
  54. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_15,NEXUS_5,1.0,en].png
  55. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_16,NEXUS_5,1.0,en].png
  56. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_17,NEXUS_5,1.0,en].png
  57. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_18,NEXUS_5,1.0,en].png
  58. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_19,NEXUS_5,1.0,en].png
  59. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_2,NEXUS_5,1.0,en].png
  60. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_20,NEXUS_5,1.0,en].png
  61. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_21,NEXUS_5,1.0,en].png
  62. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_3,NEXUS_5,1.0,en].png
  63. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_4,NEXUS_5,1.0,en].png
  64. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_5,NEXUS_5,1.0,en].png
  65. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_6,NEXUS_5,1.0,en].png
  66. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_7,NEXUS_5,1.0,en].png
  67. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_8,NEXUS_5,1.0,en].png
  68. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_9,NEXUS_5,1.0,en].png

1
.idea/dictionaries/shared.xml

@ -16,7 +16,6 @@
<w>snackbar</w> <w>snackbar</w>
<w>swipeable</w> <w>swipeable</w>
<w>textfields</w> <w>textfields</w>
<w>tombstoned</w>
</words> </words>
</dictionary> </dictionary>
</component> </component>

2
features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListPresenter.kt

@ -170,7 +170,7 @@ class InviteListPresenter @Inject constructor(
AvatarData( AvatarData(
id = roomId.value, id = roomId.value,
name = name, name = name,
url = avatarUrl, url = avatarURLString,
size = AvatarSize.RoomInviteItem, size = AvatarSize.RoomInviteItem,
) )

20
features/invitelist/impl/src/test/kotlin/io/element/android/features/invitelist/impl/InviteListPresenterTests.kt

@ -30,6 +30,7 @@ import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomMembershipState import io.element.android.libraries.matrix.api.room.RoomMembershipState
import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.api.roomlist.RoomSummary
import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails
import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.AN_AVATAR_URL
import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_ROOM_ID_2 import io.element.android.libraries.matrix.test.A_ROOM_ID_2
@ -38,7 +39,6 @@ import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.A_USER_NAME import io.element.android.libraries.matrix.test.A_USER_NAME
import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.aRoomSummaryDetails
import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService
import io.element.android.libraries.push.api.notifications.NotificationDrawerManager import io.element.android.libraries.push.api.notifications.NotificationDrawerManager
import io.element.android.libraries.push.test.notifications.FakeNotificationDrawerManager import io.element.android.libraries.push.test.notifications.FakeNotificationDrawerManager
@ -425,12 +425,14 @@ class InviteListPresenterTests {
postInviteRooms( postInviteRooms(
listOf( listOf(
RoomSummary.Filled( RoomSummary.Filled(
aRoomSummaryDetails( RoomSummaryDetails(
roomId = A_ROOM_ID, roomId = A_ROOM_ID,
name = A_ROOM_NAME, name = A_ROOM_NAME,
avatarUrl = null, avatarURLString = null,
isDirect = false, isDirect = false,
lastMessage = null, lastMessage = null,
lastMessageTimestamp = null,
unreadNotificationCount = 0,
inviter = RoomMember( inviter = RoomMember(
userId = A_USER_ID, userId = A_USER_ID,
displayName = A_USER_NAME, displayName = A_USER_NAME,
@ -452,12 +454,14 @@ class InviteListPresenterTests {
postInviteRooms( postInviteRooms(
listOf( listOf(
RoomSummary.Filled( RoomSummary.Filled(
aRoomSummaryDetails( RoomSummaryDetails(
roomId = A_ROOM_ID, roomId = A_ROOM_ID,
name = A_ROOM_NAME, name = A_ROOM_NAME,
avatarUrl = null, avatarURLString = null,
isDirect = true, isDirect = true,
lastMessage = null, lastMessage = null,
lastMessageTimestamp = null,
unreadNotificationCount = 0,
inviter = RoomMember( inviter = RoomMember(
userId = A_USER_ID, userId = A_USER_ID,
displayName = A_USER_NAME, displayName = A_USER_NAME,
@ -476,12 +480,14 @@ class InviteListPresenterTests {
} }
private fun aRoomSummary(id: RoomId = A_ROOM_ID) = RoomSummary.Filled( private fun aRoomSummary(id: RoomId = A_ROOM_ID) = RoomSummary.Filled(
aRoomSummaryDetails( RoomSummaryDetails(
roomId = id, roomId = id,
name = A_ROOM_NAME, name = A_ROOM_NAME,
avatarUrl = null, avatarURLString = null,
isDirect = false, isDirect = false,
lastMessage = null, lastMessage = null,
lastMessageTimestamp = null,
unreadNotificationCount = 0,
) )
) )

30
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesStateProvider.kt

@ -18,6 +18,9 @@ package io.element.android.features.messages.impl.forward
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.message.RoomMessage
import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
@ -48,3 +51,30 @@ fun aForwardMessagesState(
forwardingSucceeded = forwardingSucceeded, forwardingSucceeded = forwardingSucceeded,
eventSink = {} eventSink = {}
) )
internal fun aForwardMessagesRoomList() = persistentListOf(
aRoomDetailsState(),
aRoomDetailsState(roomId = RoomId("!room2:domain"), canonicalAlias = "#element-x-room:matrix.org"),
)
fun aRoomDetailsState(
roomId: RoomId = RoomId("!room:domain"),
name: String = "roomName",
canonicalAlias: String? = null,
isDirect: Boolean = true,
avatarURLString: String? = null,
lastMessage: RoomMessage? = null,
lastMessageTimestamp: Long? = null,
unreadNotificationCount: Int = 0,
inviter: RoomMember? = null,
) = RoomSummaryDetails(
roomId = roomId,
name = name,
canonicalAlias = canonicalAlias,
isDirect = isDirect,
avatarURLString = avatarURLString,
lastMessage = lastMessage,
lastMessageTimestamp = lastMessageTimestamp,
unreadNotificationCount = unreadNotificationCount,
inviter = inviter,
)

6
features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesPresenterTests.kt

@ -23,7 +23,7 @@ import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.aRoomSummaryDetails import io.element.android.libraries.matrix.test.room.aRoomSummaryDetail
import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.WarmUpRule
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
@ -55,7 +55,7 @@ class ForwardMessagesPresenterTests {
presenter.present() presenter.present()
}.test { }.test {
skipItems(1) skipItems(1)
val summary = aRoomSummaryDetails() val summary = aRoomSummaryDetail()
presenter.onRoomSelected(listOf(summary.roomId)) presenter.onRoomSelected(listOf(summary.roomId))
val forwardingState = awaitItem() val forwardingState = awaitItem()
assertThat(forwardingState.isForwarding).isTrue() assertThat(forwardingState.isForwarding).isTrue()
@ -75,7 +75,7 @@ class ForwardMessagesPresenterTests {
// Test failed forwarding // Test failed forwarding
room.givenForwardEventResult(Result.failure(Throwable("error"))) room.givenForwardEventResult(Result.failure(Throwable("error")))
skipItems(1) skipItems(1)
val summary = aRoomSummaryDetails() val summary = aRoomSummaryDetail()
presenter.onRoomSelected(listOf(summary.roomId)) presenter.onRoomSelected(listOf(summary.roomId))
skipItems(1) skipItems(1)
val failedForwardState = awaitItem() val failedForwardState = awaitItem()

13
features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingStateProvider.kt

@ -24,7 +24,7 @@ import io.element.android.libraries.matrix.api.roomlist.RoomSummary
import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
open class EditDefaultNotificationSettingStateProvider : PreviewParameterProvider<EditDefaultNotificationSettingState> { open class EditDefaultNotificationSettingStateProvider: PreviewParameterProvider<EditDefaultNotificationSettingState> {
override val values: Sequence<EditDefaultNotificationSettingState> override val values: Sequence<EditDefaultNotificationSettingState>
get() = sequenceOf( get() = sequenceOf(
anEditDefaultNotificationSettingsState(), anEditDefaultNotificationSettingsState(),
@ -52,14 +52,11 @@ private fun aRoomSummary() = RoomSummary.Filled(
RoomSummaryDetails( RoomSummaryDetails(
roomId = RoomId("!roomId:domain"), roomId = RoomId("!roomId:domain"),
name = "Room", name = "Room",
avatarUrl = null, avatarURLString = null,
isDirect = false, isDirect = false,
lastMessage = null, lastMessage = null,
userDefinedNotificationMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY, lastMessageTimestamp = null,
canonicalAlias = null, unreadNotificationCount = 0,
inviter = null, notificationMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
hasRoomCall = false,
numUnreadMentions = 0,
numUnreadMessages = 0,
) )
) )

4
features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt

@ -86,7 +86,7 @@ fun EditDefaultNotificationSettingView(
if (state.roomsWithUserDefinedMode.isNotEmpty()) { if (state.roomsWithUserDefinedMode.isNotEmpty()) {
PreferenceCategory(title = stringResource(id = R.string.screen_notification_settings_edit_custom_settings_section_title)) { PreferenceCategory(title = stringResource(id = R.string.screen_notification_settings_edit_custom_settings_section_title)) {
state.roomsWithUserDefinedMode.forEach { summary -> state.roomsWithUserDefinedMode.forEach { summary ->
val subtitle = when (summary.details.userDefinedNotificationMode) { val subtitle = when (summary.details.notificationMode) {
RoomNotificationMode.ALL_MESSAGES -> stringResource(id = R.string.screen_notification_settings_edit_mode_all_messages) RoomNotificationMode.ALL_MESSAGES -> stringResource(id = R.string.screen_notification_settings_edit_mode_all_messages)
RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY -> { RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY -> {
stringResource(id = R.string.screen_notification_settings_edit_mode_mentions_and_keywords) stringResource(id = R.string.screen_notification_settings_edit_mode_mentions_and_keywords)
@ -97,7 +97,7 @@ fun EditDefaultNotificationSettingView(
val avatarData = AvatarData( val avatarData = AvatarData(
id = summary.identifier(), id = summary.identifier(),
name = summary.details.name, name = summary.details.name,
url = summary.details.avatarUrl, url = summary.details.avatarURLString,
size = AvatarSize.CustomRoomNotificationSetting, size = AvatarSize.CustomRoomNotificationSetting,
) )
ListItem( ListItem(

8
features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/notifications/EditDefaultNotificationSettingsPresenterTests.kt

@ -29,7 +29,7 @@ import io.element.android.libraries.matrix.test.A_THROWABLE
import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.aRoomSummaryDetails import io.element.android.libraries.matrix.test.room.aRoomSummaryDetail
import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService
import io.element.android.tests.testutils.awaitLastSequentialItem import io.element.android.tests.testutils.awaitLastSequentialItem
import io.element.android.tests.testutils.consumeItemsUntilPredicate import io.element.android.tests.testutils.consumeItemsUntilPredicate
@ -72,11 +72,11 @@ class EditDefaultNotificationSettingsPresenterTests {
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
presenter.present() presenter.present()
}.test { }.test {
roomListService.postAllRooms(listOf(RoomSummary.Filled(aRoomSummaryDetails(notificationMode = RoomNotificationMode.ALL_MESSAGES)))) roomListService.postAllRooms(listOf(RoomSummary.Filled(aRoomSummaryDetail(notificationMode = RoomNotificationMode.ALL_MESSAGES))))
val loadedState = consumeItemsUntilPredicate { state -> val loadedState = consumeItemsUntilPredicate { state ->
state.roomsWithUserDefinedMode.any { it.details.userDefinedNotificationMode == RoomNotificationMode.ALL_MESSAGES } state.roomsWithUserDefinedMode.any { it.details.notificationMode == RoomNotificationMode.ALL_MESSAGES }
}.last() }.last()
assertThat(loadedState.roomsWithUserDefinedMode.any { it.details.userDefinedNotificationMode == RoomNotificationMode.ALL_MESSAGES }).isTrue() assertThat(loadedState.roomsWithUserDefinedMode.any { it.details.notificationMode == RoomNotificationMode.ALL_MESSAGES }).isTrue()
} }
} }

4
features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListStateProvider.kt

@ -71,7 +71,7 @@ internal fun aRoomListRoomSummaryList(): ImmutableList<RoomListRoomSummary> {
return persistentListOf( return persistentListOf(
RoomListRoomSummary( RoomListRoomSummary(
name = "Room", name = "Room",
numberOfUnreadMessages = 1, hasUnread = true,
timestamp = "14:18", timestamp = "14:18",
lastMessage = "A very very very very long message which suites on two lines", lastMessage = "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),
@ -80,7 +80,7 @@ internal fun aRoomListRoomSummaryList(): ImmutableList<RoomListRoomSummary> {
), ),
RoomListRoomSummary( RoomListRoomSummary(
name = "Room#2", name = "Room#2",
numberOfUnreadMessages = 0, hasUnread = false,
timestamp = "14:16", timestamp = "14:16",
lastMessage = "A short message", lastMessage = "A short message",
avatarData = AvatarData("!id", "Z", size = AvatarSize.RoomListItem), avatarData = AvatarData("!id", "Z", size = AvatarSize.RoomListItem),

68
features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt

@ -43,7 +43,6 @@ 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.roomlist.impl.model.RoomListRoomSummary import io.element.android.features.roomlist.impl.model.RoomListRoomSummary
import io.element.android.features.roomlist.impl.model.RoomListRoomSummaryProvider import io.element.android.features.roomlist.impl.model.RoomListRoomSummaryProvider
import io.element.android.features.roomlist.impl.model.isTimestampHighlighted
import io.element.android.libraries.core.extensions.orEmpty import io.element.android.libraries.core.extensions.orEmpty
import io.element.android.libraries.designsystem.atomic.atoms.UnreadIndicatorAtom import io.element.android.libraries.designsystem.atomic.atoms.UnreadIndicatorAtom
import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.Avatar
@ -142,7 +141,7 @@ private fun RowScope.NameAndTimestampRow(room: RoomListRoomSummary) {
Text( Text(
text = room.timestamp ?: "", text = room.timestamp ?: "",
style = ElementTheme.typography.fontBodySmMedium, style = ElementTheme.typography.fontBodySmMedium,
color = if (room.isTimestampHighlighted()) { color = if (room.hasUnread) {
ElementTheme.colors.unreadIndicator ElementTheme.colors.unreadIndicator
} else { } else {
MaterialTheme.roomListRoomMessageDate() MaterialTheme.roomListRoomMessageDate()
@ -174,23 +173,7 @@ private fun RowScope.LastMessageAndIndicatorRow(room: RoomListRoomSummary) {
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
// Video call // Video call
OnGoingCallIcon( if (room.hasOngoingCall) {
room.hasRoomCall,
)
// Other indicators
NotificationIcons(
room.userDefinedNotificationMode,
room.numberOfUnreadMessages,
room.numberOfUnreadMentions,
)
}
}
@Composable
private fun OnGoingCallIcon(
hasRoomCall: Boolean,
) {
if (hasRoomCall) {
Icon( Icon(
modifier = Modifier.size(16.dp), modifier = Modifier.size(16.dp),
imageVector = CompoundIcons.VideoCallSolid, imageVector = CompoundIcons.VideoCallSolid,
@ -198,53 +181,32 @@ private fun OnGoingCallIcon(
tint = ElementTheme.colors.unreadIndicator, tint = ElementTheme.colors.unreadIndicator,
) )
} }
} NotificationIcon(room)
if (room.hasUnread) {
@Composable
private fun RowScope.NotificationIcons(
userDefinedNotificationMode: RoomNotificationMode?,
numberOfUnreadMessages: Int,
numberOfUnreadMentions: Int,
) {
when (userDefinedNotificationMode) {
null,
RoomNotificationMode.ALL_MESSAGES -> {
if (numberOfUnreadMentions > 0) {
Icon(
modifier = Modifier.size(16.dp),
contentDescription = null,
imageVector = CompoundIcons.Mention,
tint = ElementTheme.colors.unreadIndicator,
)
UnreadIndicatorAtom()
} else if (numberOfUnreadMessages > 0) {
UnreadIndicatorAtom() UnreadIndicatorAtom()
} }
} }
RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY -> { }
if (numberOfUnreadMentions > 0) {
@Composable
private fun NotificationIcon(room: RoomListRoomSummary) {
val tint = if (room.hasUnread) ElementTheme.colors.unreadIndicator else ElementTheme.colors.iconQuaternary
when (room.notificationMode) {
null, RoomNotificationMode.ALL_MESSAGES -> return
RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY ->
Icon( Icon(
modifier = Modifier.size(16.dp), modifier = Modifier.size(16.dp),
contentDescription = null, contentDescription = null,
imageVector = CompoundIcons.Mention, imageVector = CompoundIcons.Mention,
tint = ElementTheme.colors.unreadIndicator, tint = tint,
) )
UnreadIndicatorAtom() RoomNotificationMode.MUTE ->
} else if (numberOfUnreadMessages > 0) {
UnreadIndicatorAtom(color = ElementTheme.colors.iconQuaternary)
}
}
RoomNotificationMode.MUTE -> {
Icon( Icon(
modifier = Modifier.size(16.dp), modifier = Modifier.size(16.dp),
contentDescription = null, contentDescription = null,
imageVector = CompoundIcons.NotificationsSolidOff, imageVector = CompoundIcons.NotificationsSolidOff,
tint = ElementTheme.colors.iconQuaternary, tint = tint,
) )
if (numberOfUnreadMessages > 0 || numberOfUnreadMentions > 0) {
UnreadIndicatorAtom(color = ElementTheme.colors.iconQuaternary)
}
}
} }
} }

9
features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListDataSource.kt

@ -146,7 +146,7 @@ class RoomListDataSource @Inject constructor(
val avatarData = AvatarData( val avatarData = AvatarData(
id = roomSummary.identifier(), id = roomSummary.identifier(),
name = roomSummary.details.name, name = roomSummary.details.name,
url = roomSummary.details.avatarUrl, url = roomSummary.details.avatarURLString,
size = AvatarSize.RoomListItem, size = AvatarSize.RoomListItem,
) )
val roomIdentifier = roomSummary.identifier() val roomIdentifier = roomSummary.identifier()
@ -154,15 +154,14 @@ class RoomListDataSource @Inject constructor(
id = roomSummary.identifier(), id = roomSummary.identifier(),
roomId = RoomId(roomIdentifier), roomId = RoomId(roomIdentifier),
name = roomSummary.details.name, name = roomSummary.details.name,
numberOfUnreadMessages = roomSummary.details.numUnreadMessages, hasUnread = roomSummary.details.unreadNotificationCount > 0,
numberOfUnreadMentions = roomSummary.details.numUnreadMentions,
timestamp = lastMessageTimestampFormatter.format(roomSummary.details.lastMessageTimestamp), timestamp = lastMessageTimestampFormatter.format(roomSummary.details.lastMessageTimestamp),
lastMessage = roomSummary.details.lastMessage?.let { message -> lastMessage = roomSummary.details.lastMessage?.let { message ->
roomLastMessageFormatter.format(message.event, roomSummary.details.isDirect) roomLastMessageFormatter.format(message.event, roomSummary.details.isDirect)
}.orEmpty(), }.orEmpty(),
avatarData = avatarData, avatarData = avatarData,
userDefinedNotificationMode = roomSummary.details.userDefinedNotificationMode, notificationMode = roomSummary.details.notificationMode,
hasRoomCall = roomSummary.details.hasRoomCall, hasOngoingCall = roomSummary.details.hasOngoingCall,
) )
} }
null -> null null -> null

17
features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummary.kt

@ -27,22 +27,11 @@ data class RoomListRoomSummary(
val id: String, val id: String,
val roomId: RoomId, val roomId: RoomId,
val name: String = "", val name: String = "",
val hasUnread: Boolean = false,
val timestamp: String? = null, val timestamp: String? = null,
val lastMessage: CharSequence? = null, val lastMessage: CharSequence? = null,
val avatarData: AvatarData = AvatarData(id, name, size = AvatarSize.RoomListItem), val avatarData: AvatarData = AvatarData(id, name, size = AvatarSize.RoomListItem),
val isPlaceholder: Boolean = false, val isPlaceholder: Boolean = false,
val userDefinedNotificationMode: RoomNotificationMode? = null, val notificationMode: RoomNotificationMode? = null,
val numberOfUnreadMessages: Int = 0, val hasOngoingCall: Boolean = false,
val numberOfUnreadMentions: Int = 0,
val hasRoomCall: Boolean = false,
) )
fun RoomListRoomSummary.isTimestampHighlighted(): Boolean {
return hasRoomCall ||
when (userDefinedNotificationMode) {
null,
RoomNotificationMode.ALL_MESSAGES -> numberOfUnreadMessages > 0 || numberOfUnreadMentions > 0
RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY -> numberOfUnreadMentions > 0
RoomNotificationMode.MUTE -> false
}
}

83
features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryProvider.kt

@ -25,83 +25,32 @@ import io.element.android.libraries.matrix.api.room.RoomNotificationMode
open class RoomListRoomSummaryProvider : PreviewParameterProvider<RoomListRoomSummary> { open class RoomListRoomSummaryProvider : PreviewParameterProvider<RoomListRoomSummary> {
override val values: Sequence<RoomListRoomSummary> override val values: Sequence<RoomListRoomSummary>
get() = sequenceOf( get() = sequenceOf(
listOf( aRoomListRoomSummary(),
aRoomListRoomSummary(isPlaceholder = true), aRoomListRoomSummary().copy(lastMessage = null),
aRoomListRoomSummary(timestamp = null), aRoomListRoomSummary().copy(hasUnread = true, notificationMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY),
aRoomListRoomSummary(lastMessage = "Last message"), aRoomListRoomSummary().copy(timestamp = "88:88", notificationMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY),
aRoomListRoomSummary( aRoomListRoomSummary().copy(timestamp = "88:88", notificationMode = RoomNotificationMode.MUTE),
aRoomListRoomSummary().copy(timestamp = "88:88", hasUnread = true),
aRoomListRoomSummary().copy(isPlaceholder = true, timestamp = "88:88"),
aRoomListRoomSummary().copy(
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" + lastMessage = "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, hasUnread = true,
),
),
listOf(false, true).map { hasCall ->
listOf(
RoomNotificationMode.ALL_MESSAGES,
RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
RoomNotificationMode.MUTE,
).map { roomNotificationMode ->
listOf(
aRoomListRoomSummary(
name = roomNotificationMode.name,
lastMessage = "No activity" + if (hasCall) ", call" else "",
notificationMode = roomNotificationMode,
numberOfUnreadMessages = 0,
numberOfUnreadMentions = 0,
hasOngoingCall = hasCall,
),
aRoomListRoomSummary(
name = roomNotificationMode.name,
lastMessage = "New messages" + if (hasCall) ", call" else "",
notificationMode = roomNotificationMode,
numberOfUnreadMessages = 1,
numberOfUnreadMentions = 0,
hasOngoingCall = hasCall,
),
aRoomListRoomSummary(
name = roomNotificationMode.name,
lastMessage = "New messages, mentions" + if (hasCall) ", call" else "",
notificationMode = roomNotificationMode,
numberOfUnreadMessages = 1,
numberOfUnreadMentions = 1,
hasOngoingCall = hasCall,
),
aRoomListRoomSummary(
name = roomNotificationMode.name,
lastMessage = "New mentions" + if (hasCall) ", call" else "",
notificationMode = roomNotificationMode,
numberOfUnreadMessages = 0,
numberOfUnreadMentions = 1,
hasOngoingCall = hasCall,
), ),
aRoomListRoomSummary().copy(hasUnread = true, hasOngoingCall = true),
) )
}.flatten()
}.flatten(),
).flatten()
} }
fun aRoomListRoomSummary( fun aRoomListRoomSummary() = RoomListRoomSummary(
lastMessage: String? = null,
notificationMode: RoomNotificationMode? = null,
numberOfUnreadMessages: Int = 0,
numberOfUnreadMentions: Int = 0,
timestamp: String? = "88:88",
hasOngoingCall: Boolean = false,
isPlaceholder: Boolean = false,
name: String = "Room name",
) = RoomListRoomSummary(
id = "!roomId", id = "!roomId",
roomId = RoomId("!roomId:domain"), roomId = RoomId("!roomId:domain"),
name = name, name = "Room name",
numberOfUnreadMessages = numberOfUnreadMessages, hasUnread = false,
numberOfUnreadMentions = numberOfUnreadMentions, timestamp = null,
timestamp = timestamp, lastMessage = "Last message",
lastMessage = lastMessage,
avatarData = AvatarData("!roomId", "Room name", size = AvatarSize.RoomListItem), avatarData = AvatarData("!roomId", "Room name", size = AvatarSize.RoomListItem),
isPlaceholder = isPlaceholder, isPlaceholder = false,
userDefinedNotificationMode = notificationMode,
hasRoomCall = hasOngoingCall,
) )

9
features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTests.kt

@ -123,7 +123,7 @@ class RoomListPresenterTests {
fun `present - should start with no user and then load user with error`() = runTest { fun `present - should start with no user and then load user with error`() = runTest {
val matrixClient = FakeMatrixClient( val matrixClient = FakeMatrixClient(
userDisplayName = Result.failure(AN_EXCEPTION), userDisplayName = Result.failure(AN_EXCEPTION),
userAvatarUrl = Result.failure(AN_EXCEPTION), userAvatarURLString = Result.failure(AN_EXCEPTION),
) )
val scope = CoroutineScope(coroutineContext + SupervisorJob()) val scope = CoroutineScope(coroutineContext + SupervisorJob())
val presenter = createRoomListPresenter(client = matrixClient, coroutineScope = scope) val presenter = createRoomListPresenter(client = matrixClient, coroutineScope = scope)
@ -385,11 +385,11 @@ class RoomListPresenterTests {
notificationSettingsService.setRoomNotificationMode(A_ROOM_ID, userDefinedMode) notificationSettingsService.setRoomNotificationMode(A_ROOM_ID, userDefinedMode)
val updatedState = consumeItemsUntilPredicate { state -> val updatedState = consumeItemsUntilPredicate { state ->
state.roomList.any { it.id == A_ROOM_ID.value && it.userDefinedNotificationMode == userDefinedMode } state.roomList.any { it.id == A_ROOM_ID.value && it.notificationMode == userDefinedMode }
}.last() }.last()
val room = updatedState.roomList.find { it.id == A_ROOM_ID.value } val room = updatedState.roomList.find { it.id == A_ROOM_ID.value }
assertThat(room?.userDefinedNotificationMode).isEqualTo(userDefinedMode) assertThat(room?.notificationMode).isEqualTo(userDefinedMode)
cancelAndIgnoreRemainingEvents() cancelAndIgnoreRemainingEvents()
scope.cancel() scope.cancel()
} }
@ -439,8 +439,7 @@ private val aRoomListRoomSummary = RoomListRoomSummary(
id = A_ROOM_ID.value, id = A_ROOM_ID.value,
roomId = A_ROOM_ID, roomId = A_ROOM_ID,
name = A_ROOM_NAME, name = A_ROOM_NAME,
numberOfUnreadMentions = 1, hasUnread = true,
numberOfUnreadMessages = 2,
timestamp = A_FORMATTED_DATE, timestamp = A_FORMATTED_DATE,
lastMessage = "", lastMessage = "",
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),

2
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt

@ -72,7 +72,7 @@ interface MatrixClient : Closeable {
*/ */
suspend fun logout(ignoreSdkError: Boolean): String? suspend fun logout(ignoreSdkError: Boolean): String?
suspend fun loadUserDisplayName(): Result<String> suspend fun loadUserDisplayName(): Result<String>
suspend fun loadUserAvatarUrl(): Result<String?> suspend fun loadUserAvatarURLString(): Result<String?>
suspend fun getAccountManagementUrl(action: AccountManagementAction?): Result<String?> suspend fun getAccountManagementUrl(action: AccountManagementAction?): Result<String?>
suspend fun uploadMedia(mimeType: String, data: ByteArray, progressCallback: ProgressCallback?): Result<String> suspend fun uploadMedia(mimeType: String, data: ByteArray, progressCallback: ProgressCallback?): Result<String>
fun roomMembershipObserver(): RoomMembershipObserver fun roomMembershipObserver(): RoomMembershipObserver

18
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomSummary.kt

@ -36,15 +36,13 @@ sealed interface RoomSummary {
data class RoomSummaryDetails( data class RoomSummaryDetails(
val roomId: RoomId, val roomId: RoomId,
val name: String, val name: String,
val canonicalAlias: String?, val canonicalAlias: String? = null,
val isDirect: Boolean, val isDirect: Boolean,
val avatarUrl: String?, val avatarURLString: String?,
val lastMessage: RoomMessage?, val lastMessage: RoomMessage?,
val numUnreadMessages: Int, val lastMessageTimestamp: Long?,
val numUnreadMentions: Int, val unreadNotificationCount: Int,
val inviter: RoomMember?, val inviter: RoomMember? = null,
val userDefinedNotificationMode: RoomNotificationMode?, val notificationMode: RoomNotificationMode? = null,
val hasRoomCall: Boolean, val hasOngoingCall: Boolean = false,
) { )
val lastMessageTimestamp = lastMessage?.originServerTs
}

4
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/user/CurrentUser.kt

@ -19,11 +19,11 @@ package io.element.android.libraries.matrix.api.user
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
/** /**
* Get the current user, as [MatrixUser], using [MatrixClient.loadUserAvatarUrl] * Get the current user, as [MatrixUser], using [MatrixClient.loadUserAvatarURLString]
* and [MatrixClient.loadUserDisplayName]. * and [MatrixClient.loadUserDisplayName].
*/ */
suspend fun MatrixClient.getCurrentUser(): MatrixUser { suspend fun MatrixClient.getCurrentUser(): MatrixUser {
val userAvatarUrl = loadUserAvatarUrl().getOrNull() val userAvatarUrl = loadUserAvatarURLString().getOrNull()
val userDisplayName = loadUserDisplayName().getOrNull() val userDisplayName = loadUserDisplayName().getOrNull()
return MatrixUser( return MatrixUser(
userId = sessionId, userId = sessionId,

2
libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt

@ -412,7 +412,7 @@ class RustMatrixClient(
} }
} }
override suspend fun loadUserAvatarUrl(): Result<String?> = withContext(sessionDispatcher) { override suspend fun loadUserAvatarURLString(): Result<String?> = withContext(sessionDispatcher) {
runCatching { runCatching {
client.avatarUrl() client.avatarUrl()
} }

10
libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt

@ -35,13 +35,13 @@ class RoomSummaryDetailsFactory(private val roomMessageFactory: RoomMessageFacto
name = roomInfo.name ?: roomInfo.id, name = roomInfo.name ?: roomInfo.id,
canonicalAlias = roomInfo.canonicalAlias, canonicalAlias = roomInfo.canonicalAlias,
isDirect = roomInfo.isDirect, isDirect = roomInfo.isDirect,
avatarUrl = roomInfo.avatarUrl, avatarURLString = roomInfo.avatarUrl,
unreadNotificationCount = roomInfo.notificationCount.toInt(),
lastMessage = latestRoomMessage, lastMessage = latestRoomMessage,
lastMessageTimestamp = latestRoomMessage?.originServerTs,
inviter = roomInfo.inviter?.let(RoomMemberMapper::map), inviter = roomInfo.inviter?.let(RoomMemberMapper::map),
userDefinedNotificationMode = roomInfo.userDefinedNotificationMode?.let(RoomNotificationSettingsMapper::mapMode), notificationMode = roomInfo.userDefinedNotificationMode?.let(RoomNotificationSettingsMapper::mapMode),
hasRoomCall = roomInfo.hasRoomCall, hasOngoingCall = roomInfo.hasRoomCall,
numUnreadMentions = roomInfo.numUnreadMentions.toInt(),
numUnreadMessages = roomInfo.numUnreadMessages.toInt(),
) )
} }
} }

6
libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt

@ -48,7 +48,7 @@ import kotlinx.coroutines.delay
class FakeMatrixClient( class FakeMatrixClient(
override val sessionId: SessionId = A_SESSION_ID, override val sessionId: SessionId = A_SESSION_ID,
private val userDisplayName: Result<String> = Result.success(A_USER_NAME), private val userDisplayName: Result<String> = Result.success(A_USER_NAME),
private val userAvatarUrl: Result<String> = Result.success(AN_AVATAR_URL), private val userAvatarURLString: Result<String> = Result.success(AN_AVATAR_URL),
override val roomListService: RoomListService = FakeRoomListService(), override val roomListService: RoomListService = FakeRoomListService(),
override val mediaLoader: MatrixMediaLoader = FakeMediaLoader(), override val mediaLoader: MatrixMediaLoader = FakeMediaLoader(),
private val sessionVerificationService: FakeSessionVerificationService = FakeSessionVerificationService(), private val sessionVerificationService: FakeSessionVerificationService = FakeSessionVerificationService(),
@ -136,8 +136,8 @@ class FakeMatrixClient(
return userDisplayName return userDisplayName
} }
override suspend fun loadUserAvatarUrl(): Result<String?> { override suspend fun loadUserAvatarURLString(): Result<String?> {
return userAvatarUrl return userAvatarURLString
} }
override suspend fun getAccountManagementUrl(action: AccountManagementAction?): Result<String?> { override suspend fun getAccountManagementUrl(action: AccountManagementAction?): Result<String?> {

37
libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt

@ -19,7 +19,6 @@ package io.element.android.libraries.matrix.test.room
import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.api.room.message.RoomMessage import io.element.android.libraries.matrix.api.room.message.RoomMessage
import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.api.roomlist.RoomSummary
@ -35,48 +34,42 @@ fun aRoomSummaryFilled(
roomId: RoomId = A_ROOM_ID, roomId: RoomId = A_ROOM_ID,
name: String = A_ROOM_NAME, name: String = A_ROOM_NAME,
isDirect: Boolean = false, isDirect: Boolean = false,
avatarUrl: String? = null, avatarURLString: String? = null,
lastMessage: RoomMessage? = aRoomMessage(), lastMessage: RoomMessage? = aRoomMessage(),
numUnreadMentions: Int = 1, lastMessageTimestamp: Long? = null,
numUnreadMessages: Int = 2, unreadNotificationCount: Int = 2,
notificationMode: RoomNotificationMode? = null, notificationMode: RoomNotificationMode? = null,
) = RoomSummary.Filled( ) = RoomSummary.Filled(
aRoomSummaryDetails( aRoomSummaryDetail(
roomId = roomId, roomId = roomId,
name = name, name = name,
isDirect = isDirect, isDirect = isDirect,
avatarUrl = avatarUrl, avatarURLString = avatarURLString,
lastMessage = lastMessage, lastMessage = lastMessage,
numUnreadMentions = numUnreadMentions, lastMessageTimestamp = lastMessageTimestamp,
numUnreadMessages = numUnreadMessages, unreadNotificationCount = unreadNotificationCount,
notificationMode = notificationMode, notificationMode = notificationMode,
) )
) )
fun aRoomSummaryDetails( fun aRoomSummaryDetail(
roomId: RoomId = A_ROOM_ID, roomId: RoomId = A_ROOM_ID,
name: String = A_ROOM_NAME, name: String = A_ROOM_NAME,
isDirect: Boolean = false, isDirect: Boolean = false,
avatarUrl: String? = null, avatarURLString: String? = null,
lastMessage: RoomMessage? = aRoomMessage(), lastMessage: RoomMessage? = aRoomMessage(),
lastMessageTimestamp: Long? = null,
unreadNotificationCount: Int = 2,
notificationMode: RoomNotificationMode? = null, notificationMode: RoomNotificationMode? = null,
inviter: RoomMember? = null,
canonicalAlias: String? = null,
hasOngoingCall: Boolean = false,
numUnreadMentions: Int = 0,
numUnreadMessages: Int = 0,
) = RoomSummaryDetails( ) = RoomSummaryDetails(
roomId = roomId, roomId = roomId,
name = name, name = name,
isDirect = isDirect, isDirect = isDirect,
avatarUrl = avatarUrl, avatarURLString = avatarURLString,
lastMessage = lastMessage, lastMessage = lastMessage,
userDefinedNotificationMode = notificationMode, lastMessageTimestamp = lastMessageTimestamp,
canonicalAlias = canonicalAlias, unreadNotificationCount = unreadNotificationCount,
inviter = inviter, notificationMode = notificationMode
hasRoomCall = hasOngoingCall,
numUnreadMentions = numUnreadMentions,
numUnreadMessages = numUnreadMessages,
) )
fun aRoomMessage( fun aRoomMessage(

43
libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedRoom.kt

@ -44,9 +44,6 @@ import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Surface import io.element.android.libraries.designsystem.theme.components.Surface
import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.api.room.message.RoomMessage
import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
@ -63,7 +60,7 @@ fun SelectedRoom(
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Avatar(AvatarData(roomSummary.roomId.value, roomSummary.name, roomSummary.avatarUrl, AvatarSize.SelectedRoom)) Avatar(AvatarData(roomSummary.roomId.value, roomSummary.name, roomSummary.avatarURLString, AvatarSize.SelectedRoom))
Text( Text(
text = roomSummary.name, text = roomSummary.name,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
@ -97,33 +94,17 @@ fun SelectedRoom(
@Composable @Composable
internal fun SelectedRoomPreview() = ElementPreview { internal fun SelectedRoomPreview() = ElementPreview {
SelectedRoom( SelectedRoom(
roomSummary = aRoomSummaryDetails(), roomSummary = RoomSummaryDetails(
roomId = RoomId("!room:domain"),
name = "roomName",
canonicalAlias = null,
isDirect = true,
avatarURLString = null,
lastMessage = null,
lastMessageTimestamp = null,
unreadNotificationCount = 0,
inviter = null,
),
onRoomRemoved = {}, onRoomRemoved = {},
) )
} }
fun aRoomSummaryDetails(
roomId: RoomId = RoomId("!room:domain"),
name: String = "roomName",
canonicalAlias: String? = null,
isDirect: Boolean = true,
avatarUrl: String? = null,
lastMessage: RoomMessage? = null,
inviter: RoomMember? = null,
notificationMode: RoomNotificationMode? = null,
hasOngoingCall: Boolean = false,
numUnreadMentions: Int = 0,
numUnreadMessages: Int = 0,
) = RoomSummaryDetails(
roomId = roomId,
name = name,
canonicalAlias = canonicalAlias,
isDirect = isDirect,
avatarUrl = avatarUrl,
lastMessage = lastMessage,
inviter = inviter,
userDefinedNotificationMode = notificationMode,
hasRoomCall = hasOngoingCall,
numUnreadMentions = numUnreadMentions,
numUnreadMessages = numUnreadMessages,
)

2
libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotificationDrawerManager.kt

@ -297,7 +297,7 @@ class DefaultNotificationDrawerManager @Inject constructor(
operation = { operation = {
// myUserDisplayName cannot be empty else NotificationCompat.MessagingStyle() will crash // myUserDisplayName cannot be empty else NotificationCompat.MessagingStyle() will crash
val myUserDisplayName = client.loadUserDisplayName().getOrNull() ?: sessionId.value val myUserDisplayName = client.loadUserDisplayName().getOrNull() ?: sessionId.value
val userAvatarUrl = client.loadUserAvatarUrl().getOrNull() val userAvatarUrl = client.loadUserAvatarURLString().getOrNull()
MatrixUser( MatrixUser(
userId = sessionId, userId = sessionId,
displayName = myUserDisplayName, displayName = myUserDisplayName,

31
libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectStateProvider.kt

@ -19,8 +19,9 @@ package io.element.android.libraries.roomselect.impl
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.message.RoomMessage
import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails
import io.element.android.libraries.matrix.ui.components.aRoomSummaryDetails
import io.element.android.libraries.roomselect.api.RoomSelectMode import io.element.android.libraries.roomselect.api.RoomSelectMode
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
@ -40,7 +41,7 @@ open class RoomSelectStateProvider : PreviewParameterProvider<RoomSelectState> {
resultState = SearchBarResultState.Results(aForwardMessagesRoomList()), resultState = SearchBarResultState.Results(aForwardMessagesRoomList()),
query = "Test", query = "Test",
isSearchActive = true, isSearchActive = true,
selectedRooms = persistentListOf(aRoomSummaryDetails(roomId = RoomId("!room2:domain"))) selectedRooms = persistentListOf(aRoomDetailsState(roomId = RoomId("!room2:domain")))
), ),
// Add other states here // Add other states here
) )
@ -61,10 +62,32 @@ private fun aRoomSelectState(
) )
private fun aForwardMessagesRoomList() = persistentListOf( private fun aForwardMessagesRoomList() = persistentListOf(
aRoomSummaryDetails(), aRoomDetailsState(),
aRoomSummaryDetails( aRoomDetailsState(
roomId = RoomId("!room2:domain"), roomId = RoomId("!room2:domain"),
name = "Room with alias", name = "Room with alias",
canonicalAlias = "#alias:example.org", canonicalAlias = "#alias:example.org",
), ),
) )
private fun aRoomDetailsState(
roomId: RoomId = RoomId("!room:domain"),
name: String = "roomName",
canonicalAlias: String? = null,
isDirect: Boolean = true,
avatarURLString: String? = null,
lastMessage: RoomMessage? = null,
lastMessageTimestamp: Long? = null,
unreadNotificationCount: Int = 0,
inviter: RoomMember? = null,
) = RoomSummaryDetails(
roomId = roomId,
name = name,
canonicalAlias = canonicalAlias,
isDirect = isDirect,
avatarURLString = avatarURLString,
lastMessage = lastMessage,
lastMessageTimestamp = lastMessageTimestamp,
unreadNotificationCount = unreadNotificationCount,
inviter = inviter,
)

2
libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectView.kt

@ -222,7 +222,7 @@ private fun RoomSummaryView(
avatarData = AvatarData( avatarData = AvatarData(
id = summary.roomId.value, id = summary.roomId.value,
name = summary.name, name = summary.name,
url = summary.avatarUrl, url = summary.avatarURLString,
size = AvatarSize.RoomSelectRoomListItem, size = AvatarSize.RoomSelectRoomListItem,
), ),
) )

8
libraries/roomselect/impl/src/test/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenterTests.kt

@ -24,7 +24,7 @@ import io.element.android.libraries.roomselect.api.RoomSelectMode
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.api.roomlist.RoomSummary
import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.room.aRoomSummaryDetails import io.element.android.libraries.matrix.test.room.aRoomSummaryDetail
import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService
import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.WarmUpRule
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
@ -73,7 +73,7 @@ class RoomSelectPresenterTests {
@Test @Test
fun `present - update query`() = runTest { fun `present - update query`() = runTest {
val roomListService = FakeRoomListService().apply { val roomListService = FakeRoomListService().apply {
postAllRooms(listOf(RoomSummary.Filled(aRoomSummaryDetails()))) postAllRooms(listOf(RoomSummary.Filled(aRoomSummaryDetail())))
} }
val client = FakeMatrixClient(roomListService = roomListService) val client = FakeMatrixClient(roomListService = roomListService)
val presenter = aPresenter(client = client) val presenter = aPresenter(client = client)
@ -81,7 +81,7 @@ class RoomSelectPresenterTests {
presenter.present() presenter.present()
}.test { }.test {
val initialState = awaitItem() val initialState = awaitItem()
assertThat(awaitItem().resultState as? SearchBarResultState.Results).isEqualTo(SearchBarResultState.Results(listOf(aRoomSummaryDetails()))) assertThat(awaitItem().resultState as? SearchBarResultState.Results).isEqualTo(SearchBarResultState.Results(listOf(aRoomSummaryDetail())))
initialState.eventSink(RoomSelectEvents.UpdateQuery("string not contained")) initialState.eventSink(RoomSelectEvents.UpdateQuery("string not contained"))
assertThat(awaitItem().query).isEqualTo("string not contained") assertThat(awaitItem().query).isEqualTo("string not contained")
@ -97,7 +97,7 @@ class RoomSelectPresenterTests {
}.test { }.test {
val initialState = awaitItem() val initialState = awaitItem()
skipItems(1) skipItems(1)
val summary = aRoomSummaryDetails() val summary = aRoomSummaryDetail()
initialState.eventSink(RoomSelectEvents.SetSelectedRoom(summary)) initialState.eventSink(RoomSelectEvents.SetSelectedRoom(summary))
assertThat(awaitItem().selectedRooms).isEqualTo(persistentListOf(summary)) assertThat(awaitItem().selectedRooms).isEqualTo(persistentListOf(summary))

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_0,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_10,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_11,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_12,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_13,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_14,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_15,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_16,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_17,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_18,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_19,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_2,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_20,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_21,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_3,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_4,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_5,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_6,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_7,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_8,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Day-8_8_null_9,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_0,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_10,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_11,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_12,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_13,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_14,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_15,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_16,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_17,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_18,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_19,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_2,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_20,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_21,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_3,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_4,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_5,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_6,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_7,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_8,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.components_RoomSummaryRow_null_RoomSummaryRow-Night-8_9_null_9,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.
Loading…
Cancel
Save