Merge pull request #5490 from element-hq/feature/bma/improveImmutables

Ensure that we are using Immutable instead of Persistent
This commit is contained in:
Benoit Marty 2025-10-09 11:48:32 +02:00 committed by GitHub
commit 7ce2c08f6e
86 changed files with 305 additions and 269 deletions

View file

@ -37,10 +37,8 @@ import io.element.android.libraries.matrix.ui.model.roleOf
import io.element.android.libraries.matrix.ui.room.PowerLevelRoomMemberComparator import io.element.android.libraries.matrix.ui.room.PowerLevelRoomMemberComparator
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
@ -73,11 +71,11 @@ class ChangeRolesPresenter(
} }
val exitState: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) } val exitState: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
val saveState: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) } val saveState: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
val usersWithRole = produceState(initialValue = persistentListOf()) { val usersWithRole = produceState<ImmutableList<MatrixUser>>(initialValue = persistentListOf()) {
room.usersWithRole(role).map { members -> members.map { it.toMatrixUser() } } room.usersWithRole(role).map { members -> members.map { it.toMatrixUser() } }
.onEach { users -> .onEach { users ->
val previous: PersistentList<MatrixUser> = value val previous = value
value = users.toPersistentList() value = users.toImmutableList()
// Users who were selected but didn't have the role, so their role change was pending // Users who were selected but didn't have the role, so their role change was pending
val toAdd = selectedUsers.value.filter { user -> users.none { it.userId == user.userId } && previous.none { it.userId == user.userId } } val toAdd = selectedUsers.value.filter { user -> users.none { it.userId == user.userId } && previous.none { it.userId == user.userId } }
// Users who no longer have the role // Users who no longer have the role

View file

@ -32,8 +32,8 @@ import io.element.android.libraries.previewutils.room.aRoomMemberList
import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.services.analytics.test.FakeAnalyticsService
import io.element.android.tests.testutils.testCoroutineDispatchers import io.element.android.tests.testutils.testCoroutineDispatchers
import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.persistentMapOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentMap import kotlinx.collections.immutable.toImmutableMap
import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.junit.Test import org.junit.Test
@ -103,7 +103,7 @@ class ChangeRolesPresenterTest {
// Owner - creator // Owner - creator
aRoomMember(userId = creatorUserId, role = RoomMember.Role.Owner(isCreator = true)) aRoomMember(userId = creatorUserId, role = RoomMember.Role.Owner(isCreator = true))
) )
givenRoomMembersState(RoomMembersState.Ready(roomMemberList.toPersistentList())) givenRoomMembersState(RoomMembersState.Ready(roomMemberList.toImmutableList()))
} }
val presenter = createChangeRolesPresenter(room = room) val presenter = createChangeRolesPresenter(room = room)
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
@ -124,7 +124,7 @@ class ChangeRolesPresenterTest {
val creatorUserId = UserId("@creator:matrix.org") val creatorUserId = UserId("@creator:matrix.org")
val memberList = aRoomMemberList() val memberList = aRoomMemberList()
.plus(aRoomMember(displayName = "CREATOR", role = RoomMember.Role.Owner(isCreator = true), userId = creatorUserId)) .plus(aRoomMember(displayName = "CREATOR", role = RoomMember.Role.Owner(isCreator = true), userId = creatorUserId))
.toPersistentList() .toImmutableList()
givenRoomInfo(aRoomInfo(roomCreators = listOf(creatorUserId))) givenRoomInfo(aRoomInfo(roomCreators = listOf(creatorUserId)))
givenRoomMembersState(RoomMembersState.Ready(memberList)) givenRoomMembersState(RoomMembersState.Ready(memberList))
} }
@ -203,7 +203,7 @@ class ChangeRolesPresenterTest {
assertThat(initialResults?.moderators).hasSize(1) assertThat(initialResults?.moderators).hasSize(1)
assertThat(initialResults?.admins).hasSize(1) assertThat(initialResults?.admins).hasSize(1)
room.givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList().take(1).toPersistentList())) room.givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList().take(1).toImmutableList()))
skipItems(1) skipItems(1)
val searchResults = (awaitItem().searchResults as? SearchBarResultState.Results)?.results val searchResults = (awaitItem().searchResults as? SearchBarResultState.Results)?.results
@ -552,7 +552,7 @@ class ChangeRolesPresenterTest {
private fun roomPowerLevelsWithRoles(vararg pairs: Pair<UserId, RoomMember.Role>): RoomPowerLevels { private fun roomPowerLevelsWithRoles(vararg pairs: Pair<UserId, RoomMember.Role>): RoomPowerLevels {
return RoomPowerLevels( return RoomPowerLevels(
values = defaultRoomPowerLevelValues(), values = defaultRoomPowerLevelValues(),
users = pairs.associate { (userId, role) -> userId to role.powerLevel }.toPersistentMap() users = pairs.associate { (userId, role) -> userId to role.powerLevel }.toImmutableMap()
) )
} }
} }

View file

@ -11,7 +11,7 @@ import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.sessionstorage.api.SessionData import io.element.android.libraries.sessionstorage.api.SessionData
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
class CurrentUserWithNeighborsBuilder { class CurrentUserWithNeighborsBuilder {
/** /**
@ -64,6 +64,6 @@ class CurrentUserWithNeighborsBuilder {
} }
} }
} }
.toPersistentList() .toImmutableList()
} }
} }

View file

@ -21,7 +21,7 @@ import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
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.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
open class HomeStateProvider : PreviewParameterProvider<HomeState> { open class HomeStateProvider : PreviewParameterProvider<HomeState> {
override val values: Sequence<HomeState> override val values: Sequence<HomeState>
@ -63,7 +63,7 @@ internal fun aHomeState(
directLogoutState: DirectLogoutState = aDirectLogoutState(), directLogoutState: DirectLogoutState = aDirectLogoutState(),
eventSink: (HomeEvents) -> Unit = {} eventSink: (HomeEvents) -> Unit = {}
) = HomeState( ) = HomeState(
currentUserAndNeighbors = currentUserAndNeighbors.toPersistentList(), currentUserAndNeighbors = currentUserAndNeighbors.toImmutableList(),
showAvatarIndicator = showAvatarIndicator, showAvatarIndicator = showAvatarIndicator,
hasNetworkConnection = hasNetworkConnection, hasNetworkConnection = hasNetworkConnection,
snackbarMessage = snackbarMessage, snackbarMessage = snackbarMessage,

View file

@ -72,7 +72,7 @@ import io.element.android.libraries.testtags.testTag
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
@ -374,7 +374,7 @@ internal fun DefaultRoomListTopBarWithIndicatorPreview() = ElementPreview {
internal fun DefaultRoomListTopBarMultiAccountPreview() = ElementPreview { internal fun DefaultRoomListTopBarMultiAccountPreview() = ElementPreview {
DefaultRoomListTopBar( DefaultRoomListTopBar(
title = stringResource(R.string.screen_roomlist_main_space_title), title = stringResource(R.string.screen_roomlist_main_space_title),
currentUserAndNeighbors = aMatrixUserList().take(3).toPersistentList(), currentUserAndNeighbors = aMatrixUserList().take(3).toImmutableList(),
showAvatarIndicator = false, showAvatarIndicator = false,
areSearchResultsDisplayed = false, areSearchResultsDisplayed = false,
scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState()), scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState()),

View file

@ -14,7 +14,7 @@ import dev.zacsweers.metro.Inject
import io.element.android.features.home.impl.filters.selection.FilterSelectionStrategy import io.element.android.features.home.impl.filters.selection.FilterSelectionStrategy
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.roomlist.RoomListService
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import io.element.android.libraries.matrix.api.roomlist.RoomListFilter as MatrixRoomListFilter import io.element.android.libraries.matrix.api.roomlist.RoomListFilter as MatrixRoomListFilter
@ -23,7 +23,7 @@ class RoomListFiltersPresenter(
private val roomListService: RoomListService, private val roomListService: RoomListService,
private val filterSelectionStrategy: FilterSelectionStrategy, private val filterSelectionStrategy: FilterSelectionStrategy,
) : Presenter<RoomListFiltersState> { ) : Presenter<RoomListFiltersState> {
private val initialFilters = filterSelectionStrategy.filterSelectionStates.value.toPersistentList() private val initialFilters = filterSelectionStrategy.filterSelectionStates.value.toImmutableList()
@Composable @Composable
override fun present(): RoomListFiltersState { override fun present(): RoomListFiltersState {
@ -41,7 +41,7 @@ class RoomListFiltersPresenter(
val filters by produceState(initialValue = initialFilters) { val filters by produceState(initialValue = initialFilters) {
filterSelectionStrategy.filterSelectionStates filterSelectionStrategy.filterSelectionStates
.map { filters -> .map { filters ->
value = filters.toPersistentList() value = filters.toImmutableList()
filters.mapNotNull { filterState -> filters.mapNotNull { filterState ->
if (!filterState.isSelected) { if (!filterState.isSelected) {
return@mapNotNull null return@mapNotNull null

View file

@ -9,7 +9,7 @@ package io.element.android.features.home.impl.filters
import io.element.android.features.home.impl.filters.selection.FilterSelectionState import io.element.android.features.home.impl.filters.selection.FilterSelectionState
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
data class RoomListFiltersState( data class RoomListFiltersState(
val filterSelectionStates: ImmutableList<FilterSelectionState>, val filterSelectionStates: ImmutableList<FilterSelectionState>,
@ -21,6 +21,6 @@ data class RoomListFiltersState(
return filterSelectionStates return filterSelectionStates
.filter { it.isSelected } .filter { it.isSelected }
.map { it.filter } .map { it.filter }
.toPersistentList() .toImmutableList()
} }
} }

View file

@ -16,7 +16,7 @@ import io.element.android.libraries.push.api.battery.BatteryOptimizationState
import io.element.android.libraries.push.api.battery.aBatteryOptimizationState import io.element.android.libraries.push.api.battery.aBatteryOptimizationState
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentSet import kotlinx.collections.immutable.toImmutableSet
open class RoomListContentStateProvider : PreviewParameterProvider<RoomListContentState> { open class RoomListContentStateProvider : PreviewParameterProvider<RoomListContentState> {
override val values: Sequence<RoomListContentState> override val values: Sequence<RoomListContentState>
@ -45,7 +45,7 @@ internal fun aRoomsContentState(
fullScreenIntentPermissionsState = fullScreenIntentPermissionsState, fullScreenIntentPermissionsState = fullScreenIntentPermissionsState,
batteryOptimizationState = batteryOptimizationState, batteryOptimizationState = batteryOptimizationState,
summaries = summaries, summaries = summaries,
seenRoomInvites = seenRoomInvites.toPersistentSet(), seenRoomInvites = seenRoomInvites.toImmutableSet(),
) )
internal fun aSkeletonContentState() = RoomListContentState.Skeleton(16) internal fun aSkeletonContentState() = RoomListContentState.Skeleton(16)

View file

@ -51,8 +51,8 @@ import io.element.android.libraries.push.api.battery.BatteryOptimizationState
import io.element.android.libraries.push.api.notifications.NotificationCleaner import io.element.android.libraries.push.api.notifications.NotificationCleaner
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import io.element.android.services.analyticsproviders.api.trackers.captureInteraction import io.element.android.services.analyticsproviders.api.trackers.captureInteraction
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentSet import kotlinx.collections.immutable.toImmutableSet
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
@ -240,8 +240,8 @@ class RoomListPresenter(
showNewNotificationSoundBanner = showNewNotificationSoundBanner, showNewNotificationSoundBanner = showNewNotificationSoundBanner,
fullScreenIntentPermissionsState = fullScreenIntentPermissionsPresenter.present(), fullScreenIntentPermissionsState = fullScreenIntentPermissionsPresenter.present(),
batteryOptimizationState = batteryOptimizationPresenter.present(), batteryOptimizationState = batteryOptimizationPresenter.present(),
summaries = roomSummaries.dataOrNull().orEmpty().toPersistentList(), summaries = roomSummaries.dataOrNull().orEmpty().toImmutableList(),
seenRoomInvites = seenRoomInvites.toPersistentSet(), seenRoomInvites = seenRoomInvites.toImmutableSet(),
) )
} }
} }

View file

@ -25,7 +25,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.push.api.battery.aBatteryOptimizationState import io.element.android.libraries.push.api.battery.aBatteryOptimizationState
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
open class RoomListStateProvider : PreviewParameterProvider<RoomListState> { open class RoomListStateProvider : PreviewParameterProvider<RoomListState> {
override val values: Sequence<RoomListState> override val values: Sequence<RoomListState>
@ -122,5 +122,5 @@ internal fun generateRoomListRoomSummaryList(
avatarData = AvatarData("!id$index", "${(65 + index % 26).toChar()}", size = AvatarSize.RoomListItem), avatarData = AvatarData("!id$index", "${(65 + index % 26).toChar()}", size = AvatarSize.RoomListItem),
id = "!roomId$index:domain", id = "!roomId$index:domain",
) )
}.toPersistentList() }.toImmutableList()
} }

View file

@ -15,8 +15,8 @@ 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.RoomListFilter
import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.roomlist.loadAllIncrementally import io.element.android.libraries.matrix.api.roomlist.loadAllIncrementally
import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
@ -36,11 +36,11 @@ class RoomListSearchDataSource(
source = RoomList.Source.All, source = RoomList.Source.All,
) )
val roomSummaries: Flow<PersistentList<RoomListRoomSummary>> = roomList.filteredSummaries val roomSummaries: Flow<ImmutableList<RoomListRoomSummary>> = roomList.filteredSummaries
.map { roomSummaries -> .map { roomSummaries ->
roomSummaries roomSummaries
.map(roomSummaryFactory::create) .map(roomSummaryFactory::create)
.toPersistentList() .toImmutableList()
} }
.flowOn(coroutineDispatchers.computation) .flowOn(coroutineDispatchers.computation)

View file

@ -17,7 +17,7 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.ui.safety.rememberHideInvitesAvatar import io.element.android.libraries.matrix.ui.safety.rememberHideInvitesAvatar
import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.persistentSetOf
import kotlinx.collections.immutable.toPersistentSet import kotlinx.collections.immutable.toImmutableSet
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
@Inject @Inject
@ -30,7 +30,7 @@ class HomeSpacesPresenter(
val hideInvitesAvatar by client.rememberHideInvitesAvatar() val hideInvitesAvatar by client.rememberHideInvitesAvatar()
val spaceRooms by client.spaceService.spaceRoomsFlow.collectAsState(emptyList()) val spaceRooms by client.spaceService.spaceRoomsFlow.collectAsState(emptyList())
val seenSpaceInvites by remember { val seenSpaceInvites by remember {
seenInvitesStore.seenRoomIds().map { it.toPersistentSet() } seenInvitesStore.seenRoomIds().map { it.toImmutableSet() }
}.collectAsState(persistentSetOf()) }.collectAsState(persistentSetOf())
fun handleEvents(event: HomeSpacesEvents) { fun handleEvents(event: HomeSpacesEvents) {

View file

@ -13,7 +13,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.RoomNotificationMode
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_NAME import io.element.android.libraries.matrix.test.A_ROOM_NAME
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import org.junit.Test import org.junit.Test
class RoomListBaseRoomSummaryTest { class RoomListBaseRoomSummaryTest {
@ -105,7 +105,7 @@ internal fun createRoomListRoomSummary(
canonicalAlias = null, canonicalAlias = null,
inviteSender = null, inviteSender = null,
isDm = false, isDm = false,
heroes = heroes.toPersistentList(), heroes = heroes.toImmutableList(),
isTombstoned = isTombstoned, isTombstoned = isTombstoned,
isSpace = isSpace isSpace = isSpace
) )

View file

@ -53,7 +53,7 @@ import io.element.android.libraries.matrix.api.spaces.SpaceRoom
import io.element.android.libraries.matrix.ui.model.toInviteSender import io.element.android.libraries.matrix.ui.model.toInviteSender
import io.element.android.libraries.matrix.ui.safety.rememberHideInvitesAvatar import io.element.android.libraries.matrix.ui.safety.rememberHideInvitesAvatar
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.util.Optional import java.util.Optional
@ -291,7 +291,7 @@ private fun SpaceRoom.toContentState(): ContentState {
joinRule = joinRule, joinRule = joinRule,
details = LoadedDetails.Space( details = LoadedDetails.Space(
childrenCount = childrenCount, childrenCount = childrenCount,
heroes = heroes.toPersistentList(), heroes = heroes.toImmutableList(),
) )
) )
} }

View file

@ -24,7 +24,7 @@ import io.element.android.libraries.matrix.api.room.join.JoinRoom
import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.ui.model.InviteSender import io.element.android.libraries.matrix.ui.model.InviteSender
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
open class JoinRoomStateProvider : PreviewParameterProvider<JoinRoomState> { open class JoinRoomStateProvider : PreviewParameterProvider<JoinRoomState> {
override val values: Sequence<JoinRoomState> override val values: Sequence<JoinRoomState>
@ -189,7 +189,7 @@ fun aLoadedDetailsSpace(
heroes: List<MatrixUser> = emptyList(), heroes: List<MatrixUser> = emptyList(),
) = LoadedDetails.Space( ) = LoadedDetails.Space(
childrenCount = childrenCount, childrenCount = childrenCount,
heroes = heroes.toPersistentList() heroes = heroes.toImmutableList()
) )
fun aJoinRoomState( fun aJoinRoomState(

View file

@ -20,7 +20,7 @@ import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.core.extensions.runCatchingExceptions
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
@Inject @Inject
class DependencyLicensesListPresenter( class DependencyLicensesListPresenter(
@ -37,7 +37,7 @@ class DependencyLicensesListPresenter(
var filter by remember { mutableStateOf("") } var filter by remember { mutableStateOf("") }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
runCatchingExceptions { runCatchingExceptions {
licenses = AsyncData.Success(licensesProvider.provides().toPersistentList()) licenses = AsyncData.Success(licensesProvider.provides().toImmutableList())
}.onFailure { }.onFailure {
licenses = AsyncData.Failure(it) licenses = AsyncData.Failure(it)
} }
@ -50,7 +50,7 @@ class DependencyLicensesListPresenter(
it.safeName.contains(safeFilter, ignoreCase = true) || it.safeName.contains(safeFilter, ignoreCase = true) ||
it.groupId.contains(safeFilter, ignoreCase = true) || it.groupId.contains(safeFilter, ignoreCase = true) ||
it.artifactId.contains(safeFilter, ignoreCase = true) it.artifactId.contains(safeFilter, ignoreCase = true)
}.toPersistentList()) }.toImmutableList())
} else { } else {
filteredLicenses = licenses filteredLicenses = licenses
} }

View file

@ -8,7 +8,7 @@
package io.element.android.features.lockscreen.impl.pin.model package io.element.android.features.lockscreen.impl.pin.model
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
data class PinEntry( data class PinEntry(
val digits: ImmutableList<PinDigit>, val digits: ImmutableList<PinDigit>,
@ -17,7 +17,7 @@ data class PinEntry(
fun createEmpty(size: Int): PinEntry { fun createEmpty(size: Int): PinEntry {
val digits = List(size) { PinDigit.Empty } val digits = List(size) { PinDigit.Empty }
return PinEntry( return PinEntry(
digits = digits.toPersistentList() digits = digits.toImmutableList()
) )
} }
} }
@ -37,7 +37,7 @@ data class PinEntry(
newDigits[index] = PinDigit.Filled(char) newDigits[index] = PinDigit.Filled(char)
} }
} }
return copy(digits = newDigits.toPersistentList()) return copy(digits = newDigits.toImmutableList())
} }
fun deleteLast(): PinEntry { fun deleteLast(): PinEntry {
@ -46,7 +46,7 @@ data class PinEntry(
newDigits.indexOfLast { it is PinDigit.Filled }.also { lastFilled -> newDigits.indexOfLast { it is PinDigit.Filled }.also { lastFilled ->
newDigits[lastFilled] = PinDigit.Empty newDigits[lastFilled] = PinDigit.Empty
} }
return copy(digits = newDigits.toPersistentList()) return copy(digits = newDigits.toImmutableList())
} }
fun addDigit(digit: Char): PinEntry { fun addDigit(digit: Char): PinEntry {
@ -55,7 +55,7 @@ data class PinEntry(
newDigits.indexOfFirst { it is PinDigit.Empty }.also { firstEmpty -> newDigits.indexOfFirst { it is PinDigit.Empty }.also { firstEmpty ->
newDigits[firstEmpty] = PinDigit.Filled(digit) newDigits[firstEmpty] = PinDigit.Filled(digit)
} }
return copy(digits = newDigits.toPersistentList()) return copy(digits = newDigits.toImmutableList())
} }
fun clear(): PinEntry { fun clear(): PinEntry {

View file

@ -10,7 +10,7 @@ package io.element.android.features.messages.api.timeline.voicemessages.composer
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.designsystem.components.media.createFakeWaveform import io.element.android.libraries.designsystem.components.media.createFakeWaveform
import io.element.android.libraries.textcomposer.model.VoiceMessageState import io.element.android.libraries.textcomposer.model.VoiceMessageState
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
open class VoiceMessageComposerStateProvider : PreviewParameterProvider<VoiceMessageComposerState> { open class VoiceMessageComposerStateProvider : PreviewParameterProvider<VoiceMessageComposerState> {
@ -42,4 +42,4 @@ fun aVoiceMessagePreviewState() = VoiceMessageState.Preview(
waveform = createFakeWaveform(), waveform = createFakeWaveform(),
) )
internal var aWaveformLevels = List(100) { it.toFloat() / 100 }.toPersistentList() internal var aWaveformLevels = List(100) { it.toFloat() / 100 }.toImmutableList()

View file

@ -89,7 +89,7 @@ import io.element.android.libraries.matrix.ui.room.getDirectRoomMember
import io.element.android.libraries.textcomposer.model.MessageComposerMode import io.element.android.libraries.textcomposer.model.MessageComposerMode
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -166,7 +166,7 @@ class MessagesPresenter(
derivedStateOf { roomInfo.avatarData() } derivedStateOf { roomInfo.avatarData() }
} }
val heroes by remember { val heroes by remember {
derivedStateOf { roomInfo.heroes().toPersistentList() } derivedStateOf { roomInfo.heroes().toImmutableList() }
} }
var hasDismissedInviteDialog by rememberSaveable { var hasDismissedInviteDialog by rememberSaveable {

View file

@ -24,7 +24,7 @@ import io.element.android.features.messages.impl.timeline.model.event.aTimelineI
import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
open class ActionListStateProvider : PreviewParameterProvider<ActionListState> { open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
override val values: Sequence<ActionListState> override val values: Sequence<ActionListState>
@ -209,7 +209,7 @@ fun aTimelineItemActionList(
TimelineItemAction.ViewSource, TimelineItemAction.ViewSource,
) )
.sortedWith(TimelineItemActionComparator()) .sortedWith(TimelineItemActionComparator())
.toPersistentList() .toImmutableList()
} }
fun aTimelineItemPollActionList(): ImmutableList<TimelineItemAction> { fun aTimelineItemPollActionList(): ImmutableList<TimelineItemAction> {
@ -222,5 +222,5 @@ fun aTimelineItemPollActionList(): ImmutableList<TimelineItemAction> {
TimelineItemAction.Redact, TimelineItemAction.Redact,
) )
.sortedWith(TimelineItemActionComparator()) .sortedWith(TimelineItemActionComparator())
.toPersistentList() .toImmutableList()
} }

View file

@ -29,7 +29,7 @@ import io.element.android.libraries.mediaviewer.api.local.LocalMedia
import io.element.android.libraries.preferences.api.store.SessionPreferencesStore import io.element.android.libraries.preferences.api.store.SessionPreferencesStore
import io.element.android.libraries.preferences.api.store.VideoCompressionPreset import io.element.android.libraries.preferences.api.store.VideoCompressionPreset
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import timber.log.Timber import timber.log.Timber
import kotlin.math.roundToLong import kotlin.math.roundToLong
@ -111,7 +111,7 @@ class DefaultMediaOptimizationSelectorPresenter(
canUpload = calculatedSize <= (maxUploadSize as AsyncData.Success).data canUpload = calculatedSize <= (maxUploadSize as AsyncData.Success).data
) )
} }
.toPersistentList() .toImmutableList()
.also { sizes -> .also { sizes ->
Timber.d(sizes.joinToString("\n") { "Calculated size for ${it.preset}: ${it.sizeInBytes} MB. Max upload size: $maxUploadSize" }) Timber.d(sizes.joinToString("\n") { "Calculated size for ${it.preset}: ${it.sizeInBytes} MB. Max upload size: $maxUploadSize" })
} }

View file

@ -22,7 +22,7 @@ import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.timeline.TimelineProvider import io.element.android.libraries.matrix.api.timeline.TimelineProvider
import io.element.android.libraries.matrix.api.timeline.getActiveTimeline import io.element.android.libraries.matrix.api.timeline.getActiveTimeline
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -43,7 +43,7 @@ class ForwardMessagesPresenter(
private val forwardingActionState: MutableState<AsyncAction<List<RoomId>>> = mutableStateOf(AsyncAction.Uninitialized) private val forwardingActionState: MutableState<AsyncAction<List<RoomId>>> = mutableStateOf(AsyncAction.Uninitialized)
fun onRoomSelected(roomIds: List<RoomId>) { fun onRoomSelected(roomIds: List<RoomId>) {
sessionCoroutineScope.forwardEvent(eventId, roomIds.toPersistentList(), forwardingActionState) sessionCoroutineScope.forwardEvent(eventId, roomIds.toImmutableList(), forwardingActionState)
} }
@Composable @Composable

View file

@ -79,7 +79,7 @@ import io.element.android.services.analyticsproviders.api.trackers.captureIntera
import io.element.android.wysiwyg.compose.RichTextEditorState import io.element.android.wysiwyg.compose.RichTextEditorState
import io.element.android.wysiwyg.display.TextDisplay import io.element.android.wysiwyg.display.TextDisplay
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.FlowPreview
@ -379,7 +379,7 @@ class MessageComposerPresenter(
showAttachmentSourcePicker = showAttachmentSourcePicker, showAttachmentSourcePicker = showAttachmentSourcePicker,
showTextFormatting = showTextFormatting, showTextFormatting = showTextFormatting,
canShareLocation = canShareLocation.value, canShareLocation = canShareLocation.value,
suggestions = suggestions.toPersistentList(), suggestions = suggestions.toImmutableList(),
resolveMentionDisplay = resolveMentionDisplay, resolveMentionDisplay = resolveMentionDisplay,
resolveAtRoomMentionDisplay = resolveAtRoomMentionDisplay, resolveAtRoomMentionDisplay = resolveAtRoomMentionDisplay,
eventSink = { handleEvents(it) }, eventSink = { handleEvents(it) },

View file

@ -41,7 +41,6 @@ import io.element.android.libraries.matrix.ui.messages.reply.aProfileTimelineDet
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentList
import java.util.UUID import java.util.UUID
import kotlin.random.Random import kotlin.random.Random
@ -197,7 +196,7 @@ fun aTimelineItemReactions(
) )
) )
} }
}.toPersistentList() }.toImmutableList()
) )
} }

View file

@ -33,7 +33,7 @@ import io.element.android.features.messages.impl.timeline.model.event.aTimelineI
import io.element.android.features.messages.impl.timeline.util.defaultTimelineContentPadding import io.element.android.features.messages.impl.timeline.util.defaultTimelineContentPadding
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.persistentListOf
@Composable @Composable
fun TimelineItemStateEventRow( fun TimelineItemStateEventRow(
@ -100,7 +100,7 @@ internal fun TimelineItemStateEventRowPreview() = ElementPreview {
content = aTimelineItemStateEventContent(), content = aTimelineItemStateEventContent(),
groupPosition = TimelineItemGroupPosition.None, groupPosition = TimelineItemGroupPosition.None,
readReceiptState = TimelineItemReadReceipts( readReceiptState = TimelineItemReadReceipts(
receipts = listOf(aReadReceiptData(0)).toPersistentList(), receipts = persistentListOf(aReadReceiptData(0)),
) )
), ),
renderReadReceipts = true, renderReadReceipts = true,

View file

@ -21,7 +21,7 @@ import io.element.android.libraries.core.coroutine.CoroutineDispatchers
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.timeline.MatrixTimelineItem import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
@ -94,7 +94,7 @@ class TimelineItemsFactory(
newTimelineItemStates.add(updatedItem) newTimelineItemStates.add(updatedItem)
} }
} }
val result = timelineItemGrouper.group(newTimelineItemStates).toPersistentList() val result = timelineItemGrouper.group(newTimelineItemStates).toImmutableList()
this._timelineItems.emit(result) this._timelineItems.emit(result)
} }

View file

@ -8,7 +8,7 @@
package io.element.android.features.messages.impl.timeline.model package io.element.android.features.messages.impl.timeline.model
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
data class TimelineItemReactions( data class TimelineItemReactions(
val reactions: ImmutableList<AggregatedReaction> val reactions: ImmutableList<AggregatedReaction>
@ -17,5 +17,5 @@ data class TimelineItemReactions(
get() = reactions get() = reactions
.filter { it.isHighlighted } .filter { it.isHighlighted }
.map { it.key } .map { it.key }
.toPersistentList() .toImmutableList()
} }

View file

@ -7,9 +7,9 @@
package io.element.android.features.messages.impl.timeline.model package io.element.android.features.messages.impl.timeline.model
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
fun aTimelineItemReactions() = TimelineItemReactions( fun aTimelineItemReactions() = TimelineItemReactions(
// Use values from AggregatedReactionProvider // Use values from AggregatedReactionProvider
reactions = AggregatedReactionProvider().values.toPersistentList() reactions = AggregatedReactionProvider().values.toImmutableList()
) )

View file

@ -11,7 +11,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.core.mimetype.MimeTypes import io.element.android.libraries.core.mimetype.MimeTypes
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.media.MediaSource import io.element.android.libraries.matrix.api.media.MediaSource
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlin.time.Duration import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.minutes
@ -53,7 +53,7 @@ fun aTimelineItemVoiceContent(
duration = duration, duration = duration,
mediaSource = mediaSource, mediaSource = mediaSource,
mimeType = mimeType, mimeType = mimeType,
waveform = waveform.toPersistentList(), waveform = waveform.toImmutableList(),
formattedFileSize = "1.0 MB", formattedFileSize = "1.0 MB",
fileExtension = "ogg", fileExtension = "ogg",
) )

View file

@ -1,15 +0,0 @@
/*
* Copyright 2022-2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.messages.impl.timeline.util
internal inline fun <reified T> MutableList<T?>.invalidateLast() {
val indexOfLast = size
if (indexOfLast > 0) {
set(indexOfLast - 1, null)
}
}

View file

@ -43,7 +43,6 @@ import io.element.android.libraries.voicerecorder.api.VoiceRecorderState
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
@ -199,7 +198,7 @@ class DefaultVoiceMessageComposerPresenter(
voiceMessageState = when (val state = recorderState) { voiceMessageState = when (val state = recorderState) {
is VoiceRecorderState.Recording -> VoiceMessageState.Recording( is VoiceRecorderState.Recording -> VoiceMessageState.Recording(
duration = state.elapsedTime, duration = state.elapsedTime,
levels = state.levels.toPersistentList(), levels = state.levels.toImmutableList(),
) )
is VoiceRecorderState.Finished -> is VoiceRecorderState.Finished ->
previewState( previewState(

View file

@ -36,7 +36,7 @@ import io.element.android.tests.testutils.clickOn
import io.element.android.tests.testutils.setSafeContent import io.element.android.tests.testutils.setSafeContent
import io.element.android.wysiwyg.link.Link import io.element.android.wysiwyg.link.Link
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.rules.TestRule import org.junit.rules.TestRule
@ -148,7 +148,7 @@ class TimelineViewTest {
eventId = EventId("\$event_$it"), eventId = EventId("\$event_$it"),
content = aTimelineItemUnknownContent(), content = aTimelineItemUnknownContent(),
) )
}.toPersistentList() }.toImmutableList()
rule.setTimelineView( rule.setTimelineView(
state = aTimelineState( state = aTimelineState(

View file

@ -26,7 +26,7 @@ import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.testCoroutineDispatchers import io.element.android.tests.testutils.testCoroutineDispatchers
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentMap import kotlinx.collections.immutable.toImmutableMap
import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.junit.Rule import org.junit.Rule
@ -92,7 +92,7 @@ class EmojiPickerPresenterTest {
categories: ImmutableList<Pair<EmojibaseCategory, ImmutableList<Emoji>>> = persistentListOf(emojiCategory()), categories: ImmutableList<Pair<EmojibaseCategory, ImmutableList<Emoji>>> = persistentListOf(emojiCategory()),
recentEmojis: ImmutableList<String> = persistentListOf(), recentEmojis: ImmutableList<String> = persistentListOf(),
) = EmojiPickerPresenter( ) = EmojiPickerPresenter(
emojibaseStore = EmojibaseStore(categories.toMap().toPersistentMap()), emojibaseStore = EmojibaseStore(categories.toMap().toImmutableMap()),
recentEmojis = recentEmojis, recentEmojis = recentEmojis,
coroutineDispatchers = testCoroutineDispatchers(), coroutineDispatchers = testCoroutineDispatchers(),
) )

View file

@ -46,7 +46,6 @@ import io.element.android.services.analytics.test.FakeAnalyticsService
import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.lambdaRecorder
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.advanceUntilIdle
@ -85,7 +84,7 @@ class VoiceMessageComposerPresenterTest {
companion object { companion object {
private val RECORDING_DURATION = 1.seconds private val RECORDING_DURATION = 1.seconds
private val RECORDING_STATE = VoiceMessageState.Recording(RECORDING_DURATION, listOf(0.1f, 0.2f).toPersistentList()) private val RECORDING_STATE = VoiceMessageState.Recording(RECORDING_DURATION, listOf(0.1f, 0.2f).toImmutableList())
} }
@Test @Test

View file

@ -33,7 +33,6 @@ import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
@ -79,7 +78,7 @@ class CreatePollPresenter(
repository.getPoll(mode.eventId).onSuccess { repository.getPoll(mode.eventId).onSuccess {
val loadedPoll = PollFormState( val loadedPoll = PollFormState(
question = it.question, question = it.question,
answers = it.answers.map(PollAnswer::text).toPersistentList(), answers = it.answers.map(PollAnswer::text).toImmutableList(),
isDisclosed = it.kind.isDisclosed, isDisclosed = it.kind.isDisclosed,
) )
initialPoll = loadedPoll initialPoll = loadedPoll

View file

@ -9,8 +9,7 @@ package io.element.android.features.poll.impl.create
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.matrix.api.poll.PollKind import io.element.android.libraries.matrix.api.poll.PollKind
import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.persistentListOf
class CreatePollStateProvider : PreviewParameterProvider<CreatePollState> { class CreatePollStateProvider : PreviewParameterProvider<CreatePollState> {
override val values: Sequence<CreatePollState> override val values: Sequence<CreatePollState>
@ -20,7 +19,7 @@ class CreatePollStateProvider : PreviewParameterProvider<CreatePollState> {
canCreate = false, canCreate = false,
canAddAnswer = true, canAddAnswer = true,
question = "", question = "",
answers = persistentListOf( answers = listOf(
Answer("", false), Answer("", false),
Answer("", false) Answer("", false)
), ),
@ -33,7 +32,7 @@ class CreatePollStateProvider : PreviewParameterProvider<CreatePollState> {
canCreate = true, canCreate = true,
canAddAnswer = true, canAddAnswer = true,
question = "What type of food should we have?", question = "What type of food should we have?",
answers = persistentListOf( answers = listOf(
Answer("Italian \uD83C\uDDEE\uD83C\uDDF9", false), Answer("Italian \uD83C\uDDEE\uD83C\uDDF9", false),
Answer("Chinese \uD83C\uDDE8\uD83C\uDDF3", false), Answer("Chinese \uD83C\uDDE8\uD83C\uDDF3", false),
), ),
@ -46,7 +45,7 @@ class CreatePollStateProvider : PreviewParameterProvider<CreatePollState> {
canCreate = true, canCreate = true,
canAddAnswer = true, canAddAnswer = true,
question = "What type of food should we have?", question = "What type of food should we have?",
answers = persistentListOf( answers = listOf(
Answer("Italian \uD83C\uDDEE\uD83C\uDDF9", false), Answer("Italian \uD83C\uDDEE\uD83C\uDDF9", false),
Answer("Chinese \uD83C\uDDE8\uD83C\uDDF3", false), Answer("Chinese \uD83C\uDDE8\uD83C\uDDF3", false),
), ),
@ -59,7 +58,7 @@ class CreatePollStateProvider : PreviewParameterProvider<CreatePollState> {
canCreate = true, canCreate = true,
canAddAnswer = true, canAddAnswer = true,
question = "What type of food should we have?", question = "What type of food should we have?",
answers = persistentListOf( answers = listOf(
Answer("Italian \uD83C\uDDEE\uD83C\uDDF9", true), Answer("Italian \uD83C\uDDEE\uD83C\uDDF9", true),
Answer("Chinese \uD83C\uDDE8\uD83C\uDDF3", true), Answer("Chinese \uD83C\uDDE8\uD83C\uDDF3", true),
Answer("Brazilian \uD83C\uDDE7\uD83C\uDDF7", true), Answer("Brazilian \uD83C\uDDE7\uD83C\uDDF7", true),
@ -74,7 +73,7 @@ class CreatePollStateProvider : PreviewParameterProvider<CreatePollState> {
canCreate = true, canCreate = true,
canAddAnswer = false, canAddAnswer = false,
question = "Should there be more than 20 answers?", question = "Should there be more than 20 answers?",
answers = persistentListOf( answers = listOf(
Answer("1", true), Answer("1", true),
Answer("2", true), Answer("2", true),
Answer("3", true), Answer("3", true),
@ -108,7 +107,7 @@ class CreatePollStateProvider : PreviewParameterProvider<CreatePollState> {
" Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor" + " Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor" +
" in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt" + " in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt" +
" in culpa qui officia deserunt mollit anim id est laborum.", " in culpa qui officia deserunt mollit anim id est laborum.",
answers = persistentListOf( answers = listOf(
Answer( Answer(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." + "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 commodo consequat. Duis a.", " Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis a.",
@ -129,7 +128,7 @@ class CreatePollStateProvider : PreviewParameterProvider<CreatePollState> {
canCreate = false, canCreate = false,
canAddAnswer = true, canAddAnswer = true,
question = "", question = "",
answers = persistentListOf( answers = listOf(
Answer("", false), Answer("", false),
Answer("", false) Answer("", false)
), ),
@ -142,7 +141,7 @@ class CreatePollStateProvider : PreviewParameterProvider<CreatePollState> {
canCreate = false, canCreate = false,
canAddAnswer = true, canAddAnswer = true,
question = "", question = "",
answers = persistentListOf( answers = listOf(
Answer("", false), Answer("", false),
Answer("", false) Answer("", false)
), ),
@ -158,7 +157,7 @@ private fun aCreatePollState(
canCreate: Boolean, canCreate: Boolean,
canAddAnswer: Boolean, canAddAnswer: Boolean,
question: String, question: String,
answers: PersistentList<Answer>, answers: List<Answer>,
showBackConfirmation: Boolean, showBackConfirmation: Boolean,
showDeleteConfirmation: Boolean, showDeleteConfirmation: Boolean,
pollKind: PollKind pollKind: PollKind
@ -168,7 +167,7 @@ private fun aCreatePollState(
canSave = canCreate, canSave = canCreate,
canAddAnswer = canAddAnswer, canAddAnswer = canAddAnswer,
question = question, question = question,
answers = answers, answers = answers.toImmutableList(),
showBackConfirmation = showBackConfirmation, showBackConfirmation = showBackConfirmation,
showDeleteConfirmation = showDeleteConfirmation, showDeleteConfirmation = showDeleteConfirmation,
pollKind = pollKind, pollKind = pollKind,

View file

@ -13,7 +13,7 @@ import io.element.android.features.poll.impl.PollConstants
import io.element.android.features.poll.impl.PollConstants.MIN_ANSWERS import io.element.android.features.poll.impl.PollConstants.MIN_ANSWERS
import io.element.android.libraries.matrix.api.poll.PollKind import io.element.android.libraries.matrix.api.poll.PollKind
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
/** /**
* Represents the state of the poll creation / edit form. * Represents the state of the poll creation / edit form.
@ -28,7 +28,7 @@ data class PollFormState(
companion object { companion object {
val Empty = PollFormState( val Empty = PollFormState(
question = "", question = "",
answers = MutableList(MIN_ANSWERS) { "" }.toPersistentList(), answers = MutableList(MIN_ANSWERS) { "" }.toImmutableList(),
isDisclosed = true, isDisclosed = true,
) )
} }
@ -49,7 +49,7 @@ data class PollFormState(
return this return this
} }
return copy(answers = (answers + "").toPersistentList()) return copy(answers = (answers + "").toImmutableList())
} }
/** /**
@ -66,7 +66,7 @@ data class PollFormState(
return this return this
} }
return copy(answers = answers.filterIndexed { i, _ -> i != index }.toPersistentList()) return copy(answers = answers.filterIndexed { i, _ -> i != index }.toImmutableList())
} }
/** /**
@ -82,7 +82,7 @@ data class PollFormState(
fun withAnswerChanged(index: Int, rawAnswer: String): PollFormState = fun withAnswerChanged(index: Int, rawAnswer: String): PollFormState =
copy(answers = answers.toMutableList().apply { copy(answers = answers.toMutableList().apply {
this[index] = rawAnswer.take(PollConstants.MAX_ANSWER_LENGTH) this[index] = rawAnswer.take(PollConstants.MAX_ANSWER_LENGTH)
}.toPersistentList()) }.toImmutableList())
/** /**
* Whether a new answer can be added. * Whether a new answer can be added.
@ -114,7 +114,7 @@ internal val pollFormStateSaver = mapSaver(
restore = { saved -> restore = { saved ->
PollFormState( PollFormState(
question = saved["question"] as String, question = saved["question"] as String,
answers = (saved["answers"] as Array<*>).map { it as String }.toPersistentList(), answers = (saved["answers"] as Array<*>).map { it as String }.toImmutableList(),
isDisclosed = saved["isDisclosed"] as Boolean, isDisclosed = saved["isDisclosed"] as Boolean,
) )
} }

View file

@ -13,7 +13,7 @@ import io.element.android.features.poll.api.pollcontent.aPollContentState
import io.element.android.features.poll.impl.history.model.PollHistoryFilter import io.element.android.features.poll.impl.history.model.PollHistoryFilter
import io.element.android.features.poll.impl.history.model.PollHistoryItem import io.element.android.features.poll.impl.history.model.PollHistoryItem
import io.element.android.features.poll.impl.history.model.PollHistoryItems import io.element.android.features.poll.impl.history.model.PollHistoryItems
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
class PollHistoryStateProvider : PreviewParameterProvider<PollHistoryState> { class PollHistoryStateProvider : PreviewParameterProvider<PollHistoryState> {
override val values: Sequence<PollHistoryState> override val values: Sequence<PollHistoryState>
@ -53,8 +53,8 @@ internal fun aPollHistoryState(
hasMoreToLoad = hasMoreToLoad, hasMoreToLoad = hasMoreToLoad,
activeFilter = activeFilter, activeFilter = activeFilter,
pollHistoryItems = PollHistoryItems( pollHistoryItems = PollHistoryItems(
ongoing = currentItems.toPersistentList(), ongoing = currentItems.toImmutableList(),
past = currentItems.toPersistentList(), past = currentItems.toImmutableList(),
), ),
eventSink = eventSink, eventSink = eventSink,
) )

View file

@ -14,7 +14,7 @@ import io.element.android.libraries.dateformatter.api.DateFormatter
import io.element.android.libraries.dateformatter.api.DateFormatterMode import io.element.android.libraries.dateformatter.api.DateFormatterMode
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import io.element.android.libraries.matrix.api.timeline.item.event.PollContent import io.element.android.libraries.matrix.api.timeline.item.event.PollContent
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@Inject @Inject
@ -36,8 +36,8 @@ class PollHistoryItemsFactory(
} }
} }
PollHistoryItems( PollHistoryItems(
ongoing = ongoing.toPersistentList(), ongoing = ongoing.toImmutableList(),
past = past.toPersistentList() past = past.toImmutableList()
) )
} }

View file

@ -9,7 +9,7 @@ package io.element.android.features.poll.impl.create
import androidx.compose.runtime.saveable.SaverScope import androidx.compose.runtime.saveable.SaverScope
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.persistentListOf
import org.junit.Test import org.junit.Test
class PollFormStateSaverTest { class PollFormStateSaverTest {
@ -21,7 +21,7 @@ class PollFormStateSaverTest {
fun `test save and restore`() { fun `test save and restore`() {
val state = PollFormState( val state = PollFormState(
question = "question", question = "question",
answers = listOf("answer1", "answer2").toPersistentList(), answers = persistentListOf("answer1", "answer2"),
isDisclosed = true, isDisclosed = true,
) )

View file

@ -10,7 +10,7 @@ package io.element.android.features.poll.impl.create
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.features.poll.impl.PollConstants import io.element.android.features.poll.impl.PollConstants
import io.element.android.libraries.matrix.api.poll.PollKind import io.element.android.libraries.matrix.api.poll.PollKind
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import org.junit.Test import org.junit.Test
class PollFormStateTest { class PollFormStateTest {
@ -47,7 +47,7 @@ class PollFormStateTest {
val state = PollFormState.Empty val state = PollFormState.Empty
val newState = state.withAnswerChanged(1, "New answer") val newState = state.withAnswerChanged(1, "New answer")
assertThat(newState).isEqualTo(PollFormState.Empty.copy( assertThat(newState).isEqualTo(PollFormState.Empty.copy(
answers = listOf("", "New answer").toPersistentList() answers = listOf("", "New answer").toImmutableList()
)) ))
} }
@ -58,7 +58,7 @@ class PollFormStateTest {
val state = PollFormState.Empty val state = PollFormState.Empty
val newState = state.withAnswerChanged(1, tooLongAnswer) val newState = state.withAnswerChanged(1, tooLongAnswer)
assertThat(newState).isEqualTo(PollFormState.Empty.copy( assertThat(newState).isEqualTo(PollFormState.Empty.copy(
answers = listOf("", truncatedAnswer).toPersistentList() answers = listOf("", truncatedAnswer).toImmutableList()
)) ))
} }
@ -101,7 +101,7 @@ class PollFormStateTest {
@Test @Test
fun `is valid is false when not enough answers`() { fun `is valid is false when not enough answers`() {
val state = aValidPollFormState().copy(answers = listOf("").toPersistentList()) val state = aValidPollFormState().copy(answers = listOf("").toImmutableList())
assertThat(state.isValid).isFalse() assertThat(state.isValid).isFalse()
} }
@ -127,10 +127,10 @@ class PollFormStateTest {
private fun aValidPollFormState(): PollFormState { private fun aValidPollFormState(): PollFormState {
return PollFormState.Empty.copy( return PollFormState.Empty.copy(
question = "question", question = "question",
answers = listOf("answer1", "answer2").toPersistentList(), answers = listOf("answer1", "answer2").toImmutableList(),
isDisclosed = true, isDisclosed = true,
) )
} }
private fun PollFormState.withBlankAnswers(numAnswers: Int): PollFormState = private fun PollFormState.withBlankAnswers(numAnswers: Int): PollFormState =
copy(answers = List(numAnswers) { "" }.toPersistentList()) copy(answers = List(numAnswers) { "" }.toImmutableList())

View file

@ -45,7 +45,7 @@ import io.element.android.libraries.preferences.api.store.VideoCompressionPreset
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.services.analytics.compose.LocalAnalyticsService import io.element.android.services.analytics.compose.LocalAnalyticsService
import io.element.android.services.analyticsproviders.api.trackers.captureInteraction import io.element.android.services.analyticsproviders.api.trackers.captureInteraction
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
@Composable @Composable
fun AdvancedSettingsView( fun AdvancedSettingsView(
@ -73,7 +73,7 @@ fun AdvancedSettingsView(
PreferenceDropdown( PreferenceDropdown(
title = stringResource(id = CommonStrings.common_appearance), title = stringResource(id = CommonStrings.common_appearance),
selectedOption = state.theme, selectedOption = state.theme,
options = ThemeOption.entries.toPersistentList(), options = ThemeOption.entries.toImmutableList(),
onSelectOption = { themeOption -> onSelectOption = { themeOption ->
state.eventSink(AdvancedSettingsEvents.SetTheme(themeOption)) state.eventSink(AdvancedSettingsEvents.SetTheme(themeOption))
} }

View file

@ -25,7 +25,7 @@ import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
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.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -83,7 +83,7 @@ class BlockedUsersPresenter(
} }
} }
return BlockedUsersState( return BlockedUsersState(
blockedUsers = ignoredMatrixUser.toPersistentList(), blockedUsers = ignoredMatrixUser.toImmutableList(),
unblockUserAction = unblockUserAction.value, unblockUserAction = unblockUserAction.value,
eventSink = ::handleEvents eventSink = ::handleEvents
) )

View file

@ -11,7 +11,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.ui.components.aMatrixUserList import io.element.android.libraries.matrix.ui.components.aMatrixUserList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
class BlockedUsersStateProvider : PreviewParameterProvider<BlockedUsersState> { class BlockedUsersStateProvider : PreviewParameterProvider<BlockedUsersState> {
override val values: Sequence<BlockedUsersState> override val values: Sequence<BlockedUsersState>
@ -32,7 +32,7 @@ internal fun aBlockedUsersState(
eventSink: (BlockedUsersEvents) -> Unit = {}, eventSink: (BlockedUsersEvents) -> Unit = {},
): BlockedUsersState { ): BlockedUsersState {
return BlockedUsersState( return BlockedUsersState(
blockedUsers = blockedUsers.toPersistentList(), blockedUsers = blockedUsers.toImmutableList(),
unblockUserAction = unblockUserAction, unblockUserAction = unblockUserAction,
eventSink = eventSink, eventSink = eventSink,
) )

View file

@ -37,11 +37,9 @@ import io.element.android.libraries.featureflag.api.Feature
import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.featureflag.ui.model.FeatureUiModel import io.element.android.libraries.featureflag.ui.model.FeatureUiModel
import io.element.android.libraries.matrix.api.tracing.TraceLogPack
import io.element.android.libraries.preferences.api.store.AppPreferencesStore import io.element.android.libraries.preferences.api.store.AppPreferencesStore
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
@ -82,11 +80,11 @@ class DeveloperSettingsPresenter(
appPreferencesStore.getTracingLogLevelFlow().map { AsyncData.Success(it.toLogLevelItem()) } appPreferencesStore.getTracingLogLevelFlow().map { AsyncData.Success(it.toLogLevelItem()) }
} }
val tracingLogLevel by tracingLogLevelFlow.collectAsState(initial = AsyncData.Uninitialized) val tracingLogLevel by tracingLogLevelFlow.collectAsState(initial = AsyncData.Uninitialized)
val tracingLogPacks by produceState(persistentListOf<TraceLogPack>()) { val tracingLogPacks by produceState(persistentListOf()) {
appPreferencesStore.getTracingLogPacksFlow() appPreferencesStore.getTracingLogPacksFlow()
// Sort the entries alphabetically by its title // Sort the entries alphabetically by its title
.map { it.sortedBy { it.title }.toPersistentList() } .map { it.sortedBy { it.title } }
.collectLatest { value = it } .collectLatest { value = it.toImmutableList() }
} }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {

View file

@ -14,7 +14,7 @@ import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.featureflag.ui.model.aFeatureUiModelList import io.element.android.libraries.featureflag.ui.model.aFeatureUiModelList
import io.element.android.libraries.matrix.api.tracing.TraceLogPack import io.element.android.libraries.matrix.api.tracing.TraceLogPack
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
open class DeveloperSettingsStateProvider : PreviewParameterProvider<DeveloperSettingsState> { open class DeveloperSettingsStateProvider : PreviewParameterProvider<DeveloperSettingsState> {
override val values: Sequence<DeveloperSettingsState> override val values: Sequence<DeveloperSettingsState>
@ -43,7 +43,7 @@ fun aDeveloperSettingsState(
clearCacheAction = clearCacheAction, clearCacheAction = clearCacheAction,
customElementCallBaseUrlState = customElementCallBaseUrlState, customElementCallBaseUrlState = customElementCallBaseUrlState,
tracingLogLevel = AsyncData.Success(LogLevelItem.INFO), tracingLogLevel = AsyncData.Success(LogLevelItem.INFO),
tracingLogPacks = traceLogPacks.toPersistentList(), tracingLogPacks = traceLogPacks.toImmutableList(),
eventSink = eventSink, eventSink = eventSink,
) )

View file

@ -36,7 +36,7 @@ import io.element.android.libraries.featureflag.ui.FeatureListView
import io.element.android.libraries.featureflag.ui.model.FeatureUiModel import io.element.android.libraries.featureflag.ui.model.FeatureUiModel
import io.element.android.libraries.matrix.api.tracing.TraceLogPack import io.element.android.libraries.matrix.api.tracing.TraceLogPack
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
@Composable @Composable
fun DeveloperSettingsView( fun DeveloperSettingsView(
@ -66,7 +66,7 @@ fun DeveloperSettingsView(
title = "Tracing log level", title = "Tracing log level",
supportingText = "Requires app reboot", supportingText = "Requires app reboot",
selectedOption = state.tracingLogLevel.dataOrNull(), selectedOption = state.tracingLogLevel.dataOrNull(),
options = LogLevelItem.entries.toPersistentList(), options = LogLevelItem.entries.toImmutableList(),
onSelectOption = { logLevel -> onSelectOption = { logLevel ->
state.eventSink(DeveloperSettingsEvents.SetTracingLogLevel(logLevel)) state.eventSink(DeveloperSettingsEvents.SetTracingLogLevel(logLevel))
} }

View file

@ -35,7 +35,7 @@ import io.element.android.libraries.matrix.api.verification.SessionVerificationS
import io.element.android.libraries.sessionstorage.api.SessionStore import io.element.android.libraries.sessionstorage.api.SessionStore
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
@ -80,7 +80,7 @@ class PreferencesRootPresenter(
avatarUrl = it.userAvatarUrl, avatarUrl = it.userAvatarUrl,
) )
} }
.toPersistentList() .toImmutableList()
} }
}.collectAsState(initial = persistentListOf()) }.collectAsState(initial = persistentListOf())

View file

@ -13,7 +13,7 @@ import io.element.android.libraries.matrix.api.core.DeviceId
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.ui.components.aMatrixUser import io.element.android.libraries.matrix.ui.components.aMatrixUser
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
fun aPreferencesRootState( fun aPreferencesRootState(
myUser: MatrixUser = aMatrixUser(), myUser: MatrixUser = aMatrixUser(),
@ -24,7 +24,7 @@ fun aPreferencesRootState(
version = "Version 1.1 (1)", version = "Version 1.1 (1)",
deviceId = DeviceId("ILAKNDNASDLK"), deviceId = DeviceId("ILAKNDNASDLK"),
isMultiAccountEnabled = true, isMultiAccountEnabled = true,
otherSessions = otherSessions.toPersistentList(), otherSessions = otherSessions.toImmutableList(),
showSecureBackup = true, showSecureBackup = true,
showSecureBackupBadge = true, showSecureBackupBadge = true,
accountManagementUrl = "aUrl", accountManagementUrl = "aUrl",

View file

@ -51,7 +51,7 @@ import io.element.android.libraries.preferences.api.store.AppPreferencesStore
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import io.element.android.services.analyticsproviders.api.trackers.captureInteraction import io.element.android.services.analyticsproviders.api.trackers.captureInteraction
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
@ -194,7 +194,7 @@ class RoomDetailsPresenter(
isFavorite = isFavorite, isFavorite = isFavorite,
displayRolesAndPermissionsSettings = !isDm && isUserAdmin, displayRolesAndPermissionsSettings = !isDm && isUserAdmin,
isPublic = joinRule == JoinRule.Public, isPublic = joinRule == JoinRule.Public,
heroes = roomInfo.heroes.toPersistentList(), heroes = roomInfo.heroes.toImmutableList(),
pinnedMessagesCount = pinnedMessagesCount, pinnedMessagesCount = pinnedMessagesCount,
snackbarMessage = snackbarMessage, snackbarMessage = snackbarMessage,
canShowKnockRequests = canShowKnockRequests, canShowKnockRequests = canShowKnockRequests,

View file

@ -18,7 +18,7 @@ import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomNotificationSettings import io.element.android.libraries.matrix.api.room.RoomNotificationSettings
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
data class RoomDetailsState( data class RoomDetailsState(
val roomId: RoomId, val roomId: RoomId,
@ -59,7 +59,7 @@ data class RoomDetailsState(
if (isPublic) { if (isPublic) {
add(RoomBadge.PUBLIC) add(RoomBadge.PUBLIC)
} }
}.toPersistentList() }.toImmutableList()
} }
@Immutable @Immutable

View file

@ -27,7 +27,7 @@ import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.api.room.RoomNotificationSettings import io.element.android.libraries.matrix.api.room.RoomNotificationSettings
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.ui.components.aMatrixUserList import io.element.android.libraries.matrix.ui.components.aMatrixUserList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
open class RoomDetailsStateProvider : PreviewParameterProvider<RoomDetailsState> { open class RoomDetailsStateProvider : PreviewParameterProvider<RoomDetailsState> {
override val values: Sequence<RoomDetailsState> override val values: Sequence<RoomDetailsState>
@ -135,7 +135,7 @@ fun aRoomDetailsState(
isFavorite = isFavorite, isFavorite = isFavorite,
displayRolesAndPermissionsSettings = displayAdminSettings, displayRolesAndPermissionsSettings = displayAdminSettings,
isPublic = isPublic, isPublic = isPublic,
heroes = heroes.toPersistentList(), heroes = heroes.toImmutableList(),
pinnedMessagesCount = pinnedMessagesCount, pinnedMessagesCount = pinnedMessagesCount,
snackbarMessage = snackbarMessage, snackbarMessage = snackbarMessage,
canShowKnockRequests = canShowKnockRequests, canShowKnockRequests = canShowKnockRequests,

View file

@ -89,7 +89,6 @@ import io.element.android.services.analytics.compose.LocalAnalyticsService
import io.element.android.services.analyticsproviders.api.trackers.captureInteraction import io.element.android.services.analyticsproviders.api.trackers.captureInteraction
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentList
@Composable @Composable
fun RoomDetailsView( fun RoomDetailsView(
@ -400,7 +399,7 @@ private fun RoomHeaderSection(
avatarType = AvatarType.Room( avatarType = AvatarType.Room(
heroes = heroes.map { user -> heroes = heroes.map { user ->
user.getAvatarData(size = AvatarSize.RoomDetailsHeader) user.getAvatarData(size = AvatarSize.RoomDetailsHeader)
}.toPersistentList(), }.toImmutableList(),
isTombstoned = isTombstoned, isTombstoned = isTombstoned,
), ),
contentDescription = avatarUrl?.let { stringResource(CommonStrings.a11y_room_avatar) }, contentDescription = avatarUrl?.let { stringResource(CommonStrings.a11y_room_avatar) },

View file

@ -38,7 +38,7 @@ import io.element.android.libraries.matrix.ui.room.roomMemberIdentityStateChange
import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.persistentMapOf
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentMap import kotlinx.collections.immutable.toImmutableMap
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
@ -69,10 +69,10 @@ class RoomMemberListPresenter(
val canInvite by room.canInviteAsState(syncUpdateFlow.value) val canInvite by room.canInviteAsState(syncUpdateFlow.value)
val roomModerationState = roomMembersModerationPresenter.present() val roomModerationState = roomMembersModerationPresenter.present()
val roomMemberIdentityStates by produceState(persistentMapOf<UserId, IdentityState>()) { val roomMemberIdentityStates by produceState(persistentMapOf()) {
room.roomMemberIdentityStateChange(waitForEncryption = true) room.roomMemberIdentityStateChange(waitForEncryption = true)
.onEach { identities -> .onEach { identities ->
value = identities.associateBy({ it.identityRoomMember.userId }, { it.identityState }).toPersistentMap() value = identities.associateBy({ it.identityRoomMember.userId }, { it.identityState }).toImmutableMap()
} }
.launchIn(this) .launchIn(this)
} }

View file

@ -11,7 +11,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncAction
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.powerlevels.RoomPowerLevelsValues import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
class ChangeRoomPermissionsStateProvider : PreviewParameterProvider<ChangeRoomPermissionsState> { class ChangeRoomPermissionsStateProvider : PreviewParameterProvider<ChangeRoomPermissionsState> {
override val values: Sequence<ChangeRoomPermissionsState> override val values: Sequence<ChangeRoomPermissionsState>
@ -45,7 +45,7 @@ internal fun aChangeRoomPermissionsState(
) = ChangeRoomPermissionsState( ) = ChangeRoomPermissionsState(
section = section, section = section,
currentPermissions = currentPermissions, currentPermissions = currentPermissions,
items = items.toPersistentList(), items = items.toImmutableList(),
hasChanges = hasChanges, hasChanges = hasChanges,
saveAction = saveAction, saveAction = saveAction,
confirmExitAction = confirmExitAction, confirmExitAction = confirmExitAction,

View file

@ -14,7 +14,7 @@ import io.element.android.features.roommembermoderation.api.RoomMemberModeration
import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncAction
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.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
class InternalRoomMemberModerationStateProvider : PreviewParameterProvider<InternalRoomMemberModerationState> { class InternalRoomMemberModerationStateProvider : PreviewParameterProvider<InternalRoomMemberModerationState> {
override val values: Sequence<InternalRoomMemberModerationState> override val values: Sequence<InternalRoomMemberModerationState>
@ -86,7 +86,7 @@ fun aRoomMembersModerationState(
canKick = canKick, canKick = canKick,
canBan = canBan, canBan = canBan,
selectedUser = selectedUser, selectedUser = selectedUser,
actions = actions.toPersistentList(), actions = actions.toImmutableList(),
kickUserAsyncAction = kickUserAsyncAction, kickUserAsyncAction = kickUserAsyncAction,
banUserAsyncAction = banUserAsyncAction, banUserAsyncAction = banUserAsyncAction,
unbanUserAsyncAction = unbanUserAsyncAction, unbanUserAsyncAction = unbanUserAsyncAction,

View file

@ -35,9 +35,9 @@ import io.element.android.libraries.matrix.ui.room.canBanAsState
import io.element.android.libraries.matrix.ui.room.canKickAsState import io.element.android.libraries.matrix.ui.room.canKickAsState
import io.element.android.libraries.matrix.ui.room.userPowerLevelAsState import io.element.android.libraries.matrix.ui.room.userPowerLevelAsState
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.drop
@ -68,7 +68,7 @@ class RoomMemberModerationPresenter(
var selectedUser by remember { var selectedUser by remember {
mutableStateOf<MatrixUser?>(null) mutableStateOf<MatrixUser?>(null)
} }
val moderationActions = remember { mutableStateOf(persistentListOf<ModerationActionState>()) } val moderationActions = remember { mutableStateOf<ImmutableList<ModerationActionState>>(persistentListOf()) }
fun handleEvent(event: RoomMemberModerationEvents) { fun handleEvent(event: RoomMemberModerationEvents) {
when (event) { when (event) {
@ -149,7 +149,7 @@ class RoomMemberModerationPresenter(
canKick: Boolean, canKick: Boolean,
canBan: Boolean, canBan: Boolean,
currentUserMemberPowerLevel: Long, currentUserMemberPowerLevel: Long,
): PersistentList<ModerationActionState> { ): ImmutableList<ModerationActionState> {
return buildList { return buildList {
add(ModerationActionState(action = ModerationAction.DisplayProfile, isEnabled = true)) add(ModerationActionState(action = ModerationAction.DisplayProfile, isEnabled = true))
// Assume the member is a regular user when it's unknown // Assume the member is a regular user when it's unknown
@ -168,7 +168,7 @@ class RoomMemberModerationPresenter(
add(ModerationActionState(action = ModerationAction.BanUser, isEnabled = canModerateThisUser)) add(ModerationActionState(action = ModerationAction.BanUser, isEnabled = canModerateThisUser))
} }
} }
}.toPersistentList() }.toImmutableList()
} }
private fun CoroutineScope.kickUser( private fun CoroutineScope.kickUser(

View file

@ -30,7 +30,7 @@ import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.test import io.element.android.tests.testutils.test
import io.element.android.tests.testutils.testCoroutineDispatchers import io.element.android.tests.testutils.testCoroutineDispatchers
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.junit.Rule import org.junit.Rule
@ -360,7 +360,7 @@ class RoomMemberModerationPresenterTest {
updateMembersResult = { Result.success(Unit) } updateMembersResult = { Result.success(Unit) }
), ),
).apply { ).apply {
val roomMembers = listOfNotNull(targetRoomMember).toPersistentList() val roomMembers = listOfNotNull(targetRoomMember).toImmutableList()
givenRoomMembersState(state = RoomMembersState.Ready(roomMembers)) givenRoomMembersState(state = RoomMembersState.Ready(roomMembers))
} }
} }

View file

@ -15,7 +15,7 @@ import io.element.android.libraries.matrix.api.spaces.SpaceRoom
import io.element.android.libraries.previewutils.room.aSpaceRoom import io.element.android.libraries.previewutils.room.aSpaceRoom
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
class LeaveSpaceStateProvider : PreviewParameterProvider<LeaveSpaceState> { class LeaveSpaceStateProvider : PreviewParameterProvider<LeaveSpaceState> {
override val values: Sequence<LeaveSpaceState> override val values: Sequence<LeaveSpaceState>
@ -92,13 +92,13 @@ class LeaveSpaceStateProvider : PreviewParameterProvider<LeaveSpaceState> {
), ),
aLeaveSpaceState( aLeaveSpaceState(
selectableSpaceRooms = AsyncData.Success( selectableSpaceRooms = AsyncData.Success(
List(10) { aSelectableSpaceRoom() }.toPersistentList() List(10) { aSelectableSpaceRoom() }.toImmutableList()
), ),
leaveSpaceAction = AsyncAction.Loading, leaveSpaceAction = AsyncAction.Loading,
), ),
aLeaveSpaceState( aLeaveSpaceState(
selectableSpaceRooms = AsyncData.Success( selectableSpaceRooms = AsyncData.Success(
List(10) { aSelectableSpaceRoom() }.toPersistentList() List(10) { aSelectableSpaceRoom() }.toImmutableList()
), ),
leaveSpaceAction = AsyncAction.Failure(Exception("An error")), leaveSpaceAction = AsyncAction.Failure(Exception("An error")),
), ),

View file

@ -33,11 +33,12 @@ import io.element.android.libraries.matrix.api.room.join.JoinRoom
import io.element.android.libraries.matrix.api.spaces.SpaceRoom import io.element.android.libraries.matrix.api.spaces.SpaceRoom
import io.element.android.libraries.matrix.api.spaces.SpaceRoomList import io.element.android.libraries.matrix.api.spaces.SpaceRoomList
import io.element.android.libraries.matrix.ui.safety.rememberHideInvitesAvatar import io.element.android.libraries.matrix.ui.safety.rememberHideInvitesAvatar
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.persistentSetOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentMap import kotlinx.collections.immutable.toImmutableMap
import kotlinx.collections.immutable.toPersistentSet import kotlinx.collections.immutable.toImmutableSet
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -52,18 +53,18 @@ class SpacePresenter(
private val acceptDeclineInvitePresenter: Presenter<AcceptDeclineInviteState>, private val acceptDeclineInvitePresenter: Presenter<AcceptDeclineInviteState>,
@SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope, @SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope,
) : Presenter<SpaceState> { ) : Presenter<SpaceState> {
private var children by mutableStateOf(persistentListOf<SpaceRoom>()) private var children by mutableStateOf<ImmutableList<SpaceRoom>>(persistentListOf())
@Composable @Composable
override fun present(): SpaceState { override fun present(): SpaceState {
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
paginate() paginate()
spaceRoomList.spaceRoomsFlow.collect { children = it.toPersistentList() } spaceRoomList.spaceRoomsFlow.collect { children = it.toImmutableList() }
} }
val hideInvitesAvatar by client.rememberHideInvitesAvatar() val hideInvitesAvatar by client.rememberHideInvitesAvatar()
val seenSpaceInvites by remember { val seenSpaceInvites by remember {
seenInvitesStore.seenRoomIds().map { it.toPersistentSet() } seenInvitesStore.seenRoomIds().map { it.toImmutableSet() }
}.collectAsState(persistentSetOf()) }.collectAsState(persistentSetOf())
val localCoroutineScope = rememberCoroutineScope() val localCoroutineScope = rememberCoroutineScope()
@ -120,7 +121,7 @@ class SpacePresenter(
seenSpaceInvites = seenSpaceInvites, seenSpaceInvites = seenSpaceInvites,
hideInvitesAvatar = hideInvitesAvatar, hideInvitesAvatar = hideInvitesAvatar,
hasMoreToLoad = hasMoreToLoad, hasMoreToLoad = hasMoreToLoad,
joinActions = joinActions.toPersistentMap(), joinActions = joinActions.toImmutableMap(),
acceptDeclineInviteState = acceptDeclineInviteState, acceptDeclineInviteState = acceptDeclineInviteState,
eventSink = ::handleEvents, eventSink = ::handleEvents,
) )

View file

@ -10,7 +10,7 @@ package io.element.android.features.space.impl.leave
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.AsyncData
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import org.junit.Test import org.junit.Test
class LeaveSpaceStateTest { class LeaveSpaceStateTest {
@ -64,7 +64,7 @@ class LeaveSpaceStateTest {
listOf( listOf(
aSelectableSpaceRoom(isLastAdmin = false, isSelected = true), aSelectableSpaceRoom(isLastAdmin = false, isSelected = true),
aSelectableSpaceRoom(isLastAdmin = false, isSelected = false), aSelectableSpaceRoom(isLastAdmin = false, isSelected = false),
).toPersistentList() ).toImmutableList()
) )
) )
assertThat(sut.showQuickAction).isTrue() assertThat(sut.showQuickAction).isTrue()
@ -81,7 +81,7 @@ class LeaveSpaceStateTest {
listOf( listOf(
aSelectableSpaceRoom(isLastAdmin = false, isSelected = true), aSelectableSpaceRoom(isLastAdmin = false, isSelected = true),
aSelectableSpaceRoom(isLastAdmin = false, isSelected = true), aSelectableSpaceRoom(isLastAdmin = false, isSelected = true),
).toPersistentList() ).toImmutableList()
) )
) )
assertThat(sut.showQuickAction).isTrue() assertThat(sut.showQuickAction).isTrue()
@ -95,11 +95,11 @@ class LeaveSpaceStateTest {
fun `test 1 last admin, 2 selected`() { fun `test 1 last admin, 2 selected`() {
val sut = aLeaveSpaceState( val sut = aLeaveSpaceState(
selectableSpaceRooms = AsyncData.Success( selectableSpaceRooms = AsyncData.Success(
listOf( persistentListOf(
aSelectableSpaceRoom(isLastAdmin = true, isSelected = false), aSelectableSpaceRoom(isLastAdmin = true, isSelected = false),
aSelectableSpaceRoom(isLastAdmin = false, isSelected = true), aSelectableSpaceRoom(isLastAdmin = false, isSelected = true),
aSelectableSpaceRoom(isLastAdmin = false, isSelected = true), aSelectableSpaceRoom(isLastAdmin = false, isSelected = true),
).toPersistentList() )
) )
) )
assertThat(sut.showQuickAction).isTrue() assertThat(sut.showQuickAction).isTrue()
@ -116,7 +116,7 @@ class LeaveSpaceStateTest {
listOf( listOf(
aSelectableSpaceRoom(isLastAdmin = true, isSelected = false), aSelectableSpaceRoom(isLastAdmin = true, isSelected = false),
aSelectableSpaceRoom(isLastAdmin = true, isSelected = false), aSelectableSpaceRoom(isLastAdmin = true, isSelected = false),
).toPersistentList() ).toImmutableList()
) )
) )
assertThat(sut.showQuickAction).isFalse() assertThat(sut.showQuickAction).isFalse()

View file

@ -19,8 +19,9 @@ import dev.zacsweers.metro.AssistedInject
import io.element.android.features.viewfolder.impl.model.Item import io.element.android.features.viewfolder.impl.model.Item
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.core.meta.BuildMeta
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
@AssistedInject @AssistedInject
class ViewFolderPresenter( class ViewFolderPresenter(
@ -36,7 +37,7 @@ class ViewFolderPresenter(
@Composable @Composable
override fun present(): ViewFolderState { override fun present(): ViewFolderState {
var content by remember { mutableStateOf(persistentListOf<Item>()) } var content by remember { mutableStateOf<ImmutableList<Item>>(persistentListOf()) }
val title = remember { val title = remember {
buildString { buildString {
if (path.contains(buildMeta.applicationId)) { if (path.contains(buildMeta.applicationId)) {
@ -49,7 +50,7 @@ class ViewFolderPresenter(
content = buildList { content = buildList {
if (canGoUp) add(Item.Parent) if (canGoUp) add(Item.Parent)
addAll(folderExplorer.getItems(path)) addAll(folderExplorer.getItems(path))
}.toPersistentList() }.toImmutableList()
} }
return ViewFolderState( return ViewFolderState(
title = title, title = title,

View file

@ -15,8 +15,9 @@ import io.element.android.libraries.architecture.Presenter
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.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.sessionstorage.api.SessionStore import io.element.android.libraries.sessionstorage.api.SessionStore
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
@Inject @Inject
class AccountSelectPresenter( class AccountSelectPresenter(
@ -24,7 +25,7 @@ class AccountSelectPresenter(
) : Presenter<AccountSelectState> { ) : Presenter<AccountSelectState> {
@Composable @Composable
override fun present(): AccountSelectState { override fun present(): AccountSelectState {
val accounts by produceState(persistentListOf()) { val accounts by produceState<ImmutableList<MatrixUser>>(persistentListOf()) {
// Do not use sessionStore.sessionsFlow() to not make it change when an account is selected. // Do not use sessionStore.sessionsFlow() to not make it change when an account is selected.
value = sessionStore.getAllSessions() value = sessionStore.getAllSessions()
.map { .map {
@ -34,7 +35,7 @@ class AccountSelectPresenter(
avatarUrl = it.userAvatarUrl, avatarUrl = it.userAvatarUrl,
) )
} }
.toPersistentList() .toImmutableList()
} }
return AccountSelectState( return AccountSelectState(

View file

@ -10,7 +10,7 @@ package io.element.android.libraries.accountselect.impl
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.ui.components.aMatrixUserList import io.element.android.libraries.matrix.ui.components.aMatrixUserList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
open class AccountSelectStateProvider : PreviewParameterProvider<AccountSelectState> { open class AccountSelectStateProvider : PreviewParameterProvider<AccountSelectState> {
override val values: Sequence<AccountSelectState> override val values: Sequence<AccountSelectState>
@ -23,5 +23,5 @@ open class AccountSelectStateProvider : PreviewParameterProvider<AccountSelectSt
private fun anAccountSelectState( private fun anAccountSelectState(
accounts: List<MatrixUser> = listOf(), accounts: List<MatrixUser> = listOf(),
) = AccountSelectState( ) = AccountSelectState(
accounts = accounts.toPersistentList(), accounts = accounts.toImmutableList(),
) )

View file

@ -27,7 +27,7 @@ import io.element.android.libraries.designsystem.components.avatar.avatarShape
import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.preview.PreviewGroup
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import java.util.Collections import java.util.Collections
import kotlin.math.PI import kotlin.math.PI
import kotlin.math.cos import kotlin.math.cos
@ -134,7 +134,7 @@ internal fun AvatarClusterPreview() = ElementThemedPreview {
) { ) {
for (ngOfAvatars in 1..5) { for (ngOfAvatars in 1..5) {
AvatarCluster( AvatarCluster(
avatars = List(ngOfAvatars) { anAvatarData(it) }.toPersistentList(), avatars = List(ngOfAvatars) { anAvatarData(it) }.toImmutableList(),
avatarType = avatarType, avatarType = avatarType,
) )
} }

View file

@ -8,7 +8,7 @@
package io.element.android.libraries.designsystem.components.media package io.element.android.libraries.designsystem.components.media
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlin.random.Random import kotlin.random.Random
/** /**
@ -21,5 +21,5 @@ import kotlin.random.Random
fun createFakeWaveform(length: Int = 1000): ImmutableList<Float> { fun createFakeWaveform(length: Int = 1000): ImmutableList<Float> {
val random = Random(seed = 2) val random = Random(seed = 2)
return List(length) { random.nextFloat() } return List(length) { random.nextFloat() }
.toPersistentList() .toImmutableList()
} }

View file

@ -39,7 +39,7 @@ import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlin.math.roundToInt import kotlin.math.roundToInt
private const val DEFAULT_GRAPHICS_LAYER_ALPHA: Float = 0.99F private const val DEFAULT_GRAPHICS_LAYER_ALPHA: Float = 0.99F
@ -187,14 +187,14 @@ internal fun WaveformPlaybackViewPreview() = ElementPreview {
showCursor = false, showCursor = false,
playbackProgress = 0.5f, playbackProgress = 0.5f,
onSeek = {}, onSeek = {},
waveform = aWaveForm().toPersistentList(), waveform = aWaveForm().toImmutableList(),
) )
WaveformPlaybackView( WaveformPlaybackView(
modifier = Modifier.height(34.dp), modifier = Modifier.height(34.dp),
showCursor = true, showCursor = true,
playbackProgress = 0.5f, playbackProgress = 0.5f,
onSeek = {}, onSeek = {},
waveform = List(1024) { it / 1024f }.toPersistentList(), waveform = List(1024) { it / 1024f }.toImmutableList(),
) )
} }
} }
@ -215,7 +215,7 @@ private fun ImmutableList<Float>.normalisedData(maxSamplesCount: Int): Immutable
this this
} }
return result.toPersistentList() return result.toImmutableList()
} }
fun aWaveForm(): List<Float> { fun aWaveForm(): List<Float> {

View file

@ -28,14 +28,14 @@ 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.Icon
import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.Text
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
internal class CompoundIconChunkProvider : PreviewParameterProvider<IconChunk> { internal class CompoundIconChunkProvider : PreviewParameterProvider<IconChunk> {
override val values: Sequence<IconChunk> override val values: Sequence<IconChunk>
get() { get() {
val chunks = CompoundIcons.allResIds.chunked(36) val chunks = CompoundIcons.allResIds.chunked(36)
return chunks.mapIndexed { index, chunk -> return chunks.mapIndexed { index, chunk ->
IconChunk(index = index + 1, total = chunks.size, icons = chunk.toPersistentList()) IconChunk(index = index + 1, total = chunks.size, icons = chunk.toImmutableList())
} }
.asSequence() .asSequence()
} }
@ -46,7 +46,7 @@ internal class OtherIconChunkProvider : PreviewParameterProvider<IconChunk> {
get() { get() {
val chunks = iconsOther.chunked(36) val chunks = iconsOther.chunked(36)
return chunks.mapIndexed { index, chunk -> return chunks.mapIndexed { index, chunk ->
IconChunk(index = index + 1, total = chunks.size, icons = chunk.toPersistentList()) IconChunk(index = index + 1, total = chunks.size, icons = chunk.toImmutableList())
} }
.asSequence() .asSequence()
} }

View file

@ -12,7 +12,7 @@ import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.RoomMembersState
import io.element.android.libraries.matrix.api.room.activeRoomMembers import io.element.android.libraries.matrix.api.room.activeRoomMembers
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
@ -38,7 +38,7 @@ fun BaseRoom.usersWithRole(role: RoomMember.Role): Flow<ImmutableList<RoomMember
.combine(readyMembersFlow) { powerLevels, membersState -> .combine(readyMembersFlow) { powerLevels, membersState ->
membersState.activeRoomMembers() membersState.activeRoomMembers()
.filter { powerLevels.contains(it.userId) } .filter { powerLevels.contains(it.userId) }
.toPersistentList() .toImmutableList()
} }
.distinctUntilChanged() .distinctUntilChanged()
} }

View file

@ -77,7 +77,7 @@ import io.element.android.libraries.sessionstorage.api.SessionStore
import io.element.android.services.toolbox.api.systemclock.SystemClock import io.element.android.services.toolbox.api.systemclock.SystemClock
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.TimeoutCancellationException import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
@ -238,11 +238,11 @@ class RustMatrixClient(
override val ignoredUsersFlow = mxCallbackFlow<ImmutableList<UserId>> { override val ignoredUsersFlow = mxCallbackFlow<ImmutableList<UserId>> {
// Fetch the initial value manually, the SDK won't return it automatically // Fetch the initial value manually, the SDK won't return it automatically
channel.trySend(innerClient.ignoredUsers().map(::UserId).toPersistentList()) channel.trySend(innerClient.ignoredUsers().map(::UserId).toImmutableList())
innerClient.subscribeToIgnoredUsers(object : IgnoredUsersListener { innerClient.subscribeToIgnoredUsers(object : IgnoredUsersListener {
override fun call(ignoredUserIds: List<String>) { override fun call(ignoredUserIds: List<String>) {
channel.trySend(ignoredUserIds.map(::UserId).toPersistentList()) channel.trySend(ignoredUserIds.map(::UserId).toImmutableList())
} }
}) })
} }

View file

@ -22,7 +22,7 @@ import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper
import io.element.android.libraries.matrix.impl.room.powerlevels.RoomPowerLevelsValuesMapper import io.element.android.libraries.matrix.impl.room.powerlevels.RoomPowerLevelsValuesMapper
import io.element.android.libraries.matrix.impl.room.tombstone.map import io.element.android.libraries.matrix.impl.room.tombstone.map
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentMap import kotlinx.collections.immutable.toImmutableMap
import org.matrix.rustcomponents.sdk.Membership import org.matrix.rustcomponents.sdk.Membership
import org.matrix.rustcomponents.sdk.RoomHero import org.matrix.rustcomponents.sdk.RoomHero
import uniffi.matrix_sdk_base.EncryptionState import uniffi.matrix_sdk_base.EncryptionState
@ -103,6 +103,6 @@ fun RoomHero.map(): MatrixUser = MatrixUser(
fun mapPowerLevels(roomPowerLevels: RustRoomPowerLevels): RoomPowerLevels { fun mapPowerLevels(roomPowerLevels: RustRoomPowerLevels): RoomPowerLevels {
return RoomPowerLevels( return RoomPowerLevels(
values = RoomPowerLevelsValuesMapper.map(roomPowerLevels.values()), values = RoomPowerLevelsValuesMapper.map(roomPowerLevels.values()),
users = roomPowerLevels.userPowerLevels().mapKeys { (key, _) -> UserId(key) }.toPersistentMap() users = roomPowerLevels.userPowerLevels().mapKeys { (key, _) -> UserId(key) }.toImmutableMap()
) )
} }

View file

@ -8,7 +8,7 @@
package io.element.android.libraries.matrix.impl.room.join package io.element.android.libraries.matrix.impl.room.join
import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.join.JoinRule
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import org.matrix.rustcomponents.sdk.JoinRule as RustJoinRule import org.matrix.rustcomponents.sdk.JoinRule as RustJoinRule
fun RustJoinRule.map(): JoinRule { fun RustJoinRule.map(): JoinRule {
@ -17,9 +17,9 @@ fun RustJoinRule.map(): JoinRule {
RustJoinRule.Private -> JoinRule.Private RustJoinRule.Private -> JoinRule.Private
RustJoinRule.Knock -> JoinRule.Knock RustJoinRule.Knock -> JoinRule.Knock
RustJoinRule.Invite -> JoinRule.Invite RustJoinRule.Invite -> JoinRule.Invite
is RustJoinRule.Restricted -> JoinRule.Restricted(rules.map { it.map() }.toPersistentList()) is RustJoinRule.Restricted -> JoinRule.Restricted(rules.map { it.map() }.toImmutableList())
is RustJoinRule.Custom -> JoinRule.Custom(repr) is RustJoinRule.Custom -> JoinRule.Custom(repr)
is RustJoinRule.KnockRestricted -> JoinRule.KnockRestricted(rules.map { it.map() }.toPersistentList()) is RustJoinRule.KnockRestricted -> JoinRule.KnockRestricted(rules.map { it.map() }.toImmutableList())
} }
} }

View file

@ -8,9 +8,6 @@
package io.element.android.libraries.matrix.impl.room package io.element.android.libraries.matrix.impl.room
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomAlias
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.CurrentUserMembership
import io.element.android.libraries.matrix.api.room.RoomInfo import io.element.android.libraries.matrix.api.room.RoomInfo
import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.RoomNotificationMode
@ -34,7 +31,6 @@ import io.element.android.libraries.matrix.test.room.defaultRoomPowerLevelValues
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.persistentMapOf
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentList
import org.junit.Test import org.junit.Test
import org.matrix.rustcomponents.sdk.Membership import org.matrix.rustcomponents.sdk.Membership
import uniffi.matrix_sdk_base.EncryptionState import uniffi.matrix_sdk_base.EncryptionState
@ -113,15 +109,15 @@ class RoomInfoMapperTest {
notificationCount = 11L, notificationCount = 11L,
userDefinedNotificationMode = RoomNotificationMode.MUTE, userDefinedNotificationMode = RoomNotificationMode.MUTE,
hasRoomCall = true, hasRoomCall = true,
activeRoomCallParticipants = listOf(A_USER_ID_3).toImmutableList(), activeRoomCallParticipants = persistentListOf(A_USER_ID_3),
heroes = listOf( heroes = persistentListOf(
MatrixUser( MatrixUser(
userId = A_USER_ID, userId = A_USER_ID,
displayName = "displayName", displayName = "displayName",
avatarUrl = "avatarUrl", avatarUrl = "avatarUrl",
) )
).toImmutableList(), ),
pinnedEventIds = listOf(AN_EVENT_ID).toPersistentList(), pinnedEventIds = persistentListOf(AN_EVENT_ID),
creators = persistentListOf(A_USER_ID), creators = persistentListOf(A_USER_ID),
isMarkedUnread = false, isMarkedUnread = false,
numUnreadMessages = 12L, numUnreadMessages = 12L,
@ -191,7 +187,7 @@ class RoomInfoMapperTest {
successorRoom = null, successorRoom = null,
isFavorite = true, isFavorite = true,
canonicalAlias = null, canonicalAlias = null,
alternativeAliases = emptyList<RoomAlias>().toPersistentList(), alternativeAliases = persistentListOf(),
currentUserMembership = CurrentUserMembership.INVITED, currentUserMembership = CurrentUserMembership.INVITED,
inviter = null, inviter = null,
activeMembersCount = 2L, activeMembersCount = 2L,
@ -205,9 +201,9 @@ class RoomInfoMapperTest {
notificationCount = 11L, notificationCount = 11L,
userDefinedNotificationMode = null, userDefinedNotificationMode = null,
hasRoomCall = false, hasRoomCall = false,
activeRoomCallParticipants = emptyList<UserId>().toImmutableList(), activeRoomCallParticipants = persistentListOf(),
heroes = emptyList<MatrixUser>().toImmutableList(), heroes = persistentListOf(),
pinnedEventIds = emptyList<EventId>().toPersistentList(), pinnedEventIds = persistentListOf(),
creators = persistentListOf(), creators = persistentListOf(),
isMarkedUnread = true, isMarkedUnread = true,
numUnreadMessages = 12L, numUnreadMessages = 12L,

View file

@ -32,7 +32,6 @@ import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.persistentMapOf
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentList
fun aRoomSummary( fun aRoomSummary(
info: RoomInfo = aRoomInfo(), info: RoomInfo = aRoomInfo(),
@ -109,7 +108,7 @@ fun aRoomSummary(
userDefinedNotificationMode = userDefinedNotificationMode, userDefinedNotificationMode = userDefinedNotificationMode,
hasRoomCall = hasRoomCall, hasRoomCall = hasRoomCall,
activeRoomCallParticipants = activeRoomCallParticipants.toImmutableList(), activeRoomCallParticipants = activeRoomCallParticipants.toImmutableList(),
heroes = heroes.toPersistentList(), heroes = heroes.toImmutableList(),
pinnedEventIds = pinnedEventIds.toImmutableList(), pinnedEventIds = pinnedEventIds.toImmutableList(),
creators = roomCreators.toImmutableList(), creators = roomCreators.toImmutableList(),
isMarkedUnread = isMarkedUnread, isMarkedUnread = isMarkedUnread,

View file

@ -16,7 +16,7 @@ import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.roomMembers import io.element.android.libraries.matrix.api.room.roomMembers
import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.matrix.ui.model.getAvatarData
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
@ -46,7 +46,7 @@ fun JoinedRoom.roomMemberIdentityStateChange(waitForEncryption: Boolean): Flow<I
identityRoomMember = member, identityRoomMember = member,
identityState = identityStateChange.identityState, identityState = identityStateChange.identityState,
) )
}.toPersistentList() }.toImmutableList()
}.distinctUntilChanged() }.distinctUntilChanged()
} }
} }

View file

@ -15,7 +15,7 @@ import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import io.element.android.libraries.mediaviewer.impl.model.MediaItem import io.element.android.libraries.mediaviewer.impl.model.MediaItem
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
@ -69,7 +69,7 @@ class TimelineMediaItemsFactory(
newTimelineItemStates.add(cacheItem) newTimelineItemStates.add(cacheItem)
} }
} }
_timelineItems.emit(newTimelineItemStates.toPersistentList()) _timelineItems.emit(newTimelineItemStates.toImmutableList())
} }
private fun buildAndCacheItem( private fun buildAndCacheItem(

View file

@ -53,7 +53,7 @@ import io.element.android.libraries.voiceplayer.api.VoiceMessageEvents
import io.element.android.libraries.voiceplayer.api.VoiceMessageState import io.element.android.libraries.voiceplayer.api.VoiceMessageState
import io.element.android.libraries.voiceplayer.api.VoiceMessageStateProvider import io.element.android.libraries.voiceplayer.api.VoiceMessageStateProvider
import io.element.android.libraries.voiceplayer.api.aVoiceMessageState import io.element.android.libraries.voiceplayer.api.aVoiceMessageState
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@Composable @Composable
@ -133,7 +133,7 @@ private fun VoiceInfoRow(
.height(34.dp), .height(34.dp),
showCursor = state.showCursor, showCursor = state.showCursor,
playbackProgress = state.progress, playbackProgress = state.progress,
waveform = voice.mediaInfo.waveform.orEmpty().toPersistentList(), waveform = voice.mediaInfo.waveform.orEmpty().toImmutableList(),
onSeek = { onSeek = {
state.eventSink(VoiceMessageEvents.Seek(it)) state.eventSink(VoiceMessageEvents.Seek(it))
}, },

View file

@ -71,7 +71,7 @@ import io.element.android.libraries.mediaviewer.impl.local.player.rememberExoPla
import io.element.android.libraries.mediaviewer.impl.local.player.seekToEnsurePlaying import io.element.android.libraries.mediaviewer.impl.local.player.seekToEnsurePlaying
import io.element.android.libraries.mediaviewer.impl.local.player.togglePlay import io.element.android.libraries.mediaviewer.impl.local.player.togglePlay
import io.element.android.libraries.mediaviewer.impl.local.rememberLocalMediaViewState import io.element.android.libraries.mediaviewer.impl.local.rememberLocalMediaViewState
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@SuppressLint("UnsafeOptInUsageError") @SuppressLint("UnsafeOptInUsageError")
@ -252,7 +252,7 @@ private fun ExoPlayerMediaAudioView(
.height(48.dp), .height(48.dp),
playbackProgress = mediaPlayerControllerState.progressAsFloat, playbackProgress = mediaPlayerControllerState.progressAsFloat,
showCursor = true, showCursor = true,
waveform = waveform.toPersistentList(), waveform = waveform.toImmutableList(),
onSeek = { onSeek = {
exoPlayer.seekToEnsurePlaying((it * exoPlayer.duration).toLong()) exoPlayer.seekToEnsurePlaying((it * exoPlayer.duration).toLong())
}, },

View file

@ -30,9 +30,9 @@ import io.element.android.libraries.mediaviewer.impl.model.mediaInfo
import io.element.android.libraries.mediaviewer.impl.model.mediaSource import io.element.android.libraries.mediaviewer.impl.model.mediaSource
import io.element.android.libraries.mediaviewer.impl.model.thumbnailSource import io.element.android.libraries.mediaviewer.impl.model.thumbnailSource
import io.element.android.services.toolbox.api.systemclock.SystemClock import io.element.android.services.toolbox.api.systemclock.SystemClock
import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
@ -72,12 +72,12 @@ class MediaViewerDataSource(
} }
@Composable @Composable
fun collectAsState(): State<PersistentList<MediaViewerPageData>> { fun collectAsState(): State<ImmutableList<MediaViewerPageData>> {
return remember { dataFlow() }.collectAsState(initialData()) return remember { dataFlow() }.collectAsState(initialData())
} }
@VisibleForTesting @VisibleForTesting
internal fun dataFlow(): Flow<PersistentList<MediaViewerPageData>> { internal fun dataFlow(): Flow<ImmutableList<MediaViewerPageData>> {
return galleryDataSource.groupedMediaItemsFlow() return galleryDataSource.groupedMediaItemsFlow()
.map { groupedItems -> .map { groupedItems ->
when (groupedItems) { when (groupedItems) {
@ -106,7 +106,7 @@ class MediaViewerDataSource(
} }
} }
private fun initialData(): PersistentList<MediaViewerPageData> { private fun initialData(): ImmutableList<MediaViewerPageData> {
val initialMediaItems = val initialMediaItems =
galleryDataSource.getLastData().dataOrNull()?.getItems(galleryMode).orEmpty() galleryDataSource.getLastData().dataOrNull()?.getItems(galleryMode).orEmpty()
return buildMediaViewerPageList(initialMediaItems) return buildMediaViewerPageList(initialMediaItems)
@ -149,7 +149,7 @@ class MediaViewerDataSource(
) )
} }
} }
}.toPersistentList() }.toImmutableList()
fun clearLoadingError(data: MediaViewerPageData.MediaViewerData) { fun clearLoadingError(data: MediaViewerPageData.MediaViewerData) {
localMediaStates[data.mediaSource.url]?.value = AsyncData.Uninitialized localMediaStates[data.mediaSource.url]?.value = AsyncData.Uninitialized

View file

@ -40,7 +40,7 @@ import io.element.android.libraries.mediaviewer.impl.R
import io.element.android.libraries.mediaviewer.impl.details.MediaBottomSheetState import io.element.android.libraries.mediaviewer.impl.details.MediaBottomSheetState
import io.element.android.libraries.mediaviewer.impl.local.LocalMediaActions import io.element.android.libraries.mediaviewer.impl.local.LocalMediaActions
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.ImmutableList
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
@ -162,7 +162,7 @@ class MediaViewerPresenter(
@Composable @Composable
private fun NoMoreItemsBackwardSnackBarDisplayer( private fun NoMoreItemsBackwardSnackBarDisplayer(
currentIndex: IntState, currentIndex: IntState,
data: State<PersistentList<MediaViewerPageData>>, data: State<ImmutableList<MediaViewerPageData>>,
) { ) {
val isRenderingLoadingBackward by remember { val isRenderingLoadingBackward by remember {
derivedStateOf { derivedStateOf {
@ -186,7 +186,7 @@ class MediaViewerPresenter(
@Composable @Composable
private fun NoMoreItemsForwardSnackBarDisplayer( private fun NoMoreItemsForwardSnackBarDisplayer(
currentIndex: IntState, currentIndex: IntState,
data: State<PersistentList<MediaViewerPageData>>, data: State<ImmutableList<MediaViewerPageData>>,
) { ) {
val isRenderingLoadingForward by remember { val isRenderingLoadingForward by remember {
derivedStateOf { derivedStateOf {

View file

@ -26,7 +26,7 @@ import io.element.android.libraries.mediaviewer.api.local.LocalMedia
import io.element.android.libraries.mediaviewer.impl.details.MediaBottomSheetState import io.element.android.libraries.mediaviewer.impl.details.MediaBottomSheetState
import io.element.android.libraries.mediaviewer.impl.details.aMediaDeleteConfirmationState import io.element.android.libraries.mediaviewer.impl.details.aMediaDeleteConfirmationState
import io.element.android.libraries.mediaviewer.impl.details.aMediaDetailsBottomSheetState import io.element.android.libraries.mediaviewer.impl.details.aMediaDetailsBottomSheetState
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
open class MediaViewerStateProvider : PreviewParameterProvider<MediaViewerState> { open class MediaViewerStateProvider : PreviewParameterProvider<MediaViewerState> {
override val values: Sequence<MediaViewerState> override val values: Sequence<MediaViewerState>
@ -204,7 +204,7 @@ fun aMediaViewerState(
eventSink: (MediaViewerEvents) -> Unit = {}, eventSink: (MediaViewerEvents) -> Unit = {},
) = MediaViewerState( ) = MediaViewerState(
initiallySelectedEventId = EventId("\$a:b"), initiallySelectedEventId = EventId("\$a:b"),
listData = listData.toPersistentList(), listData = listData.toImmutableList(),
currentIndex = currentIndex, currentIndex = currentIndex,
snackbarMessage = null, snackbarMessage = null,
canShowInfo = canShowInfo, canShowInfo = canShowInfo,

View file

@ -16,8 +16,8 @@ import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.roomlist.loadAllIncrementally import io.element.android.libraries.matrix.api.roomlist.loadAllIncrementally
import io.element.android.libraries.matrix.ui.model.SelectRoomInfo import io.element.android.libraries.matrix.ui.model.SelectRoomInfo
import io.element.android.libraries.matrix.ui.model.toSelectRoomInfo import io.element.android.libraries.matrix.ui.model.toSelectRoomInfo
import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
@ -40,13 +40,13 @@ class RoomSelectSearchDataSource(
source = RoomList.Source.All, source = RoomList.Source.All,
) )
val roomInfoList: Flow<PersistentList<SelectRoomInfo>> = roomList.filteredSummaries val roomInfoList: Flow<ImmutableList<SelectRoomInfo>> = roomList.filteredSummaries
.map { roomSummaries -> .map { roomSummaries ->
roomSummaries roomSummaries
.filter { it.info.currentUserMembership == CurrentUserMembership.JOINED } .filter { it.info.currentUserMembership == CurrentUserMembership.JOINED }
.distinctBy { it.roomId } // This should be removed once we're sure no duplicate Rooms can be received .distinctBy { it.roomId } // This should be removed once we're sure no duplicate Rooms can be received
.map { roomSummary -> roomSummary.toSelectRoomInfo() } .map { roomSummary -> roomSummary.toSelectRoomInfo() }
.toPersistentList() .toImmutableList()
} }
.flowOn(coroutineDispatchers.computation) .flowOn(coroutineDispatchers.computation)

View file

@ -53,7 +53,7 @@ import io.element.android.libraries.matrix.ui.model.getAvatarData
import io.element.android.libraries.roomselect.api.RoomSelectMode import io.element.android.libraries.roomselect.api.RoomSelectMode
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
@Suppress("MultipleEmitters") // False positive @Suppress("MultipleEmitters") // False positive
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@ -214,7 +214,7 @@ private fun RoomSummaryView(
avatarType = AvatarType.Room( avatarType = AvatarType.Room(
heroes = roomInfo.heroes.map { user -> heroes = roomInfo.heroes.map { user ->
user.getAvatarData(size = AvatarSize.RoomSelectRoomListItem) user.getAvatarData(size = AvatarSize.RoomSelectRoomListItem)
}.toPersistentList(), }.toImmutableList(),
isTombstoned = roomInfo.isTombstoned, isTombstoned = roomInfo.isTombstoned,
), ),
) )

View file

@ -35,7 +35,7 @@ import io.element.android.libraries.designsystem.components.media.drawWaveform
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import java.lang.Float.min import java.lang.Float.min
private const val DEFAULT_GRAPHICS_LAYER_ALPHA: Float = 0.99F private const val DEFAULT_GRAPHICS_LAYER_ALPHA: Float = 0.99F
@ -62,21 +62,21 @@ fun LiveWaveformView(
Box( Box(
contentAlignment = Alignment.CenterEnd, contentAlignment = Alignment.CenterEnd,
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.height(waveFormHeight) .height(waveFormHeight)
.onSizeChanged { parentWidth = it.width } .onSizeChanged { parentWidth = it.width }
) { ) {
Canvas( Canvas(
modifier = Modifier modifier = Modifier
.width(Dp(waveformWidth)) .width(Dp(waveformWidth))
.graphicsLayer(alpha = DEFAULT_GRAPHICS_LAYER_ALPHA) .graphicsLayer(alpha = DEFAULT_GRAPHICS_LAYER_ALPHA)
.then(modifier) .then(modifier)
) { ) {
val width = min(waveformWidth, parentWidth.toFloat()) val width = min(waveformWidth, parentWidth.toFloat())
canvasSize = DpSize(width.dp, size.height.toDp()) canvasSize = DpSize(width.dp, size.height.toDp())
val countThatFitsWidth = (parentWidth.toFloat() / (lineWidth.toPx() + linePadding.toPx())).toInt() val countThatFitsWidth = (parentWidth.toFloat() / (lineWidth.toPx() + linePadding.toPx())).toInt()
drawWaveform( drawWaveform(
waveformData = levels.takeLast(countThatFitsWidth).toPersistentList(), waveformData = levels.takeLast(countThatFitsWidth).toImmutableList(),
canvasSizePx = Size(canvasSize.width.toPx(), size.height), canvasSizePx = Size(canvasSize.width.toPx(), size.height),
brush = brush, brush = brush,
lineWidth = lineWidth, lineWidth = lineWidth,
@ -91,11 +91,11 @@ fun LiveWaveformView(
internal fun LiveWaveformViewPreview() = ElementPreview { internal fun LiveWaveformViewPreview() = ElementPreview {
Column { Column {
LiveWaveformView( LiveWaveformView(
levels = List(100) { it.toFloat() / 100 }.toPersistentList(), levels = List(100) { it.toFloat() / 100 }.toImmutableList(),
modifier = Modifier.height(34.dp), modifier = Modifier.height(34.dp),
) )
LiveWaveformView( LiveWaveformView(
levels = List(40) { it.toFloat() / 40 }.toPersistentList(), levels = List(40) { it.toFloat() / 40 }.toImmutableList(),
modifier = Modifier.height(34.dp), modifier = Modifier.height(34.dp),
) )
} }

View file

@ -35,7 +35,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.ui.utils.time.formatShort import io.element.android.libraries.ui.utils.time.formatShort
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toImmutableList
import kotlin.time.Duration import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
@ -101,5 +101,5 @@ private fun RedRecordingDot() {
@PreviewsDayNight @PreviewsDayNight
@Composable @Composable
internal fun VoiceMessageRecordingPreview() = ElementPreview { internal fun VoiceMessageRecordingPreview() = ElementPreview {
VoiceMessageRecording(List(100) { it.toFloat() / 100 }.toPersistentList(), 0.seconds) VoiceMessageRecording(List(100) { it.toFloat() / 100 }.toImmutableList(), 0.seconds)
} }

View file

@ -0,0 +1,63 @@
/*
* Copyright 2023, 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.tests.konsist
import com.lemonappdev.konsist.api.Konsist
import com.lemonappdev.konsist.api.ext.list.withoutName
import com.lemonappdev.konsist.api.verify.assertFalse
import org.junit.Test
class KonsistImmutableTest {
/**
* toPersistentList() returns a PersistentList which allow mutations, while toImmutableList() returns
* an ImmutableList which does not allow mutations. Generally, we do not use the mutation features,
* so we should prefer toImmutableList.
*/
@Test
fun `toPersistentList() should not be used instead of toImmutableList()`() {
Konsist
.scopeFromProject()
.functions()
.withoutName("toPersistentList() should not be used instead of toImmutableList()")
.assertFalse(additionalMessage = "Please use toImmutableList() instead of toPersistentList()") {
it.text.contains(".toPersistentList()")
}
}
/**
* toPersistentSet() returns a PersistentSet which allow mutations, while toImmutableSet() returns
* an ImmutableSet which does not allow mutations. Generally, we do not use the mutation features,
* so we should prefer toImmutableSet.
*/
@Test
fun `toPersistentSet() should not be used instead of toImmutableSet()`() {
Konsist
.scopeFromProject()
.functions()
.withoutName("toPersistentSet() should not be used instead of toImmutableSet()")
.assertFalse(additionalMessage = "Please use toImmutableSet() instead of toPersistentSet()") {
it.text.contains(".toPersistentSet()")
}
}
/**
* toPersistentMap() returns a PersistentMap which allow mutations, while toImmutableMap() returns
* an ImmutableMap which does not allow mutations. Generally, we do not use the mutation features,
* so we should prefer toImmutableMap.
*/
@Test
fun `toPersistentMap() should not be used instead of toImmutableMap()`() {
Konsist
.scopeFromProject()
.functions()
.withoutName("toPersistentMap() should not be used instead of toImmutableMap()")
.assertFalse(additionalMessage = "Please use toImmutableMap() instead of toPersistentMap()") {
it.text.contains(".toPersistentMap()")
}
}
}