Merge pull request #5503 from element-hq/feature/bma/immutableCleanup

Do some cleanup on our immutable annotation usage
This commit is contained in:
Benoit Marty 2025-10-10 17:42:26 +02:00 committed by GitHub
commit 3fb110d991
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
73 changed files with 178 additions and 107 deletions

View file

@ -8,10 +8,13 @@
package io.element.android.features.createroom.impl.configureroom
import android.net.Uri
import androidx.compose.runtime.Immutable
import io.element.android.libraries.matrix.api.user.MatrixUser
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
// Annotate with @Immutable since `Uri` is unstable
@Immutable
data class CreateRoomConfig(
val roomName: String? = null,
val topic: String? = null,

View file

@ -7,7 +7,6 @@
package io.element.android.features.home.impl
import androidx.compose.runtime.Immutable
import io.element.android.features.home.impl.roomlist.RoomListState
import io.element.android.features.home.impl.spaces.HomeSpacesState
import io.element.android.features.logout.api.direct.DirectLogoutState
@ -15,7 +14,6 @@ import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
import io.element.android.libraries.matrix.api.user.MatrixUser
import kotlinx.collections.immutable.ImmutableList
@Immutable
data class HomeState(
/**
* The current user of this session, in case of multiple accounts, will contains 3 items, with the

View file

@ -19,7 +19,6 @@ import io.element.android.libraries.push.api.battery.BatteryOptimizationState
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.ImmutableSet
@Immutable
data class RoomListState(
val contextMenu: ContextMenu,
val declineInviteMenu: DeclineInviteMenu,

View file

@ -16,7 +16,9 @@ import io.element.android.features.invite.api.SeenInvitesStore
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.ui.safety.rememberHideInvitesAvatar
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentSetOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toImmutableSet
import kotlinx.coroutines.flow.map
@ -28,7 +30,10 @@ class HomeSpacesPresenter(
@Composable
override fun present(): HomeSpacesState {
val hideInvitesAvatar by client.rememberHideInvitesAvatar()
val spaceRooms by client.spaceService.spaceRoomsFlow.collectAsState(emptyList())
val spaceRooms by remember {
client.spaceService.spaceRoomsFlow.map { it.toImmutableList() }
}.collectAsState(persistentListOf())
val seenSpaceInvites by remember {
seenInvitesStore.seenRoomIds().map { it.toImmutableSet() }
}.collectAsState(persistentSetOf())

View file

@ -9,11 +9,12 @@ package io.element.android.features.home.impl.spaces
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.spaces.SpaceRoom
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.ImmutableSet
data class HomeSpacesState(
val space: CurrentSpace,
val spaceRooms: List<SpaceRoom>,
val spaceRooms: ImmutableList<SpaceRoom>,
val seenSpaceInvites: ImmutableSet<RoomId>,
val hideInvitesAvatar: Boolean,
val eventSink: (HomeSpacesEvents) -> Unit,

View file

@ -11,6 +11,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.spaces.SpaceRoom
import io.element.android.libraries.previewutils.room.aSpaceRoom
import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toImmutableSet
open class HomeSpacesStateProvider : PreviewParameterProvider<HomeSpacesState> {
@ -39,7 +40,7 @@ internal fun aHomeSpacesState(
eventSink: (HomeSpacesEvents) -> Unit = {},
) = HomeSpacesState(
space = space,
spaceRooms = spaceRooms,
spaceRooms = spaceRooms.toImmutableList(),
seenSpaceInvites = seenSpaceInvites.toImmutableSet(),
hideInvitesAvatar = hideInvitesAvatar,
eventSink = eventSink,

View file

@ -24,7 +24,6 @@ import kotlinx.collections.immutable.ImmutableList
internal const val MAX_KNOCK_MESSAGE_LENGTH = 500
@Immutable
data class JoinRoomState(
val roomIdOrAlias: RoomIdOrAlias,
val contentState: ContentState,

View file

@ -7,6 +7,9 @@
package io.element.android.features.leaveroom.api
import androidx.compose.runtime.Immutable
@Immutable
interface LeaveRoomState {
val eventSink: (LeaveRoomEvent) -> Unit
}

View file

@ -17,6 +17,7 @@ import io.element.android.features.login.impl.accountprovider.AccountProvider
import io.element.android.features.login.impl.changeserver.ChangeServerState
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.uri.ensureProtocol
import kotlinx.collections.immutable.toImmutableList
@Inject
class ChangeAccountProviderPresenter(
@ -39,6 +40,7 @@ class ChangeAccountProviderPresenter(
isValid = true,
)
}
.toImmutableList()
}
val canSearchForAccountProviders = remember {

View file

@ -9,10 +9,11 @@ package io.element.android.features.login.impl.screens.changeaccountprovider
import io.element.android.features.login.impl.accountprovider.AccountProvider
import io.element.android.features.login.impl.changeserver.ChangeServerState
import kotlinx.collections.immutable.ImmutableList
// Do not use default value, so no member get forgotten in the presenters.
data class ChangeAccountProviderState(
val accountProviders: List<AccountProvider>,
val accountProviders: ImmutableList<AccountProvider>,
val canSearchForAccountProviders: Boolean,
val changeServerState: ChangeServerState,
)

View file

@ -12,6 +12,7 @@ import io.element.android.features.login.impl.accountprovider.AccountProvider
import io.element.android.features.login.impl.accountprovider.anAccountProvider
import io.element.android.features.login.impl.changeserver.ChangeServerState
import io.element.android.features.login.impl.changeserver.aChangeServerState
import kotlinx.collections.immutable.toImmutableList
open class ChangeAccountProviderStateProvider : PreviewParameterProvider<ChangeAccountProviderState> {
override val values: Sequence<ChangeAccountProviderState>
@ -29,7 +30,7 @@ fun aChangeAccountProviderState(
canSearchForAccountProviders: Boolean = true,
changeServerState: ChangeServerState = aChangeServerState(),
) = ChangeAccountProviderState(
accountProviders = accountProviders,
accountProviders = accountProviders.toImmutableList(),
canSearchForAccountProviders = canSearchForAccountProviders,
changeServerState = changeServerState,
)

View file

@ -21,6 +21,7 @@ import io.element.android.features.login.impl.login.LoginHelper
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.uri.ensureProtocol
import kotlinx.collections.immutable.toImmutableList
@Inject
class ChooseAccountProviderPresenter(
@ -69,6 +70,7 @@ class ChooseAccountProviderPresenter(
isValid = true,
)
}
.toImmutableList()
}
return ChooseAccountProviderState(

View file

@ -10,10 +10,11 @@ package io.element.android.features.login.impl.screens.chooseaccountprovider
import io.element.android.features.login.impl.accountprovider.AccountProvider
import io.element.android.features.login.impl.login.LoginMode
import io.element.android.libraries.architecture.AsyncData
import kotlinx.collections.immutable.ImmutableList
// Do not use default value, so no member get forgotten in the presenters.
data class ChooseAccountProviderState(
val accountProviders: List<AccountProvider>,
val accountProviders: ImmutableList<AccountProvider>,
val selectedAccountProvider: AccountProvider?,
val loginMode: AsyncData<LoginMode>,
val eventSink: (ChooseAccountProviderEvents) -> Unit,

View file

@ -12,6 +12,7 @@ import io.element.android.features.login.impl.accountprovider.AccountProvider
import io.element.android.features.login.impl.accountprovider.anAccountProvider
import io.element.android.features.login.impl.login.LoginMode
import io.element.android.libraries.architecture.AsyncData
import kotlinx.collections.immutable.toImmutableList
open class ChooseAccountProviderStateProvider : PreviewParameterProvider<ChooseAccountProviderState> {
private val server1 = anAccountProvider(
@ -70,7 +71,7 @@ fun aChooseAccountProviderState(
loginMode: AsyncData<LoginMode> = AsyncData.Uninitialized,
eventSink: (ChooseAccountProviderEvents) -> Unit = {},
) = ChooseAccountProviderState(
accountProviders = accountProviders,
accountProviders = accountProviders.toImmutableList(),
selectedAccountProvider = selectedAccountProvider,
loginMode = loginMode,
eventSink = eventSink,

View file

@ -7,7 +7,6 @@
package io.element.android.features.messages.impl
import androidx.compose.runtime.Immutable
import io.element.android.features.messages.api.timeline.voicemessages.composer.VoiceMessageComposerState
import io.element.android.features.messages.impl.actionlist.ActionListState
import io.element.android.features.messages.impl.crypto.identity.IdentityChangeState
@ -29,7 +28,6 @@ import io.element.android.libraries.matrix.api.encryption.identity.IdentityState
import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom
import kotlinx.collections.immutable.ImmutableList
@Immutable
data class MessagesState(
val roomId: RoomId,
val roomName: String?,

View file

@ -13,7 +13,6 @@ import io.element.android.features.messages.impl.crypto.sendfailure.VerifiedUser
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import kotlinx.collections.immutable.ImmutableList
@Immutable
data class ActionListState(
val target: Target,
val eventSink: (ActionListEvents) -> Unit,

View file

@ -9,11 +9,9 @@ package io.element.android.features.messages.impl.actionlist.model
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.compose.runtime.Immutable
import io.element.android.libraries.designsystem.icons.CompoundDrawables
import io.element.android.libraries.ui.strings.CommonStrings
@Immutable
enum class TimelineItemAction(
@StringRes val titleRes: Int,
@DrawableRes val icon: Int,

View file

@ -7,9 +7,6 @@
package io.element.android.features.messages.impl.attachments.preview
import androidx.compose.runtime.Immutable
@Immutable
sealed interface AttachmentsPreviewEvents {
data object SendAttachment : AttachmentsPreviewEvents
data object CancelAndDismiss : AttachmentsPreviewEvents

View file

@ -8,12 +8,10 @@
package io.element.android.features.messages.impl.messagecomposer
import android.net.Uri
import androidx.compose.runtime.Immutable
import io.element.android.libraries.textcomposer.mentions.ResolvedSuggestion
import io.element.android.libraries.textcomposer.model.MessageComposerMode
import io.element.android.libraries.textcomposer.model.Suggestion
@Immutable
sealed interface MessageComposerEvents {
data object ToggleFullScreenState : MessageComposerEvents
data object SendMessage : MessageComposerEvents
@ -30,6 +28,7 @@ sealed interface MessageComposerEvents {
data object Location : PickAttachmentSource
data object Poll : PickAttachmentSource
}
data class ToggleTextFormatting(val enabled: Boolean) : MessageComposerEvents
data class Error(val error: Throwable) : MessageComposerEvents
data class TypingNotice(val isTyping: Boolean) : MessageComposerEvents

View file

@ -105,7 +105,7 @@ class PinnedMessagesListPresenter(
// We do not care about the call state here.
roomCallState = aStandByCallState(),
// don't compute this value or the pin icon will be shown
pinnedEventIds = emptyList(),
pinnedEventIds = persistentListOf(),
typingNotificationState = TypingNotificationState(
renderTypingNotifications = false,
typingMembers = persistentListOf(),

View file

@ -21,7 +21,6 @@ import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield
import kotlinx.collections.immutable.ImmutableList
import kotlin.time.Duration
@Immutable
data class TimelineState(
val timelineItems: ImmutableList<TimelineItem>,
val timelineRoomInfo: TimelineRoomInfo,
@ -72,14 +71,13 @@ sealed interface FocusRequestState {
}
}
@Immutable
data class TimelineRoomInfo(
val isDm: Boolean,
val name: String?,
val userHasPermissionToSendMessage: Boolean,
val userHasPermissionToSendReaction: Boolean,
val roomCallState: RoomCallState,
val pinnedEventIds: List<EventId>,
val pinnedEventIds: ImmutableList<EventId>,
val typingNotificationState: TypingNotificationState,
val predecessorRoom: PredecessorRoom?,
)

View file

@ -259,7 +259,7 @@ internal fun aTimelineRoomInfo(
userHasPermissionToSendMessage = userHasPermissionToSendMessage,
userHasPermissionToSendReaction = true,
roomCallState = aStandByCallState(),
pinnedEventIds = pinnedEventIds,
pinnedEventIds = pinnedEventIds.toImmutableList(),
typingNotificationState = typingNotificationState,
predecessorRoom = predecessorRoom,
)

View file

@ -8,11 +8,14 @@
package io.element.android.features.messages.impl.timeline.components.customreaction.picker
import androidx.annotation.StringRes
import androidx.compose.runtime.Immutable
import io.element.android.emojibasebindings.Emoji
import io.element.android.libraries.designsystem.theme.components.IconSource
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
import kotlinx.collections.immutable.ImmutableList
// Emoji is unstable (because from an external library?), so we annotate with @Immutable
@Immutable
data class EmojiPickerState(
val categories: ImmutableList<EmojiCategory>,
val allEmojis: ImmutableList<Emoji>,

View file

@ -7,10 +7,8 @@
package io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet
import androidx.compose.runtime.Immutable
import io.element.android.features.messages.impl.timeline.model.TimelineItem
@Immutable
data class ReadReceiptBottomSheetState(
val selectedEvent: TimelineItem.Event?,
val eventSink: (ReadReceiptBottomSheetEvents) -> Unit,

View file

@ -21,7 +21,6 @@ import io.element.android.features.messages.impl.timeline.model.TimelineItemReac
import io.element.android.features.messages.impl.timeline.model.TimelineItemReadReceipts
import io.element.android.features.messages.impl.timeline.model.TimelineItemThreadInfo
import io.element.android.features.messages.impl.utils.messagesummary.MessageSummaryFormatter
import io.element.android.libraries.architecture.map
import io.element.android.libraries.core.bool.orTrue
import io.element.android.libraries.dateformatter.api.DateFormatter
import io.element.android.libraries.dateformatter.api.DateFormatterMode
@ -37,7 +36,6 @@ import io.element.android.libraries.matrix.api.timeline.item.event.getDisambigua
import io.element.android.libraries.matrix.ui.messages.reply.map
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import java.util.Date
@AssistedInject
class TimelineItemEventFactory(
@ -146,10 +144,9 @@ class TimelineItemEventFactory(
senders = reaction.senders
.sortedByDescending { it.timestamp }
.map {
val date = Date(it.timestamp)
AggregatedReactionSender(
senderId = it.senderId,
timestamp = date,
timestamp = it.timestamp,
sentTime = dateFormatter.format(
it.timestamp,
DateFormatterMode.TimeOrDate,

View file

@ -33,13 +33,14 @@ fun anAggregatedReaction(
val timeFormatter = DateFormat.getTimeInstance(DateFormat.SHORT, java.util.Locale.US).apply {
timeZone = TimeZone.getTimeZone("UTC")
}
val date = Date(1_689_061_264L)
val timestamp = 1_689_061_264L
val date = Date(timestamp)
val senders = buildList {
repeat(count) { index ->
add(
AggregatedReactionSender(
senderId = if (isHighlighted && index == 0) userId else UserId("@user$index:server.org"),
timestamp = date,
timestamp = timestamp,
sentTime = timeFormatter.format(date),
)
)

View file

@ -7,15 +7,12 @@
package io.element.android.features.messages.impl.timeline.model
import androidx.compose.runtime.Immutable
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.user.MatrixUser
import java.util.Date
@Immutable
data class AggregatedReactionSender(
val senderId: UserId,
val timestamp: Date,
val timestamp: Long,
val sentTime: String,
val user: MatrixUser? = null
)

View file

@ -57,13 +57,11 @@ sealed interface TimelineItem {
is GroupedEvents -> "groupedEvent"
}
@Immutable
data class Virtual(
val id: UniqueId,
val model: TimelineItemVirtualModel
) : TimelineItem
@Immutable
data class Event(
val id: UniqueId,
// Note: eventId can be null when the event is a local echo
@ -124,7 +122,6 @@ sealed interface TimelineItem {
val sendhandle: SendHandle? get() = sendHandleProvider()
}
@Immutable
data class GroupedEvents(
val id: UniqueId,
val events: ImmutableList<Event>,

View file

@ -7,6 +7,8 @@
package io.element.android.features.preferences.impl.about
import kotlinx.collections.immutable.ImmutableList
data class AboutState(
val elementLegals: List<ElementLegal>,
val elementLegals: ImmutableList<ElementLegal>,
)

View file

@ -8,6 +8,7 @@
package io.element.android.features.preferences.impl.about
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import kotlinx.collections.immutable.toImmutableList
open class AboutStateProvider : PreviewParameterProvider<AboutState> {
override val values: Sequence<AboutState>
@ -19,5 +20,5 @@ open class AboutStateProvider : PreviewParameterProvider<AboutState> {
fun anAboutState(
elementLegals: List<ElementLegal> = getAllLegals(),
) = AboutState(
elementLegals = elementLegals,
elementLegals = elementLegals.toImmutableList(),
)

View file

@ -10,6 +10,8 @@ package io.element.android.features.preferences.impl.about
import androidx.annotation.StringRes
import io.element.android.features.preferences.impl.BuildConfig
import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
private const val COPYRIGHT_URL = BuildConfig.URL_COPYRIGHT
private const val USE_POLICY_URL = BuildConfig.URL_ACCEPTABLE_USE
@ -24,8 +26,8 @@ sealed class ElementLegal(
data object PrivacyPolicy : ElementLegal(CommonStrings.common_privacy_policy, PRIVACY_URL)
}
fun getAllLegals(): List<ElementLegal> {
return listOf(
fun getAllLegals(): ImmutableList<ElementLegal> {
return persistentListOf(
ElementLegal.Copyright,
ElementLegal.AcceptableUsePolicy,
ElementLegal.PrivacyPolicy,

View file

@ -7,7 +7,6 @@
package io.element.android.features.preferences.impl.notifications
import androidx.compose.runtime.Immutable
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsState
@ -15,7 +14,6 @@ import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.pushproviders.api.Distributor
import kotlinx.collections.immutable.ImmutableList
@Immutable
data class NotificationSettingsState(
val matrixSettings: MatrixSettings,
val appSettings: AppSettings,

View file

@ -8,12 +8,15 @@
package io.element.android.features.preferences.impl.user.editprofile
import android.net.Uri
import androidx.compose.runtime.Immutable
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.ui.media.AvatarAction
import io.element.android.libraries.permissions.api.PermissionsState
import kotlinx.collections.immutable.ImmutableList
// Annotate with @Immutable since `Uri` is unstable
@Immutable
data class EditUserProfileState(
val userId: UserId,
val displayName: String,

View file

@ -7,9 +7,6 @@
package io.element.android.features.rageshake.api.crash
import androidx.compose.runtime.Immutable
@Immutable
data class CrashDetectionState(
val appName: String,
val crashDetected: Boolean,

View file

@ -7,10 +7,8 @@
package io.element.android.features.rageshake.api.detection
import androidx.compose.runtime.Immutable
import io.element.android.features.rageshake.api.preferences.RageshakePreferencesState
@Immutable
data class RageshakeDetectionState(
val takeScreenshot: Boolean,
val showDialog: Boolean,

View file

@ -7,12 +7,10 @@
package io.element.android.features.roomaliasresolver.impl
import androidx.compose.runtime.Immutable
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.core.RoomAlias
import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias
@Immutable
data class RoomAliasResolverState(
val roomAlias: RoomAlias,
val resolveState: AsyncData<ResolvedRoomAlias>,

View file

@ -8,12 +8,15 @@
package io.element.android.features.roomdetails.impl.edit
import android.net.Uri
import androidx.compose.runtime.Immutable
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.ui.media.AvatarAction
import io.element.android.libraries.permissions.api.PermissionsState
import kotlinx.collections.immutable.ImmutableList
// Annotate with @Immutable since `Uri` is unstable
@Immutable
data class RoomDetailsEditState(
val roomId: RoomId,
/** The raw room name (i.e. the room name from the state event `m.room.name`), not the display name. */

View file

@ -6,7 +6,7 @@
*/
plugins {
id("io.element.android-library")
id("io.element.android-compose-library")
id("kotlin-parcelize")
}

View file

@ -8,7 +8,6 @@
package io.element.android.features.roomdirectory.api
import android.os.Parcelable
import androidx.compose.runtime.Immutable
import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.matrix.api.core.RoomAlias
@ -17,7 +16,6 @@ import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
@Parcelize
@Immutable
data class RoomDescription(
val roomId: RoomId,
val name: String?,

View file

@ -42,14 +42,14 @@ class RoomDirectoryPresenterTest {
@Test
fun `present - room directory list emits empty state`() = runTest {
val directoryListStateFlow = MutableSharedFlow<RoomDirectoryList.State>(replay = 1)
val directoryListStateFlow = MutableSharedFlow<RoomDirectoryList.SearchResult>(replay = 1)
val roomDirectoryList = FakeRoomDirectoryList(directoryListStateFlow)
val roomDirectoryService = FakeRoomDirectoryService { roomDirectoryList }
val presenter = createRoomDirectoryPresenter(roomDirectoryService = roomDirectoryService)
presenter.test {
skipItems(1)
directoryListStateFlow.emit(
RoomDirectoryList.State(false, emptyList())
RoomDirectoryList.SearchResult(false, emptyList())
)
awaitItem().also { state ->
assertThat(state.displayEmptyState).isTrue()
@ -60,14 +60,14 @@ class RoomDirectoryPresenterTest {
@Test
fun `present - room directory list emits non-empty state`() = runTest {
val directoryListStateFlow = MutableSharedFlow<RoomDirectoryList.State>(replay = 1)
val directoryListStateFlow = MutableSharedFlow<RoomDirectoryList.SearchResult>(replay = 1)
val roomDirectoryList = FakeRoomDirectoryList(directoryListStateFlow)
val roomDirectoryService = FakeRoomDirectoryService { roomDirectoryList }
val presenter = createRoomDirectoryPresenter(roomDirectoryService = roomDirectoryService)
presenter.test {
skipItems(1)
directoryListStateFlow.emit(
RoomDirectoryList.State(
RoomDirectoryList.SearchResult(
hasMoreToLoad = true,
items = listOf(aRoomDescription())
)

View file

@ -7,6 +7,9 @@
package io.element.android.features.roommembermoderation.api
import androidx.compose.runtime.Immutable
@Immutable
interface RoomMemberModerationState {
val canKick: Boolean
val canBan: Boolean

View file

@ -10,6 +10,7 @@ package io.element.android.features.space.impl.leave
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.AsyncData
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
data class LeaveSpaceState(
val spaceName: String?,
@ -18,10 +19,15 @@ data class LeaveSpaceState(
val leaveSpaceAction: AsyncAction<Unit>,
val eventSink: (LeaveSpaceEvents) -> Unit,
) {
private val rooms = selectableSpaceRooms.dataOrNull().orEmpty()
private val partition = rooms.partition { it.isLastAdmin }
private val lastAdminRooms = partition.first
private val selectableRooms = partition.second
private val rooms = selectableSpaceRooms.dataOrNull().orEmpty().toImmutableList()
private val lastAdminRooms: ImmutableList<SelectableSpaceRoom>
private val selectableRooms: ImmutableList<SelectableSpaceRoom>
init {
val partition = rooms.partition { it.isLastAdmin }
lastAdminRooms = partition.first.toImmutableList()
selectableRooms = partition.second.toImmutableList()
}
/**
* True if we should show the quick action to select/deselect all rooms.

View file

@ -6,7 +6,7 @@
*/
plugins {
id("io.element.android-library")
id("io.element.android-compose-library")
id("kotlin-parcelize")
}

View file

@ -7,13 +7,11 @@
package io.element.android.features.verifysession.impl.incoming
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable
import io.element.android.libraries.matrix.api.core.DeviceId
import io.element.android.libraries.matrix.api.verification.SessionVerificationData
import io.element.android.libraries.matrix.api.verification.VerificationRequest
@Immutable
data class IncomingVerificationState(
val step: Step,
val request: VerificationRequest.Incoming,

View file

@ -7,13 +7,11 @@
package io.element.android.features.verifysession.impl.outgoing
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.verification.SessionVerificationData
import io.element.android.libraries.matrix.api.verification.VerificationRequest
@Immutable
data class OutgoingVerificationState(
val step: Step,
val request: VerificationRequest.Outgoing,