diff --git a/anvilannotations/src/main/java/io/element/android/x/anvilannotations/ContributesViewModel.kt b/anvilannotations/src/main/java/io/element/android/x/anvilannotations/ContributesViewModel.kt deleted file mode 100644 index 0695e93263..0000000000 --- a/anvilannotations/src/main/java/io/element/android/x/anvilannotations/ContributesViewModel.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2022 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.x.anvilannotations - -import kotlin.reflect.KClass - -/** - * Adds view model to the specified component graph. - * Equivalent to the following declaration in a dagger module: - * - * @Binds - * @IntoMap - * @ViewModelKey(YourViewModel::class) - * public abstract fun bindYourViewModelFactory(factory: YourViewModel.Factory): AssistedViewModelFactory<*, *> - */ -@Target(AnnotationTarget.CLASS) -annotation class ContributesViewModel( - val scope: KClass<*>, -) diff --git a/anvilcodegen/src/main/java/io/element/android/x/anvilcodegen/ContributesViewModelCodeGenerator.kt b/anvilcodegen/src/main/java/io/element/android/x/anvilcodegen/ContributesViewModelCodeGenerator.kt deleted file mode 100644 index e84d6cdd5f..0000000000 --- a/anvilcodegen/src/main/java/io/element/android/x/anvilcodegen/ContributesViewModelCodeGenerator.kt +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2022 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. - */ - -@file:OptIn(ExperimentalAnvilApi::class) - -package io.element.android.x.anvilcodegen - -import com.google.auto.service.AutoService -import com.squareup.anvil.annotations.ContributesTo -import com.squareup.anvil.annotations.ExperimentalAnvilApi -import com.squareup.anvil.compiler.api.AnvilCompilationException -import com.squareup.anvil.compiler.api.AnvilContext -import com.squareup.anvil.compiler.api.CodeGenerator -import com.squareup.anvil.compiler.api.GeneratedFile -import com.squareup.anvil.compiler.api.createGeneratedFile -import com.squareup.anvil.compiler.internal.asClassName -import com.squareup.anvil.compiler.internal.buildFile -import com.squareup.anvil.compiler.internal.fqName -import com.squareup.anvil.compiler.internal.reference.ClassReference -import com.squareup.anvil.compiler.internal.reference.asClassName -import com.squareup.anvil.compiler.internal.reference.classAndInnerClassReferences -import com.squareup.kotlinpoet.AnnotationSpec -import com.squareup.kotlinpoet.ClassName -import com.squareup.kotlinpoet.FileSpec -import com.squareup.kotlinpoet.FunSpec -import com.squareup.kotlinpoet.KModifier -import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy -import com.squareup.kotlinpoet.STAR -import com.squareup.kotlinpoet.TypeSpec -import dagger.Binds -import dagger.Module -import dagger.assisted.Assisted -import dagger.assisted.AssistedFactory -import dagger.assisted.AssistedInject -import dagger.multibindings.IntoMap -import io.element.android.x.anvilannotations.ContributesViewModel -import java.io.File -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.psi.KtFile - -/** - * This is an anvil plugin that allows ViewModels to use [ContributesViewModel] alone and let this plugin automatically - * handle the rest of the Dagger wiring required for constructor injection. - */ -@AutoService(CodeGenerator::class) -class ContributesViewModelCodeGenerator : CodeGenerator { - - override fun isApplicable(context: AnvilContext): Boolean = true - - override fun generateCode(codeGenDir: File, module: ModuleDescriptor, projectFiles: Collection): Collection { - return projectFiles.classAndInnerClassReferences(module) - .filter { it.isAnnotatedWith(ContributesViewModel::class.fqName) } - .flatMap { listOf(generateModule(it, codeGenDir, module), generateAssistedFactory(it, codeGenDir, module)) } - .toList() - } - - private fun generateModule(vmClass: ClassReference.Psi, codeGenDir: File, module: ModuleDescriptor): GeneratedFile { - val generatedPackage = vmClass.packageFqName.toString() - val moduleClassName = "${vmClass.shortName}_Module" - val scope = vmClass.annotations.single { it.fqName == ContributesViewModel::class.fqName }.scope() - val content = FileSpec.buildFile(generatedPackage, moduleClassName) { - addType( - TypeSpec.classBuilder(moduleClassName) - .addModifiers(KModifier.ABSTRACT) - .addAnnotation(Module::class) - .addAnnotation(AnnotationSpec.builder(ContributesTo::class).addMember("%T::class", scope.asClassName()).build()) - .addFunction( - FunSpec.builder("bind${vmClass.shortName}Factory") - .addModifiers(KModifier.ABSTRACT) - .addParameter("factory", ClassName(generatedPackage, "${vmClass.shortName}_AssistedFactory")) - .returns(assistedViewModelFactoryFqName.asClassName(module).parameterizedBy(STAR, STAR)) - .addAnnotation(Binds::class) - .addAnnotation(IntoMap::class) - .addAnnotation( - AnnotationSpec.Companion - .builder(viewModelKeyFqName.asClassName(module)) - .addMember("%T::class", vmClass.asClassName()) - .build() - ) - .build(), - ) - .build(), - ) - } - return createGeneratedFile(codeGenDir, generatedPackage, moduleClassName, content) - } - - private fun generateAssistedFactory(vmClass: ClassReference.Psi, codeGenDir: File, module: ModuleDescriptor): GeneratedFile { - val generatedPackage = vmClass.packageFqName.toString() - val assistedFactoryClassName = "${vmClass.shortName}_AssistedFactory" - val constructor = vmClass.constructors.singleOrNull { it.isAnnotatedWith(AssistedInject::class.fqName) } - val assistedParameter = constructor?.parameters?.singleOrNull { it.isAnnotatedWith(Assisted::class.fqName) } - if (constructor == null || assistedParameter == null) { - throw AnvilCompilationException( - "${vmClass.fqName} must have an @AssistedInject constructor with @Assisted initialState: S parameter", - element = vmClass.clazz, - ) - } - if (assistedParameter.name != "initialState") { - throw AnvilCompilationException( - "${vmClass.fqName} @Assisted parameter must be named initialState", - element = assistedParameter.parameter, - ) - } - val vmClassName = vmClass.asClassName() - val stateClassName = assistedParameter.type().asTypeName() - val content = FileSpec.buildFile(generatedPackage, assistedFactoryClassName) { - addType( - TypeSpec.interfaceBuilder(assistedFactoryClassName) - .addSuperinterface(assistedViewModelFactoryFqName.asClassName(module).parameterizedBy(vmClassName, stateClassName)) - .addAnnotation(AssistedFactory::class) - .addFunction( - FunSpec.builder("create") - .addModifiers(KModifier.OVERRIDE, KModifier.ABSTRACT) - .addParameter("initialState", stateClassName) - .returns(vmClassName) - .build(), - ) - .build(), - ) - } - return createGeneratedFile(codeGenDir, generatedPackage, assistedFactoryClassName, content) - } - - companion object { - private val assistedViewModelFactoryFqName = FqName("io.element.android.x.architecture.viewmodel.AssistedViewModelFactory") - private val viewModelKeyFqName = FqName("io.element.android.x.architecture.viewmodel.ViewModelKey") - } -} diff --git a/app/build.gradle.kts b/app/build.gradle.kts index d3ce5a7a78..6c89c54683 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -175,11 +175,9 @@ dependencies { implementation(libs.androidx.corektx) implementation(libs.androidx.lifecycle.runtime) - implementation(libs.androidx.lifecycle.viewmodel.compose) implementation(libs.androidx.activity.compose) implementation(libs.androidx.startup) implementation(libs.coil) - implementation(libs.mavericks.compose) implementation(libs.dagger) kapt(libs.dagger.compiler) diff --git a/app/src/main/java/io/element/android/x/ElementXApplication.kt b/app/src/main/java/io/element/android/x/ElementXApplication.kt index 923a1ddc15..285c56d5d8 100644 --- a/app/src/main/java/io/element/android/x/ElementXApplication.kt +++ b/app/src/main/java/io/element/android/x/ElementXApplication.kt @@ -23,7 +23,6 @@ import io.element.android.x.di.AppComponent import io.element.android.x.di.DaggerAppComponent import io.element.android.x.initializer.CrashInitializer import io.element.android.x.initializer.MatrixInitializer -import io.element.android.x.initializer.MavericksInitializer import io.element.android.x.initializer.TimberInitializer class ElementXApplication : Application(), DaggerComponentOwner { @@ -40,7 +39,6 @@ class ElementXApplication : Application(), DaggerComponentOwner { initializeComponent(CrashInitializer::class.java) initializeComponent(TimberInitializer::class.java) initializeComponent(MatrixInitializer::class.java) - initializeComponent(MavericksInitializer::class.java) } } } diff --git a/app/src/main/java/io/element/android/x/di/AppComponent.kt b/app/src/main/java/io/element/android/x/di/AppComponent.kt index 30f801e31d..342c18e3a4 100644 --- a/app/src/main/java/io/element/android/x/di/AppComponent.kt +++ b/app/src/main/java/io/element/android/x/di/AppComponent.kt @@ -21,7 +21,6 @@ import com.squareup.anvil.annotations.MergeComponent import dagger.BindsInstance import dagger.Component import io.element.android.x.architecture.NodeFactoriesBindings -import io.element.android.x.architecture.viewmodel.DaggerMavericksBindings @SingleIn(AppScope::class) @MergeComponent(AppScope::class) diff --git a/app/src/main/java/io/element/android/x/di/SessionComponent.kt b/app/src/main/java/io/element/android/x/di/SessionComponent.kt index 0ba9a12d58..298c97e66c 100644 --- a/app/src/main/java/io/element/android/x/di/SessionComponent.kt +++ b/app/src/main/java/io/element/android/x/di/SessionComponent.kt @@ -20,7 +20,6 @@ import com.squareup.anvil.annotations.ContributesTo import com.squareup.anvil.annotations.MergeSubcomponent import dagger.BindsInstance import dagger.Subcomponent -import io.element.android.x.architecture.viewmodel.DaggerMavericksBindings import io.element.android.x.architecture.NodeFactoriesBindings import io.element.android.x.matrix.MatrixClient diff --git a/app/src/main/java/io/element/android/x/initializer/MavericksInitializer.kt b/app/src/main/java/io/element/android/x/initializer/MavericksInitializer.kt deleted file mode 100644 index f7d48b66c1..0000000000 --- a/app/src/main/java/io/element/android/x/initializer/MavericksInitializer.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2022 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.x.initializer - -import android.content.Context -import androidx.startup.Initializer -import com.airbnb.mvrx.Mavericks - -class MavericksInitializer : Initializer { - - override fun create(context: Context) { - Mavericks.initialize(context) - } - - override fun dependencies(): List>> = listOf() -} diff --git a/features/login/build.gradle.kts b/features/login/build.gradle.kts index de9192e437..29987189e9 100644 --- a/features/login/build.gradle.kts +++ b/features/login/build.gradle.kts @@ -41,7 +41,6 @@ dependencies { implementation(project(":libraries:designsystem")) implementation(project(":libraries:elementresources")) implementation(libs.appyx.core) - implementation(libs.mavericks.compose) ksp(libs.showkase.processor) testImplementation(libs.test.junit) androidTestImplementation(libs.test.junitext) diff --git a/features/messages/build.gradle.kts b/features/messages/build.gradle.kts index 9fc69683f1..861cb183c4 100644 --- a/features/messages/build.gradle.kts +++ b/features/messages/build.gradle.kts @@ -41,7 +41,6 @@ dependencies { implementation(project(":libraries:designsystem")) implementation(project(":libraries:textcomposer")) implementation(libs.appyx.core) - implementation(libs.mavericks.compose) implementation(libs.coil.compose) implementation(libs.datetime) implementation(libs.accompanist.flowlayout) diff --git a/features/onboarding/build.gradle.kts b/features/onboarding/build.gradle.kts index 791b3c47bc..4c25a25ea3 100644 --- a/features/onboarding/build.gradle.kts +++ b/features/onboarding/build.gradle.kts @@ -30,7 +30,6 @@ dependencies { implementation(project(":libraries:elementresources")) implementation(project(":libraries:designsystem")) implementation(project(":libraries:architecture")) - implementation(libs.mavericks.compose) implementation(libs.accompanist.pager) implementation(libs.accompanist.pagerindicator) implementation(libs.appyx.core) diff --git a/features/preferences/build.gradle.kts b/features/preferences/build.gradle.kts index e8c4b9abb3..32ad183d13 100644 --- a/features/preferences/build.gradle.kts +++ b/features/preferences/build.gradle.kts @@ -42,7 +42,6 @@ dependencies { implementation(project(":features:logout")) implementation(project(":libraries:designsystem")) implementation(project(":libraries:elementresources")) - implementation(libs.mavericks.compose) implementation(libs.datetime) implementation(libs.accompanist.placeholder) testImplementation(libs.test.junit) diff --git a/features/rageshake/build.gradle.kts b/features/rageshake/build.gradle.kts index 2cd99b6dea..92f9b75aaa 100644 --- a/features/rageshake/build.gradle.kts +++ b/features/rageshake/build.gradle.kts @@ -39,7 +39,6 @@ dependencies { implementation(project(":anvilannotations")) implementation(project(":libraries:designsystem")) implementation(project(":libraries:elementresources")) - implementation(libs.mavericks.compose) implementation(libs.squareup.seismic) implementation(libs.androidx.datastore.preferences) implementation(libs.coil) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9010629926..ea10bd7cfd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -17,7 +17,6 @@ constraintlayout = "2.1.4" recyclerview = "1.2.1" lifecycle = "2.5.1" activity_compose = "1.6.1" -fragment = "1.5.5" startup = "1.1.1" # Compose @@ -42,7 +41,6 @@ test_hamcrest = "2.2" test_orchestrator = "1.4.1" #other -mavericks = "3.0.1" coil = "2.2.1" datetime = "0.4.0" wysiwyg = "0.7.0.1" @@ -79,9 +77,7 @@ androidx_lifecycle_runtime = { module = "androidx.lifecycle:lifecycle-runtime-kt androidx_lifecycle_compose = { module = "androidx.lifecycle:compose", version.ref = "lifecycle" } androidx_lifecycle_process = { module = "androidx.lifecycle:lifecycle-process", version.ref = "lifecycle" } -androidx_lifecycle_viewmodel_compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle" } androidx_activity_compose = { module = "androidx.activity:activity-compose", version.ref = "activity_compose" } -androidx_fragment = { module = "androidx.fragment:fragment-ktx", version.ref = "fragment" } androidx_startup = { module = "androidx.startup:startup-runtime", version.ref = "startup" } androidx_compose_bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose_bom" } @@ -117,7 +113,6 @@ test_hamcrest = { module = "org.hamcrest:hamcrest", version.ref = "test_hamcrest test_orchestrator = { module = "androidx.test:orchestrator", version.ref = "test_orchestrator" } # Others -mavericks_compose = { module = "com.airbnb.android:mavericks-compose", version.ref = "mavericks" } coil = { module = "io.coil-kt:coil", version.ref = "coil" } coil_compose = { module = "io.coil-kt:coil-compose", version.ref = "coil" } datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "datetime" } diff --git a/libraries/architecture/build.gradle.kts b/libraries/architecture/build.gradle.kts index 5efea85ebf..37b3fc1af7 100644 --- a/libraries/architecture/build.gradle.kts +++ b/libraries/architecture/build.gradle.kts @@ -14,5 +14,4 @@ dependencies { api(libs.dagger) api(libs.appyx.core) api(libs.androidx.lifecycle.runtime) - api(libs.mavericks.compose) } diff --git a/libraries/architecture/src/main/java/io/element/android/x/architecture/viewmodel/AssistedViewModelFactory.kt b/libraries/architecture/src/main/java/io/element/android/x/architecture/viewmodel/AssistedViewModelFactory.kt deleted file mode 100644 index 9adc3558aa..0000000000 --- a/libraries/architecture/src/main/java/io/element/android/x/architecture/viewmodel/AssistedViewModelFactory.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2022 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.x.architecture.viewmodel - -import com.airbnb.mvrx.MavericksState -import com.airbnb.mvrx.MavericksViewModel - -interface AssistedViewModelFactory, S : MavericksState> { - fun create(initialState: S): VM -} diff --git a/libraries/architecture/src/main/java/io/element/android/x/architecture/viewmodel/DaggerMavericksViewModelFactory.kt b/libraries/architecture/src/main/java/io/element/android/x/architecture/viewmodel/DaggerMavericksViewModelFactory.kt deleted file mode 100644 index 5c31a2b22d..0000000000 --- a/libraries/architecture/src/main/java/io/element/android/x/architecture/viewmodel/DaggerMavericksViewModelFactory.kt +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2022 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.x.architecture.viewmodel - -import com.airbnb.mvrx.MavericksState -import com.airbnb.mvrx.MavericksViewModel -import com.airbnb.mvrx.MavericksViewModelFactory -import com.airbnb.mvrx.ViewModelContext -import io.element.android.x.architecture.bindings - -/** - * To connect Mavericks ViewModel creation with Anvil's dependency injection, add the following to your MavericksViewModel. - * - * Example: - * - * @ContributesViewModel(YourScope::class) - * class MyViewModel @AssistedInject constructor( - * @Assisted initialState: MyState, - * …, - * ): MavericksViewModel(...) { - * … - * - * companion object : MavericksViewModelFactory by daggerMavericksViewModelFactory() - * } - */ - -inline fun , S : MavericksState> daggerMavericksViewModelFactory() = DaggerMavericksViewModelFactory(VM::class.java) - -/** - * A [MavericksViewModelFactory] makes it easy to create instances of a ViewModel - * using its AssistedInject Factory. This class should be implemented by the companion object - * of every ViewModel which uses AssistedInject via [daggerMavericksViewModelFactory]. - * - * @param VM The ViewModel type - * @param S The ViewState type - * @param viewModelClass The [Class] of the ViewModel being requested for creation - * - * This class accesses the map of ViewModel class to [AssistedViewModelFactory]s from the nearest [DaggerComponentOwner] and - * uses it to retrieve the requested ViewModel's factory class. It then creates an instance of this ViewModel - * using the retrieved factory and returns it. - * @see daggerMavericksViewModelFactory - */ -class DaggerMavericksViewModelFactory, S : MavericksState>( - private val viewModelClass: Class -) : MavericksViewModelFactory { - - override fun create(viewModelContext: ViewModelContext, state: S): VM { - val bindings: DaggerMavericksBindings = viewModelContext.activity.bindings() - val viewModelFactoryMap = bindings.viewModelFactories() - val viewModelFactory = viewModelFactoryMap[viewModelClass] ?: error("Cannot find ViewModelFactory for ${viewModelClass.name}.") - - @Suppress("UNCHECKED_CAST") - val castedViewModelFactory = viewModelFactory as? AssistedViewModelFactory - val viewModel = castedViewModelFactory?.create(state) - return viewModel as VM - } -} - -interface DaggerMavericksBindings { - fun viewModelFactories(): Map>, AssistedViewModelFactory<*, *>> -} diff --git a/libraries/architecture/src/main/java/io/element/android/x/architecture/viewmodel/ViewModelKey.kt b/libraries/architecture/src/main/java/io/element/android/x/architecture/viewmodel/ViewModelKey.kt deleted file mode 100644 index 35b9b487be..0000000000 --- a/libraries/architecture/src/main/java/io/element/android/x/architecture/viewmodel/ViewModelKey.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2022 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.x.architecture.viewmodel - -import com.airbnb.mvrx.MavericksViewModel -import dagger.MapKey -import kotlin.reflect.KClass - -@Retention(AnnotationRetention.RUNTIME) -@Target(AnnotationTarget.FUNCTION) -@MapKey -annotation class ViewModelKey(val value: KClass>) diff --git a/libraries/architecture/src/main/java/io/element/android/x/architecture/viewmodel/ViewModelSupport.kt b/libraries/architecture/src/main/java/io/element/android/x/architecture/viewmodel/ViewModelSupport.kt deleted file mode 100644 index 7a7fc576c2..0000000000 --- a/libraries/architecture/src/main/java/io/element/android/x/architecture/viewmodel/ViewModelSupport.kt +++ /dev/null @@ -1,121 +0,0 @@ -package io.element.android.x.architecture.viewmodel - -import android.os.Bundle -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.lifecycle.DEFAULT_ARGS_KEY -import androidx.lifecycle.DefaultLifecycleObserver -import androidx.lifecycle.HasDefaultViewModelProviderFactory -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.SAVED_STATE_REGISTRY_OWNER_KEY -import androidx.lifecycle.SavedStateViewModelFactory -import androidx.lifecycle.VIEW_MODEL_STORE_OWNER_KEY -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.ViewModelStore -import androidx.lifecycle.ViewModelStoreOwner -import androidx.lifecycle.enableSavedStateHandles -import androidx.lifecycle.viewmodel.CreationExtras -import androidx.lifecycle.viewmodel.MutableCreationExtras -import androidx.savedstate.SavedStateRegistry -import androidx.savedstate.SavedStateRegistryController -import androidx.savedstate.SavedStateRegistryOwner -import com.bumble.appyx.core.modality.BuildContext -import com.bumble.appyx.core.node.Node -import com.bumble.appyx.core.plugin.Plugin - -fun viewModelSupportNode(buildContext: BuildContext, plugins: List = emptyList(), composable: @Composable (Modifier) -> Unit): Node = - ViewModelSupportNode(buildContext, plugins, composable) - -class ViewModelSupportNode( - buildContext: BuildContext, - plugins: List = emptyList(), - private val composable: @Composable (Modifier) -> Unit, -) : Node( - buildContext, plugins = plugins -), ViewModelStoreOwner, SavedStateRegistryOwner { - - private val viewModelSupport = ViewModelSupport( - lifecycle, - buildContext.savedStateMap?.get("SAVED_STATE_REGISTRY") as Bundle?, - ) - - override fun getViewModelStore(): ViewModelStore { - return viewModelSupport.viewModelStore - } - - override val savedStateRegistry: SavedStateRegistry - get() = viewModelSupport.savedStateRegistry - - @Composable - override fun View(modifier: Modifier) { - composable(modifier) - } -} - -private class ViewModelSupport( - private val lifecycle: Lifecycle, - private val initialSavedState: Bundle?, - val defaultArgs: Bundle? = null, -) : ViewModelStoreOwner, HasDefaultViewModelProviderFactory, SavedStateRegistryOwner { - - private val viewModelStore = ViewModelStore() - private val savedStateRegistryController: SavedStateRegistryController = - SavedStateRegistryController.create(this) - - //Don't replace the initial saved state until we have at least started - private var canSaveState: Boolean = false - - init { - savedStateRegistryController.performAttach() - - // We copy the bundle because the `savedStateRegistryController` will modify it. - // We don't want to modify `initialSavedState` since we may need to return that as our - // state in `saveState`. - savedStateRegistryController.performRestore(initialSavedState?.let { Bundle(it) }) - enableSavedStateHandles() - - lifecycle.addObserver(object : DefaultLifecycleObserver { - override fun onStart(owner: LifecycleOwner) { - canSaveState = true - } - - override fun onDestroy(owner: LifecycleOwner) { - viewModelStore.clear() - } - }) - } - - override fun getViewModelStore(): ViewModelStore { - return viewModelStore - } - - override fun getDefaultViewModelProviderFactory(): ViewModelProvider.Factory { - return SavedStateViewModelFactory(null, this, defaultArgs) - } - - override fun getDefaultViewModelCreationExtras(): CreationExtras { - val extras = MutableCreationExtras() - extras[SAVED_STATE_REGISTRY_OWNER_KEY] = this - extras[VIEW_MODEL_STORE_OWNER_KEY] = this - defaultArgs?.let { args -> - extras[DEFAULT_ARGS_KEY] = args - } - return extras - } - - override val savedStateRegistry: SavedStateRegistry - get() = savedStateRegistryController.savedStateRegistry - - override fun getLifecycle(): Lifecycle { - return lifecycle - } - - fun saveState(): Bundle? { - return if (canSaveState) { - Bundle().also(savedStateRegistryController::performSave) - } else { - initialSavedState - } - } -} diff --git a/libraries/matrixui/src/main/java/io/element/android/x/matrix/ui/viewmodels/user/UserViewModel.kt b/libraries/matrixui/src/main/java/io/element/android/x/matrix/ui/viewmodels/user/UserViewModel.kt deleted file mode 100644 index 6e621ec08c..0000000000 --- a/libraries/matrixui/src/main/java/io/element/android/x/matrix/ui/viewmodels/user/UserViewModel.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2022 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.x.matrix.ui.viewmodels.user - -import com.airbnb.mvrx.MavericksViewModel -import com.airbnb.mvrx.MavericksViewModelFactory -import dagger.assisted.Assisted -import dagger.assisted.AssistedInject -import io.element.android.x.anvilannotations.ContributesViewModel -import io.element.android.x.architecture.viewmodel.daggerMavericksViewModelFactory -import io.element.android.x.designsystem.components.avatar.AvatarSize -import io.element.android.x.di.SessionScope -import io.element.android.x.matrix.MatrixClient -import io.element.android.x.matrix.ui.MatrixItemHelper - -@ContributesViewModel(SessionScope::class) -class UserViewModel @AssistedInject constructor( - client: MatrixClient, - @Assisted initialState: UserViewState -) : MavericksViewModel(initialState) { - - companion object : MavericksViewModelFactory by daggerMavericksViewModelFactory() - - private val matrixUserHelper = MatrixItemHelper(client) - - init { - handleInit() - } - - private fun handleInit() { - matrixUserHelper.getCurrentUserData(avatarSize = AvatarSize.SMALL).execute { - copy(user = it) - } - } -} diff --git a/libraries/matrixui/src/main/java/io/element/android/x/matrix/ui/viewmodels/user/UserViewState.kt b/libraries/matrixui/src/main/java/io/element/android/x/matrix/ui/viewmodels/user/UserViewState.kt deleted file mode 100644 index 60d7c5bd48..0000000000 --- a/libraries/matrixui/src/main/java/io/element/android/x/matrix/ui/viewmodels/user/UserViewState.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2022 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.x.matrix.ui.viewmodels.user - -import com.airbnb.mvrx.Async -import com.airbnb.mvrx.MavericksState -import com.airbnb.mvrx.Uninitialized -import io.element.android.x.matrix.ui.model.MatrixUser - -data class UserViewState( - val user: Async = Uninitialized, -) : MavericksState diff --git a/plugins/src/main/java/extension/DependencyHandleScope.kt b/plugins/src/main/java/extension/DependencyHandleScope.kt index 71d94f6ad0..bdfa1460bf 100644 --- a/plugins/src/main/java/extension/DependencyHandleScope.kt +++ b/plugins/src/main/java/extension/DependencyHandleScope.kt @@ -43,7 +43,6 @@ fun DependencyHandlerScope.composeDependencies() { implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.5.1") implementation("androidx.activity:activity-compose:1.6.1") implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1") - implementation("com.airbnb.android:mavericks-compose:3.0.1") debugImplementation("androidx.compose.ui:ui-tooling") debugImplementation("androidx.compose.ui:ui-test-manifest") implementation("com.airbnb.android:showkase:1.0.0-beta14")