diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomConfig.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomConfig.kt new file mode 100644 index 0000000000..0aedf12d0f --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomConfig.kt @@ -0,0 +1,30 @@ +/* + * 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 + +import io.element.android.features.createroom.impl.configureroom.RoomPrivacy +import io.element.android.libraries.matrix.ui.model.MatrixUser +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf + +data class CreateRoomConfig( + val roomName: String? = null, + val topic: String? = null, + val avatarUrl: String? = null, + val invites: ImmutableList = persistentListOf(), + val privacy: RoomPrivacy? = null, +) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt new file mode 100644 index 0000000000..ed61431511 --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt @@ -0,0 +1,35 @@ +/* + * 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 + +import io.element.android.features.createroom.impl.di.CreateRoomScope +import io.element.android.libraries.di.SingleIn +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import javax.inject.Inject + +@SingleIn(CreateRoomScope::class) +class CreateRoomDataStore @Inject constructor() { + + private val createRoomConfigFlow: MutableStateFlow = MutableStateFlow(CreateRoomConfig()) + + fun getCreateRoomConfig(): Flow = createRoomConfigFlow + + fun setCreateRoomConfig(createRoomConfig: CreateRoomConfig) { + createRoomConfigFlow.tryEmit(createRoomConfig) + } +} diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomFlowNode.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomFlowNode.kt index a50c9ab1d0..c663814c19 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomFlowNode.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomFlowNode.kt @@ -32,10 +32,13 @@ import io.element.android.anvilannotations.ContributesNode import io.element.android.features.createroom.api.CreateRoomEntryPoint import io.element.android.features.createroom.impl.addpeople.AddPeopleNode import io.element.android.features.createroom.impl.configureroom.ConfigureRoomNode +import io.element.android.features.createroom.impl.di.CreateRoomComponent import io.element.android.features.createroom.impl.root.CreateRoomRootNode import io.element.android.libraries.architecture.BackstackNode import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler +import io.element.android.libraries.architecture.bindings import io.element.android.libraries.architecture.createNode +import io.element.android.libraries.di.DaggerComponentOwner import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.ui.model.MatrixUser @@ -45,14 +48,22 @@ import kotlinx.parcelize.Parcelize class CreateRoomFlowNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, -) : BackstackNode( - backstack = BackStack( - initialElement = NavTarget.Root, - savedStateMap = buildContext.savedStateMap, - ), - buildContext = buildContext, - plugins = plugins -) { +) : DaggerComponentOwner, + BackstackNode( + backstack = BackStack( + initialElement = NavTarget.Root, + savedStateMap = buildContext.savedStateMap, + ), + buildContext = buildContext, + plugins = plugins + ) { + + private val component by lazy { + parent!!.bindings().createRoomComponentBuilder().build() + } + + override val daggerComponent: Any + get() = component sealed interface NavTarget : Parcelable { @Parcelize @@ -62,7 +73,7 @@ class CreateRoomFlowNode @AssistedInject constructor( object NewRoom : NavTarget @Parcelize - data class ConfigureRoom(val users: List) : NavTarget + object ConfigureRoom : NavTarget } override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { @@ -82,13 +93,13 @@ class CreateRoomFlowNode @AssistedInject constructor( NavTarget.NewRoom -> { val callback = object : AddPeopleNode.Callback { override fun onContinue(selectedUsers: List) { - backstack.push(NavTarget.ConfigureRoom(selectedUsers)) + backstack.push(NavTarget.ConfigureRoom) } } createNode(context = buildContext, plugins = listOf(callback)) } - is NavTarget.ConfigureRoom -> { - createNode(context = buildContext, plugins = listOf(ConfigureRoomNode.Inputs(navTarget.users))) + NavTarget.ConfigureRoom -> { + createNode(context = buildContext) } } } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleNode.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleNode.kt index 91b1d5a721..2d060a6644 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleNode.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleNode.kt @@ -25,10 +25,10 @@ import com.bumble.appyx.core.plugin.plugins import dagger.assisted.Assisted import dagger.assisted.AssistedInject import io.element.android.anvilannotations.ContributesNode -import io.element.android.libraries.di.SessionScope +import io.element.android.features.createroom.impl.di.CreateRoomScope import io.element.android.libraries.matrix.ui.model.MatrixUser -@ContributesNode(SessionScope::class) +@ContributesNode(CreateRoomScope::class) class AddPeopleNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenter.kt index da51a36335..7090a642af 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenter.kt @@ -17,8 +17,12 @@ package io.element.android.features.createroom.impl.addpeople import androidx.compose.runtime.Composable -import io.element.android.features.userlist.api.SelectionMode +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import io.element.android.features.createroom.impl.CreateRoomConfig +import io.element.android.features.createroom.impl.CreateRoomDataStore import io.element.android.features.userlist.api.MatrixUserDataSource +import io.element.android.features.userlist.api.SelectionMode import io.element.android.features.userlist.api.UserListPresenter import io.element.android.features.userlist.api.UserListPresenterArgs import io.element.android.libraries.architecture.Presenter @@ -28,6 +32,7 @@ import javax.inject.Named class AddPeoplePresenter @Inject constructor( private val userListPresenterFactory: UserListPresenter.Factory, @Named("AllUsers") private val matrixUserDataSource: MatrixUserDataSource, + private val dataStore: CreateRoomDataStore, ) : Presenter { private val userListPresenter by lazy { @@ -40,7 +45,10 @@ class AddPeoplePresenter @Inject constructor( @Composable override fun present(): AddPeopleState { val userListState = userListPresenter.present() - + val createRoomConfig = dataStore.getCreateRoomConfig().collectAsState(CreateRoomConfig()) + LaunchedEffect(userListState.selectedUsers) { + dataStore.setCreateRoomConfig(createRoomConfig.value.copy(invites = userListState.selectedUsers)) + } fun handleEvents(event: AddPeopleEvents) { // do nothing for now } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomNode.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomNode.kt index ec5bf67787..08a4f5f64b 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomNode.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomNode.kt @@ -24,27 +24,15 @@ import com.bumble.appyx.core.plugin.Plugin import dagger.assisted.Assisted import dagger.assisted.AssistedInject import io.element.android.anvilannotations.ContributesNode -import io.element.android.libraries.architecture.NodeInputs -import io.element.android.libraries.architecture.inputs -import io.element.android.libraries.di.SessionScope -import io.element.android.libraries.matrix.ui.model.MatrixUser +import io.element.android.features.createroom.impl.di.CreateRoomScope -@ContributesNode(SessionScope::class) +@ContributesNode(CreateRoomScope::class) class ConfigureRoomNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, - private val presenterFactory: ConfigureRoomPresenter.Factory, + private val presenter: ConfigureRoomPresenter, ) : Node(buildContext, plugins = plugins) { - data class Inputs( - val selectedUsers: List - ) : NodeInputs - - private val inputs: Inputs = inputs() - private val presenter by lazy { - presenterFactory.create(ConfigureRoomPresenterArgs(inputs.selectedUsers)) - } - @Composable override fun View(modifier: Modifier) { val state = presenter.present() 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 c8bad29f93..7a877a872b 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 @@ -16,54 +16,40 @@ package io.element.android.features.createroom.impl.configureroom -import android.net.Uri import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue -import dagger.assisted.Assisted -import dagger.assisted.AssistedFactory -import dagger.assisted.AssistedInject +import io.element.android.features.createroom.impl.CreateRoomConfig +import io.element.android.features.createroom.impl.CreateRoomDataStore import io.element.android.libraries.architecture.Presenter -import kotlinx.collections.immutable.toImmutableList +import javax.inject.Inject -class ConfigureRoomPresenter @AssistedInject constructor( - @Assisted val args: ConfigureRoomPresenterArgs, +class ConfigureRoomPresenter @Inject constructor( + private val dataStore: CreateRoomDataStore, ) : Presenter { - @AssistedFactory - interface Factory { - fun create(args: ConfigureRoomPresenterArgs): ConfigureRoomPresenter - } - @Composable override fun present(): ConfigureRoomState { - var roomName by rememberSaveable { mutableStateOf("") } - var topic by rememberSaveable { mutableStateOf("") } - var avatarUri by rememberSaveable { mutableStateOf(null) } - var privacy by rememberSaveable { mutableStateOf(null) } - val isCreateButtonEnabled by rememberSaveable(roomName, privacy) { - val enabled = roomName.isNotEmpty() && privacy != null + val createRoomConfig = dataStore.getCreateRoomConfig().collectAsState(CreateRoomConfig()) + val isCreateButtonEnabled by rememberSaveable(createRoomConfig.value.roomName, createRoomConfig.value.privacy) { + val enabled = createRoomConfig.value.roomName.isNullOrEmpty().not() && createRoomConfig.value.privacy != null mutableStateOf(enabled) } fun handleEvents(event: ConfigureRoomEvents) { when (event) { - is ConfigureRoomEvents.AvatarUriChanged -> avatarUri = event.uri - is ConfigureRoomEvents.RoomNameChanged -> roomName = event.name - is ConfigureRoomEvents.TopicChanged -> topic = event.topic - is ConfigureRoomEvents.RoomPrivacyChanged -> privacy = event.privacy - ConfigureRoomEvents.CreateRoom -> Unit // TODO + is ConfigureRoomEvents.AvatarUriChanged -> dataStore.setCreateRoomConfig(createRoomConfig.value.copy(avatarUrl = event.uri?.toString())) + is ConfigureRoomEvents.RoomNameChanged -> dataStore.setCreateRoomConfig(createRoomConfig.value.copy(roomName = event.name)) + is ConfigureRoomEvents.TopicChanged -> dataStore.setCreateRoomConfig(createRoomConfig.value.copy(topic = event.topic.takeUnless { it.isEmpty() })) + is ConfigureRoomEvents.RoomPrivacyChanged -> dataStore.setCreateRoomConfig(createRoomConfig.value.copy(privacy = event.privacy)) + ConfigureRoomEvents.CreateRoom -> Unit } } return ConfigureRoomState( - selectedUsers = args.selectedUsers.toImmutableList(), - roomName = roomName, - topic = topic, - avatarUri = avatarUri, - privacy = privacy, + createRoomConfig.value, isCreateButtonEnabled = isCreateButtonEnabled, 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 23f5691267..47be0b1f17 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 @@ -16,16 +16,10 @@ package io.element.android.features.createroom.impl.configureroom -import android.net.Uri -import io.element.android.libraries.matrix.ui.model.MatrixUser -import kotlinx.collections.immutable.ImmutableList +import io.element.android.features.createroom.impl.CreateRoomConfig data class ConfigureRoomState( - val selectedUsers: ImmutableList, - val roomName: String, - val topic: String, - val avatarUri: Uri?, - val privacy: RoomPrivacy?, + val config: CreateRoomConfig, val isCreateButtonEnabled: Boolean, 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 3e4961f56a..b1614381ae 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 @@ -17,8 +17,7 @@ package io.element.android.features.createroom.impl.configureroom import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.libraries.matrix.ui.components.aMatrixUserList -import kotlinx.collections.immutable.toImmutableList +import io.element.android.features.createroom.impl.CreateRoomConfig open class ConfigureRoomStateProvider : PreviewParameterProvider { override val values: Sequence @@ -28,11 +27,7 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider