Merge pull request #5508 from element-hq/feature/bma/noUriInComposeState
Replace Uri by String in States that are used in Composable function.
This commit is contained in:
commit
7ad659a4c8
16 changed files with 78 additions and 87 deletions
|
|
@ -17,6 +17,7 @@ import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
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.core.net.toUri
|
||||||
import dev.zacsweers.metro.Inject
|
import dev.zacsweers.metro.Inject
|
||||||
import im.vector.app.features.analytics.plan.CreatedRoom
|
import im.vector.app.features.analytics.plan.CreatedRoom
|
||||||
import io.element.android.libraries.architecture.AsyncAction
|
import io.element.android.libraries.architecture.AsyncAction
|
||||||
|
|
@ -157,7 +158,7 @@ class ConfigureRoomPresenter(
|
||||||
createRoomAction: MutableState<AsyncAction<RoomId>>
|
createRoomAction: MutableState<AsyncAction<RoomId>>
|
||||||
) = launch {
|
) = launch {
|
||||||
suspend {
|
suspend {
|
||||||
val avatarUrl = config.avatarUri?.let { uploadAvatar(it) }
|
val avatarUrl = config.avatarUri?.let { uploadAvatar(it.toUri()) }
|
||||||
val params = if (config.roomVisibility is RoomVisibilityState.Public) {
|
val params = if (config.roomVisibility is RoomVisibilityState.Public) {
|
||||||
CreateRoomParameters(
|
CreateRoomParameters(
|
||||||
name = config.roomName,
|
name = config.roomName,
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
package io.element.android.features.createroom.impl.configureroom
|
package io.element.android.features.createroom.impl.configureroom
|
||||||
|
|
||||||
import android.net.Uri
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
|
@ -192,7 +191,7 @@ private fun ConfigureRoomToolbar(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun RoomNameWithAvatar(
|
private fun RoomNameWithAvatar(
|
||||||
avatarUri: Uri?,
|
avatarUri: String?,
|
||||||
roomName: String,
|
roomName: String,
|
||||||
onAvatarClick: () -> Unit,
|
onAvatarClick: () -> Unit,
|
||||||
onChangeRoomName: (String) -> Unit,
|
onChangeRoomName: (String) -> Unit,
|
||||||
|
|
|
||||||
|
|
@ -7,18 +7,14 @@
|
||||||
|
|
||||||
package io.element.android.features.createroom.impl.configureroom
|
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 io.element.android.libraries.matrix.api.user.MatrixUser
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
|
|
||||||
// Annotate with @Immutable since `Uri` is unstable
|
|
||||||
@Immutable
|
|
||||||
data class CreateRoomConfig(
|
data class CreateRoomConfig(
|
||||||
val roomName: String? = null,
|
val roomName: String? = null,
|
||||||
val topic: String? = null,
|
val topic: String? = null,
|
||||||
val avatarUri: Uri? = null,
|
val avatarUri: String? = null,
|
||||||
val invites: ImmutableList<MatrixUser> = persistentListOf(),
|
val invites: ImmutableList<MatrixUser> = persistentListOf(),
|
||||||
val roomVisibility: RoomVisibilityState = RoomVisibilityState.Private,
|
val roomVisibility: RoomVisibilityState = RoomVisibilityState.Private,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ class CreateRoomConfigStore(
|
||||||
fun setAvatarUri(uri: Uri?, cached: Boolean = false) {
|
fun setAvatarUri(uri: Uri?, cached: Boolean = false) {
|
||||||
cachedAvatarUri = uri.takeIf { cached }
|
cachedAvatarUri = uri.takeIf { cached }
|
||||||
createRoomConfigFlow.getAndUpdate { config ->
|
createRoomConfigFlow.getAndUpdate { config ->
|
||||||
config.copy(avatarUri = uri)
|
config.copy(avatarUri = uri?.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
package io.element.android.features.startchat.impl.configureroom
|
package io.element.android.features.startchat.impl.configureroom
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import androidx.core.net.toUri
|
||||||
import app.cash.turbine.TurbineTestContext
|
import app.cash.turbine.TurbineTestContext
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import im.vector.app.features.analytics.plan.CreatedRoom
|
import im.vector.app.features.analytics.plan.CreatedRoom
|
||||||
|
|
@ -155,15 +156,15 @@ class ConfigureRoomPresenterTest {
|
||||||
// Pick avatar
|
// Pick avatar
|
||||||
pickerProvider.givenResult(null)
|
pickerProvider.givenResult(null)
|
||||||
// From gallery
|
// From gallery
|
||||||
val uriFromGallery = Uri.parse(AN_URI_FROM_GALLERY)
|
val uriFromGallery = AN_URI_FROM_GALLERY
|
||||||
pickerProvider.givenResult(uriFromGallery)
|
pickerProvider.givenResult(uriFromGallery.toUri())
|
||||||
newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.ChoosePhoto))
|
newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.ChoosePhoto))
|
||||||
newState = awaitItem()
|
newState = awaitItem()
|
||||||
expectedConfig = expectedConfig.copy(avatarUri = uriFromGallery)
|
expectedConfig = expectedConfig.copy(avatarUri = uriFromGallery)
|
||||||
assertThat(newState.config).isEqualTo(expectedConfig)
|
assertThat(newState.config).isEqualTo(expectedConfig)
|
||||||
// From camera
|
// From camera
|
||||||
val uriFromCamera = Uri.parse(AN_URI_FROM_CAMERA)
|
val uriFromCamera = AN_URI_FROM_CAMERA
|
||||||
pickerProvider.givenResult(uriFromCamera)
|
pickerProvider.givenResult(uriFromCamera.toUri())
|
||||||
assertThat(newState.cameraPermissionState.permissionGranted).isFalse()
|
assertThat(newState.cameraPermissionState.permissionGranted).isFalse()
|
||||||
newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
||||||
newState = awaitItem()
|
newState = awaitItem()
|
||||||
|
|
@ -175,8 +176,8 @@ class ConfigureRoomPresenterTest {
|
||||||
expectedConfig = expectedConfig.copy(avatarUri = uriFromCamera)
|
expectedConfig = expectedConfig.copy(avatarUri = uriFromCamera)
|
||||||
assertThat(newState.config).isEqualTo(expectedConfig)
|
assertThat(newState.config).isEqualTo(expectedConfig)
|
||||||
// Do it again, no permission is requested
|
// Do it again, no permission is requested
|
||||||
val uriFromCamera2 = Uri.parse(AN_URI_FROM_CAMERA_2)
|
val uriFromCamera2 = AN_URI_FROM_CAMERA_2
|
||||||
pickerProvider.givenResult(uriFromCamera2)
|
pickerProvider.givenResult(uriFromCamera2.toUri())
|
||||||
newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
||||||
newState = awaitItem()
|
newState = awaitItem()
|
||||||
expectedConfig = expectedConfig.copy(avatarUri = uriFromCamera2)
|
expectedConfig = expectedConfig.copy(avatarUri = uriFromCamera2)
|
||||||
|
|
|
||||||
|
|
@ -62,21 +62,21 @@ class EditUserProfilePresenter(
|
||||||
@Composable
|
@Composable
|
||||||
override fun present(): EditUserProfileState {
|
override fun present(): EditUserProfileState {
|
||||||
val cameraPermissionState = cameraPermissionPresenter.present()
|
val cameraPermissionState = cameraPermissionPresenter.present()
|
||||||
var userAvatarUri by rememberSaveable { mutableStateOf(matrixUser.avatarUrl?.toUri()) }
|
var userAvatarUri by rememberSaveable { mutableStateOf(matrixUser.avatarUrl) }
|
||||||
var userDisplayName by rememberSaveable { mutableStateOf(matrixUser.displayName) }
|
var userDisplayName by rememberSaveable { mutableStateOf(matrixUser.displayName) }
|
||||||
val cameraPhotoPicker = mediaPickerProvider.registerCameraPhotoPicker(
|
val cameraPhotoPicker = mediaPickerProvider.registerCameraPhotoPicker(
|
||||||
onResult = { uri ->
|
onResult = { uri ->
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
temporaryUriDeleter.delete(userAvatarUri)
|
temporaryUriDeleter.delete(userAvatarUri?.toUri())
|
||||||
userAvatarUri = uri
|
userAvatarUri = uri.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
val galleryImagePicker = mediaPickerProvider.registerGalleryImagePicker(
|
val galleryImagePicker = mediaPickerProvider.registerGalleryImagePicker(
|
||||||
onResult = { uri ->
|
onResult = { uri ->
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
temporaryUriDeleter.delete(userAvatarUri)
|
temporaryUriDeleter.delete(userAvatarUri?.toUri())
|
||||||
userAvatarUri = uri
|
userAvatarUri = uri.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -102,7 +102,12 @@ class EditUserProfilePresenter(
|
||||||
val localCoroutineScope = rememberCoroutineScope()
|
val localCoroutineScope = rememberCoroutineScope()
|
||||||
fun handleEvents(event: EditUserProfileEvents) {
|
fun handleEvents(event: EditUserProfileEvents) {
|
||||||
when (event) {
|
when (event) {
|
||||||
is EditUserProfileEvents.Save -> localCoroutineScope.saveChanges(userDisplayName, userAvatarUri, matrixUser, saveAction)
|
is EditUserProfileEvents.Save -> localCoroutineScope.saveChanges(
|
||||||
|
name = userDisplayName,
|
||||||
|
avatarUri = userAvatarUri?.toUri(),
|
||||||
|
currentUser = matrixUser,
|
||||||
|
action = saveAction,
|
||||||
|
)
|
||||||
is EditUserProfileEvents.HandleAvatarAction -> {
|
is EditUserProfileEvents.HandleAvatarAction -> {
|
||||||
when (event.action) {
|
when (event.action) {
|
||||||
AvatarAction.ChoosePhoto -> galleryImagePicker.launch()
|
AvatarAction.ChoosePhoto -> galleryImagePicker.launch()
|
||||||
|
|
@ -113,7 +118,7 @@ class EditUserProfilePresenter(
|
||||||
cameraPermissionState.eventSink(PermissionsEvents.RequestPermissions)
|
cameraPermissionState.eventSink(PermissionsEvents.RequestPermissions)
|
||||||
}
|
}
|
||||||
AvatarAction.Remove -> {
|
AvatarAction.Remove -> {
|
||||||
temporaryUriDeleter.delete(userAvatarUri)
|
temporaryUriDeleter.delete(userAvatarUri?.toUri())
|
||||||
userAvatarUri = null
|
userAvatarUri = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -145,9 +150,8 @@ class EditUserProfilePresenter(
|
||||||
private fun hasDisplayNameChanged(name: String?, currentUser: MatrixUser) =
|
private fun hasDisplayNameChanged(name: String?, currentUser: MatrixUser) =
|
||||||
name?.trim() != currentUser.displayName?.trim()
|
name?.trim() != currentUser.displayName?.trim()
|
||||||
|
|
||||||
private fun hasAvatarUrlChanged(avatarUri: Uri?, currentUser: MatrixUser) =
|
private fun hasAvatarUrlChanged(avatarUri: String?, currentUser: MatrixUser) =
|
||||||
// Need to call `toUri()?.toString()` to make the test pass (we mockk Uri)
|
avatarUri?.trim() != currentUser.avatarUrl?.trim()
|
||||||
avatarUri?.toString()?.trim() != currentUser.avatarUrl?.toUri()?.toString()?.trim()
|
|
||||||
|
|
||||||
private fun CoroutineScope.saveChanges(
|
private fun CoroutineScope.saveChanges(
|
||||||
name: String?,
|
name: String?,
|
||||||
|
|
|
||||||
|
|
@ -7,20 +7,16 @@
|
||||||
|
|
||||||
package io.element.android.features.preferences.impl.user.editprofile
|
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.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.ui.media.AvatarAction
|
import io.element.android.libraries.matrix.ui.media.AvatarAction
|
||||||
import io.element.android.libraries.permissions.api.PermissionsState
|
import io.element.android.libraries.permissions.api.PermissionsState
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
|
||||||
// Annotate with @Immutable since `Uri` is unstable
|
|
||||||
@Immutable
|
|
||||||
data class EditUserProfileState(
|
data class EditUserProfileState(
|
||||||
val userId: UserId,
|
val userId: UserId,
|
||||||
val displayName: String,
|
val displayName: String,
|
||||||
val userAvatarUrl: Uri?,
|
val userAvatarUrl: String?,
|
||||||
val avatarActions: ImmutableList<AvatarAction>,
|
val avatarActions: ImmutableList<AvatarAction>,
|
||||||
val saveButtonEnabled: Boolean,
|
val saveButtonEnabled: Boolean,
|
||||||
val saveAction: AsyncAction<Unit>,
|
val saveAction: AsyncAction<Unit>,
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,7 @@
|
||||||
|
|
||||||
package io.element.android.features.preferences.impl.user.editprofile
|
package io.element.android.features.preferences.impl.user.editprofile
|
||||||
|
|
||||||
import android.net.Uri
|
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
import androidx.core.net.toUri
|
|
||||||
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.permissions.api.aPermissionsState
|
import io.element.android.libraries.permissions.api.aPermissionsState
|
||||||
|
|
@ -19,13 +17,13 @@ open class EditUserProfileStateProvider : PreviewParameterProvider<EditUserProfi
|
||||||
override val values: Sequence<EditUserProfileState>
|
override val values: Sequence<EditUserProfileState>
|
||||||
get() = sequenceOf(
|
get() = sequenceOf(
|
||||||
aEditUserProfileState(),
|
aEditUserProfileState(),
|
||||||
aEditUserProfileState(userAvatarUrl = "example://uri".toUri()),
|
aEditUserProfileState(userAvatarUrl = "example://uri"),
|
||||||
// Add other states here
|
// Add other states here
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun aEditUserProfileState(
|
fun aEditUserProfileState(
|
||||||
userAvatarUrl: Uri? = null,
|
userAvatarUrl: String? = null,
|
||||||
) = EditUserProfileState(
|
) = EditUserProfileState(
|
||||||
userId = UserId("@john.doe:matrix.org"),
|
userId = UserId("@john.doe:matrix.org"),
|
||||||
displayName = "John Doe",
|
displayName = "John Doe",
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,9 @@ class EditUserProfilePresenterTest {
|
||||||
mockkStatic(Uri::class)
|
mockkStatic(Uri::class)
|
||||||
|
|
||||||
every { Uri.parse(AN_AVATAR_URL) } returns userAvatarUri
|
every { Uri.parse(AN_AVATAR_URL) } returns userAvatarUri
|
||||||
|
every { userAvatarUri.toString() } returns AN_AVATAR_URL
|
||||||
every { Uri.parse(ANOTHER_AVATAR_URL) } returns anotherAvatarUri
|
every { Uri.parse(ANOTHER_AVATAR_URL) } returns anotherAvatarUri
|
||||||
|
every { anotherAvatarUri.toString() } returns ANOTHER_AVATAR_URL
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
|
@ -102,7 +104,7 @@ class EditUserProfilePresenterTest {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
assertThat(initialState.userId).isEqualTo(user.userId)
|
assertThat(initialState.userId).isEqualTo(user.userId)
|
||||||
assertThat(initialState.displayName).isEqualTo(user.displayName)
|
assertThat(initialState.displayName).isEqualTo(user.displayName)
|
||||||
assertThat(initialState.userAvatarUrl).isEqualTo(userAvatarUri)
|
assertThat(initialState.userAvatarUrl).isEqualTo(AN_AVATAR_URL)
|
||||||
assertThat(initialState.avatarActions).containsExactly(
|
assertThat(initialState.avatarActions).containsExactly(
|
||||||
AvatarAction.ChoosePhoto,
|
AvatarAction.ChoosePhoto,
|
||||||
AvatarAction.TakePhoto,
|
AvatarAction.TakePhoto,
|
||||||
|
|
@ -127,16 +129,16 @@ class EditUserProfilePresenterTest {
|
||||||
}.test {
|
}.test {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
assertThat(initialState.displayName).isEqualTo("Name")
|
assertThat(initialState.displayName).isEqualTo("Name")
|
||||||
assertThat(initialState.userAvatarUrl).isEqualTo(userAvatarUri)
|
assertThat(initialState.userAvatarUrl).isEqualTo(AN_AVATAR_URL)
|
||||||
initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("Name II"))
|
initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("Name II"))
|
||||||
awaitItem().apply {
|
awaitItem().apply {
|
||||||
assertThat(displayName).isEqualTo("Name II")
|
assertThat(displayName).isEqualTo("Name II")
|
||||||
assertThat(userAvatarUrl).isEqualTo(userAvatarUri)
|
assertThat(userAvatarUrl).isEqualTo(AN_AVATAR_URL)
|
||||||
}
|
}
|
||||||
initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("Name III"))
|
initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("Name III"))
|
||||||
awaitItem().apply {
|
awaitItem().apply {
|
||||||
assertThat(displayName).isEqualTo("Name III")
|
assertThat(displayName).isEqualTo("Name III")
|
||||||
assertThat(userAvatarUrl).isEqualTo(userAvatarUri)
|
assertThat(userAvatarUrl).isEqualTo(AN_AVATAR_URL)
|
||||||
}
|
}
|
||||||
initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.Remove))
|
initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.Remove))
|
||||||
awaitItem().apply {
|
awaitItem().apply {
|
||||||
|
|
@ -160,10 +162,10 @@ class EditUserProfilePresenterTest {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
assertThat(initialState.userAvatarUrl).isEqualTo(userAvatarUri)
|
assertThat(initialState.userAvatarUrl).isEqualTo(AN_AVATAR_URL)
|
||||||
initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.ChoosePhoto))
|
initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.ChoosePhoto))
|
||||||
awaitItem().apply {
|
awaitItem().apply {
|
||||||
assertThat(userAvatarUrl).isEqualTo(anotherAvatarUri)
|
assertThat(userAvatarUrl).isEqualTo(ANOTHER_AVATAR_URL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -185,7 +187,7 @@ class EditUserProfilePresenterTest {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
assertThat(initialState.userAvatarUrl).isEqualTo(userAvatarUri)
|
assertThat(initialState.userAvatarUrl).isEqualTo(AN_AVATAR_URL)
|
||||||
assertThat(initialState.cameraPermissionState.permissionGranted).isFalse()
|
assertThat(initialState.cameraPermissionState.permissionGranted).isFalse()
|
||||||
initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
||||||
val stateWithAskingPermission = awaitItem()
|
val stateWithAskingPermission = awaitItem()
|
||||||
|
|
@ -194,12 +196,12 @@ class EditUserProfilePresenterTest {
|
||||||
val stateWithPermission = awaitItem()
|
val stateWithPermission = awaitItem()
|
||||||
assertThat(stateWithPermission.cameraPermissionState.permissionGranted).isTrue()
|
assertThat(stateWithPermission.cameraPermissionState.permissionGranted).isTrue()
|
||||||
val stateWithNewAvatar = awaitItem()
|
val stateWithNewAvatar = awaitItem()
|
||||||
assertThat(stateWithNewAvatar.userAvatarUrl).isEqualTo(anotherAvatarUri)
|
assertThat(stateWithNewAvatar.userAvatarUrl).isEqualTo(ANOTHER_AVATAR_URL)
|
||||||
// Do it again, no permission is requested
|
// Do it again, no permission is requested
|
||||||
fakePickerProvider.givenResult(userAvatarUri)
|
fakePickerProvider.givenResult(userAvatarUri)
|
||||||
stateWithNewAvatar.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
stateWithNewAvatar.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
||||||
val stateWithNewAvatar2 = awaitItem()
|
val stateWithNewAvatar2 = awaitItem()
|
||||||
assertThat(stateWithNewAvatar2.userAvatarUrl).isEqualTo(userAvatarUri)
|
assertThat(stateWithNewAvatar2.userAvatarUrl).isEqualTo(AN_AVATAR_URL)
|
||||||
deleteCallback.assertions().isCalledExactly(2).withSequence(
|
deleteCallback.assertions().isCalledExactly(2).withSequence(
|
||||||
listOf(value(userAvatarUri)),
|
listOf(value(userAvatarUri)),
|
||||||
listOf(value(anotherAvatarUri)),
|
listOf(value(anotherAvatarUri)),
|
||||||
|
|
|
||||||
|
|
@ -61,11 +61,11 @@ class RoomDetailsEditPresenter(
|
||||||
val cameraPermissionState = cameraPermissionPresenter.present()
|
val cameraPermissionState = cameraPermissionPresenter.present()
|
||||||
val roomSyncUpdateFlow = room.syncUpdateFlow.collectAsState()
|
val roomSyncUpdateFlow = room.syncUpdateFlow.collectAsState()
|
||||||
|
|
||||||
val roomAvatarUri = room.avatarUrl()?.toUri()
|
val roomAvatarUri = room.avatarUrl()
|
||||||
var roomAvatarUriEdited by rememberSaveable { mutableStateOf<Uri?>(null) }
|
var roomAvatarUriEdited by rememberSaveable { mutableStateOf<String?>(null) }
|
||||||
LaunchedEffect(roomAvatarUri) {
|
LaunchedEffect(roomAvatarUri) {
|
||||||
// Every time the roomAvatar change (from sync), we can set the new avatar.
|
// Every time the roomAvatar change (from sync), we can set the new avatar.
|
||||||
temporaryUriDeleter.delete(roomAvatarUriEdited)
|
temporaryUriDeleter.delete(roomAvatarUriEdited?.toUri())
|
||||||
roomAvatarUriEdited = roomAvatarUri
|
roomAvatarUriEdited = roomAvatarUri
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,16 +107,16 @@ class RoomDetailsEditPresenter(
|
||||||
val cameraPhotoPicker = mediaPickerProvider.registerCameraPhotoPicker(
|
val cameraPhotoPicker = mediaPickerProvider.registerCameraPhotoPicker(
|
||||||
onResult = { uri ->
|
onResult = { uri ->
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
temporaryUriDeleter.delete(roomAvatarUriEdited)
|
temporaryUriDeleter.delete(roomAvatarUriEdited?.toUri())
|
||||||
roomAvatarUriEdited = uri
|
roomAvatarUriEdited = uri.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
val galleryImagePicker = mediaPickerProvider.registerGalleryImagePicker(
|
val galleryImagePicker = mediaPickerProvider.registerGalleryImagePicker(
|
||||||
onResult = { uri ->
|
onResult = { uri ->
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
temporaryUriDeleter.delete(roomAvatarUriEdited)
|
temporaryUriDeleter.delete(roomAvatarUriEdited?.toUri())
|
||||||
roomAvatarUriEdited = uri
|
roomAvatarUriEdited = uri.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -147,8 +147,8 @@ class RoomDetailsEditPresenter(
|
||||||
newNameTrimmed = roomRawNameEdited.trim(),
|
newNameTrimmed = roomRawNameEdited.trim(),
|
||||||
currentTopicTrimmed = roomTopicTrimmed,
|
currentTopicTrimmed = roomTopicTrimmed,
|
||||||
newTopicTrimmed = roomTopicEdited.trim(),
|
newTopicTrimmed = roomTopicEdited.trim(),
|
||||||
currentAvatar = roomAvatarUri,
|
currentAvatar = roomAvatarUri?.toUri(),
|
||||||
newAvatarUri = roomAvatarUriEdited,
|
newAvatarUri = roomAvatarUriEdited?.toUri(),
|
||||||
action = saveAction,
|
action = saveAction,
|
||||||
)
|
)
|
||||||
is RoomDetailsEditEvents.HandleAvatarAction -> {
|
is RoomDetailsEditEvents.HandleAvatarAction -> {
|
||||||
|
|
@ -161,7 +161,7 @@ class RoomDetailsEditPresenter(
|
||||||
cameraPermissionState.eventSink(PermissionsEvents.RequestPermissions)
|
cameraPermissionState.eventSink(PermissionsEvents.RequestPermissions)
|
||||||
}
|
}
|
||||||
AvatarAction.Remove -> {
|
AvatarAction.Remove -> {
|
||||||
temporaryUriDeleter.delete(roomAvatarUriEdited)
|
temporaryUriDeleter.delete(roomAvatarUriEdited?.toUri())
|
||||||
roomAvatarUriEdited = null
|
roomAvatarUriEdited = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,12 @@
|
||||||
|
|
||||||
package io.element.android.features.roomdetails.impl.edit
|
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.architecture.AsyncAction
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
import io.element.android.libraries.matrix.ui.media.AvatarAction
|
import io.element.android.libraries.matrix.ui.media.AvatarAction
|
||||||
import io.element.android.libraries.permissions.api.PermissionsState
|
import io.element.android.libraries.permissions.api.PermissionsState
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
|
||||||
// Annotate with @Immutable since `Uri` is unstable
|
|
||||||
@Immutable
|
|
||||||
data class RoomDetailsEditState(
|
data class RoomDetailsEditState(
|
||||||
val roomId: RoomId,
|
val roomId: RoomId,
|
||||||
/** The raw room name (i.e. the room name from the state event `m.room.name`), not the display name. */
|
/** The raw room name (i.e. the room name from the state event `m.room.name`), not the display name. */
|
||||||
|
|
@ -24,7 +20,7 @@ data class RoomDetailsEditState(
|
||||||
val canChangeName: Boolean,
|
val canChangeName: Boolean,
|
||||||
val roomTopic: String,
|
val roomTopic: String,
|
||||||
val canChangeTopic: Boolean,
|
val canChangeTopic: Boolean,
|
||||||
val roomAvatarUrl: Uri?,
|
val roomAvatarUrl: String?,
|
||||||
val canChangeAvatar: Boolean,
|
val canChangeAvatar: Boolean,
|
||||||
val avatarActions: ImmutableList<AvatarAction>,
|
val avatarActions: ImmutableList<AvatarAction>,
|
||||||
val saveButtonEnabled: Boolean,
|
val saveButtonEnabled: Boolean,
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,7 @@
|
||||||
|
|
||||||
package io.element.android.features.roomdetails.impl.edit
|
package io.element.android.features.roomdetails.impl.edit
|
||||||
|
|
||||||
import android.net.Uri
|
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
import androidx.core.net.toUri
|
|
||||||
import io.element.android.libraries.architecture.AsyncAction
|
import io.element.android.libraries.architecture.AsyncAction
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
import io.element.android.libraries.matrix.ui.media.AvatarAction
|
import io.element.android.libraries.matrix.ui.media.AvatarAction
|
||||||
|
|
@ -23,7 +21,7 @@ open class RoomDetailsEditStateProvider : PreviewParameterProvider<RoomDetailsEd
|
||||||
aRoomDetailsEditState(),
|
aRoomDetailsEditState(),
|
||||||
aRoomDetailsEditState(roomTopic = ""),
|
aRoomDetailsEditState(roomTopic = ""),
|
||||||
aRoomDetailsEditState(roomRawName = ""),
|
aRoomDetailsEditState(roomRawName = ""),
|
||||||
aRoomDetailsEditState(roomAvatarUrl = "example://uri".toUri()),
|
aRoomDetailsEditState(roomAvatarUrl = "example://uri"),
|
||||||
aRoomDetailsEditState(canChangeName = true, canChangeTopic = false, canChangeAvatar = true, saveButtonEnabled = false),
|
aRoomDetailsEditState(canChangeName = true, canChangeTopic = false, canChangeAvatar = true, saveButtonEnabled = false),
|
||||||
aRoomDetailsEditState(canChangeName = false, canChangeTopic = true, canChangeAvatar = false, saveButtonEnabled = false),
|
aRoomDetailsEditState(canChangeName = false, canChangeTopic = true, canChangeAvatar = false, saveButtonEnabled = false),
|
||||||
aRoomDetailsEditState(saveAction = AsyncAction.Loading),
|
aRoomDetailsEditState(saveAction = AsyncAction.Loading),
|
||||||
|
|
@ -37,7 +35,7 @@ fun aRoomDetailsEditState(
|
||||||
canChangeName: Boolean = true,
|
canChangeName: Boolean = true,
|
||||||
roomTopic: String = "a room topic that is quite long so should wrap onto multiple lines",
|
roomTopic: String = "a room topic that is quite long so should wrap onto multiple lines",
|
||||||
canChangeTopic: Boolean = true,
|
canChangeTopic: Boolean = true,
|
||||||
roomAvatarUrl: Uri? = null,
|
roomAvatarUrl: String? = null,
|
||||||
canChangeAvatar: Boolean = true,
|
canChangeAvatar: Boolean = true,
|
||||||
avatarActions: List<AvatarAction> = emptyList(),
|
avatarActions: List<AvatarAction> = emptyList(),
|
||||||
saveButtonEnabled: Boolean = true,
|
saveButtonEnabled: Boolean = true,
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,9 @@ class RoomDetailsEditPresenterTest {
|
||||||
mockkStatic(Uri::class)
|
mockkStatic(Uri::class)
|
||||||
|
|
||||||
every { Uri.parse(AN_AVATAR_URL) } returns roomAvatarUri
|
every { Uri.parse(AN_AVATAR_URL) } returns roomAvatarUri
|
||||||
|
every { roomAvatarUri.toString() } returns AN_AVATAR_URL
|
||||||
every { Uri.parse(ANOTHER_AVATAR_URL) } returns anotherAvatarUri
|
every { Uri.parse(ANOTHER_AVATAR_URL) } returns anotherAvatarUri
|
||||||
|
every { anotherAvatarUri.toString() } returns ANOTHER_AVATAR_URL
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
|
@ -107,7 +109,7 @@ class RoomDetailsEditPresenterTest {
|
||||||
val initialState = awaitFirstItem()
|
val initialState = awaitFirstItem()
|
||||||
assertThat(initialState.roomId).isEqualTo(room.roomId)
|
assertThat(initialState.roomId).isEqualTo(room.roomId)
|
||||||
assertThat(initialState.roomRawName).isEqualTo(A_ROOM_RAW_NAME)
|
assertThat(initialState.roomRawName).isEqualTo(A_ROOM_RAW_NAME)
|
||||||
assertThat(initialState.roomAvatarUrl).isEqualTo(roomAvatarUri)
|
assertThat(initialState.roomAvatarUrl).isEqualTo(AN_AVATAR_URL)
|
||||||
assertThat(initialState.roomTopic).isEqualTo(room.info().topic.orEmpty())
|
assertThat(initialState.roomTopic).isEqualTo(room.info().topic.orEmpty())
|
||||||
assertThat(initialState.avatarActions).containsExactly(
|
assertThat(initialState.avatarActions).containsExactly(
|
||||||
AvatarAction.ChoosePhoto,
|
AvatarAction.ChoosePhoto,
|
||||||
|
|
@ -233,24 +235,24 @@ class RoomDetailsEditPresenterTest {
|
||||||
val initialState = awaitFirstItem()
|
val initialState = awaitFirstItem()
|
||||||
assertThat(initialState.roomTopic).isEqualTo("My topic")
|
assertThat(initialState.roomTopic).isEqualTo("My topic")
|
||||||
assertThat(initialState.roomRawName).isEqualTo("Name")
|
assertThat(initialState.roomRawName).isEqualTo("Name")
|
||||||
assertThat(initialState.roomAvatarUrl).isEqualTo(roomAvatarUri)
|
assertThat(initialState.roomAvatarUrl).isEqualTo(AN_AVATAR_URL)
|
||||||
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("Name II"))
|
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("Name II"))
|
||||||
awaitItem().apply {
|
awaitItem().apply {
|
||||||
assertThat(roomTopic).isEqualTo("My topic")
|
assertThat(roomTopic).isEqualTo("My topic")
|
||||||
assertThat(roomRawName).isEqualTo("Name II")
|
assertThat(roomRawName).isEqualTo("Name II")
|
||||||
assertThat(roomAvatarUrl).isEqualTo(roomAvatarUri)
|
assertThat(roomAvatarUrl).isEqualTo(AN_AVATAR_URL)
|
||||||
}
|
}
|
||||||
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("Name III"))
|
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("Name III"))
|
||||||
awaitItem().apply {
|
awaitItem().apply {
|
||||||
assertThat(roomTopic).isEqualTo("My topic")
|
assertThat(roomTopic).isEqualTo("My topic")
|
||||||
assertThat(roomRawName).isEqualTo("Name III")
|
assertThat(roomRawName).isEqualTo("Name III")
|
||||||
assertThat(roomAvatarUrl).isEqualTo(roomAvatarUri)
|
assertThat(roomAvatarUrl).isEqualTo(AN_AVATAR_URL)
|
||||||
}
|
}
|
||||||
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("Another topic"))
|
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("Another topic"))
|
||||||
awaitItem().apply {
|
awaitItem().apply {
|
||||||
assertThat(roomTopic).isEqualTo("Another topic")
|
assertThat(roomTopic).isEqualTo("Another topic")
|
||||||
assertThat(roomRawName).isEqualTo("Name III")
|
assertThat(roomRawName).isEqualTo("Name III")
|
||||||
assertThat(roomAvatarUrl).isEqualTo(roomAvatarUri)
|
assertThat(roomAvatarUrl).isEqualTo(AN_AVATAR_URL)
|
||||||
}
|
}
|
||||||
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.Remove))
|
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.Remove))
|
||||||
awaitItem().apply {
|
awaitItem().apply {
|
||||||
|
|
@ -277,10 +279,10 @@ class RoomDetailsEditPresenterTest {
|
||||||
)
|
)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
val initialState = awaitFirstItem()
|
val initialState = awaitFirstItem()
|
||||||
assertThat(initialState.roomAvatarUrl).isEqualTo(roomAvatarUri)
|
assertThat(initialState.roomAvatarUrl).isEqualTo(AN_AVATAR_URL)
|
||||||
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto))
|
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto))
|
||||||
awaitItem().apply {
|
awaitItem().apply {
|
||||||
assertThat(roomAvatarUrl).isEqualTo(anotherAvatarUri)
|
assertThat(roomAvatarUrl).isEqualTo(anotherAvatarUri.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -303,7 +305,7 @@ class RoomDetailsEditPresenterTest {
|
||||||
)
|
)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
val initialState = awaitFirstItem()
|
val initialState = awaitFirstItem()
|
||||||
assertThat(initialState.roomAvatarUrl).isEqualTo(roomAvatarUri)
|
assertThat(initialState.roomAvatarUrl).isEqualTo(AN_AVATAR_URL)
|
||||||
assertThat(initialState.cameraPermissionState.permissionGranted).isFalse()
|
assertThat(initialState.cameraPermissionState.permissionGranted).isFalse()
|
||||||
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
||||||
val stateWithAskingPermission = awaitItem()
|
val stateWithAskingPermission = awaitItem()
|
||||||
|
|
@ -312,12 +314,12 @@ class RoomDetailsEditPresenterTest {
|
||||||
val stateWithPermission = awaitItem()
|
val stateWithPermission = awaitItem()
|
||||||
assertThat(stateWithPermission.cameraPermissionState.permissionGranted).isTrue()
|
assertThat(stateWithPermission.cameraPermissionState.permissionGranted).isTrue()
|
||||||
val stateWithNewAvatar = awaitItem()
|
val stateWithNewAvatar = awaitItem()
|
||||||
assertThat(stateWithNewAvatar.roomAvatarUrl).isEqualTo(anotherAvatarUri)
|
assertThat(stateWithNewAvatar.roomAvatarUrl).isEqualTo(anotherAvatarUri.toString())
|
||||||
// Do it again, no permission is requested
|
// Do it again, no permission is requested
|
||||||
fakePickerProvider.givenResult(roomAvatarUri)
|
fakePickerProvider.givenResult(roomAvatarUri)
|
||||||
stateWithNewAvatar.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
stateWithNewAvatar.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
||||||
val stateWithNewAvatar2 = awaitItem()
|
val stateWithNewAvatar2 = awaitItem()
|
||||||
assertThat(stateWithNewAvatar2.roomAvatarUrl).isEqualTo(roomAvatarUri)
|
assertThat(stateWithNewAvatar2.roomAvatarUrl).isEqualTo(AN_AVATAR_URL)
|
||||||
deleteCallback.assertions().isCalledExactly(3).withSequence(
|
deleteCallback.assertions().isCalledExactly(3).withSequence(
|
||||||
listOf(value(null)),
|
listOf(value(null)),
|
||||||
listOf(value(roomAvatarUri)),
|
listOf(value(roomAvatarUri)),
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.ui.components
|
package io.element.android.libraries.matrix.ui.components
|
||||||
|
|
||||||
import android.net.Uri
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
|
@ -28,7 +27,6 @@ import androidx.compose.ui.semantics.contentDescription
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.net.toUri
|
|
||||||
import io.element.android.compound.theme.ElementTheme
|
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.libraries.designsystem.components.avatar.Avatar
|
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
||||||
|
|
@ -47,7 +45,7 @@ import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
fun EditableAvatarView(
|
fun EditableAvatarView(
|
||||||
matrixId: String,
|
matrixId: String,
|
||||||
displayName: String?,
|
displayName: String?,
|
||||||
avatarUrl: Uri?,
|
avatarUrl: String?,
|
||||||
avatarSize: AvatarSize,
|
avatarSize: AvatarSize,
|
||||||
avatarType: AvatarType,
|
avatarType: AvatarType,
|
||||||
onAvatarClick: () -> Unit,
|
onAvatarClick: () -> Unit,
|
||||||
|
|
@ -71,13 +69,13 @@ fun EditableAvatarView(
|
||||||
contentDescription = a11yAvatar
|
contentDescription = a11yAvatar
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
when (avatarUrl?.scheme) {
|
when {
|
||||||
null, "mxc" -> {
|
avatarUrl == null || avatarUrl.startsWith("mxc://") -> {
|
||||||
Avatar(
|
Avatar(
|
||||||
avatarData = AvatarData(
|
avatarData = AvatarData(
|
||||||
id = matrixId,
|
id = matrixId,
|
||||||
name = displayName,
|
name = displayName,
|
||||||
url = avatarUrl?.toString(),
|
url = avatarUrl,
|
||||||
size = avatarSize,
|
size = avatarSize,
|
||||||
),
|
),
|
||||||
avatarType = avatarType,
|
avatarType = avatarType,
|
||||||
|
|
@ -114,7 +112,7 @@ fun EditableAvatarView(
|
||||||
@PreviewsDayNight
|
@PreviewsDayNight
|
||||||
@Composable
|
@Composable
|
||||||
internal fun EditableAvatarViewPreview(
|
internal fun EditableAvatarViewPreview(
|
||||||
@PreviewParameter(EditableAvatarViewUriProvider::class) uri: Uri?
|
@PreviewParameter(EditableAvatarViewUriProvider::class) uri: String?
|
||||||
) = ElementPreview(
|
) = ElementPreview(
|
||||||
drawableFallbackForImages = CommonDrawables.sample_avatar,
|
drawableFallbackForImages = CommonDrawables.sample_avatar,
|
||||||
) {
|
) {
|
||||||
|
|
@ -128,11 +126,11 @@ internal fun EditableAvatarViewPreview(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
open class EditableAvatarViewUriProvider : PreviewParameterProvider<Uri?> {
|
open class EditableAvatarViewUriProvider : PreviewParameterProvider<String?> {
|
||||||
override val values: Sequence<Uri?>
|
override val values: Sequence<String?>
|
||||||
get() = sequenceOf(
|
get() = sequenceOf(
|
||||||
null,
|
null,
|
||||||
"mxc://matrix.org/123456".toUri(),
|
"mxc://matrix.org/123456",
|
||||||
"https://example.com/avatar.jpg".toUri(),
|
"https://example.com/avatar.jpg",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.ui.components
|
package io.element.android.libraries.matrix.ui.components
|
||||||
|
|
||||||
import android.net.Uri
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
|
|
@ -43,7 +42,7 @@ import io.element.android.libraries.designsystem.theme.temporaryColorBgSpecial
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun UnsavedAvatar(
|
fun UnsavedAvatar(
|
||||||
avatarUri: Uri?,
|
avatarUri: String?,
|
||||||
avatarSize: AvatarSize,
|
avatarSize: AvatarSize,
|
||||||
avatarType: AvatarType,
|
avatarType: AvatarType,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
|
@ -86,8 +85,8 @@ internal fun UnsavedAvatarPreview() = ElementPreview {
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
) {
|
) {
|
||||||
UnsavedAvatar(null, AvatarSize.EditRoomDetails, AvatarType.User)
|
UnsavedAvatar(null, AvatarSize.EditRoomDetails, AvatarType.User)
|
||||||
UnsavedAvatar(Uri.EMPTY, AvatarSize.EditRoomDetails, AvatarType.User)
|
UnsavedAvatar("", AvatarSize.EditRoomDetails, AvatarType.User)
|
||||||
UnsavedAvatar(null, AvatarSize.EditRoomDetails, AvatarType.Space())
|
UnsavedAvatar(null, AvatarSize.EditRoomDetails, AvatarType.Space())
|
||||||
UnsavedAvatar(Uri.EMPTY, AvatarSize.EditRoomDetails, AvatarType.Space())
|
UnsavedAvatar("", AvatarSize.EditRoomDetails, AvatarType.Space())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ class KonsistClassNameTest {
|
||||||
.withAllParentsOf(PreviewParameterProvider::class)
|
.withAllParentsOf(PreviewParameterProvider::class)
|
||||||
.withoutName(
|
.withoutName(
|
||||||
"AspectRatioProvider",
|
"AspectRatioProvider",
|
||||||
|
"EditableAvatarViewUriProvider",
|
||||||
"LoginModeViewErrorProvider",
|
"LoginModeViewErrorProvider",
|
||||||
"OverlapRatioProvider",
|
"OverlapRatioProvider",
|
||||||
"TextFileContentProvider",
|
"TextFileContentProvider",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue