diff --git a/app/src/main/kotlin/io/element/android/x/node/RootFlowNode.kt b/app/src/main/kotlin/io/element/android/x/node/RootFlowNode.kt index dc746d53ef..ae3c31008d 100644 --- a/app/src/main/kotlin/io/element/android/x/node/RootFlowNode.kt +++ b/app/src/main/kotlin/io/element/android/x/node/RootFlowNode.kt @@ -21,8 +21,6 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.CircularProgressIndicator import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.lifecycle.lifecycleScope @@ -38,7 +36,6 @@ import com.bumble.appyx.navmodel.backstack.operation.push import io.element.android.features.rageshake.bugreport.BugReportNode import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler import io.element.android.libraries.architecture.createNode -import io.element.android.libraries.architecture.presenterConnector import io.element.android.libraries.di.DaggerComponentOwner import io.element.android.libraries.matrix.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.core.SessionId @@ -60,7 +57,7 @@ class RootFlowNode( private val appComponentOwner: DaggerComponentOwner, private val authenticationService: MatrixAuthenticationService, private val matrixClientsHolder: MatrixClientsHolder, - presenter: RootPresenter + private val presenter: RootPresenter ) : ParentNode( navModel = backstack, @@ -69,8 +66,6 @@ class RootFlowNode( DaggerComponentOwner by appComponentOwner { - private val presenterConnector = presenterConnector(presenter) - override fun onBuilt() { super.onBuilt() observeLoggedInState() @@ -131,7 +126,7 @@ class RootFlowNode( @Composable override fun View(modifier: Modifier) { - val state by presenterConnector.stateFlow.collectAsState() + val state = presenter.present() RootView( state = state, modifier = modifier, diff --git a/features/login/src/main/kotlin/io/element/android/features/login/changeserver/ChangeServerNode.kt b/features/login/src/main/kotlin/io/element/android/features/login/changeserver/ChangeServerNode.kt index b0c8b96ed5..232b0a6497 100644 --- a/features/login/src/main/kotlin/io/element/android/features/login/changeserver/ChangeServerNode.kt +++ b/features/login/src/main/kotlin/io/element/android/features/login/changeserver/ChangeServerNode.kt @@ -17,8 +17,6 @@ package io.element.android.features.login.changeserver import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node @@ -26,25 +24,22 @@ 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.presenterConnector import io.element.android.libraries.di.AppScope @ContributesNode(AppScope::class) class ChangeServerNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, - presenter: ChangeServerPresenter, + private val presenter: ChangeServerPresenter, ) : Node(buildContext, plugins = plugins) { - private val presenterConnector = presenterConnector(presenter) - private fun onSuccess() { navigateUp() } @Composable override fun View(modifier: Modifier) { - val state by presenterConnector.stateFlow.collectAsState() + val state = presenter.present() ChangeServerView( state = state, modifier = modifier, diff --git a/features/login/src/main/kotlin/io/element/android/features/login/root/LoginRootNode.kt b/features/login/src/main/kotlin/io/element/android/features/login/root/LoginRootNode.kt index 695a4eccb1..f29eb2a7e5 100644 --- a/features/login/src/main/kotlin/io/element/android/features/login/root/LoginRootNode.kt +++ b/features/login/src/main/kotlin/io/element/android/features/login/root/LoginRootNode.kt @@ -17,8 +17,6 @@ package io.element.android.features.login.root import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.lifecycle.Lifecycle import com.bumble.appyx.core.modality.BuildContext @@ -28,7 +26,6 @@ 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.architecture.presenterConnector import io.element.android.libraries.designsystem.utils.OnLifecycleEvent import io.element.android.libraries.di.AppScope @@ -36,11 +33,9 @@ import io.element.android.libraries.di.AppScope class LoginRootNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, - presenter: LoginRootPresenter, + private val presenter: LoginRootPresenter, ) : Node(buildContext, plugins = plugins) { - private val presenterConnector = presenterConnector(presenter) - interface Callback : Plugin { fun onChangeHomeServer() } @@ -51,7 +46,7 @@ class LoginRootNode @AssistedInject constructor( @Composable override fun View(modifier: Modifier) { - val state by presenterConnector.stateFlow.collectAsState() + val state = presenter.present() OnLifecycleEvent { _, event -> when (event) { Lifecycle.Event.ON_RESUME -> state.eventSink(LoginRootEvents.RefreshHomeServer) diff --git a/features/messages/src/main/kotlin/io/element/android/features/messages/MessagesNode.kt b/features/messages/src/main/kotlin/io/element/android/features/messages/MessagesNode.kt index ff8776b6aa..0b3db020bf 100644 --- a/features/messages/src/main/kotlin/io/element/android/features/messages/MessagesNode.kt +++ b/features/messages/src/main/kotlin/io/element/android/features/messages/MessagesNode.kt @@ -17,8 +17,6 @@ package io.element.android.features.messages import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node @@ -26,21 +24,18 @@ 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.presenterConnector import io.element.android.libraries.di.RoomScope @ContributesNode(RoomScope::class) class MessagesNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, - presenter: MessagesPresenter, + private val presenter: MessagesPresenter, ) : Node(buildContext, plugins = plugins) { - private val connector = presenterConnector(presenter) - @Composable override fun View(modifier: Modifier) { - val state by connector.stateFlow.collectAsState() + val state = presenter.present() MessagesView( state = state, onBackPressed = this::navigateUp, diff --git a/features/messages/src/main/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenter.kt b/features/messages/src/main/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenter.kt index 24e3f2461d..29d5030b4e 100644 --- a/features/messages/src/main/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenter.kt +++ b/features/messages/src/main/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenter.kt @@ -20,6 +20,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.data.StableCharSequence @@ -40,7 +41,7 @@ class MessageComposerPresenter @Inject constructor( val isFullScreen = rememberSaveable { mutableStateOf(false) } - val text: MutableState = rememberSaveable { + val text: MutableState = remember { mutableStateOf(StableCharSequence("")) } val composerMode: MutableState = rememberSaveable { diff --git a/features/preferences/src/main/kotlin/io/element/android/features/preferences/root/PreferencesRootNode.kt b/features/preferences/src/main/kotlin/io/element/android/features/preferences/root/PreferencesRootNode.kt index 92688e5b32..cd9ed99302 100644 --- a/features/preferences/src/main/kotlin/io/element/android/features/preferences/root/PreferencesRootNode.kt +++ b/features/preferences/src/main/kotlin/io/element/android/features/preferences/root/PreferencesRootNode.kt @@ -17,8 +17,6 @@ package io.element.android.features.preferences.root import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node @@ -27,29 +25,26 @@ 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.architecture.presenterConnector import io.element.android.libraries.di.SessionScope @ContributesNode(SessionScope::class) class PreferencesRootNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, - presenter: PreferencesRootPresenter, + private val presenter: PreferencesRootPresenter, ) : Node(buildContext, plugins = plugins) { interface Callback : Plugin { fun onOpenBugReport() } - private val presenterConnector = presenterConnector(presenter) - private fun onOpenBugReport() { plugins().forEach { it.onOpenBugReport() } } @Composable override fun View(modifier: Modifier) { - val state by presenterConnector.stateFlow.collectAsState() + val state = presenter.present() PreferencesRootView( state = state, modifier = modifier, diff --git a/features/rageshake/src/main/kotlin/io/element/android/features/rageshake/bugreport/BugReportNode.kt b/features/rageshake/src/main/kotlin/io/element/android/features/rageshake/bugreport/BugReportNode.kt index b7a32c9b05..8c0ffceee8 100644 --- a/features/rageshake/src/main/kotlin/io/element/android/features/rageshake/bugreport/BugReportNode.kt +++ b/features/rageshake/src/main/kotlin/io/element/android/features/rageshake/bugreport/BugReportNode.kt @@ -17,8 +17,6 @@ package io.element.android.features.rageshake.bugreport import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node @@ -27,25 +25,22 @@ 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.architecture.presenterConnector import io.element.android.libraries.di.AppScope @ContributesNode(AppScope::class) class BugReportNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, - presenter: BugReportPresenter, + private val presenter: BugReportPresenter, ) : Node(buildContext, plugins = plugins) { - private val presenterConnector = presenterConnector(presenter) - interface Callback : Plugin { fun onBugReportSent() } @Composable override fun View(modifier: Modifier) { - val state by presenterConnector.stateFlow.collectAsState() + val state = presenter.present() BugReportView( state = state, modifier = modifier, diff --git a/features/roomlist/src/main/kotlin/io/element/android/features/roomlist/RoomListNode.kt b/features/roomlist/src/main/kotlin/io/element/android/features/roomlist/RoomListNode.kt index f492e09871..ecf6dc3c98 100644 --- a/features/roomlist/src/main/kotlin/io/element/android/features/roomlist/RoomListNode.kt +++ b/features/roomlist/src/main/kotlin/io/element/android/features/roomlist/RoomListNode.kt @@ -17,8 +17,6 @@ package io.element.android.features.roomlist import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node @@ -27,7 +25,6 @@ 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.architecture.presenterConnector import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.core.RoomId @@ -35,7 +32,7 @@ import io.element.android.libraries.matrix.core.RoomId class RoomListNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, - presenter: RoomListPresenter, + private val presenter: RoomListPresenter, ) : Node(buildContext, plugins = plugins) { interface Callback : Plugin { @@ -43,8 +40,6 @@ class RoomListNode @AssistedInject constructor( fun onSettingsClicked() } - private val connector = presenterConnector(presenter) - private fun onRoomClicked(roomId: RoomId) { plugins().forEach { it.onRoomClicked(roomId) } } @@ -55,7 +50,7 @@ class RoomListNode @AssistedInject constructor( @Composable override fun View(modifier: Modifier) { - val state by connector.stateFlow.collectAsState() + val state = presenter.present() RoomListView( state = state, modifier = modifier, diff --git a/features/template/src/main/kotlin/io/element/android/features/template/TemplateNode.kt b/features/template/src/main/kotlin/io/element/android/features/template/TemplateNode.kt index 6e08d6887d..4be5178ede 100644 --- a/features/template/src/main/kotlin/io/element/android/features/template/TemplateNode.kt +++ b/features/template/src/main/kotlin/io/element/android/features/template/TemplateNode.kt @@ -17,15 +17,12 @@ package io.element.android.features.template import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin import dagger.assisted.Assisted import dagger.assisted.AssistedInject -import io.element.android.libraries.architecture.presenterConnector import io.element.android.anvilannotations.ContributesNode import io.element.android.libraries.di.AppScope @@ -34,14 +31,12 @@ import io.element.android.libraries.di.AppScope class TemplateNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, - presenter: TemplatePresenter, + private val presenter: TemplatePresenter, ) : Node(buildContext, plugins = plugins) { - private val presenterConnector = presenterConnector(presenter) - @Composable override fun View(modifier: Modifier) { - val state by presenterConnector.stateFlow.collectAsState() + val state = presenter.present() TemplateView( state = state, modifier = modifier diff --git a/libraries/architecture/build.gradle.kts b/libraries/architecture/build.gradle.kts index 9c4ae9e3ac..1d0c0417ca 100644 --- a/libraries/architecture/build.gradle.kts +++ b/libraries/architecture/build.gradle.kts @@ -28,6 +28,5 @@ dependencies { api(projects.libraries.di) api(libs.dagger) api(libs.appyx.core) - api(libs.molecule.runtime) api(libs.androidx.lifecycle.runtime) } diff --git a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/PresenterConnector.kt b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/PresenterConnector.kt deleted file mode 100644 index 0e97dba712..0000000000 --- a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/PresenterConnector.kt +++ /dev/null @@ -1,37 +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.libraries.architecture - -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.lifecycleScope -import app.cash.molecule.AndroidUiDispatcher -import app.cash.molecule.RecompositionClock -import app.cash.molecule.launchMolecule -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.StateFlow - -inline fun LifecycleOwner.presenterConnector(presenter: Presenter): LifecyclePresenterConnector = - LifecyclePresenterConnector(lifecycleOwner = this, presenter = presenter) - -class LifecyclePresenterConnector(lifecycleOwner: LifecycleOwner, presenter: Presenter) { - - private val moleculeScope = CoroutineScope(lifecycleOwner.lifecycleScope.coroutineContext + AndroidUiDispatcher.Main) - - val stateFlow: StateFlow = moleculeScope.launchMolecule(RecompositionClock.Immediate) { - presenter.present() - } -}