diff --git a/appicon/enterprise/src/main/res/mipmap-hdpi/ic_launcher_background_enterprise.webp b/appicon/enterprise/src/main/res/mipmap-hdpi/ic_launcher_background_enterprise.webp index f051ae3c81..45f7756748 100644 Binary files a/appicon/enterprise/src/main/res/mipmap-hdpi/ic_launcher_background_enterprise.webp and b/appicon/enterprise/src/main/res/mipmap-hdpi/ic_launcher_background_enterprise.webp differ diff --git a/appicon/enterprise/src/main/res/mipmap-mdpi/ic_launcher_background_enterprise.webp b/appicon/enterprise/src/main/res/mipmap-mdpi/ic_launcher_background_enterprise.webp index 27d9d1db19..937dbf1c5d 100644 Binary files a/appicon/enterprise/src/main/res/mipmap-mdpi/ic_launcher_background_enterprise.webp and b/appicon/enterprise/src/main/res/mipmap-mdpi/ic_launcher_background_enterprise.webp differ diff --git a/appicon/enterprise/src/main/res/mipmap-xhdpi/ic_launcher_background_enterprise.webp b/appicon/enterprise/src/main/res/mipmap-xhdpi/ic_launcher_background_enterprise.webp index 4dbc6db066..f73e1d5ff4 100644 Binary files a/appicon/enterprise/src/main/res/mipmap-xhdpi/ic_launcher_background_enterprise.webp and b/appicon/enterprise/src/main/res/mipmap-xhdpi/ic_launcher_background_enterprise.webp differ diff --git a/appicon/enterprise/src/main/res/mipmap-xxhdpi/ic_launcher_background_enterprise.webp b/appicon/enterprise/src/main/res/mipmap-xxhdpi/ic_launcher_background_enterprise.webp index b635d5cbb5..65027bb480 100644 Binary files a/appicon/enterprise/src/main/res/mipmap-xxhdpi/ic_launcher_background_enterprise.webp and b/appicon/enterprise/src/main/res/mipmap-xxhdpi/ic_launcher_background_enterprise.webp differ diff --git a/appicon/enterprise/src/main/res/mipmap-xxhdpi/ic_launcher_foreground_enterprise.webp b/appicon/enterprise/src/main/res/mipmap-xxhdpi/ic_launcher_foreground_enterprise.webp index 2250307a03..90b491a343 100644 Binary files a/appicon/enterprise/src/main/res/mipmap-xxhdpi/ic_launcher_foreground_enterprise.webp and b/appicon/enterprise/src/main/res/mipmap-xxhdpi/ic_launcher_foreground_enterprise.webp differ diff --git a/appicon/enterprise/src/main/res/mipmap-xxxhdpi/ic_launcher_background_enterprise.webp b/appicon/enterprise/src/main/res/mipmap-xxxhdpi/ic_launcher_background_enterprise.webp index b5cb68c7bb..7ae770c812 100644 Binary files a/appicon/enterprise/src/main/res/mipmap-xxxhdpi/ic_launcher_background_enterprise.webp and b/appicon/enterprise/src/main/res/mipmap-xxxhdpi/ic_launcher_background_enterprise.webp differ diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesPresenterTest.kt index e30011999f..ffa100d95e 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesPresenterTest.kt @@ -25,7 +25,7 @@ import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomId 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.aRoomSummaryDetails +import io.element.android.libraries.matrix.test.room.aRoomSummary import io.element.android.libraries.matrix.test.timeline.FakeTimeline import io.element.android.libraries.matrix.test.timeline.LiveTimelineProvider import io.element.android.tests.testutils.WarmUpRule @@ -64,7 +64,7 @@ class ForwardMessagesPresenterTest { presenter.present() }.test { skipItems(1) - val summary = aRoomSummaryDetails() + val summary = aRoomSummary() presenter.onRoomSelected(listOf(summary.roomId)) val forwardingState = awaitItem() assertThat(forwardingState.forwardAction.isLoading()).isTrue() @@ -88,7 +88,7 @@ class ForwardMessagesPresenterTest { presenter.present() }.test { skipItems(1) - val summary = aRoomSummaryDetails() + val summary = aRoomSummary() presenter.onRoomSelected(listOf(summary.roomId)) skipItems(1) val failedForwardState = awaitItem() diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingPresenter.kt index 3f1f62aafc..36f4b8f00b 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingPresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingPresenter.kt @@ -66,7 +66,7 @@ class EditDefaultNotificationSettingPresenter @AssistedInject constructor( val changeNotificationSettingAction: MutableState> = remember { mutableStateOf(AsyncAction.Uninitialized) } - val roomsWithUserDefinedMode: MutableState> = remember { + val roomsWithUserDefinedMode: MutableState> = remember { mutableStateOf(listOf()) } @@ -115,7 +115,7 @@ class EditDefaultNotificationSettingPresenter @AssistedInject constructor( .launchIn(this) } - private fun CoroutineScope.observeRoomSummaries(roomsWithUserDefinedMode: MutableState>) { + private fun CoroutineScope.observeRoomSummaries(roomsWithUserDefinedMode: MutableState>) { roomListService.allRooms .summaries .onEach { @@ -126,18 +126,18 @@ class EditDefaultNotificationSettingPresenter @AssistedInject constructor( private fun CoroutineScope.updateRoomsWithUserDefinedMode( summaries: List, - roomsWithUserDefinedMode: MutableState> + roomsWithUserDefinedMode: MutableState> ) = launch { val roomWithUserDefinedRules: Set = notificationSettingsService.getRoomsWithUserDefinedRules().getOrThrow().toSet() val sortedSummaries = summaries - .filterIsInstance() + .filterIsInstance() .filter { - val room = matrixClient.getRoom(it.details.roomId) ?: return@filter false - roomWithUserDefinedRules.contains(it.identifier()) && isOneToOne == room.isOneToOne + val room = matrixClient.getRoom(it.roomId) ?: return@filter false + roomWithUserDefinedRules.contains(it.roomId.value) && isOneToOne == room.isOneToOne } // locale sensitive sorting - .sortedWith(compareBy(Collator.getInstance()) { it.details.name }) + .sortedWith(compareBy(Collator.getInstance()) { it.name }) roomsWithUserDefinedMode.value = sortedSummaries } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingState.kt index 68b29232b0..99d7ccbf79 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingState.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingState.kt @@ -24,7 +24,7 @@ import kotlinx.collections.immutable.ImmutableList data class EditDefaultNotificationSettingState( val isOneToOne: Boolean, val mode: RoomNotificationMode?, - val roomsWithUserDefinedMode: ImmutableList, + val roomsWithUserDefinedMode: ImmutableList, val changeNotificationSettingAction: AsyncAction, val displayMentionsOnlyDisclaimer: Boolean, val eventSink: (EditDefaultNotificationSettingStateEvents) -> Unit, diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingStateProvider.kt index 703050227e..293375abfe 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingStateProvider.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingStateProvider.kt @@ -20,7 +20,6 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.RoomNotificationMode -import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.ui.components.aRoomSummaryDetails import kotlinx.collections.immutable.persistentListOf @@ -53,13 +52,11 @@ private fun anEditDefaultNotificationSettingsState( private fun aRoomSummary( name: String?, -) = RoomSummary.Filled( - aRoomSummaryDetails( - roomId = RoomId("!roomId:domain"), - name = name, - avatarUrl = null, - isDirect = false, - lastMessage = null, - notificationMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY, - ) +) = aRoomSummaryDetails( + roomId = RoomId("!roomId:domain"), + name = name, + avatarUrl = null, + isDirect = false, + lastMessage = null, + notificationMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY, ) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt index c69970bd3f..2adf34a98b 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt @@ -89,7 +89,7 @@ fun EditDefaultNotificationSettingView( if (state.roomsWithUserDefinedMode.isNotEmpty()) { PreferenceCategory(title = stringResource(id = R.string.screen_notification_settings_edit_custom_settings_section_title)) { state.roomsWithUserDefinedMode.forEach { summary -> - val subtitle = when (summary.details.userDefinedNotificationMode) { + val subtitle = when (summary.userDefinedNotificationMode) { RoomNotificationMode.ALL_MESSAGES -> stringResource(id = R.string.screen_notification_settings_edit_mode_all_messages) RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY -> { stringResource(id = R.string.screen_notification_settings_edit_mode_mentions_and_keywords) @@ -99,7 +99,7 @@ fun EditDefaultNotificationSettingView( } ListItem( headlineContent = { - val roomName = summary.details.name + val roomName = summary.name Text( text = roomName ?: stringResource(id = CommonStrings.common_no_room_name), fontStyle = FontStyle.Italic.takeIf { roomName == null } @@ -110,14 +110,14 @@ fun EditDefaultNotificationSettingView( }, leadingContent = ListItemContent.Custom { CompositeAvatar( - avatarData = summary.details.getAvatarData(size = AvatarSize.CustomRoomNotificationSetting), - heroes = summary.details.heroes.map { user -> + avatarData = summary.getAvatarData(size = AvatarSize.CustomRoomNotificationSetting), + heroes = summary.heroes.map { user -> user.getAvatarData(size = AvatarSize.CustomRoomNotificationSetting) }.toPersistentList() ) }, onClick = { - openRoomNotificationSettings(summary.details.roomId) + openRoomNotificationSettings(summary.roomId) } ) } diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/notifications/EditDefaultNotificationSettingsPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/notifications/EditDefaultNotificationSettingsPresenterTest.kt index 0d5921047c..784bec715b 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/notifications/EditDefaultNotificationSettingsPresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/notifications/EditDefaultNotificationSettingsPresenterTest.kt @@ -23,13 +23,12 @@ import com.google.common.truth.Truth.assertThat import io.element.android.features.preferences.impl.notifications.edit.EditDefaultNotificationSettingPresenter import io.element.android.features.preferences.impl.notifications.edit.EditDefaultNotificationSettingStateEvents import io.element.android.libraries.matrix.api.room.RoomNotificationMode -import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_THROWABLE import io.element.android.libraries.matrix.test.FakeMatrixClient 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.aRoomSummaryDetails +import io.element.android.libraries.matrix.test.room.aRoomSummary import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService import io.element.android.tests.testutils.awaitLastSequentialItem import io.element.android.tests.testutils.consumeItemsUntilPredicate @@ -72,11 +71,11 @@ class EditDefaultNotificationSettingsPresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { - roomListService.postAllRooms(listOf(RoomSummary.Filled(aRoomSummaryDetails(notificationMode = RoomNotificationMode.ALL_MESSAGES)))) + roomListService.postAllRooms(listOf(aRoomSummary(notificationMode = RoomNotificationMode.ALL_MESSAGES))) val loadedState = consumeItemsUntilPredicate { state -> - state.roomsWithUserDefinedMode.any { it.details.userDefinedNotificationMode == RoomNotificationMode.ALL_MESSAGES } + state.roomsWithUserDefinedMode.any { it.userDefinedNotificationMode == RoomNotificationMode.ALL_MESSAGES } }.last() - assertThat(loadedState.roomsWithUserDefinedMode.any { it.details.userDefinedNotificationMode == RoomNotificationMode.ALL_MESSAGES }).isTrue() + assertThat(loadedState.roomsWithUserDefinedMode.any { it.userDefinedNotificationMode == RoomNotificationMode.ALL_MESSAGES }).isTrue() } } diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListEvents.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListEvents.kt index aa1e8e2832..7919fd2274 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListEvents.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListEvents.kt @@ -20,7 +20,6 @@ import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.libraries.matrix.api.core.RoomId sealed interface RoomListEvents { - data class UpdateVisibleRange(val range: IntRange) : RoomListEvents data object DismissRequestVerificationPrompt : RoomListEvents data object DismissRecoveryKeyPrompt : RoomListEvents data object ToggleSearchResults : RoomListEvents diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt index e85dcac2ee..8d838441e6 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt @@ -78,8 +78,6 @@ import kotlinx.coroutines.flow.takeWhile import kotlinx.coroutines.launch import javax.inject.Inject -private const val EXTENDED_RANGE_SIZE = 40 - class RoomListPresenter @Inject constructor( private val client: MatrixClient, private val networkMonitor: NetworkMonitor, @@ -124,7 +122,6 @@ class RoomListPresenter @Inject constructor( fun handleEvents(event: RoomListEvents) { when (event) { - is RoomListEvents.UpdateVisibleRange -> updateVisibleRange(event.range) RoomListEvents.DismissRequestVerificationPrompt -> securityBannerDismissed = true RoomListEvents.DismissRecoveryKeyPrompt -> securityBannerDismissed = true RoomListEvents.ToggleSearchResults -> searchState.eventSink(RoomListSearchEvents.ToggleSearchVisibility) @@ -286,16 +283,6 @@ class RoomListPresenter @Inject constructor( } } } - - private fun updateVisibleRange(range: IntRange) { - if (range.isEmpty()) return - val midExtendedRangeSize = EXTENDED_RANGE_SIZE / 2 - val extendedRangeStart = (range.first - midExtendedRangeSize).coerceAtLeast(0) - // Safe to give bigger size than room list - val extendedRangeEnd = range.last + midExtendedRangeSize - val extendedRange = IntRange(extendedRangeStart, extendedRangeEnd) - client.roomListService.updateAllRoomsVisibleRange(extendedRange) - } } @VisibleForTesting diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListContentView.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListContentView.kt index 377606cacf..ad4a7b0c26 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListContentView.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListContentView.kt @@ -30,17 +30,11 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.runtime.Composable -import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.input.nestedscroll.NestedScrollConnection -import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.unit.Velocity import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons @@ -171,25 +165,9 @@ private fun RoomsViewList( modifier: Modifier = Modifier, ) { val lazyListState = rememberLazyListState() - val visibleRange by remember { - derivedStateOf { - val layoutInfo = lazyListState.layoutInfo - val firstItemIndex = layoutInfo.visibleItemsInfo.firstOrNull()?.index ?: 0 - val size = layoutInfo.visibleItemsInfo.size - firstItemIndex until firstItemIndex + size - } - } - val nestedScrollConnection = remember { - object : NestedScrollConnection { - override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity { - eventSink(RoomListEvents.UpdateVisibleRange(visibleRange)) - return super.onPostFling(consumed, available) - } - } - } LazyColumn( state = lazyListState, - modifier = modifier.nestedScroll(nestedScrollConnection), + modifier = modifier, // FAB height is 56dp, bottom padding is 16dp, we add 8dp as extra margin -> 56+16+8 = 80 contentPadding = PaddingValues(bottom = 80.dp) ) { diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListDataSource.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListDataSource.kt index e2508446e7..21d3da1eef 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListDataSource.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListDataSource.kt @@ -54,7 +54,7 @@ class RoomListDataSource @Inject constructor( private val lock = Mutex() private val diffCache = MutableListDiffCache() private val diffCacheUpdater = DiffCacheUpdater(diffCache = diffCache, detectMoves = true) { old, new -> - old?.identifier() == new?.identifier() + old?.roomId == new?.roomId } fun launchIn(coroutineScope: CoroutineScope) { @@ -96,12 +96,8 @@ class RoomListDataSource @Inject constructor( } private fun buildAndCacheItem(roomSummaries: List, index: Int): RoomListRoomSummary? { - val roomListRoomSummary = when (val roomSummary = roomSummaries.getOrNull(index)) { - is RoomSummary.Empty -> RoomListRoomSummaryFactory.createPlaceholder(roomSummary.identifier) - is RoomSummary.Filled -> roomListRoomSummaryFactory.create(roomSummary) - null -> null - } - diffCache[index] = roomListRoomSummary - return roomListRoomSummary + val roomListSummary = roomSummaries.getOrNull(index)?.let { roomListRoomSummaryFactory.create(it) } + diffCache[index] = roomListSummary + return roomListSummary } } diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListRoomSummaryFactory.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListRoomSummaryFactory.kt index 18ba73bdc1..3cde0908b4 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListRoomSummaryFactory.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListRoomSummaryFactory.kt @@ -20,16 +20,12 @@ import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.features.roomlist.impl.model.RoomSummaryDisplayType import io.element.android.libraries.core.extensions.orEmpty import io.element.android.libraries.dateformatter.api.LastMessageTimestampFormatter -import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.eventformatter.api.RoomLastMessageFormatter -import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.roomlist.RoomSummary -import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.matrix.ui.model.toInviteSender -import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import javax.inject.Inject @@ -37,37 +33,7 @@ class RoomListRoomSummaryFactory @Inject constructor( private val lastMessageTimestampFormatter: LastMessageTimestampFormatter, private val roomLastMessageFormatter: RoomLastMessageFormatter, ) { - companion object { - fun createPlaceholder(id: String): RoomListRoomSummary { - return RoomListRoomSummary( - id = id, - roomId = RoomId(id), - displayType = RoomSummaryDisplayType.PLACEHOLDER, - name = "Short name", - timestamp = "hh:mm", - lastMessage = "Last message for placeholder", - avatarData = AvatarData(id, "S", size = AvatarSize.RoomListItem), - numberOfUnreadMessages = 0, - numberOfUnreadMentions = 0, - numberOfUnreadNotifications = 0, - isMarkedUnread = false, - userDefinedNotificationMode = null, - hasRoomCall = false, - isDirect = false, - isFavorite = false, - inviteSender = null, - isDm = false, - canonicalAlias = null, - heroes = persistentListOf(), - ) - } - } - - fun create(roomSummary: RoomSummary.Filled): RoomListRoomSummary { - return create(roomSummary.details) - } - - private fun create(details: RoomSummaryDetails): RoomListRoomSummary { + fun create(details: RoomSummary): RoomListRoomSummary { val avatarData = details.getAvatarData(size = AvatarSize.RoomListItem) return RoomListRoomSummary( id = details.roomId.value, diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearchDataSource.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearchDataSource.kt index 165c92bff8..286254952c 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearchDataSource.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearchDataSource.kt @@ -22,7 +22,6 @@ import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.matrix.api.roomlist.RoomList import io.element.android.libraries.matrix.api.roomlist.RoomListFilter import io.element.android.libraries.matrix.api.roomlist.RoomListService -import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.api.roomlist.loadAllIncrementally import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.toPersistentList @@ -48,7 +47,6 @@ class RoomListSearchDataSource @Inject constructor( val roomSummaries: Flow> = roomList.filteredSummaries .map { roomSummaries -> roomSummaries - .filterIsInstance() .map(roomSummaryFactory::create) .toPersistentList() } diff --git a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTest.kt b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTest.kt index 919eb87045..b70db9c87b 100644 --- a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTest.kt +++ b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTest.kt @@ -68,7 +68,7 @@ import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService 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.aRoomInfo -import io.element.android.libraries.matrix.test.room.aRoomSummaryFilled +import io.element.android.libraries.matrix.test.room.aRoomSummary import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService import io.element.android.libraries.matrix.test.sync.FakeSyncService import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService @@ -183,7 +183,7 @@ class RoomListPresenterTest { roomListService.postAllRoomsLoadingState(RoomList.LoadingState.Loaded(1)) roomListService.postAllRooms( listOf( - aRoomSummaryFilled( + aRoomSummary( numUnreadMentions = 1, numUnreadMessages = 2, ) @@ -203,48 +203,6 @@ class RoomListPresenterTest { } } - @Test - fun `present - update visible range`() = runTest { - val roomListService = FakeRoomListService() - val matrixClient = FakeMatrixClient( - roomListService = roomListService - ) - val scope = CoroutineScope(coroutineContext + SupervisorJob()) - val presenter = createRoomListPresenter(client = matrixClient, coroutineScope = scope) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - roomListService.postAllRooms(listOf(aRoomSummaryFilled())) - val loadedState = awaitItem() - // check initial value - assertThat(roomListService.latestSlidingSyncRange).isNull() - // Test empty range - loadedState.eventSink.invoke(RoomListEvents.UpdateVisibleRange(IntRange(1, 0))) - assertThat(roomListService.latestSlidingSyncRange).isNull() - // Update visible range and check that range is transmitted to the SDK after computation - loadedState.eventSink.invoke(RoomListEvents.UpdateVisibleRange(IntRange(0, 0))) - assertThat(roomListService.latestSlidingSyncRange) - .isEqualTo(IntRange(0, 20)) - loadedState.eventSink.invoke(RoomListEvents.UpdateVisibleRange(IntRange(0, 1))) - assertThat(roomListService.latestSlidingSyncRange) - .isEqualTo(IntRange(0, 21)) - loadedState.eventSink.invoke(RoomListEvents.UpdateVisibleRange(IntRange(19, 29))) - assertThat(roomListService.latestSlidingSyncRange) - .isEqualTo(IntRange(0, 49)) - loadedState.eventSink.invoke(RoomListEvents.UpdateVisibleRange(IntRange(49, 59))) - assertThat(roomListService.latestSlidingSyncRange) - .isEqualTo(IntRange(29, 79)) - loadedState.eventSink.invoke(RoomListEvents.UpdateVisibleRange(IntRange(149, 159))) - assertThat(roomListService.latestSlidingSyncRange) - .isEqualTo(IntRange(129, 179)) - loadedState.eventSink.invoke(RoomListEvents.UpdateVisibleRange(IntRange(149, 259))) - assertThat(roomListService.latestSlidingSyncRange) - .isEqualTo(IntRange(129, 279)) - cancelAndIgnoreRemainingEvents() - scope.cancel() - } - } - @Test fun `present - handle DismissRequestVerificationPrompt`() = runTest { val scope = CoroutineScope(context = coroutineContext + SupervisorJob()) @@ -449,7 +407,7 @@ class RoomListPresenterTest { val notificationSettingsService = FakeNotificationSettingsService() val roomListService = FakeRoomListService() roomListService.postAllRoomsLoadingState(RoomList.LoadingState.Loaded(1)) - roomListService.postAllRooms(listOf(aRoomSummaryFilled(notificationMode = userDefinedMode))) + roomListService.postAllRooms(listOf(aRoomSummary(notificationMode = userDefinedMode))) val matrixClient = FakeMatrixClient( roomListService = roomListService, notificationSettingsService = notificationSettingsService @@ -594,7 +552,7 @@ class RoomListPresenterTest { val matrixClient = FakeMatrixClient( roomListService = roomListService, ) - val roomSummary = aRoomSummaryFilled( + val roomSummary = aRoomSummary( currentUserMembership = CurrentUserMembership.INVITED ) roomListService.postAllRoomsLoadingState(RoomList.LoadingState.Loaded(1)) @@ -610,7 +568,7 @@ class RoomListPresenterTest { }.last() val roomListRoomSummary = state.contentAsRooms().summaries.first { - it.id == roomSummary.identifier() + it.id == roomSummary.roomId.value } state.eventSink(RoomListEvents.AcceptInvite(roomListRoomSummary)) state.eventSink(RoomListEvents.DeclineInvite(roomListRoomSummary)) diff --git a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearchPresenterTest.kt b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearchPresenterTest.kt index 89c843e222..d1fe481e77 100644 --- a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearchPresenterTest.kt +++ b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearchPresenterTest.kt @@ -28,8 +28,7 @@ import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.api.roomlist.RoomListFilter import io.element.android.libraries.matrix.api.roomlist.RoomListService -import io.element.android.libraries.matrix.api.roomlist.RoomSummary -import io.element.android.libraries.matrix.test.room.aRoomSummaryFilled +import io.element.android.libraries.matrix.test.room.aRoomSummary import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.coroutines.test.TestScope @@ -117,10 +116,7 @@ class RoomListSearchPresenterTest { assertThat(state.results).isEmpty() } roomListService.postAllRooms( - listOf( - RoomSummary.Empty("1"), - aRoomSummaryFilled() - ) + listOf(aRoomSummary()) ) awaitItem().let { state -> assertThat(state.results).hasSize(1) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8acaa7a1a5..8ca82f8679 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -162,7 +162,7 @@ jsoup = "org.jsoup:jsoup:1.17.2" appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" } molecule-runtime = "app.cash.molecule:molecule-runtime:2.0.0" timber = "com.jakewharton.timber:timber:5.0.1" -matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.30" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.31" matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" } matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" } sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomListService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomListService.kt index ca2d21a706..4f9c4c0c5a 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomListService.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomListService.kt @@ -59,12 +59,6 @@ interface RoomListService { */ val allRooms: DynamicRoomList - /** - * Will set the visible range of all rooms. - * This is useful to load more data when the user scrolls down. - */ - fun updateAllRoomsVisibleRange(range: IntRange) - /** * The sync indicator as a flow. */ diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomSummary.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomSummary.kt index 1e38b00b61..6841af9721 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomSummary.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomSummary.kt @@ -24,19 +24,7 @@ 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.user.MatrixUser -sealed interface RoomSummary { - data class Empty(val identifier: String) : RoomSummary - data class Filled(val details: RoomSummaryDetails) : RoomSummary - - fun identifier(): String { - return when (this) { - is Empty -> identifier - is Filled -> details.roomId.value - } - } -} - -data class RoomSummaryDetails( +data class RoomSummary( val roomId: RoomId, val name: String?, val canonicalAlias: RoomAlias?, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index c8574a7934..453bd51cba 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -311,7 +311,7 @@ class RustMatrixClient( withTimeout(timeout) { roomListService.allRooms.summaries .filter { roomSummaries -> - roomSummaries.map { it.identifier() }.contains(roomId.value) + roomSummaries.map { it.roomId }.contains(roomId) } .first() } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListEntriesUpdateExt.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListEntriesUpdateExt.kt new file mode 100644 index 0000000000..c17b8d63c8 --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListEntriesUpdateExt.kt @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.matrix.impl.roomlist + +import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate + +internal fun RoomListEntriesUpdate.describe(): String { + return when (this) { + is RoomListEntriesUpdate.Set -> { + "Set #$index to '${value.displayName()}'" + } + is RoomListEntriesUpdate.Append -> { + "Append ${values.map { "'" + it.displayName() + "'" }}" + } + is RoomListEntriesUpdate.PushBack -> { + "PushBack '${value.displayName()}'" + } + is RoomListEntriesUpdate.PushFront -> { + "PushFront '${value.displayName()}'" + } + is RoomListEntriesUpdate.Insert -> { + "Insert at #$index: '${value.displayName()}'" + } + is RoomListEntriesUpdate.Remove -> { + "Remove #$index" + } + is RoomListEntriesUpdate.Reset -> { + "Reset all to ${values.map { "'" + it.displayName() + "'" }}" + } + RoomListEntriesUpdate.PopBack -> { + "PopBack" + } + RoomListEntriesUpdate.PopFront -> { + "PopFront" + } + RoomListEntriesUpdate.Clear -> { + "Clear" + } + is RoomListEntriesUpdate.Truncate -> { + "Truncate to $length items" + } + } +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt index d987e332c8..ad987e5cae 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt @@ -76,7 +76,7 @@ internal fun RoomListInterface.entriesFlow( } } val result = entriesWithDynamicAdapters(pageSize.toUInt(), listener) - val controller = result.controller + val controller = result.controller() controller.setFilter(initialFilterKind) roomListDynamicEvents.onEach { controllerEvents -> when (controllerEvents) { @@ -92,7 +92,8 @@ internal fun RoomListInterface.entriesFlow( } }.launchIn(this) awaitClose { - result.entriesStream.cancelAndDestroy() + result.entriesStream().cancelAndDestroy() + controller.destroy() result.destroy() } }.catch { diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilter.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilter.kt index d7f2acf87d..bc66bb6b78 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilter.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilter.kt @@ -26,21 +26,19 @@ val RoomListFilter.predicate is RoomListFilter.Any -> { _: RoomSummary -> true } RoomListFilter.None -> { _: RoomSummary -> false } RoomListFilter.Category.Group -> { roomSummary: RoomSummary -> - roomSummary is RoomSummary.Filled && !roomSummary.details.isDirect && !roomSummary.isInvited() + !roomSummary.isDirect && !roomSummary.isInvited() } RoomListFilter.Category.People -> { roomSummary: RoomSummary -> - roomSummary is RoomSummary.Filled && roomSummary.details.isDirect && !roomSummary.isInvited() + roomSummary.isDirect && !roomSummary.isInvited() } RoomListFilter.Favorite -> { roomSummary: RoomSummary -> - roomSummary is RoomSummary.Filled && roomSummary.details.isFavorite && !roomSummary.isInvited() + roomSummary.isFavorite && !roomSummary.isInvited() } RoomListFilter.Unread -> { roomSummary: RoomSummary -> - roomSummary is RoomSummary.Filled && - !roomSummary.isInvited() && - (roomSummary.details.numUnreadNotifications > 0 || roomSummary.details.isMarkedUnread) + !roomSummary.isInvited() && (roomSummary.numUnreadNotifications > 0 || roomSummary.isMarkedUnread) } is RoomListFilter.NormalizedMatchRoomName -> { roomSummary: RoomSummary -> - roomSummary is RoomSummary.Filled && roomSummary.details.name.orEmpty().contains(pattern, ignoreCase = true) + roomSummary.name.orEmpty().contains(pattern, ignoreCase = true) } RoomListFilter.Invite -> { roomSummary: RoomSummary -> roomSummary.isInvited() @@ -61,4 +59,4 @@ fun List.filter(filter: RoomListFilter): List { } } -private fun RoomSummary.isInvited() = this is RoomSummary.Filled && this.details.currentUserMembership == CurrentUserMembership.INVITED +private fun RoomSummary.isInvited() = currentUserMembership == CurrentUserMembership.INVITED diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt index f45c843694..1361d74a3d 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt @@ -18,7 +18,7 @@ package io.element.android.libraries.matrix.impl.roomlist import io.element.android.libraries.matrix.api.core.RoomAlias import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails +import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.impl.notificationsettings.RoomNotificationSettingsMapper import io.element.android.libraries.matrix.impl.room.elementHeroes import io.element.android.libraries.matrix.impl.room.map @@ -28,12 +28,12 @@ import org.matrix.rustcomponents.sdk.RoomListItem import org.matrix.rustcomponents.sdk.use class RoomSummaryDetailsFactory(private val roomMessageFactory: RoomMessageFactory = RoomMessageFactory()) { - suspend fun create(roomListItem: RoomListItem): RoomSummaryDetails { + suspend fun create(roomListItem: RoomListItem): RoomSummary { val roomInfo = roomListItem.roomInfo() val latestRoomMessage = roomListItem.latestEvent()?.use { roomMessageFactory.create(it) } - return RoomSummaryDetails( + return RoomSummary( roomId = RoomId(roomInfo.id), name = roomInfo.displayName, canonicalAlias = roomInfo.canonicalAlias?.let(::RoomAlias), diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt index 3cfd01f54c..8e4899d942 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt @@ -22,11 +22,10 @@ import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withContext import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate -import org.matrix.rustcomponents.sdk.RoomListEntry +import org.matrix.rustcomponents.sdk.RoomListItem import org.matrix.rustcomponents.sdk.RoomListServiceInterface import org.matrix.rustcomponents.sdk.use import timber.log.Timber -import java.util.UUID import kotlin.coroutines.CoroutineContext class RoomSummaryListProcessor( @@ -50,15 +49,17 @@ class RoomSummaryListProcessor( suspend fun rebuildRoomSummaries() { updateRoomSummaries { forEachIndexed { i, summary -> - this[i] = when (summary) { - is RoomSummary.Empty -> summary - is RoomSummary.Filled -> buildAndCacheRoomSummaryForIdentifier(summary.identifier()) + val result = buildAndCacheRoomSummaryForIdentifier(summary.roomId.value) + if (result != null) { + this[i] = result } } } } private suspend fun MutableList.applyUpdate(update: RoomListEntriesUpdate) { + // Remove this comment to debug changes in the room list + // Timber.d("Apply room list update: ${update.describe()}") when (update) { is RoomListEntriesUpdate.Append -> { val roomSummaries = update.values.map { @@ -104,27 +105,25 @@ class RoomSummaryListProcessor( } } - private suspend fun buildSummaryForRoomListEntry(entry: RoomListEntry): RoomSummary { - return when (entry) { - RoomListEntry.Empty -> buildEmptyRoomSummary() - is RoomListEntry.Filled -> buildAndCacheRoomSummaryForIdentifier(entry.roomId) - is RoomListEntry.Invalidated -> { - roomSummariesByIdentifier[entry.roomId] ?: buildAndCacheRoomSummaryForIdentifier(entry.roomId) - } - } + private suspend fun buildSummaryForRoomListEntry(entry: RoomListItem): RoomSummary { + return buildAndCacheRoomSummaryForRoomListItem(entry) } - private fun buildEmptyRoomSummary(): RoomSummary { - return RoomSummary.Empty(UUID.randomUUID().toString()) + private suspend fun buildAndCacheRoomSummaryForIdentifier(identifier: String): RoomSummary? { + val builtRoomSummary = roomListService.roomOrNull(identifier)?.use { roomListItem -> + buildAndCacheRoomSummaryForRoomListItem(roomListItem) + } + if (builtRoomSummary != null) { + roomSummariesByIdentifier[identifier] = builtRoomSummary + } else { + roomSummariesByIdentifier.remove(identifier) + } + return builtRoomSummary } - private suspend fun buildAndCacheRoomSummaryForIdentifier(identifier: String): RoomSummary { - val builtRoomSummary = roomListService.roomOrNull(identifier)?.use { roomListItem -> - RoomSummary.Filled( - details = roomSummaryDetailsFactory.create(roomListItem) - ) - } ?: buildEmptyRoomSummary() - roomSummariesByIdentifier[builtRoomSummary.identifier()] = builtRoomSummary + private suspend fun buildAndCacheRoomSummaryForRoomListItem(roomListItem: RoomListItem): RoomSummary { + val builtRoomSummary = roomSummaryDetailsFactory.create(roomListItem = roomListItem) + roomSummariesByIdentifier[builtRoomSummary.roomId.value] = builtRoomSummary return builtRoomSummary } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustRoomListService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustRoomListService.kt index 8b8ccc3926..d2b80a84a9 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustRoomListService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustRoomListService.kt @@ -29,10 +29,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn -import kotlinx.coroutines.launch -import org.matrix.rustcomponents.sdk.RoomListException -import org.matrix.rustcomponents.sdk.RoomListInput -import org.matrix.rustcomponents.sdk.RoomListRange import org.matrix.rustcomponents.sdk.RoomListServiceState import org.matrix.rustcomponents.sdk.RoomListServiceSyncIndicator import timber.log.Timber @@ -73,20 +69,6 @@ internal class RustRoomListService( allRooms.loadAllIncrementally(sessionCoroutineScope) } - override fun updateAllRoomsVisibleRange(range: IntRange) { - Timber.v("setVisibleRange=$range") - sessionCoroutineScope.launch { - try { - val ranges = listOf(RoomListRange(range.first.toUInt(), range.last.toUInt())) - innerRoomListService.applyInput( - RoomListInput.Viewport(ranges) - ) - } catch (exception: RoomListException) { - Timber.e(exception, "Failed updating visible range") - } - } - } - override val syncIndicator: StateFlow = innerRoomListService.syncIndicator() .map { it.toSyncIndicator() } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilterTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilterTest.kt index 02fb9cd24b..5687cd0c14 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilterTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilterTest.kt @@ -19,46 +19,31 @@ package io.element.android.libraries.matrix.impl.roomlist import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.roomlist.RoomListFilter -import io.element.android.libraries.matrix.test.room.aRoomSummaryDetails -import io.element.android.libraries.matrix.test.room.aRoomSummaryFilled +import io.element.android.libraries.matrix.test.room.aRoomSummary import kotlinx.coroutines.test.runTest import org.junit.Test class RoomListFilterTest { - private val regularRoom = aRoomSummaryFilled( - aRoomSummaryDetails( - isDirect = false - ) + private val regularRoom = aRoomSummary( + isDirect = false ) - private val directRoom = aRoomSummaryFilled( - aRoomSummaryDetails( - isDirect = true - ) + private val directRoom = aRoomSummary( + isDirect = true ) - private val favoriteRoom = aRoomSummaryFilled( - aRoomSummaryDetails( - isFavorite = true - ) + private val favoriteRoom = aRoomSummary( + isFavorite = true ) - private val markedAsUnreadRoom = aRoomSummaryFilled( - aRoomSummaryDetails( - isMarkedUnread = true - ) + private val markedAsUnreadRoom = aRoomSummary( + isMarkedUnread = true ) - private val unreadNotificationRoom = aRoomSummaryFilled( - aRoomSummaryDetails( - numUnreadNotifications = 1 - ) + private val unreadNotificationRoom = aRoomSummary( + numUnreadNotifications = 1 ) - private val roomToSearch = aRoomSummaryFilled( - aRoomSummaryDetails( - name = "Room to search" - ) + private val roomToSearch = aRoomSummary( + name = "Room to search" ) - private val invitedRoom = aRoomSummaryFilled( - aRoomSummaryDetails( - currentUserMembership = CurrentUserMembership.INVITED - ) + private val invitedRoom = aRoomSummary( + currentUserMembership = CurrentUserMembership.INVITED ) private val roomSummaries = listOf( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt index 6f42553ced..394cc5d379 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt @@ -18,23 +18,31 @@ package io.element.android.libraries.matrix.impl.roomlist import com.google.common.truth.Truth.assertThat import com.sun.jna.Pointer +import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.roomlist.RoomSummary 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_NAME +import io.element.android.libraries.matrix.test.room.aRoomSummary import io.element.android.libraries.matrix.test.room.aRoomSummaryFilled import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest import org.junit.Test +import org.matrix.rustcomponents.sdk.EventTimelineItem +import org.matrix.rustcomponents.sdk.Membership +import org.matrix.rustcomponents.sdk.NoPointer +import org.matrix.rustcomponents.sdk.RoomHero +import org.matrix.rustcomponents.sdk.RoomInfo import org.matrix.rustcomponents.sdk.RoomList import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate -import org.matrix.rustcomponents.sdk.RoomListEntry -import org.matrix.rustcomponents.sdk.RoomListInput import org.matrix.rustcomponents.sdk.RoomListItem import org.matrix.rustcomponents.sdk.RoomListServiceInterface import org.matrix.rustcomponents.sdk.RoomListServiceStateListener import org.matrix.rustcomponents.sdk.RoomListServiceSyncIndicatorListener +import org.matrix.rustcomponents.sdk.RoomMember +import org.matrix.rustcomponents.sdk.RoomNotificationMode import org.matrix.rustcomponents.sdk.TaskHandle // NOTE: this class is using a fake implementation of a Rust SDK interface which returns actual Rust objects with pointers. @@ -44,33 +52,34 @@ class RoomSummaryListProcessorTest { @Test fun `Append adds new entries at the end of the list`() = runTest { - summaries.value = listOf(aRoomSummaryFilled()) + summaries.value = listOf(aRoomSummary()) val processor = createProcessor() - processor.postUpdate(listOf(RoomListEntriesUpdate.Append(listOf(RoomListEntry.Empty, RoomListEntry.Empty, RoomListEntry.Empty)))) + val newEntry = FakeRoomListItem(A_ROOM_ID_2) + processor.postUpdate(listOf(RoomListEntriesUpdate.Append(listOf(newEntry, newEntry, newEntry)))) assertThat(summaries.value.count()).isEqualTo(4) - assertThat(summaries.value.subList(1, 4).all { it is RoomSummary.Empty }).isTrue() + assertThat(summaries.value.subList(1, 4).all { it.roomId == A_ROOM_ID_2 }).isTrue() } @Test fun `PushBack adds a new entry at the end of the list`() = runTest { summaries.value = listOf(aRoomSummaryFilled()) val processor = createProcessor() - processor.postUpdate(listOf(RoomListEntriesUpdate.PushBack(RoomListEntry.Empty))) + processor.postUpdate(listOf(RoomListEntriesUpdate.PushBack(FakeRoomListItem(A_ROOM_ID_2)))) assertThat(summaries.value.count()).isEqualTo(2) - assertThat(summaries.value.last()).isInstanceOf(RoomSummary.Empty::class.java) + assertThat(summaries.value.last().roomId).isEqualTo(A_ROOM_ID_2) } @Test fun `PushFront inserts a new entry at the start of the list`() = runTest { summaries.value = listOf(aRoomSummaryFilled()) val processor = createProcessor() - processor.postUpdate(listOf(RoomListEntriesUpdate.PushFront(RoomListEntry.Empty))) + processor.postUpdate(listOf(RoomListEntriesUpdate.PushFront(FakeRoomListItem(A_ROOM_ID_2)))) assertThat(summaries.value.count()).isEqualTo(2) - assertThat(summaries.value.first()).isInstanceOf(RoomSummary.Empty::class.java) + assertThat(summaries.value.first().roomId).isEqualTo(A_ROOM_ID_2) } @Test @@ -79,10 +88,10 @@ class RoomSummaryListProcessorTest { val processor = createProcessor() val index = 0 - processor.postUpdate(listOf(RoomListEntriesUpdate.Set(index.toUInt(), RoomListEntry.Empty))) + processor.postUpdate(listOf(RoomListEntriesUpdate.Set(index.toUInt(), FakeRoomListItem(A_ROOM_ID_2)))) assertThat(summaries.value.count()).isEqualTo(1) - assertThat(summaries.value[index]).isInstanceOf(RoomSummary.Empty::class.java) + assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID_2) } @Test @@ -91,10 +100,10 @@ class RoomSummaryListProcessorTest { val processor = createProcessor() val index = 0 - processor.postUpdate(listOf(RoomListEntriesUpdate.Insert(index.toUInt(), RoomListEntry.Empty))) + processor.postUpdate(listOf(RoomListEntriesUpdate.Insert(index.toUInt(), FakeRoomListItem(A_ROOM_ID_2)))) assertThat(summaries.value.count()).isEqualTo(2) - assertThat(summaries.value[index]).isInstanceOf(RoomSummary.Empty::class.java) + assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID_2) } @Test @@ -106,7 +115,7 @@ class RoomSummaryListProcessorTest { processor.postUpdate(listOf(RoomListEntriesUpdate.Remove(index.toUInt()))) assertThat(summaries.value.count()).isEqualTo(1) - assertThat((summaries.value[index] as RoomSummary.Filled).identifier()).isEqualTo(A_ROOM_ID_2.value) + assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID_2) } @Test @@ -118,7 +127,7 @@ class RoomSummaryListProcessorTest { processor.postUpdate(listOf(RoomListEntriesUpdate.PopBack)) assertThat(summaries.value.count()).isEqualTo(1) - assertThat((summaries.value[index] as RoomSummary.Filled).identifier()).isEqualTo(A_ROOM_ID.value) + assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID) } @Test @@ -130,7 +139,7 @@ class RoomSummaryListProcessorTest { processor.postUpdate(listOf(RoomListEntriesUpdate.PopFront)) assertThat(summaries.value.count()).isEqualTo(1) - assertThat((summaries.value[index] as RoomSummary.Filled).identifier()).isEqualTo(A_ROOM_ID_2.value) + assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID_2) } @Test @@ -152,7 +161,7 @@ class RoomSummaryListProcessorTest { processor.postUpdate(listOf(RoomListEntriesUpdate.Truncate(1u))) assertThat(summaries.value.count()).isEqualTo(1) - assertThat((summaries.value[index] as RoomSummary.Filled).identifier()).isEqualTo(A_ROOM_ID.value) + assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID) } private fun TestScope.createProcessor() = RoomSummaryListProcessor( @@ -168,8 +177,6 @@ class RoomSummaryListProcessorTest { return RoomList(Pointer.NULL) } - override suspend fun applyInput(input: RoomListInput) = Unit - override fun room(roomId: String): RoomListItem { return RoomListItem(Pointer.NULL) } @@ -183,3 +190,81 @@ class RoomSummaryListProcessorTest { } } } + +private fun aRustRoomInfo( + id: String = A_ROOM_ID.value, + displayName: String = A_ROOM_NAME, + rawName: String = A_ROOM_NAME, + topic: String? = null, + avatarUrl: String? = null, + isDirect: Boolean = false, + isPublic: Boolean = false, + isSpace: Boolean = false, + isTombstoned: Boolean = false, + isFavourite: Boolean = false, + canonicalAlias: String? = null, + alternativeAliases: List = listOf(), + membership: Membership = Membership.JOINED, + inviter: RoomMember? = null, + heroes: List = listOf(), + activeMembersCount: ULong = 0uL, + invitedMembersCount: ULong = 0uL, + joinedMembersCount: ULong = 0uL, + userPowerLevels: Map = mapOf(), + highlightCount: ULong = 0uL, + notificationCount: ULong = 0uL, + userDefinedNotificationMode: RoomNotificationMode? = null, + hasRoomCall: Boolean = false, + activeRoomCallParticipants: List = listOf(), + isMarkedUnread: Boolean = false, + numUnreadMessages: ULong = 0uL, + numUnreadNotifications: ULong = 0uL, + numUnreadMentions: ULong = 0uL, +) = RoomInfo( + id = id, + displayName = displayName, + rawName = rawName, + topic = topic, + avatarUrl = avatarUrl, + isDirect = isDirect, + isPublic = isPublic, + isSpace = isSpace, + isTombstoned = isTombstoned, + isFavourite = isFavourite, + canonicalAlias = canonicalAlias, + alternativeAliases = alternativeAliases, + membership = membership, + inviter = inviter, + heroes = heroes, + activeMembersCount = activeMembersCount, + invitedMembersCount = invitedMembersCount, + joinedMembersCount = joinedMembersCount, + userPowerLevels = userPowerLevels, + highlightCount = highlightCount, + notificationCount = notificationCount, + userDefinedNotificationMode = userDefinedNotificationMode, + hasRoomCall = hasRoomCall, + activeRoomCallParticipants = activeRoomCallParticipants, + isMarkedUnread = isMarkedUnread, + numUnreadMessages = numUnreadMessages, + numUnreadNotifications = numUnreadNotifications, + numUnreadMentions = numUnreadMentions +) + +class FakeRoomListItem( + private val roomId: RoomId, + private val roomInfo: RoomInfo = aRustRoomInfo(id = roomId.value), + private val latestEvent: EventTimelineItem? = null, +) : RoomListItem(NoPointer) { + override fun id(): String { + return roomId.value + } + + override suspend fun roomInfo(): RoomInfo { + return roomInfo + } + + override suspend fun latestEvent(): EventTimelineItem? { + return latestEvent + } +} diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt index 611a68aad6..f5ef3faa0b 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt @@ -25,7 +25,6 @@ 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.RoomSummary -import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.test.AN_EVENT_ID @@ -44,25 +43,19 @@ fun aRoomSummaryFilled( numUnreadMessages: Int = 0, notificationMode: RoomNotificationMode? = null, currentUserMembership: CurrentUserMembership = CurrentUserMembership.JOINED, -) = RoomSummary.Filled( - aRoomSummaryDetails( - roomId = roomId, - name = name, - isDirect = isDirect, - avatarUrl = avatarUrl, - lastMessage = lastMessage, - numUnreadMentions = numUnreadMentions, - numUnreadMessages = numUnreadMessages, - notificationMode = notificationMode, - currentUserMembership = currentUserMembership, - ) +) = aRoomSummary( + roomId = roomId, + name = name, + isDirect = isDirect, + avatarUrl = avatarUrl, + lastMessage = lastMessage, + numUnreadMentions = numUnreadMentions, + numUnreadMessages = numUnreadMessages, + notificationMode = notificationMode, + currentUserMembership = currentUserMembership, ) -fun aRoomSummaryFilled( - details: RoomSummaryDetails = aRoomSummaryDetails(), -) = RoomSummary.Filled(details) - -fun aRoomSummaryDetails( +fun aRoomSummary( roomId: RoomId = A_ROOM_ID, name: String? = A_ROOM_NAME, isDirect: Boolean = false, @@ -80,7 +73,7 @@ fun aRoomSummaryDetails( isFavorite: Boolean = false, currentUserMembership: CurrentUserMembership = CurrentUserMembership.JOINED, heroes: List = emptyList(), -) = RoomSummaryDetails( +) = RoomSummary( roomId = roomId, name = name, isDirect = isDirect, diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/roomlist/FakeRoomListService.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/roomlist/FakeRoomListService.kt index c489a0bb1d..f8980bb75d 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/roomlist/FakeRoomListService.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/roomlist/FakeRoomListService.kt @@ -46,9 +46,6 @@ class FakeRoomListService : RoomListService { syncIndicatorStateFlow.emit(value) } - var latestSlidingSyncRange: IntRange? = null - private set - override fun createRoomList( pageSize: Int, initialFilter: RoomListFilter, @@ -65,10 +62,6 @@ class FakeRoomListService : RoomListService { MutableStateFlow(RoomListFilter.all()) ) - override fun updateAllRoomsVisibleRange(range: IntRange) { - latestSlidingSyncRange = range - } - override val state: StateFlow = roomListStateFlow override val syncIndicator: StateFlow = syncIndicatorStateFlow diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/RoomSummaryDetailsProvider.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/RoomSummaryDetailsProvider.kt index 275848f3fc..c5e117808b 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/RoomSummaryDetailsProvider.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/RoomSummaryDetailsProvider.kt @@ -23,11 +23,11 @@ import io.element.android.libraries.matrix.api.room.CurrentUserMembership 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.RoomSummary import io.element.android.libraries.matrix.api.user.MatrixUser -open class RoomSummaryDetailsProvider : PreviewParameterProvider { - override val values: Sequence +open class RoomSummaryDetailsProvider : PreviewParameterProvider { + override val values: Sequence get() = sequenceOf( aRoomSummaryDetails(), aRoomSummaryDetails(name = null), @@ -52,7 +52,7 @@ fun aRoomSummaryDetails( isFavorite: Boolean = false, currentUserMembership: CurrentUserMembership = CurrentUserMembership.JOINED, heroes: List = emptyList(), -) = RoomSummaryDetails( +) = RoomSummary( roomId = roomId, name = name, canonicalAlias = canonicalAlias, diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedRoom.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedRoom.kt index f34b071379..ca7ccce448 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedRoom.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedRoom.kt @@ -43,15 +43,15 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight 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.Text -import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails +import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.toImmutableList @Composable fun SelectedRoom( - roomSummary: RoomSummaryDetails, - onRemoveRoom: (RoomSummaryDetails) -> Unit, + roomSummary: RoomSummary, + onRemoveRoom: (RoomSummary) -> Unit, modifier: Modifier = Modifier, ) { Box( @@ -100,10 +100,10 @@ fun SelectedRoom( @PreviewsDayNight @Composable internal fun SelectedRoomPreview( - @PreviewParameter(RoomSummaryDetailsProvider::class) roomSummaryDetails: RoomSummaryDetails + @PreviewParameter(RoomSummaryDetailsProvider::class) roomSummary: RoomSummary ) = ElementPreview { SelectedRoom( - roomSummary = roomSummaryDetails, + roomSummary = roomSummary, onRemoveRoom = {}, ) } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/RoomSummaryExtension.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/RoomSummaryExtension.kt index dd86d375f3..fcae5a1a4a 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/RoomSummaryExtension.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/RoomSummaryExtension.kt @@ -18,9 +18,9 @@ package io.element.android.libraries.matrix.ui.model import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize -import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails +import io.element.android.libraries.matrix.api.roomlist.RoomSummary -fun RoomSummaryDetails.getAvatarData(size: AvatarSize) = AvatarData( +fun RoomSummary.getAvatarData(size: AvatarSize) = AvatarData( id = roomId.value, name = name, url = avatarUrl, diff --git a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectEvents.kt b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectEvents.kt index 76dce0dd5d..6f52bbda22 100644 --- a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectEvents.kt +++ b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectEvents.kt @@ -16,10 +16,10 @@ package io.element.android.libraries.roomselect.impl -import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails +import io.element.android.libraries.matrix.api.roomlist.RoomSummary sealed interface RoomSelectEvents { - data class SetSelectedRoom(val room: RoomSummaryDetails) : RoomSelectEvents + data class SetSelectedRoom(val room: RoomSummary) : RoomSelectEvents // TODO remove to restore multi-selection data object RemoveSelectedRoom : RoomSelectEvents diff --git a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenter.kt b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenter.kt index e56d4dce09..0b8ba3734a 100644 --- a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenter.kt +++ b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenter.kt @@ -29,7 +29,7 @@ import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.designsystem.theme.components.SearchBarResultState -import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails +import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.roomselect.api.RoomSelectMode import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList @@ -45,7 +45,7 @@ class RoomSelectPresenter @AssistedInject constructor( @Composable override fun present(): RoomSelectState { - var selectedRooms by remember { mutableStateOf(persistentListOf()) } + var selectedRooms by remember { mutableStateOf(persistentListOf()) } var searchQuery by remember { mutableStateOf("") } var isSearchActive by remember { mutableStateOf(false) } diff --git a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectSearchDataSource.kt b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectSearchDataSource.kt index 021c597e1e..2ad805af2d 100644 --- a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectSearchDataSource.kt +++ b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectSearchDataSource.kt @@ -22,7 +22,6 @@ import io.element.android.libraries.matrix.api.roomlist.RoomList import io.element.android.libraries.matrix.api.roomlist.RoomListFilter import io.element.android.libraries.matrix.api.roomlist.RoomListService 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.loadAllIncrementally import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.toPersistentList @@ -48,11 +47,9 @@ class RoomSelectSearchDataSource @Inject constructor( source = RoomList.Source.All, ) - val roomSummaries: Flow> = roomList.filteredSummaries + val roomSummaries: Flow> = roomList.filteredSummaries .map { roomSummaries -> roomSummaries - .filterIsInstance() - .map { it.details } .filter { it.currentUserMembership == CurrentUserMembership.JOINED } .distinctBy { it.roomId } // This should be removed once we're sure no duplicate Rooms can be received .toPersistentList() diff --git a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectState.kt b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectState.kt index c451570cf5..8eb15cd556 100644 --- a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectState.kt +++ b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectState.kt @@ -17,15 +17,15 @@ package io.element.android.libraries.roomselect.impl import io.element.android.libraries.designsystem.theme.components.SearchBarResultState -import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails +import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.roomselect.api.RoomSelectMode import kotlinx.collections.immutable.ImmutableList data class RoomSelectState( val mode: RoomSelectMode, - val resultState: SearchBarResultState>, + val resultState: SearchBarResultState>, val query: String, val isSearchActive: Boolean, - val selectedRooms: ImmutableList, + val selectedRooms: ImmutableList, val eventSink: (RoomSelectEvents) -> Unit ) diff --git a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectStateProvider.kt b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectStateProvider.kt index 2821efd36a..134396cbe2 100644 --- a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectStateProvider.kt +++ b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectStateProvider.kt @@ -20,7 +20,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.api.core.RoomAlias import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails +import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.ui.components.aRoomSummaryDetails import io.element.android.libraries.roomselect.api.RoomSelectMode import kotlinx.collections.immutable.ImmutableList @@ -52,10 +52,10 @@ open class RoomSelectStateProvider : PreviewParameterProvider { private fun aRoomSelectState( mode: RoomSelectMode = RoomSelectMode.Forward, - resultState: SearchBarResultState> = SearchBarResultState.Initial(), + resultState: SearchBarResultState> = SearchBarResultState.Initial(), query: String = "", isSearchActive: Boolean = false, - selectedRooms: ImmutableList = persistentListOf(), + selectedRooms: ImmutableList = persistentListOf(), ) = RoomSelectState( mode = mode, resultState = resultState, diff --git a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectView.kt b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectView.kt index 7ade4f759d..ba683438e6 100644 --- a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectView.kt +++ b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectView.kt @@ -56,7 +56,7 @@ import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TextButton import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails +import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.ui.components.SelectedRoom import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.roomselect.api.RoomSelectMode @@ -73,13 +73,13 @@ fun RoomSelectView( modifier: Modifier = Modifier, ) { @Suppress("UNUSED_PARAMETER") - fun onRoomRemoved(roomSummaryDetails: RoomSummaryDetails) { + fun onRoomRemoved(roomSummary: RoomSummary) { // TODO toggle selection when multi-selection is enabled state.eventSink(RoomSelectEvents.RemoveSelectedRoom) } @Composable - fun SelectedRoomsHelper(isForwarding: Boolean, selectedRooms: ImmutableList) { + fun SelectedRoomsHelper(isForwarding: Boolean, selectedRooms: ImmutableList) { if (isForwarding) return SelectedRooms( selectedRooms = selectedRooms, @@ -193,8 +193,8 @@ fun RoomSelectView( @Composable private fun SelectedRooms( - selectedRooms: ImmutableList, - onRemoveRoom: (RoomSummaryDetails) -> Unit, + selectedRooms: ImmutableList, + onRemoveRoom: (RoomSummary) -> Unit, modifier: Modifier = Modifier, ) { LazyRow( @@ -210,9 +210,9 @@ private fun SelectedRooms( @Composable private fun RoomSummaryView( - summary: RoomSummaryDetails, + summary: RoomSummary, isSelected: Boolean, - onSelection: (RoomSummaryDetails) -> Unit, + onSelection: (RoomSummary) -> Unit, ) { Row( modifier = Modifier diff --git a/libraries/roomselect/impl/src/test/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenterTest.kt b/libraries/roomselect/impl/src/test/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenterTest.kt index b4117d3d40..0f4f5267c2 100644 --- a/libraries/roomselect/impl/src/test/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenterTest.kt +++ b/libraries/roomselect/impl/src/test/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenterTest.kt @@ -23,8 +23,7 @@ import com.google.common.truth.Truth.assertThat import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.api.roomlist.RoomListFilter import io.element.android.libraries.matrix.api.roomlist.RoomListService -import io.element.android.libraries.matrix.api.roomlist.RoomSummary -import io.element.android.libraries.matrix.test.room.aRoomSummaryDetails +import io.element.android.libraries.matrix.test.room.aRoomSummary import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService import io.element.android.libraries.roomselect.api.RoomSelectMode import io.element.android.tests.testutils.WarmUpRule @@ -69,7 +68,7 @@ class RoomSelectPresenterTest { @Test fun `present - update query`() = runTest { val roomListService = FakeRoomListService().apply { - postAllRooms(listOf(RoomSummary.Filled(aRoomSummaryDetails()))) + postAllRooms(listOf(aRoomSummary())) } val presenter = createRoomSelectPresenter( roomListService = roomListService @@ -78,7 +77,7 @@ class RoomSelectPresenterTest { presenter.present() }.test { val initialState = awaitItem() - assertThat(awaitItem().resultState as? SearchBarResultState.Results).isEqualTo(SearchBarResultState.Results(listOf(aRoomSummaryDetails()))) + assertThat(awaitItem().resultState as? SearchBarResultState.Results).isEqualTo(SearchBarResultState.Results(listOf(aRoomSummary()))) initialState.eventSink(RoomSelectEvents.ToggleSearchActive) skipItems(1) initialState.eventSink(RoomSelectEvents.UpdateQuery("string not contained")) @@ -98,7 +97,7 @@ class RoomSelectPresenterTest { @Test fun `present - select and remove a room`() = runTest { val roomListService = FakeRoomListService().apply { - postAllRooms(listOf(RoomSummary.Filled(aRoomSummaryDetails()))) + postAllRooms(listOf(aRoomSummary())) } val presenter = createRoomSelectPresenter( roomListService = roomListService, @@ -107,7 +106,7 @@ class RoomSelectPresenterTest { presenter.present() }.test { val initialState = awaitItem() - val summary = aRoomSummaryDetails() + val summary = aRoomSummary() initialState.eventSink(RoomSelectEvents.SetSelectedRoom(summary)) assertThat(awaitItem().selectedRooms).isEqualTo(persistentListOf(summary)) initialState.eventSink(RoomSelectEvents.RemoveSelectedRoom) diff --git a/tests/uitests/src/test/snapshots/images/appicon.enterprise_Icon_en.png b/tests/uitests/src/test/snapshots/images/appicon.enterprise_Icon_en.png index 1032784bd9..3d1b3338e4 100644 --- a/tests/uitests/src/test/snapshots/images/appicon.enterprise_Icon_en.png +++ b/tests/uitests/src/test/snapshots/images/appicon.enterprise_Icon_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fda6dfc8c57df5456535a8ec33f78830beaab61cc27ba4119e9576c5d641023b -size 47856 +oid sha256:fe7dd8d4416b397b63fa2b3295e94e53af62f731eaeecca43b5df298a3e834d3 +size 17253 diff --git a/tests/uitests/src/test/snapshots/images/appicon.enterprise_RoundIcon_en.png b/tests/uitests/src/test/snapshots/images/appicon.enterprise_RoundIcon_en.png index 1c729b1ba2..37bbd57740 100644 --- a/tests/uitests/src/test/snapshots/images/appicon.enterprise_RoundIcon_en.png +++ b/tests/uitests/src/test/snapshots/images/appicon.enterprise_RoundIcon_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:60b169ac392d4b51e8260c595a97dd14f267facd8f428ad69814bd27e502e189 -size 44355 +oid sha256:dd6e7de23ed7048d02a2e7f412158e2372a19c0f6106d0f2876345aadfff906e +size 16247