mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-03 16:10:00 +00:00
Address quality issues on user status
This commit is contained in:
+2
-2
@@ -24,8 +24,8 @@ import io.element.android.compound.theme.ElementTheme
|
|||||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||||
import io.element.android.features.preferences.impl.R
|
import io.element.android.features.preferences.impl.R
|
||||||
import io.element.android.features.preferences.impl.user.UserPreferences
|
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.UserStatusState
|
||||||
|
import io.element.android.features.preferences.impl.userstatus.UserStatusView
|
||||||
import io.element.android.libraries.architecture.coverage.ExcludeFromCoverage
|
import io.element.android.libraries.architecture.coverage.ExcludeFromCoverage
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||||
import io.element.android.libraries.designsystem.components.list.ListItemContent
|
import io.element.android.libraries.designsystem.components.list.ListItemContent
|
||||||
@@ -143,7 +143,7 @@ private fun ColumnScope.UserStatusSection(
|
|||||||
color = ElementTheme.colors.bgSubtleSecondary,
|
color = ElementTheme.colors.bgSubtleSecondary,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
UserStatusRow(
|
UserStatusView(
|
||||||
state = userStatusState,
|
state = userStatusState,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
)
|
)
|
||||||
|
|||||||
+21
@@ -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<UserStatusState>
|
||||||
|
}
|
||||||
+2
-3
@@ -17,13 +17,12 @@ import androidx.compose.runtime.mutableStateOf
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
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.architecture.Presenter
|
||||||
import io.element.android.libraries.di.SessionScope
|
|
||||||
import io.element.android.libraries.matrix.api.MatrixClient
|
import io.element.android.libraries.matrix.api.MatrixClient
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@ContributesBinding(SessionScope::class)
|
@Inject
|
||||||
class UserStatusPresenter(
|
class UserStatusPresenter(
|
||||||
private val matrixClient: MatrixClient,
|
private val matrixClient: MatrixClient,
|
||||||
) : Presenter<UserStatusState> {
|
) : Presenter<UserStatusState> {
|
||||||
|
|||||||
+3
-1
@@ -9,6 +9,7 @@ package io.element.android.features.preferences.impl.userstatus
|
|||||||
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.foundation.text.input.TextFieldState
|
import androidx.compose.foundation.text.input.TextFieldState
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import io.element.android.features.preferences.impl.R
|
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.DisplayedStatus
|
||||||
import io.element.android.libraries.matrix.api.user.UserStatus
|
import io.element.android.libraries.matrix.api.user.UserStatus
|
||||||
@@ -20,6 +21,7 @@ data class UserStatusState(
|
|||||||
val eventSink: (UserStatusEvent) -> Unit,
|
val eventSink: (UserStatusEvent) -> Unit,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Immutable
|
||||||
sealed interface UserStatusPickerState {
|
sealed interface UserStatusPickerState {
|
||||||
data object Hidden : UserStatusPickerState
|
data object Hidden : UserStatusPickerState
|
||||||
data object ShowingPicker : UserStatusPickerState
|
data object ShowingPicker : UserStatusPickerState
|
||||||
@@ -29,7 +31,7 @@ sealed interface UserStatusPickerState {
|
|||||||
) : 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),
|
IN_A_MEETING("💬", R.string.common_user_status_in_a_meeting),
|
||||||
FOCUS_TIME("💡", R.string.common_user_status_focus_time),
|
FOCUS_TIME("💡", R.string.common_user_status_focus_time),
|
||||||
ON_THE_ROAD("🚙", R.string.common_user_status_on_the_road),
|
ON_THE_ROAD("🚙", R.string.common_user_status_on_the_road),
|
||||||
|
|||||||
+9
-11
@@ -61,7 +61,7 @@ import io.element.android.libraries.matrix.api.user.UserStatus
|
|||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun UserStatusRow(
|
fun UserStatusView(
|
||||||
state: UserStatusState,
|
state: UserStatusState,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
@@ -85,8 +85,8 @@ fun UserStatusRow(
|
|||||||
UserStatusPickerBottomSheet(
|
UserStatusPickerBottomSheet(
|
||||||
currentRawStatus = state.rawStatus,
|
currentRawStatus = state.rawStatus,
|
||||||
onDismiss = { state.eventSink(UserStatusEvent.DismissPicker) },
|
onDismiss = { state.eventSink(UserStatusEvent.DismissPicker) },
|
||||||
onSelectPredefined = { status -> state.eventSink(UserStatusEvent.SetStatus(status)) },
|
onSelectPredefinedStatus = { status -> state.eventSink(UserStatusEvent.SetStatus(status)) },
|
||||||
onSelectCustom = { state.eventSink(UserStatusEvent.OpenCustomInput) },
|
onSelectCustomStatus = { state.eventSink(UserStatusEvent.OpenCustomInput) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,7 +95,6 @@ fun UserStatusRow(
|
|||||||
emoji = pickerState.emoji,
|
emoji = pickerState.emoji,
|
||||||
textFieldState = pickerState.textFieldState,
|
textFieldState = pickerState.textFieldState,
|
||||||
rawStatus = state.rawStatus,
|
rawStatus = state.rawStatus,
|
||||||
onEmojiChange = { state.eventSink(UserStatusEvent.UpdateCustomEmoji(it)) },
|
|
||||||
onConfirm = {
|
onConfirm = {
|
||||||
state.eventSink(
|
state.eventSink(
|
||||||
UserStatusEvent.SetStatus(UserStatus(pickerState.emoji, pickerState.textFieldState.text.toString()))
|
UserStatusEvent.SetStatus(UserStatus(pickerState.emoji, pickerState.textFieldState.text.toString()))
|
||||||
@@ -159,8 +158,8 @@ private fun CurrentStatusRow(
|
|||||||
private fun UserStatusPickerBottomSheet(
|
private fun UserStatusPickerBottomSheet(
|
||||||
currentRawStatus: UserStatus?,
|
currentRawStatus: UserStatus?,
|
||||||
onDismiss: () -> Unit,
|
onDismiss: () -> Unit,
|
||||||
onSelectPredefined: (UserStatus) -> Unit,
|
onSelectPredefinedStatus: (UserStatus) -> Unit,
|
||||||
onSelectCustom: () -> Unit,
|
onSelectCustomStatus: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val sheetState = rememberModalBottomSheetState()
|
val sheetState = rememberModalBottomSheetState()
|
||||||
@@ -191,7 +190,7 @@ private fun UserStatusPickerBottomSheet(
|
|||||||
},
|
},
|
||||||
onClick = {
|
onClick = {
|
||||||
sheetState.hide(coroutineScope) {
|
sheetState.hide(coroutineScope) {
|
||||||
onSelectPredefined(predefinedUserStatus)
|
onSelectPredefinedStatus(predefinedUserStatus)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -203,7 +202,7 @@ private fun UserStatusPickerBottomSheet(
|
|||||||
leadingContent = ListItemContent.Text(text = "✏️"),
|
leadingContent = ListItemContent.Text(text = "✏️"),
|
||||||
onClick = {
|
onClick = {
|
||||||
sheetState.hide(coroutineScope) {
|
sheetState.hide(coroutineScope) {
|
||||||
onSelectCustom()
|
onSelectCustomStatus()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -217,7 +216,6 @@ private fun CustomStatusInputRow(
|
|||||||
emoji: String,
|
emoji: String,
|
||||||
textFieldState: TextFieldState,
|
textFieldState: TextFieldState,
|
||||||
rawStatus: UserStatus?,
|
rawStatus: UserStatus?,
|
||||||
onEmojiChange: (String) -> Unit,
|
|
||||||
onConfirm: () -> Unit,
|
onConfirm: () -> Unit,
|
||||||
onCancel: () -> Unit,
|
onCancel: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
@@ -299,6 +297,6 @@ private fun CustomStatusInputRow(
|
|||||||
|
|
||||||
@PreviewsDayNight
|
@PreviewsDayNight
|
||||||
@Composable
|
@Composable
|
||||||
internal fun UserStatusRowPreview(@PreviewParameter(UserStatusStateProvider::class) state: UserStatusState) = ElementPreview {
|
internal fun UserStatusViewPreview(@PreviewParameter(UserStatusStateProvider::class) state: UserStatusState) = ElementPreview {
|
||||||
UserStatusRow(state = state)
|
UserStatusView(state = state)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -8,8 +8,10 @@
|
|||||||
package io.element.android.libraries.matrix.api.user
|
package io.element.android.libraries.matrix.api.user
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Immutable
|
||||||
sealed interface DisplayedStatus : Parcelable {
|
sealed interface DisplayedStatus : Parcelable {
|
||||||
/** Status set manually by the user via m.status. */
|
/** Status set manually by the user via m.status. */
|
||||||
@Parcelize
|
@Parcelize
|
||||||
|
|||||||
+1
@@ -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.RoomPreset as RustRoomPreset
|
||||||
import org.matrix.rustcomponents.sdk.SyncService as ClientSyncService
|
import org.matrix.rustcomponents.sdk.SyncService as ClientSyncService
|
||||||
|
|
||||||
|
@Suppress("LargeClass")
|
||||||
class RustMatrixClient(
|
class RustMatrixClient(
|
||||||
override val sessionPaths: SessionPaths,
|
override val sessionPaths: SessionPaths,
|
||||||
private val innerClient: Client,
|
private val innerClient: Client,
|
||||||
|
|||||||
Reference in New Issue
Block a user