From 29b8068d4a335f2dd5c73a693d8010b1ae0df727 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 19 Jun 2026 15:14:37 +0200 Subject: [PATCH] Address quality issues on user status --- .../impl/root/PreferencesRootView.kt | 4 ++-- .../userstatus/UserStatusBindingContainer.kt | 21 +++++++++++++++++++ .../impl/userstatus/UserStatusPresenter.kt | 5 ++--- .../impl/userstatus/UserStatusState.kt | 4 +++- .../impl/userstatus/UserStatusView.kt | 20 ++++++++---------- .../matrix/api/user/DisplayedStatus.kt | 2 ++ .../libraries/matrix/impl/RustMatrixClient.kt | 1 + 7 files changed, 40 insertions(+), 17 deletions(-) create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/userstatus/UserStatusBindingContainer.kt diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt index 324f0a9773..8f272ea8ae 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt @@ -24,8 +24,8 @@ import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.preferences.impl.R import io.element.android.features.preferences.impl.user.UserPreferences -import io.element.android.features.preferences.impl.userstatus.UserStatusRow import io.element.android.features.preferences.impl.userstatus.UserStatusState +import io.element.android.features.preferences.impl.userstatus.UserStatusView import io.element.android.libraries.architecture.coverage.ExcludeFromCoverage import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.list.ListItemContent @@ -143,7 +143,7 @@ private fun ColumnScope.UserStatusSection( color = ElementTheme.colors.bgSubtleSecondary, ) } - UserStatusRow( + UserStatusView( state = userStatusState, modifier = Modifier.fillMaxWidth(), ) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/userstatus/UserStatusBindingContainer.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/userstatus/UserStatusBindingContainer.kt new file mode 100644 index 0000000000..dfa77483f8 --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/userstatus/UserStatusBindingContainer.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2026 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.preferences.impl.userstatus + +import dev.zacsweers.metro.BindingContainer +import dev.zacsweers.metro.Binds +import dev.zacsweers.metro.ContributesTo +import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.di.SessionScope + +@ContributesTo(SessionScope::class) +@BindingContainer +interface UserStatusBindingContainer { + @Binds + fun bindUserStatusPresenter(presenter: UserStatusPresenter): Presenter +} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/userstatus/UserStatusPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/userstatus/UserStatusPresenter.kt index fac82d4505..ea09f59706 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/userstatus/UserStatusPresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/userstatus/UserStatusPresenter.kt @@ -17,13 +17,12 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue -import dev.zacsweers.metro.ContributesBinding +import dev.zacsweers.metro.Inject import io.element.android.libraries.architecture.Presenter -import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.MatrixClient import kotlinx.coroutines.launch -@ContributesBinding(SessionScope::class) +@Inject class UserStatusPresenter( private val matrixClient: MatrixClient, ) : Presenter { diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/userstatus/UserStatusState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/userstatus/UserStatusState.kt index 7cfa03fa81..fa61089144 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/userstatus/UserStatusState.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/userstatus/UserStatusState.kt @@ -9,6 +9,7 @@ package io.element.android.features.preferences.impl.userstatus import androidx.annotation.StringRes import androidx.compose.foundation.text.input.TextFieldState +import androidx.compose.runtime.Immutable import io.element.android.features.preferences.impl.R import io.element.android.libraries.matrix.api.user.DisplayedStatus import io.element.android.libraries.matrix.api.user.UserStatus @@ -20,6 +21,7 @@ data class UserStatusState( val eventSink: (UserStatusEvent) -> Unit, ) +@Immutable sealed interface UserStatusPickerState { data object Hidden : UserStatusPickerState data object ShowingPicker : UserStatusPickerState @@ -29,7 +31,7 @@ sealed interface UserStatusPickerState { ) : UserStatusPickerState } -enum class PredefinedUserStatus(val emoji: String, @param:StringRes val labelRes: Int) { +enum class PredefinedUserStatus(val emoji: String, @StringRes val labelRes: Int) { IN_A_MEETING("💬", R.string.common_user_status_in_a_meeting), FOCUS_TIME("💡", R.string.common_user_status_focus_time), ON_THE_ROAD("🚙", R.string.common_user_status_on_the_road), diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/userstatus/UserStatusView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/userstatus/UserStatusView.kt index f7d37f0adf..245052120c 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/userstatus/UserStatusView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/userstatus/UserStatusView.kt @@ -61,7 +61,7 @@ import io.element.android.libraries.matrix.api.user.UserStatus import io.element.android.libraries.ui.strings.CommonStrings @Composable -fun UserStatusRow( +fun UserStatusView( state: UserStatusState, modifier: Modifier = Modifier, ) { @@ -85,8 +85,8 @@ fun UserStatusRow( UserStatusPickerBottomSheet( currentRawStatus = state.rawStatus, onDismiss = { state.eventSink(UserStatusEvent.DismissPicker) }, - onSelectPredefined = { status -> state.eventSink(UserStatusEvent.SetStatus(status)) }, - onSelectCustom = { state.eventSink(UserStatusEvent.OpenCustomInput) }, + onSelectPredefinedStatus = { status -> state.eventSink(UserStatusEvent.SetStatus(status)) }, + onSelectCustomStatus = { state.eventSink(UserStatusEvent.OpenCustomInput) }, ) } } @@ -95,7 +95,6 @@ fun UserStatusRow( emoji = pickerState.emoji, textFieldState = pickerState.textFieldState, rawStatus = state.rawStatus, - onEmojiChange = { state.eventSink(UserStatusEvent.UpdateCustomEmoji(it)) }, onConfirm = { state.eventSink( UserStatusEvent.SetStatus(UserStatus(pickerState.emoji, pickerState.textFieldState.text.toString())) @@ -159,8 +158,8 @@ private fun CurrentStatusRow( private fun UserStatusPickerBottomSheet( currentRawStatus: UserStatus?, onDismiss: () -> Unit, - onSelectPredefined: (UserStatus) -> Unit, - onSelectCustom: () -> Unit, + onSelectPredefinedStatus: (UserStatus) -> Unit, + onSelectCustomStatus: () -> Unit, modifier: Modifier = Modifier, ) { val sheetState = rememberModalBottomSheetState() @@ -191,7 +190,7 @@ private fun UserStatusPickerBottomSheet( }, onClick = { sheetState.hide(coroutineScope) { - onSelectPredefined(predefinedUserStatus) + onSelectPredefinedStatus(predefinedUserStatus) } }, ) @@ -203,7 +202,7 @@ private fun UserStatusPickerBottomSheet( leadingContent = ListItemContent.Text(text = "✏️"), onClick = { sheetState.hide(coroutineScope) { - onSelectCustom() + onSelectCustomStatus() } }, ) @@ -217,7 +216,6 @@ private fun CustomStatusInputRow( emoji: String, textFieldState: TextFieldState, rawStatus: UserStatus?, - onEmojiChange: (String) -> Unit, onConfirm: () -> Unit, onCancel: () -> Unit, modifier: Modifier = Modifier, @@ -299,6 +297,6 @@ private fun CustomStatusInputRow( @PreviewsDayNight @Composable -internal fun UserStatusRowPreview(@PreviewParameter(UserStatusStateProvider::class) state: UserStatusState) = ElementPreview { - UserStatusRow(state = state) +internal fun UserStatusViewPreview(@PreviewParameter(UserStatusStateProvider::class) state: UserStatusState) = ElementPreview { + UserStatusView(state = state) } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/user/DisplayedStatus.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/user/DisplayedStatus.kt index 046191d7cf..581658ff28 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/user/DisplayedStatus.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/user/DisplayedStatus.kt @@ -8,8 +8,10 @@ package io.element.android.libraries.matrix.api.user import android.os.Parcelable +import androidx.compose.runtime.Immutable import kotlinx.parcelize.Parcelize +@Immutable sealed interface DisplayedStatus : Parcelable { /** Status set manually by the user via m.status. */ @Parcelize diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 92107f3ac2..4d40fa2123 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -138,6 +138,7 @@ import org.matrix.rustcomponents.sdk.CreateRoomParameters as RustCreateRoomParam import org.matrix.rustcomponents.sdk.RoomPreset as RustRoomPreset import org.matrix.rustcomponents.sdk.SyncService as ClientSyncService +@Suppress("LargeClass") class RustMatrixClient( override val sessionPaths: SessionPaths, private val innerClient: Client,