diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt index 58cdae613c..52389d97fb 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt @@ -17,6 +17,7 @@ package io.element.android.features.createroom.impl.configureroom import io.element.android.features.createroom.impl.CreateRoomConfig +import io.element.android.features.createroom.impl.configureroom.avatar.AvatarAction import io.element.android.libraries.matrix.api.user.MatrixUser sealed interface ConfigureRoomEvents { @@ -25,5 +26,6 @@ sealed interface ConfigureRoomEvents { data class RoomPrivacyChanged(val privacy: RoomPrivacy?) : ConfigureRoomEvents data class RemoveFromSelection(val matrixUser: MatrixUser) : ConfigureRoomEvents data class CreateRoom(val config: CreateRoomConfig) : ConfigureRoomEvents + data class HandleAvatarAction(val action: AvatarAction) : ConfigureRoomEvents object CancelCreateRoom : ConfigureRoomEvents } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt index e38b9c06a7..399bb2d763 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt @@ -27,8 +27,6 @@ import androidx.compose.runtime.rememberCoroutineScope import io.element.android.features.createroom.impl.CreateRoomConfig import io.element.android.features.createroom.impl.CreateRoomDataStore import io.element.android.features.createroom.impl.configureroom.avatar.AvatarAction -import io.element.android.features.createroom.impl.configureroom.avatar.AvatarActionListEvents -import io.element.android.features.createroom.impl.configureroom.avatar.AvatarActionListState import io.element.android.libraries.architecture.Async import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.execute @@ -38,7 +36,7 @@ import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters import io.element.android.libraries.matrix.api.createroom.RoomPreset import io.element.android.libraries.matrix.api.createroom.RoomVisibility import io.element.android.libraries.mediapickers.PickerProvider -import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import javax.inject.Inject @@ -65,6 +63,19 @@ class ConfigureRoomPresenter @Inject constructor( if (uri != null) dataStore.setAvatarUrl(uri.toString()) }) + val avatarActions by remember(createRoomConfig.value.avatarUrl) { + derivedStateOf { + mutableListOf( + AvatarAction.TakePhoto, + AvatarAction.ChoosePhoto, + ).apply { + if (createRoomConfig.value.avatarUrl != null) { + add(AvatarAction.Remove) + } + }.toImmutableList() + } + } + val localCoroutineScope = rememberCoroutineScope() val createRoomAction: MutableState> = remember { mutableStateOf(Async.Uninitialized) } @@ -80,31 +91,22 @@ class ConfigureRoomPresenter @Inject constructor( is ConfigureRoomEvents.RoomPrivacyChanged -> dataStore.setPrivacy(event.privacy) is ConfigureRoomEvents.RemoveFromSelection -> dataStore.selectedUserListDataStore.removeUserFromSelection(event.matrixUser) is ConfigureRoomEvents.CreateRoom -> createRoom(event.config) + is ConfigureRoomEvents.HandleAvatarAction -> { + when (event.action) { + AvatarAction.ChoosePhoto -> galleryImagePicker.launch() + AvatarAction.TakePhoto -> cameraPhotoPicker.launch() + AvatarAction.Remove -> dataStore.setAvatarUrl(null) + } + } + ConfigureRoomEvents.CancelCreateRoom -> createRoomAction.value = Async.Uninitialized } } - fun handleAvatarEvents(event: AvatarActionListEvents) { - when (event) { - is AvatarActionListEvents.HandleAction -> when (event.action) { - AvatarAction.ChoosePhoto -> galleryImagePicker.launch() - AvatarAction.TakePhoto -> cameraPhotoPicker.launch() - } - } - } - - val avatarActionListState = AvatarActionListState( - actions = persistentListOf( - AvatarAction.ChoosePhoto, - AvatarAction.TakePhoto, - ), - eventSink = ::handleAvatarEvents, - ) - return ConfigureRoomState( config = createRoomConfig.value, isCreateButtonEnabled = isCreateButtonEnabled, - avatarActionListState = avatarActionListState, + avatarActions = avatarActions, createRoomAction = createRoomAction.value, eventSink = ::handleEvents, ) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt index 1b01c3a642..0e0c465b52 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt @@ -17,14 +17,15 @@ package io.element.android.features.createroom.impl.configureroom import io.element.android.features.createroom.impl.CreateRoomConfig -import io.element.android.features.createroom.impl.configureroom.avatar.AvatarActionListState +import io.element.android.features.createroom.impl.configureroom.avatar.AvatarAction import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.api.core.RoomId +import kotlinx.collections.immutable.ImmutableList data class ConfigureRoomState( val config: CreateRoomConfig, val isCreateButtonEnabled: Boolean, - val avatarActionListState: AvatarActionListState, + val avatarActions: ImmutableList, val createRoomAction: Async, val eventSink: (ConfigureRoomEvents) -> Unit ) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt index 3383b13b2a..2dd4854f3a 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt @@ -18,8 +18,6 @@ package io.element.android.features.createroom.impl.configureroom import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.createroom.impl.CreateRoomConfig -import io.element.android.features.createroom.impl.configureroom.avatar.AvatarAction -import io.element.android.features.createroom.impl.configureroom.avatar.AvatarActionListState import io.element.android.features.userlist.api.aListOfSelectedUsers import io.element.android.libraries.architecture.Async import kotlinx.collections.immutable.persistentListOf @@ -43,10 +41,7 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider, - val eventSink: (AvatarActionListEvents) -> Unit, -) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListStateProvider.kt deleted file mode 100644 index 6cb6ce1361..0000000000 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListStateProvider.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2023 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.element.android.features.createroom.impl.configureroom.avatar - -import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import kotlinx.collections.immutable.persistentListOf - -open class ActionListStateProvider : PreviewParameterProvider { - override val values: Sequence - get() = sequenceOf(anActionListState()) -} - -fun anActionListState() = AvatarActionListState( - actions = persistentListOf(AvatarAction.TakePhoto, AvatarAction.ChoosePhoto), - eventSink = {} -) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListView.kt index 515faee0f5..f68db3a4b7 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListView.kt @@ -29,21 +29,23 @@ import androidx.compose.material.ListItem import androidx.compose.material.ModalBottomSheetState import androidx.compose.material.ModalBottomSheetValue import androidx.compose.material.Text +import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.ModalBottomSheetLayout +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.launch @Composable fun AvatarActionListView( - state: AvatarActionListState, + actions: ImmutableList, modalBottomSheetState: ModalBottomSheetState, modifier: Modifier = Modifier, onActionSelected: (action: AvatarAction) -> Unit = {}, @@ -61,7 +63,7 @@ fun AvatarActionListView( sheetState = modalBottomSheetState, sheetContent = { SheetContent( - state = state, + actions = actions, onActionClicked = ::onItemActionClicked, modifier = Modifier .navigationBarsPadding() @@ -73,11 +75,10 @@ fun AvatarActionListView( @Composable private fun SheetContent( - state: AvatarActionListState, + actions: ImmutableList, modifier: Modifier = Modifier, onActionClicked: (AvatarAction) -> Unit = { }, ) { - val actions = state.actions LazyColumn( modifier = modifier.fillMaxWidth() ) { @@ -87,12 +88,16 @@ private fun SheetContent( ListItem( modifier = Modifier.clickable { onActionClicked(action) }, text = { - Text(text = stringResource(action.titleResId)) + Text( + text = stringResource(action.titleResId), + color = if (action.destructive) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.primary, + ) }, icon = { Icon( imageVector = action.icon, contentDescription = stringResource(action.titleResId), + tint = if (action.destructive) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.primary, ) } ) @@ -102,18 +107,18 @@ private fun SheetContent( @Preview @Composable -fun SheetContentLightPreview(@PreviewParameter(ActionListStateProvider::class) state: AvatarActionListState) = - ElementPreviewLight { ContentToPreview(state) } +fun SheetContentLightPreview() = + ElementPreviewLight { ContentToPreview() } @Preview @Composable -fun SheetContentDarkPreview(@PreviewParameter(ActionListStateProvider::class) state: AvatarActionListState) = - ElementPreviewDark { ContentToPreview(state) } +fun SheetContentDarkPreview() = + ElementPreviewDark { ContentToPreview() } @Composable -private fun ContentToPreview(state: AvatarActionListState) { +private fun ContentToPreview() { AvatarActionListView( - state = state, + actions = persistentListOf(AvatarAction.ChoosePhoto, AvatarAction.TakePhoto, AvatarAction.Remove), modalBottomSheetState = ModalBottomSheetState( initialValue = ModalBottomSheetValue.Expanded ),