Start migrating Anvil KSP to Metro

This commit is contained in:
Jorge Martín 2025-08-20 15:29:50 +02:00
parent 2eacce47c0
commit 92a4b8b66b
703 changed files with 3523 additions and 2820 deletions

3
.gitmodules vendored
View file

@ -1,3 +0,0 @@
[submodule "enterprise"]
path = enterprise
url = git@github.com:element-hq/element-android-enterprise.git

View file

@ -13,7 +13,7 @@ import kotlin.reflect.KClass
* Adds Node to the specified component graph. * Adds Node to the specified component graph.
* Equivalent to the following declaration: * Equivalent to the following declaration:
* *
* @Module * @BindingContainer
* @ContributesTo(Scope::class) * @ContributesTo(Scope::class)
* abstract class YourNodeModule { * abstract class YourNodeModule {

View file

@ -11,10 +11,9 @@ plugins {
dependencies { dependencies {
implementation(projects.anvilannotations) implementation(projects.anvilannotations)
api(libs.anvil.compiler.api)
implementation(libs.anvil.compiler.utils) implementation(libs.anvil.compiler.utils)
implementation(libs.metro.runtime)
implementation(libs.kotlinpoet) implementation(libs.kotlinpoet)
implementation(libs.dagger)
implementation(libs.ksp.plugin) implementation(libs.ksp.plugin)
implementation(libs.kotlinpoet.ksp) implementation(libs.kotlinpoet.ksp)
} }

View file

@ -19,7 +19,6 @@ import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSClassDeclaration import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.google.devtools.ksp.symbol.KSType import com.google.devtools.ksp.symbol.KSType
import com.google.devtools.ksp.validate import com.google.devtools.ksp.validate
import com.squareup.anvil.annotations.ContributesTo
import com.squareup.kotlinpoet.AnnotationSpec import com.squareup.kotlinpoet.AnnotationSpec
import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.FileSpec import com.squareup.kotlinpoet.FileSpec
@ -30,12 +29,12 @@ import com.squareup.kotlinpoet.STAR
import com.squareup.kotlinpoet.TypeSpec import com.squareup.kotlinpoet.TypeSpec
import com.squareup.kotlinpoet.ksp.toTypeName import com.squareup.kotlinpoet.ksp.toTypeName
import com.squareup.kotlinpoet.ksp.writeTo import com.squareup.kotlinpoet.ksp.writeTo
import dagger.Binds import dev.zacsweers.metro.Assisted
import dagger.Module import dev.zacsweers.metro.AssistedFactory
import dagger.assisted.Assisted import dev.zacsweers.metro.BindingContainer
import dagger.assisted.AssistedFactory import dev.zacsweers.metro.Binds
import dagger.assisted.AssistedInject import dev.zacsweers.metro.ContributesTo
import dagger.multibindings.IntoMap import dev.zacsweers.metro.IntoMap
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@ -57,9 +56,9 @@ class ContributesNodeProcessor(
if (validSymbols.isEmpty()) return invalidSymbols if (validSymbols.isEmpty()) return invalidSymbols
for (ksClass in validSymbols) { for (ksClass in validSymbols) {
if (config.enableLogging) { // if (config.enableLogging) {
logger.warn("Processing ${ksClass.qualifiedName?.asString()}") logger.warn("Processing ${ksClass.qualifiedName?.asString()}")
} // }
generateModule(ksClass) generateModule(ksClass)
generateFactory(ksClass) generateFactory(ksClass)
} }
@ -77,9 +76,8 @@ class ContributesNodeProcessor(
fileName = moduleClassName, fileName = moduleClassName,
) )
.addType( .addType(
TypeSpec.classBuilder(moduleClassName) TypeSpec.interfaceBuilder(moduleClassName)
.addModifiers(KModifier.ABSTRACT) .addAnnotation(BindingContainer::class)
.addAnnotation(Module::class)
.addAnnotation(AnnotationSpec.builder(ContributesTo::class).addMember("%T::class", scope.toTypeName()).build()) .addAnnotation(AnnotationSpec.builder(ContributesTo::class).addMember("%T::class", scope.toTypeName()).build())
.addFunction( .addFunction(
FunSpec.builder("bind${ksClass.simpleName.asString()}Factory") FunSpec.builder("bind${ksClass.simpleName.asString()}Factory")
@ -103,7 +101,7 @@ class ContributesNodeProcessor(
content.writeTo( content.writeTo(
codeGenerator = codeGenerator, codeGenerator = codeGenerator,
dependencies = Dependencies( dependencies = Dependencies(
aggregating = true, aggregating = false,
ksClass.containingFile!! ksClass.containingFile!!
), ),
) )
@ -113,23 +111,23 @@ class ContributesNodeProcessor(
private fun generateFactory(ksClass: KSClassDeclaration) { private fun generateFactory(ksClass: KSClassDeclaration) {
val generatedPackage = ksClass.packageName.asString() val generatedPackage = ksClass.packageName.asString()
val assistedFactoryClassName = "${ksClass.simpleName.asString()}_AssistedFactory" val assistedFactoryClassName = "${ksClass.simpleName.asString()}_AssistedFactory"
val constructor = ksClass.getConstructors().singleOrNull { it.isAnnotationPresent(AssistedInject::class) } val constructor = ksClass.getConstructors().first { it.parameters.isNotEmpty() }
val assistedParameters = constructor?.parameters?.filter { it.isAnnotationPresent(Assisted::class) }.orEmpty() val assistedParameters = constructor.parameters.filter { it.isAnnotationPresent(Assisted::class) }
if (constructor == null || assistedParameters.size != 2) { if (assistedParameters.size != 2) {
error( error(
"${ksClass.qualifiedName} must have an @AssistedInject constructor with 2 @Assisted parameters", "${ksClass.qualifiedName?.asString()} must have an @Inject constructor with 2 @Assisted parameters. Found: ${assistedParameters.size}",
) )
} }
val contextAssistedParam = assistedParameters[0] val contextAssistedParam = assistedParameters[0]
if (contextAssistedParam.name?.asString() != "buildContext") { if (contextAssistedParam.name?.asString() != "buildContext") {
error( error(
"${ksClass.qualifiedName} @Assisted parameter must be named buildContext", "${ksClass.qualifiedName?.asString()} @Assisted parameter must be named buildContext",
) )
} }
val pluginsAssistedParam = assistedParameters[1] val pluginsAssistedParam = assistedParameters[1]
if (pluginsAssistedParam.name?.asString() != "plugins") { if (pluginsAssistedParam.name?.asString() != "plugins") {
error( error(
"${ksClass.qualifiedName} @Assisted parameter must be named plugins", "${ksClass.qualifiedName?.asString()} @Assisted parameter must be named plugins",
) )
} }
@ -156,7 +154,7 @@ class ContributesNodeProcessor(
content.writeTo( content.writeTo(
codeGenerator = codeGenerator, codeGenerator = codeGenerator,
dependencies = Dependencies( dependencies = Dependencies(
aggregating = true, aggregating = false,
ksClass.containingFile!! ksClass.containingFile!!
), ),
) )

View file

@ -9,16 +9,18 @@ package io.element.android.x
import android.app.Application import android.app.Application
import androidx.startup.AppInitializer import androidx.startup.AppInitializer
import dev.zacsweers.metro.asContribution
import dev.zacsweers.metro.createGraphFactory
import io.element.android.features.cachecleaner.api.CacheCleanerInitializer import io.element.android.features.cachecleaner.api.CacheCleanerInitializer
import io.element.android.libraries.di.DaggerComponentOwner import io.element.android.libraries.di.DaggerComponentOwner
import io.element.android.x.di.AppComponent import io.element.android.x.di.AppComponent
import io.element.android.x.di.DaggerAppComponent import io.element.android.x.di.globalGraph
import io.element.android.x.info.logApplicationInfo import io.element.android.x.info.logApplicationInfo
import io.element.android.x.initializer.CrashInitializer import io.element.android.x.initializer.CrashInitializer
import io.element.android.x.initializer.PlatformInitializer import io.element.android.x.initializer.PlatformInitializer
class ElementXApplication : Application(), DaggerComponentOwner { class ElementXApplication : Application(), DaggerComponentOwner {
override val daggerComponent: AppComponent = DaggerAppComponent.factory().create(this) override val daggerComponent: AppComponent = globalGraph.asContribution<AppComponent.Factory>().create(this)
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()

View file

@ -21,7 +21,7 @@ import com.bumble.appyx.core.node.ParentNode
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import io.element.android.appnav.RootFlowNode import io.element.android.appnav.RootFlowNode
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.di.annotations.ApplicationContext
import io.element.android.libraries.di.DaggerComponentOwner import io.element.android.libraries.di.DaggerComponentOwner
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize

View file

@ -7,7 +7,7 @@
package io.element.android.x.di package io.element.android.x.di
import com.squareup.anvil.annotations.ContributesTo import dev.zacsweers.metro.ContributesTo
import io.element.android.features.api.MigrationEntryPoint import io.element.android.features.api.MigrationEntryPoint
import io.element.android.features.enterprise.api.EnterpriseService import io.element.android.features.enterprise.api.EnterpriseService
import io.element.android.features.lockscreen.api.LockScreenEntryPoint import io.element.android.features.lockscreen.api.LockScreenEntryPoint
@ -15,7 +15,7 @@ import io.element.android.features.lockscreen.api.LockScreenService
import io.element.android.features.rageshake.api.reporter.BugReporter import io.element.android.features.rageshake.api.reporter.BugReporter
import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.matrix.api.platform.InitPlatformService import io.element.android.libraries.matrix.api.platform.InitPlatformService
import io.element.android.libraries.matrix.api.tracing.TracingService import io.element.android.libraries.matrix.api.tracing.TracingService

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023, 2024 New Vector Ltd. * Copyright 2025 New Vector Ltd.
* *
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
@ -8,20 +8,22 @@
package io.element.android.x.di package io.element.android.x.di
import android.content.Context import android.content.Context
import com.squareup.anvil.annotations.MergeComponent import dev.zacsweers.metro.ContributesTo
import dagger.BindsInstance import dev.zacsweers.metro.GraphExtension
import dev.zacsweers.metro.Provides
import io.element.android.libraries.architecture.NodeFactoriesBindings import io.element.android.libraries.architecture.NodeFactoriesBindings
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.di.annotations.ApplicationContext
import io.element.android.libraries.di.SingleIn
@SingleIn(AppScope::class) @GraphExtension(AppScope::class)
@MergeComponent(AppScope::class)
interface AppComponent : NodeFactoriesBindings { interface AppComponent : NodeFactoriesBindings {
@MergeComponent.Factory val sessionComponentFactory: SessionComponent.Factory
@ContributesTo(GlobalScope::class)
@GraphExtension.Factory
interface Factory { interface Factory {
fun create( fun create(
@ApplicationContext @BindsInstance @ApplicationContext @Provides
context: Context context: Context
): AppComponent ): AppComponent
} }

View file

@ -11,9 +11,10 @@ import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.content.res.Resources import android.content.res.Resources
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.squareup.anvil.annotations.ContributesTo import dev.zacsweers.metro.BindingContainer
import dagger.Module import dev.zacsweers.metro.ContributesTo
import dagger.Provides import dev.zacsweers.metro.Named
import dev.zacsweers.metro.Provides
import io.element.android.appconfig.ApplicationConfig import io.element.android.appconfig.ApplicationConfig
import io.element.android.features.enterprise.api.EnterpriseService import io.element.android.features.enterprise.api.EnterpriseService
import io.element.android.features.messages.impl.timeline.components.customreaction.DefaultEmojibaseProvider import io.element.android.features.messages.impl.timeline.components.customreaction.DefaultEmojibaseProvider
@ -23,10 +24,10 @@ import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.core.meta.BuildType import io.element.android.libraries.core.meta.BuildType
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.di.annotations.ApplicationContext
import io.element.android.libraries.di.CacheDirectory import io.element.android.libraries.di.CacheDirectory
import io.element.android.libraries.di.SingleIn import dev.zacsweers.metro.SingleIn
import io.element.android.libraries.di.annotations.AppCoroutineScope import io.element.android.libraries.di.annotations.AppCoroutineScope
import io.element.android.x.BuildConfig import io.element.android.x.BuildConfig
import io.element.android.x.R import io.element.android.x.R
@ -37,16 +38,17 @@ import kotlinx.coroutines.MainScope
import kotlinx.coroutines.plus import kotlinx.coroutines.plus
import java.io.File import java.io.File
@Module @BindingContainer
@ContributesTo(AppScope::class) @ContributesTo(AppScope::class)
object AppModule { object AppModule {
@Provides @Provides
@Named("baseDirectory")
fun providesBaseDirectory(@ApplicationContext context: Context): File { fun providesBaseDirectory(@ApplicationContext context: Context): File {
return File(context.filesDir, "sessions") return File(context.filesDir, "sessions")
} }
@Provides @Provides
@CacheDirectory @Named("cacheDirectory")
fun providesCacheDirectory(@ApplicationContext context: Context): File { fun providesCacheDirectory(@ApplicationContext context: Context): File {
return context.cacheDir return context.cacheDir
} }

View file

@ -7,20 +7,19 @@
package io.element.android.x.di package io.element.android.x.di
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.appnav.di.RoomComponentFactory import io.element.android.appnav.di.RoomComponentFactory
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.JoinedRoom
import javax.inject.Inject import dev.zacsweers.metro.Inject
@ContributesBinding(SessionScope::class) @ContributesBinding(SessionScope::class)
class DefaultRoomComponentFactory @Inject constructor( @Inject
private val roomComponentBuilder: RoomComponent.Builder class DefaultRoomComponentFactory(
private val sessionComponent: SessionComponent,
) : RoomComponentFactory { ) : RoomComponentFactory {
override fun create(room: JoinedRoom): Any { override fun create(room: JoinedRoom): Any {
return roomComponentBuilder return sessionComponent.roomComponentFactory
.joinedRoom(room) .create(room, room)
.baseRoom(room)
.build()
} }
} }

View file

@ -7,17 +7,18 @@
package io.element.android.x.di package io.element.android.x.di
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding
import dev.zacsweers.metro.Inject
import io.element.android.appnav.di.SessionComponentFactory import io.element.android.appnav.di.SessionComponentFactory
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import javax.inject.Inject
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultSessionComponentFactory @Inject constructor( @Inject
private val sessionComponentBuilder: SessionComponent.Builder class DefaultSessionComponentFactory(
private val appComponent: AppComponent
) : SessionComponentFactory { ) : SessionComponentFactory {
override fun create(client: MatrixClient): Any { override fun create(client: MatrixClient): Any {
return sessionComponentBuilder.client(client).build() return appComponent.sessionComponentFactory.createSessionComponent(client)
} }
} }

View file

@ -0,0 +1,16 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.x.di
import dev.zacsweers.metro.DependencyGraph
import dev.zacsweers.metro.createGraph
@DependencyGraph(GlobalScope::class)
interface GlobalGraph
internal val globalGraph = createGraph<GlobalGraph>()

View file

@ -0,0 +1,10 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.x.di
class GlobalScope private constructor()

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023, 2024 New Vector Ltd. * Copyright 2025 New Vector Ltd.
* *
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
@ -7,32 +7,24 @@
package io.element.android.x.di package io.element.android.x.di
import com.squareup.anvil.annotations.ContributesTo import dev.zacsweers.metro.ContributesTo
import com.squareup.anvil.annotations.MergeSubcomponent import dev.zacsweers.metro.GraphExtension
import dagger.BindsInstance import dev.zacsweers.metro.Provides
import io.element.android.libraries.architecture.NodeFactoriesBindings import io.element.android.libraries.architecture.NodeFactoriesBindings
import dev.zacsweers.metro.SingleIn
import io.element.android.libraries.di.RoomScope import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.di.SingleIn
import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.JoinedRoom
@SingleIn(RoomScope::class) @GraphExtension(RoomScope::class)
@MergeSubcomponent(RoomScope::class)
interface RoomComponent : NodeFactoriesBindings { interface RoomComponent : NodeFactoriesBindings {
@MergeSubcomponent.Builder
interface Builder {
@BindsInstance
fun joinedRoom(room: JoinedRoom): Builder
@BindsInstance
fun baseRoom(room: BaseRoom): Builder
fun build(): RoomComponent
}
@ContributesTo(SessionScope::class) @ContributesTo(SessionScope::class)
interface ParentBindings { @GraphExtension.Factory
fun roomComponentBuilder(): Builder interface Factory {
fun create(
@Provides joinedRoom: JoinedRoom,
@Provides baseRoom: BaseRoom
): RoomComponent
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023, 2024 New Vector Ltd. * Copyright 2025 New Vector Ltd.
* *
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
@ -7,28 +7,21 @@
package io.element.android.x.di package io.element.android.x.di
import com.squareup.anvil.annotations.ContributesTo import dev.zacsweers.metro.AppScope
import com.squareup.anvil.annotations.MergeSubcomponent import dev.zacsweers.metro.ContributesTo
import dagger.BindsInstance import dev.zacsweers.metro.GraphExtension
import dev.zacsweers.metro.Provides
import io.element.android.libraries.architecture.NodeFactoriesBindings import io.element.android.libraries.architecture.NodeFactoriesBindings
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.di.SingleIn
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
@SingleIn(SessionScope::class) @GraphExtension(SessionScope::class)
@MergeSubcomponent(SessionScope::class)
interface SessionComponent : NodeFactoriesBindings { interface SessionComponent : NodeFactoriesBindings {
@MergeSubcomponent.Builder val roomComponentFactory: RoomComponent.Factory
interface Builder {
@BindsInstance
fun client(matrixClient: MatrixClient): Builder
fun build(): SessionComponent
}
@ContributesTo(AppScope::class) @ContributesTo(AppScope::class)
interface ParentBindings { @GraphExtension.Factory
fun sessionComponentBuilder(): Builder interface Factory {
fun createSessionComponent(@Provides matrixClient: MatrixClient): SessionComponent
} }
} }

View file

@ -10,19 +10,20 @@ package io.element.android.x.intent
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import androidx.core.net.toUri import androidx.core.net.toUri
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding
import dev.zacsweers.metro.Inject
import io.element.android.libraries.deeplink.api.DeepLinkCreator import io.element.android.libraries.deeplink.api.DeepLinkCreator
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.di.ApplicationContext
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.ThreadId
import io.element.android.libraries.push.impl.intent.IntentProvider import io.element.android.libraries.push.impl.intent.IntentProvider
import io.element.android.x.MainActivity import io.element.android.x.MainActivity
import javax.inject.Inject
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultIntentProvider @Inject constructor( @Inject
class DefaultIntentProvider(
@ApplicationContext private val context: Context, @ApplicationContext private val context: Context,
private val deepLinkCreator: DeepLinkCreator, private val deepLinkCreator: DeepLinkCreator,
) : IntentProvider { ) : IntentProvider {

View file

@ -7,15 +7,16 @@
package io.element.android.x.oidc package io.element.android.x.oidc
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.matrix.api.auth.OidcRedirectUrlProvider import io.element.android.libraries.matrix.api.auth.OidcRedirectUrlProvider
import io.element.android.services.toolbox.api.strings.StringProvider import io.element.android.services.toolbox.api.strings.StringProvider
import io.element.android.x.R import io.element.android.x.R
import javax.inject.Inject import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultOidcRedirectUrlProvider @Inject constructor( @Inject
class DefaultOidcRedirectUrlProvider(
private val stringProvider: StringProvider, private val stringProvider: StringProvider,
) : OidcRedirectUrlProvider { ) : OidcRedirectUrlProvider {
override fun provide() = buildString { override fun provide() = buildString {

View file

@ -22,14 +22,14 @@ import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.node.ParentNode import com.bumble.appyx.core.node.ParentNode
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins import com.bumble.appyx.core.plugin.plugins
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.appnav.di.SessionComponentFactory import io.element.android.appnav.di.SessionComponentFactory
import io.element.android.libraries.architecture.NodeInputs import io.element.android.libraries.architecture.NodeInputs
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.architecture.inputs import io.element.android.libraries.architecture.inputs
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.DaggerComponentOwner import io.element.android.libraries.di.DaggerComponentOwner
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.ui.media.ImageLoaderHolder import io.element.android.libraries.matrix.ui.media.ImageLoaderHolder
@ -41,7 +41,8 @@ import kotlinx.parcelize.Parcelize
* This allow to inject objects with SessionScope in the constructor of [LoggedInFlowNode]. * This allow to inject objects with SessionScope in the constructor of [LoggedInFlowNode].
*/ */
@ContributesNode(AppScope::class) @ContributesNode(AppScope::class)
class LoggedInAppScopeFlowNode @AssistedInject constructor( @Inject
class LoggedInAppScopeFlowNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
sessionComponentFactory: SessionComponentFactory, sessionComponentFactory: SessionComponentFactory,

View file

@ -18,9 +18,10 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import javax.inject.Inject import dev.zacsweers.metro.Inject
class LoggedInEventProcessor @Inject constructor( @Inject
class LoggedInEventProcessor(
private val snackbarDispatcher: SnackbarDispatcher, private val snackbarDispatcher: SnackbarDispatcher,
private val roomMembershipObserver: RoomMembershipObserver, private val roomMembershipObserver: RoomMembershipObserver,
) { ) {

View file

@ -36,8 +36,8 @@ import com.bumble.appyx.navmodel.backstack.operation.pop
import com.bumble.appyx.navmodel.backstack.operation.push import com.bumble.appyx.navmodel.backstack.operation.push
import com.bumble.appyx.navmodel.backstack.operation.replace import com.bumble.appyx.navmodel.backstack.operation.replace
import com.bumble.appyx.navmodel.backstack.operation.singleTop import com.bumble.appyx.navmodel.backstack.operation.singleTop
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import im.vector.app.features.analytics.plan.JoinedRoom import im.vector.app.features.analytics.plan.JoinedRoom
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.appnav.loggedin.LoggedInNode import io.element.android.appnav.loggedin.LoggedInNode
@ -66,8 +66,9 @@ import io.element.android.libraries.architecture.BackstackView
import io.element.android.libraries.architecture.BaseFlowNode import io.element.android.libraries.architecture.BaseFlowNode
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.architecture.waitForNavTargetAttached import io.element.android.libraries.architecture.waitForNavTargetAttached
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.di.annotations.SessionCoroutineScope import io.element.android.libraries.di.annotations.SessionCoroutineScope
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
@ -100,7 +101,8 @@ import kotlin.time.Duration.Companion.seconds
import kotlin.time.toKotlinDuration import kotlin.time.toKotlinDuration
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class LoggedInFlowNode @AssistedInject constructor( @Inject
class LoggedInFlowNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val homeEntryPoint: HomeEntryPoint, private val homeEntryPoint: HomeEntryPoint,
@ -561,13 +563,15 @@ class LoggedInFlowNode @AssistedInject constructor(
} }
} }
@ContributesNode(AppScope::class)
class PlaceholderNode @AssistedInject constructor(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
) : Node(buildContext, plugins = plugins)
} }
@ContributesNode(AppScope::class)
@Inject
class PlaceholderNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
) : Node(buildContext, plugins = plugins)
@Parcelize @Parcelize
private class AttachRoomOperation( private class AttachRoomOperation(
val roomTarget: LoggedInFlowNode.NavTarget.Room, val roomTarget: LoggedInFlowNode.NavTarget.Room,

View file

@ -20,8 +20,8 @@ import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins import com.bumble.appyx.core.plugin.plugins
import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.BackStack
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.login.api.LoginEntryPoint import io.element.android.features.login.api.LoginEntryPoint
import io.element.android.features.login.api.LoginParams import io.element.android.features.login.api.LoginParams
@ -31,12 +31,13 @@ import io.element.android.libraries.architecture.NodeInputs
import io.element.android.libraries.architecture.inputs import io.element.android.libraries.architecture.inputs
import io.element.android.libraries.designsystem.utils.ForceOrientationInMobileDevices import io.element.android.libraries.designsystem.utils.ForceOrientationInMobileDevices
import io.element.android.libraries.designsystem.utils.ScreenOrientation import io.element.android.libraries.designsystem.utils.ScreenOrientation
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.matrix.ui.media.NotLoggedInImageLoaderFactory import io.element.android.libraries.matrix.ui.media.NotLoggedInImageLoaderFactory
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ContributesNode(AppScope::class) @ContributesNode(AppScope::class)
class NotLoggedInFlowNode @AssistedInject constructor( @Inject
class NotLoggedInFlowNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val loginEntryPoint: LoginEntryPoint, private val loginEntryPoint: LoginEntryPoint,

View file

@ -23,8 +23,8 @@ import com.bumble.appyx.core.state.MutableSavedStateMap
import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.pop import com.bumble.appyx.navmodel.backstack.operation.pop
import com.bumble.appyx.navmodel.backstack.operation.push import com.bumble.appyx.navmodel.backstack.operation.push
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import im.vector.app.features.analytics.plan.JoinedRoom import im.vector.app.features.analytics.plan.JoinedRoom
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.appnav.di.MatrixSessionCache import io.element.android.appnav.di.MatrixSessionCache
@ -46,7 +46,7 @@ import io.element.android.libraries.architecture.waitForChildAttached
import io.element.android.libraries.core.uri.ensureProtocol import io.element.android.libraries.core.uri.ensureProtocol
import io.element.android.libraries.deeplink.api.DeeplinkData import io.element.android.libraries.deeplink.api.DeeplinkData
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
@ -61,7 +61,8 @@ import kotlinx.parcelize.Parcelize
import timber.log.Timber import timber.log.Timber
@ContributesNode(AppScope::class) @ContributesNode(AppScope::class)
class RootFlowNode @AssistedInject constructor( @Inject
class RootFlowNode(
@Assisted val buildContext: BuildContext, @Assisted val buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val authenticationService: MatrixAuthenticationService, private val authenticationService: MatrixAuthenticationService,

View file

@ -10,9 +10,9 @@ package io.element.android.appnav.di
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import com.bumble.appyx.core.state.MutableSavedStateMap import com.bumble.appyx.core.state.MutableSavedStateMap
import com.bumble.appyx.core.state.SavedStateMap import com.bumble.appyx.core.state.SavedStateMap
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.SingleIn import dev.zacsweers.metro.SingleIn
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.MatrixClientProvider import io.element.android.libraries.matrix.api.MatrixClientProvider
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
@ -22,7 +22,7 @@ import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import timber.log.Timber import timber.log.Timber
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject import dev.zacsweers.metro.Inject
private const val SAVE_INSTANCE_KEY = "io.element.android.x.di.MatrixClientsHolder.SaveInstanceKey" private const val SAVE_INSTANCE_KEY = "io.element.android.x.di.MatrixClientsHolder.SaveInstanceKey"
@ -33,7 +33,8 @@ private const val SAVE_INSTANCE_KEY = "io.element.android.x.di.MatrixClientsHold
*/ */
@SingleIn(AppScope::class) @SingleIn(AppScope::class)
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class MatrixSessionCache @Inject constructor( @Inject
class MatrixSessionCache(
private val authenticationService: MatrixAuthenticationService, private val authenticationService: MatrixAuthenticationService,
private val syncOrchestratorFactory: SyncOrchestrator.Factory, private val syncOrchestratorFactory: SyncOrchestrator.Factory,
) : MatrixClientProvider { ) : MatrixClientProvider {

View file

@ -8,9 +8,9 @@
package io.element.android.appnav.di package io.element.android.appnav.di
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedFactory import dev.zacsweers.metro.AssistedFactory
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.features.networkmonitor.api.NetworkMonitor import io.element.android.features.networkmonitor.api.NetworkMonitor
import io.element.android.features.networkmonitor.api.NetworkStatus import io.element.android.features.networkmonitor.api.NetworkStatus
import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.core.coroutine.CoroutineDispatchers
@ -30,7 +30,8 @@ import java.util.concurrent.atomic.AtomicBoolean
import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
class SyncOrchestrator @AssistedInject constructor( @Inject
class SyncOrchestrator(
@Assisted matrixClient: MatrixClient, @Assisted matrixClient: MatrixClient,
private val appForegroundStateService: AppForegroundStateService, private val appForegroundStateService: AppForegroundStateService,
private val networkMonitor: NetworkMonitor, private val networkMonitor: NetworkMonitor,

View file

@ -17,7 +17,7 @@ import io.element.android.libraries.matrix.api.permalink.PermalinkParser
import io.element.android.libraries.oidc.api.OidcAction import io.element.android.libraries.oidc.api.OidcAction
import io.element.android.libraries.oidc.api.OidcIntentResolver import io.element.android.libraries.oidc.api.OidcIntentResolver
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import dev.zacsweers.metro.Inject
sealed interface ResolvedIntent { sealed interface ResolvedIntent {
data class Navigation(val deeplinkData: DeeplinkData) : ResolvedIntent data class Navigation(val deeplinkData: DeeplinkData) : ResolvedIntent
@ -27,7 +27,8 @@ sealed interface ResolvedIntent {
data class IncomingShare(val intent: Intent) : ResolvedIntent data class IncomingShare(val intent: Intent) : ResolvedIntent
} }
class IntentResolver @Inject constructor( @Inject
class IntentResolver(
private val deeplinkParser: DeeplinkParser, private val deeplinkParser: DeeplinkParser,
private val loginIntentResolver: LoginIntentResolver, private val loginIntentResolver: LoginIntentResolver,
private val oidcIntentResolver: OidcIntentResolver, private val oidcIntentResolver: OidcIntentResolver,

View file

@ -13,13 +13,14 @@ import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins import com.bumble.appyx.core.plugin.plugins
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class LoggedInNode @AssistedInject constructor( @Inject
class LoggedInNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val loggedInPresenter: LoggedInPresenter, private val loggedInPresenter: LoggedInPresenter,

View file

@ -42,11 +42,12 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import dev.zacsweers.metro.Inject
private val pusherTag = LoggerTag("Pusher", LoggerTag.PushLoggerTag) private val pusherTag = LoggerTag("Pusher", LoggerTag.PushLoggerTag)
class LoggedInPresenter @Inject constructor( @Inject
class LoggedInPresenter(
private val matrixClient: MatrixClient, private val matrixClient: MatrixClient,
private val syncService: SyncService, private val syncService: SyncService,
private val pushService: PushService, private val pushService: PushService,

View file

@ -14,13 +14,14 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import dev.zacsweers.metro.Inject
/** /**
* This migration is temporary, will be safe to remove after some time. * This migration is temporary, will be safe to remove after some time.
* The goal is to set the server config if it's not set, and remove the local data. * The goal is to set the server config if it's not set, and remove the local data.
*/ */
class MediaPreviewConfigMigration @Inject constructor( @Inject
class MediaPreviewConfigMigration(
private val mediaPreviewService: MediaPreviewService, private val mediaPreviewService: MediaPreviewService,
private val appPreferencesStore: AppPreferencesStore, private val appPreferencesStore: AppPreferencesStore,
@SessionCoroutineScope @SessionCoroutineScope

View file

@ -10,7 +10,7 @@ package io.element.android.appnav.loggedin
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import io.element.android.features.networkmonitor.api.NetworkStatus import io.element.android.features.networkmonitor.api.NetworkStatus
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.di.SingleIn import dev.zacsweers.metro.SingleIn
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.sync.SyncService
import io.element.android.libraries.matrix.api.sync.SyncState import io.element.android.libraries.matrix.api.sync.SyncState
@ -21,13 +21,14 @@ import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import dev.zacsweers.metro.Inject
@VisibleForTesting @VisibleForTesting
const val SEND_QUEUES_RETRY_DELAY_MILLIS = 500L const val SEND_QUEUES_RETRY_DELAY_MILLIS = 500L
@SingleIn(SessionScope::class) @SingleIn(SessionScope::class)
class SendQueues @Inject constructor( @Inject
class SendQueues(
private val matrixClient: MatrixClient, private val matrixClient: MatrixClient,
private val syncService: SyncService, private val syncService: SyncService,
) { ) {

View file

@ -21,8 +21,8 @@ import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins import com.bumble.appyx.core.plugin.plugins
import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.newRoot import com.bumble.appyx.navmodel.backstack.operation.newRoot
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import im.vector.app.features.analytics.plan.JoinedRoom import im.vector.app.features.analytics.plan.JoinedRoom
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.appnav.room.joined.JoinedRoomFlowNode import io.element.android.appnav.room.joined.JoinedRoomFlowNode
@ -63,7 +63,8 @@ import java.util.Optional
import kotlin.jvm.optionals.getOrNull import kotlin.jvm.optionals.getOrNull
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class RoomFlowNode @AssistedInject constructor( @Inject
class RoomFlowNode(
@Assisted val buildContext: BuildContext, @Assisted val buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val client: MatrixClient, private val client: MatrixClient,

View file

@ -24,8 +24,8 @@ import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins import com.bumble.appyx.core.plugin.plugins
import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.newRoot import com.bumble.appyx.navmodel.backstack.operation.newRoot
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.appnav.room.RoomNavigationTarget import io.element.android.appnav.room.RoomNavigationTarget
import io.element.android.libraries.architecture.BackstackView import io.element.android.libraries.architecture.BackstackView
@ -45,7 +45,8 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class JoinedRoomFlowNode @AssistedInject constructor( @Inject
class JoinedRoomFlowNode(
@Assisted val buildContext: BuildContext, @Assisted val buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
loadingRoomStateFlowFactory: LoadingRoomStateFlowFactory, loadingRoomStateFlowFactory: LoadingRoomStateFlowFactory,

View file

@ -17,8 +17,8 @@ import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.push import com.bumble.appyx.navmodel.backstack.operation.push
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.appnav.di.RoomComponentFactory import io.element.android.appnav.di.RoomComponentFactory
import io.element.android.appnav.room.RoomNavigationTarget import io.element.android.appnav.room.RoomNavigationTarget
@ -45,7 +45,8 @@ import kotlinx.parcelize.Parcelize
import timber.log.Timber import timber.log.Timber
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class JoinedRoomLoadedFlowNode @AssistedInject constructor( @Inject
class JoinedRoomLoadedFlowNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val messagesEntryPoint: MessagesEntryPoint, private val messagesEntryPoint: MessagesEntryPoint,

View file

@ -18,7 +18,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import javax.inject.Inject import dev.zacsweers.metro.Inject
private const val SAVE_INSTANCE_KEY = "io.element.android.x.RootNavStateFlowFactory.SAVE_INSTANCE_KEY" private const val SAVE_INSTANCE_KEY = "io.element.android.x.RootNavStateFlowFactory.SAVE_INSTANCE_KEY"
@ -26,7 +26,8 @@ private const val SAVE_INSTANCE_KEY = "io.element.android.x.RootNavStateFlowFact
* This class is responsible for creating a flow of [RootNavState]. * This class is responsible for creating a flow of [RootNavState].
* It gathers data from multiple datasource and creates a unique one. * It gathers data from multiple datasource and creates a unique one.
*/ */
class RootNavStateFlowFactory @Inject constructor( @Inject
class RootNavStateFlowFactory(
private val authenticationService: MatrixAuthenticationService, private val authenticationService: MatrixAuthenticationService,
private val cacheService: CacheService, private val cacheService: CacheService,
private val matrixSessionCache: MatrixSessionCache, private val matrixSessionCache: MatrixSessionCache,

View file

@ -18,9 +18,10 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.SdkMetadata import io.element.android.libraries.matrix.api.SdkMetadata
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import io.element.android.services.apperror.api.AppErrorStateService import io.element.android.services.apperror.api.AppErrorStateService
import javax.inject.Inject import dev.zacsweers.metro.Inject
class RootPresenter @Inject constructor( @Inject
class RootPresenter(
private val crashDetectionPresenter: Presenter<CrashDetectionState>, private val crashDetectionPresenter: Presenter<CrashDetectionState>,
private val rageshakeDetectionPresenter: Presenter<RageshakeDetectionState>, private val rageshakeDetectionPresenter: Presenter<RageshakeDetectionState>,
private val appErrorStateService: AppErrorStateService, private val appErrorStateService: AppErrorStateService,

@ -1 +0,0 @@
Subproject commit 9c78fd98e895ca8bf92ffc6604111155c8759cc0

View file

@ -14,16 +14,17 @@ import androidx.compose.ui.Modifier
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.appconfig.AnalyticsConfig import io.element.android.appconfig.AnalyticsConfig
import io.element.android.compound.theme.ElementTheme import io.element.android.compound.theme.ElementTheme
import io.element.android.libraries.androidutils.browser.openUrlInChromeCustomTab import io.element.android.libraries.androidutils.browser.openUrlInChromeCustomTab
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
@ContributesNode(AppScope::class) @ContributesNode(AppScope::class)
class AnalyticsOptInNode @AssistedInject constructor( @Inject
class AnalyticsOptInNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val presenter: AnalyticsOptInPresenter, private val presenter: AnalyticsOptInPresenter,

View file

@ -16,9 +16,10 @@ import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import dev.zacsweers.metro.Inject
class AnalyticsOptInPresenter @Inject constructor( @Inject
class AnalyticsOptInPresenter(
private val buildMeta: BuildMeta, private val buildMeta: BuildMeta,
private val analyticsService: AnalyticsService, private val analyticsService: AnalyticsService,
) : Presenter<AnalyticsOptInState> { ) : Presenter<AnalyticsOptInState> {

View file

@ -9,14 +9,15 @@ package io.element.android.features.analytics.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.analytics.api.AnalyticsEntryPoint import io.element.android.features.analytics.api.AnalyticsEntryPoint
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import javax.inject.Inject import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultAnalyticsEntryPoint @Inject constructor() : AnalyticsEntryPoint { @Inject
class DefaultAnalyticsEntryPoint() : AnalyticsEntryPoint {
override fun createNode(parentNode: Node, buildContext: BuildContext): Node { override fun createNode(parentNode: Node, buildContext: BuildContext): Node {
return parentNode.createNode<AnalyticsOptInNode>(buildContext) return parentNode.createNode<AnalyticsOptInNode>(buildContext)
} }

View file

@ -7,16 +7,16 @@
package io.element.android.features.analytics.impl.di package io.element.android.features.analytics.impl.di
import com.squareup.anvil.annotations.ContributesTo import dev.zacsweers.metro.BindingContainer
import dagger.Binds import dev.zacsweers.metro.Binds
import dagger.Module import dev.zacsweers.metro.ContributesTo
import io.element.android.features.analytics.api.preferences.AnalyticsPreferencesState import io.element.android.features.analytics.api.preferences.AnalyticsPreferencesState
import io.element.android.features.analytics.impl.preferences.AnalyticsPreferencesPresenter import io.element.android.features.analytics.impl.preferences.AnalyticsPreferencesPresenter
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
@ContributesTo(AppScope::class) @ContributesTo(AppScope::class)
@Module @BindingContainer
interface AnalyticsModule { interface AnalyticsModule {
@Binds @Binds
fun bindAnalyticsPreferencesPresenter(presenter: AnalyticsPreferencesPresenter): Presenter<AnalyticsPreferencesState> fun bindAnalyticsPreferencesPresenter(presenter: AnalyticsPreferencesPresenter): Presenter<AnalyticsPreferencesState>

View file

@ -18,9 +18,10 @@ import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import dev.zacsweers.metro.Inject
class AnalyticsPreferencesPresenter @Inject constructor( @Inject
class AnalyticsPreferencesPresenter(
private val analyticsService: AnalyticsService, private val analyticsService: AnalyticsService,
private val buildMeta: BuildMeta, private val buildMeta: BuildMeta,
) : Presenter<AnalyticsPreferencesState> { ) : Presenter<AnalyticsPreferencesState> {

View file

@ -7,8 +7,8 @@
package io.element.android.features.cachecleaner.api package io.element.android.features.cachecleaner.api
import com.squareup.anvil.annotations.ContributesTo import dev.zacsweers.metro.ContributesTo
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
@ContributesTo(AppScope::class) @ContributesTo(AppScope::class)
interface CacheCleanerBindings { interface CacheCleanerBindings {

View file

@ -7,28 +7,30 @@
package io.element.android.features.cachecleaner.impl package io.element.android.features.cachecleaner.impl
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.cachecleaner.api.CacheCleaner import io.element.android.features.cachecleaner.api.CacheCleaner
import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.core.extensions.runCatchingExceptions
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.CacheDirectory import io.element.android.libraries.di.CacheDirectory
import io.element.android.libraries.di.annotations.AppCoroutineScope import io.element.android.libraries.di.annotations.AppCoroutineScope
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
import java.io.File import java.io.File
import javax.inject.Inject import dev.zacsweers.metro.Inject
import dev.zacsweers.metro.Named
/** /**
* Default implementation of [CacheCleaner]. * Default implementation of [CacheCleaner].
*/ */
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultCacheCleaner @Inject constructor( @Inject
class DefaultCacheCleaner(
@AppCoroutineScope @AppCoroutineScope
private val coroutineScope: CoroutineScope, private val coroutineScope: CoroutineScope,
private val dispatchers: CoroutineDispatchers, private val dispatchers: CoroutineDispatchers,
@CacheDirectory private val cacheDir: File, @Named("cacheDirectory") private val cacheDir: File,
) : CacheCleaner { ) : CacheCleaner {
companion object { companion object {
val SUBDIRS_TO_CLEANUP = listOf("temp/media", "temp/voice") val SUBDIRS_TO_CLEANUP = listOf("temp/media", "temp/voice")

View file

@ -8,20 +8,21 @@
package io.element.android.features.call.impl package io.element.android.features.call.impl
import android.content.Context import android.content.Context
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.call.api.CallType import io.element.android.features.call.api.CallType
import io.element.android.features.call.api.ElementCallEntryPoint import io.element.android.features.call.api.ElementCallEntryPoint
import io.element.android.features.call.impl.notifications.CallNotificationData import io.element.android.features.call.impl.notifications.CallNotificationData
import io.element.android.features.call.impl.utils.ActiveCallManager import io.element.android.features.call.impl.utils.ActiveCallManager
import io.element.android.features.call.impl.utils.IntentProvider import io.element.android.features.call.impl.utils.IntentProvider
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.di.annotations.ApplicationContext
import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.UserId
import javax.inject.Inject import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultElementCallEntryPoint @Inject constructor( @Inject
class DefaultElementCallEntryPoint(
@ApplicationContext private val context: Context, @ApplicationContext private val context: Context,
private val activeCallManager: ActiveCallManager, private val activeCallManager: ActiveCallManager,
) : ElementCallEntryPoint { ) : ElementCallEntryPoint {

View file

@ -7,11 +7,11 @@
package io.element.android.features.call.impl.di package io.element.android.features.call.impl.di
import com.squareup.anvil.annotations.ContributesTo import dev.zacsweers.metro.ContributesTo
import io.element.android.features.call.impl.receivers.DeclineCallBroadcastReceiver import io.element.android.features.call.impl.receivers.DeclineCallBroadcastReceiver
import io.element.android.features.call.impl.ui.ElementCallActivity import io.element.android.features.call.impl.ui.ElementCallActivity
import io.element.android.features.call.impl.ui.IncomingCallActivity import io.element.android.features.call.impl.ui.IncomingCallActivity
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
@ContributesTo(AppScope::class) @ContributesTo(AppScope::class)
interface CallBindings { interface CallBindings {

View file

@ -21,7 +21,7 @@ import io.element.android.features.call.impl.receivers.DeclineCallBroadcastRecei
import io.element.android.features.call.impl.ui.IncomingCallActivity import io.element.android.features.call.impl.ui.IncomingCallActivity
import io.element.android.features.call.impl.utils.IntentProvider import io.element.android.features.call.impl.utils.IntentProvider
import io.element.android.libraries.designsystem.utils.CommonDrawables import io.element.android.libraries.designsystem.utils.CommonDrawables
import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.di.annotations.ApplicationContext
import io.element.android.libraries.matrix.api.MatrixClientProvider import io.element.android.libraries.matrix.api.MatrixClientProvider
import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
@ -29,13 +29,14 @@ import io.element.android.libraries.matrix.api.core.SessionId
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.ImageLoaderHolder import io.element.android.libraries.matrix.ui.media.ImageLoaderHolder
import io.element.android.libraries.push.api.notifications.NotificationBitmapLoader import io.element.android.libraries.push.api.notifications.NotificationBitmapLoader
import javax.inject.Inject import dev.zacsweers.metro.Inject
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
/** /**
* Creates a notification for a ringing call. * Creates a notification for a ringing call.
*/ */
class RingingCallNotificationCreator @Inject constructor( @Inject
class RingingCallNotificationCreator(
@ApplicationContext private val context: Context, @ApplicationContext private val context: Context,
private val matrixClientProvider: MatrixClientProvider, private val matrixClientProvider: MatrixClientProvider,
private val imageLoaderHolder: ImageLoaderHolder, private val imageLoaderHolder: ImageLoaderHolder,

View file

@ -18,11 +18,12 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.log.logger.LoggerTag import io.element.android.libraries.core.log.logger.LoggerTag
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import dev.zacsweers.metro.Inject
private val loggerTag = LoggerTag("PiP") private val loggerTag = LoggerTag("PiP")
class PictureInPicturePresenter @Inject constructor( @Inject
class PictureInPicturePresenter(
pipSupportProvider: PipSupportProvider, pipSupportProvider: PipSupportProvider,
) : Presenter<PictureInPictureState> { ) : Presenter<PictureInPictureState> {
private val isPipSupported = pipSupportProvider.isPipSupported() private val isPipSupported = pipSupportProvider.isPipSupported()

View file

@ -11,11 +11,11 @@ import android.content.Context
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Build import android.os.Build
import androidx.annotation.ChecksSdkIntAtLeast import androidx.annotation.ChecksSdkIntAtLeast
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.core.bool.orFalse import io.element.android.libraries.core.bool.orFalse
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.di.annotations.ApplicationContext
import javax.inject.Inject import dev.zacsweers.metro.Inject
interface PipSupportProvider { interface PipSupportProvider {
@ChecksSdkIntAtLeast(Build.VERSION_CODES.O) @ChecksSdkIntAtLeast(Build.VERSION_CODES.O)
@ -23,7 +23,8 @@ interface PipSupportProvider {
} }
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultPipSupportProvider @Inject constructor( @Inject
class DefaultPipSupportProvider(
@ApplicationContext private val context: Context, @ApplicationContext private val context: Context,
) : PipSupportProvider { ) : PipSupportProvider {
override fun isPipSupported(): Boolean { override fun isPipSupported(): Boolean {

View file

@ -19,7 +19,7 @@ import io.element.android.libraries.architecture.bindings
import io.element.android.libraries.di.annotations.AppCoroutineScope import io.element.android.libraries.di.annotations.AppCoroutineScope
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import dev.zacsweers.metro.Inject
/** /**
* Broadcast receiver to decline the incoming call. * Broadcast receiver to decline the incoming call.

View file

@ -17,9 +17,9 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedFactory import dev.zacsweers.metro.AssistedFactory
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.plan.MobileScreen
import io.element.android.compound.theme.ElementTheme import io.element.android.compound.theme.ElementTheme
import io.element.android.features.call.api.CallType import io.element.android.features.call.api.CallType
@ -49,7 +49,8 @@ import timber.log.Timber
import java.util.UUID import java.util.UUID
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
class CallScreenPresenter @AssistedInject constructor( @Inject
class CallScreenPresenter(
@Assisted private val callType: CallType, @Assisted private val callType: CallType,
@Assisted private val navigator: CallScreenNavigator, @Assisted private val navigator: CallScreenNavigator,
private val callWidgetProvider: CallWidgetProvider, private val callWidgetProvider: CallWidgetProvider,

View file

@ -50,7 +50,7 @@ import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.designsystem.theme.ElementThemeApp import io.element.android.libraries.designsystem.theme.ElementThemeApp
import io.element.android.libraries.preferences.api.store.AppPreferencesStore import io.element.android.libraries.preferences.api.store.AppPreferencesStore
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import dev.zacsweers.metro.Inject
private val loggerTag = LoggerTag("ElementCallActivity") private val loggerTag = LoggerTag("ElementCallActivity")

View file

@ -30,7 +30,7 @@ import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import dev.zacsweers.metro.Inject
/** /**
* Activity that's displayed as a full screen intent when an incoming call is received. * Activity that's displayed as a full screen intent when an incoming call is received.

View file

@ -9,9 +9,9 @@ package io.element.android.features.call.impl.ui
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import javax.inject.Inject import dev.zacsweers.metro.Inject
interface LanguageTagProvider { interface LanguageTagProvider {
@Composable @Composable
@ -19,7 +19,8 @@ interface LanguageTagProvider {
} }
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultLanguageTagProvider @Inject constructor() : LanguageTagProvider { @Inject
class DefaultLanguageTagProvider() : LanguageTagProvider {
@Composable @Composable
override fun provideLanguageTag(): String? { override fun provideLanguageTag(): String? {
return LocalConfiguration.current.locales.get(0)?.toLanguageTag() return LocalConfiguration.current.locales.get(0)?.toLanguageTag()

View file

@ -15,16 +15,16 @@ import androidx.core.app.NotificationManagerCompat
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import coil3.SingletonImageLoader import coil3.SingletonImageLoader
import coil3.annotation.DelicateCoilApi import coil3.annotation.DelicateCoilApi
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.appconfig.ElementCallConfig import io.element.android.appconfig.ElementCallConfig
import io.element.android.features.call.api.CallType import io.element.android.features.call.api.CallType
import io.element.android.features.call.api.CurrentCall import io.element.android.features.call.api.CurrentCall
import io.element.android.features.call.impl.notifications.CallNotificationData import io.element.android.features.call.impl.notifications.CallNotificationData
import io.element.android.features.call.impl.notifications.RingingCallNotificationCreator import io.element.android.features.call.impl.notifications.RingingCallNotificationCreator
import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.core.extensions.runCatchingExceptions
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.di.annotations.ApplicationContext
import io.element.android.libraries.di.SingleIn import dev.zacsweers.metro.SingleIn
import io.element.android.libraries.di.annotations.AppCoroutineScope import io.element.android.libraries.di.annotations.AppCoroutineScope
import io.element.android.libraries.matrix.api.MatrixClientProvider import io.element.android.libraries.matrix.api.MatrixClientProvider
import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.SessionId
@ -52,7 +52,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import dev.zacsweers.metro.Inject
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
/** /**
@ -86,7 +86,8 @@ interface ActiveCallManager {
@SingleIn(AppScope::class) @SingleIn(AppScope::class)
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultActiveCallManager @Inject constructor( @Inject
class DefaultActiveCallManager(
@ApplicationContext context: Context, @ApplicationContext context: Context,
@AppCoroutineScope @AppCoroutineScope
private val coroutineScope: CoroutineScope, private val coroutineScope: CoroutineScope,

View file

@ -9,9 +9,10 @@ package io.element.android.features.call.impl.utils
import android.net.Uri import android.net.Uri
import androidx.core.net.toUri import androidx.core.net.toUri
import javax.inject.Inject import dev.zacsweers.metro.Inject
class CallIntentDataParser @Inject constructor() { @Inject
class CallIntentDataParser() {
private val validHttpSchemes = sequenceOf("https") private val validHttpSchemes = sequenceOf("https")
private val knownHosts = sequenceOf( private val knownHosts = sequenceOf(
"call.element.io", "call.element.io",

View file

@ -7,14 +7,15 @@
package io.element.android.features.call.impl.utils package io.element.android.features.call.impl.utils
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.call.impl.BuildConfig import io.element.android.features.call.impl.BuildConfig
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.matrix.api.widget.CallAnalyticCredentialsProvider import io.element.android.libraries.matrix.api.widget.CallAnalyticCredentialsProvider
import javax.inject.Inject import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultCallAnalyticCredentialsProvider @Inject constructor() : CallAnalyticCredentialsProvider { @Inject
class DefaultCallAnalyticCredentialsProvider() : CallAnalyticCredentialsProvider {
override val posthogUserId: String? = BuildConfig.POSTHOG_USER_ID.takeIf { it.isNotBlank() } override val posthogUserId: String? = BuildConfig.POSTHOG_USER_ID.takeIf { it.isNotBlank() }
override val posthogApiHost: String? = BuildConfig.POSTHOG_API_HOST.takeIf { it.isNotBlank() } override val posthogApiHost: String? = BuildConfig.POSTHOG_API_HOST.takeIf { it.isNotBlank() }
override val posthogApiKey: String? = BuildConfig.POSTHOG_API_KEY.takeIf { it.isNotBlank() } override val posthogApiKey: String? = BuildConfig.POSTHOG_API_KEY.takeIf { it.isNotBlank() }

View file

@ -7,9 +7,9 @@
package io.element.android.features.call.impl.utils package io.element.android.features.call.impl.utils
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.core.extensions.runCatchingExceptions
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.matrix.api.MatrixClientProvider import io.element.android.libraries.matrix.api.MatrixClientProvider
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.SessionId
@ -18,12 +18,13 @@ import io.element.android.libraries.matrix.api.widget.CallWidgetSettingsProvider
import io.element.android.libraries.preferences.api.store.AppPreferencesStore import io.element.android.libraries.preferences.api.store.AppPreferencesStore
import io.element.android.services.appnavstate.api.ActiveRoomsHolder import io.element.android.services.appnavstate.api.ActiveRoomsHolder
import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.firstOrNull
import javax.inject.Inject import dev.zacsweers.metro.Inject
private const val EMBEDDED_CALL_WIDGET_BASE_URL = "https://appassets.androidplatform.net/element-call/index.html" private const val EMBEDDED_CALL_WIDGET_BASE_URL = "https://appassets.androidplatform.net/element-call/index.html"
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultCallWidgetProvider @Inject constructor( @Inject
class DefaultCallWidgetProvider(
private val matrixClientsProvider: MatrixClientProvider, private val matrixClientsProvider: MatrixClientProvider,
private val appPreferencesStore: AppPreferencesStore, private val appPreferencesStore: AppPreferencesStore,
private val callWidgetSettingsProvider: CallWidgetSettingsProvider, private val callWidgetSettingsProvider: CallWidgetSettingsProvider,

View file

@ -7,17 +7,18 @@
package io.element.android.features.call.impl.utils package io.element.android.features.call.impl.utils
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.call.api.CurrentCall import io.element.android.features.call.api.CurrentCall
import io.element.android.features.call.api.CurrentCallService import io.element.android.features.call.api.CurrentCallService
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.SingleIn import dev.zacsweers.metro.SingleIn
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import javax.inject.Inject import dev.zacsweers.metro.Inject
@SingleIn(AppScope::class) @SingleIn(AppScope::class)
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultCurrentCallService @Inject constructor() : CurrentCallService { @Inject
class DefaultCurrentCallService() : CurrentCallService {
override val currentCall = MutableStateFlow<CurrentCall>(CurrentCall.None) override val currentCall = MutableStateFlow<CurrentCall>(CurrentCall.None)
fun onCallStarted(call: CurrentCall) { fun onCallStarted(call: CurrentCall) {

View file

@ -14,8 +14,8 @@ import androidx.compose.ui.Modifier
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.changeroommemberroes.api.ChangeRoomMemberRolesListType import io.element.android.features.changeroommemberroes.api.ChangeRoomMemberRolesListType
import io.element.android.libraries.architecture.NodeInputs import io.element.android.libraries.architecture.NodeInputs
@ -26,7 +26,8 @@ import io.element.android.libraries.matrix.api.room.RoomMember
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
@ContributesNode(RoomScope::class) @ContributesNode(RoomScope::class)
class ChangeRolesNode @AssistedInject constructor( @Inject
class ChangeRolesNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
presenterFactory: ChangeRolesPresenter.Factory, presenterFactory: ChangeRolesPresenter.Factory,

View file

@ -18,9 +18,9 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedFactory import dev.zacsweers.metro.AssistedFactory
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import im.vector.app.features.analytics.plan.RoomModeration import im.vector.app.features.analytics.plan.RoomModeration
import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
@ -47,7 +47,8 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class ChangeRolesPresenter @AssistedInject constructor( @Inject
class ChangeRolesPresenter(
@Assisted private val role: RoomMember.Role, @Assisted private val role: RoomMember.Role,
private val room: JoinedRoom, private val room: JoinedRoom,
private val dispatchers: CoroutineDispatchers, private val dispatchers: CoroutineDispatchers,

View file

@ -16,8 +16,8 @@ import com.bumble.appyx.core.navigation.model.permanent.PermanentNavModel
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.node.ParentNode import com.bumble.appyx.core.node.ParentNode
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.appnav.di.RoomComponentFactory import io.element.android.appnav.di.RoomComponentFactory
import io.element.android.features.changeroommemberroes.api.ChangeRoomMemberRolesEntryPoint import io.element.android.features.changeroommemberroes.api.ChangeRoomMemberRolesEntryPoint
@ -32,7 +32,8 @@ import io.element.android.libraries.matrix.api.room.JoinedRoom
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class ChangeRoomMemberRolesRootNode @AssistedInject constructor( @Inject
class ChangeRoomMemberRolesRootNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
roomComponentFactory: RoomComponentFactory, roomComponentFactory: RoomComponentFactory,

View file

@ -9,16 +9,17 @@ package io.element.android.features.changeroommemberroles.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.changeroommemberroes.api.ChangeRoomMemberRolesEntryPoint import io.element.android.features.changeroommemberroes.api.ChangeRoomMemberRolesEntryPoint
import io.element.android.features.changeroommemberroes.api.ChangeRoomMemberRolesListType import io.element.android.features.changeroommemberroes.api.ChangeRoomMemberRolesListType
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.JoinedRoom
import javax.inject.Inject import dev.zacsweers.metro.Inject
@ContributesBinding(SessionScope::class) @ContributesBinding(SessionScope::class)
class DefaultChangeRoomMemberRolesEntyPoint @Inject constructor() : ChangeRoomMemberRolesEntryPoint { @Inject
class DefaultChangeRoomMemberRolesEntyPoint() : ChangeRoomMemberRolesEntryPoint {
override fun builder(parentNode: Node, buildContext: BuildContext): ChangeRoomMemberRolesEntryPoint.Builder { override fun builder(parentNode: Node, buildContext: BuildContext): ChangeRoomMemberRolesEntryPoint.Builder {
return object : ChangeRoomMemberRolesEntryPoint.Builder { return object : ChangeRoomMemberRolesEntryPoint.Builder {
private lateinit var changeRoomMemberRolesListType: ChangeRoomMemberRolesListType private lateinit var changeRoomMemberRolesListType: ChangeRoomMemberRolesListType

View file

@ -13,9 +13,10 @@ import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.roomMembers import io.element.android.libraries.matrix.api.room.roomMembers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import javax.inject.Inject import dev.zacsweers.metro.Inject
class RoomMemberListDataSource @Inject constructor( @Inject
class RoomMemberListDataSource(
private val room: BaseRoom, private val room: BaseRoom,
private val coroutineDispatchers: CoroutineDispatchers, private val coroutineDispatchers: CoroutineDispatchers,
) { ) {

View file

@ -16,8 +16,8 @@ import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins import com.bumble.appyx.core.plugin.plugins
import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.replace import com.bumble.appyx.navmodel.backstack.operation.replace
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.createroom.api.CreateRoomEntryPoint import io.element.android.features.createroom.api.CreateRoomEntryPoint
import io.element.android.features.createroom.impl.addpeople.AddPeopleNode import io.element.android.features.createroom.impl.addpeople.AddPeopleNode
@ -30,7 +30,8 @@ import io.element.android.libraries.matrix.api.core.RoomId
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class CreateRoomFlowNode @AssistedInject constructor( @Inject
class CreateRoomFlowNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
) : BaseFlowNode<CreateRoomFlowNode.NavTarget>( ) : BaseFlowNode<CreateRoomFlowNode.NavTarget>(

View file

@ -10,14 +10,15 @@ package io.element.android.features.createroom.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.createroom.api.CreateRoomEntryPoint import io.element.android.features.createroom.api.CreateRoomEntryPoint
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import javax.inject.Inject import dev.zacsweers.metro.Inject
@ContributesBinding(SessionScope::class) @ContributesBinding(SessionScope::class)
class DefaultCreateRoomEntryPoint @Inject constructor() : CreateRoomEntryPoint { @Inject
class DefaultCreateRoomEntryPoint() : CreateRoomEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): CreateRoomEntryPoint.NodeBuilder { override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): CreateRoomEntryPoint.NodeBuilder {
val plugins = ArrayList<Plugin>() val plugins = ArrayList<Plugin>()

View file

@ -13,8 +13,8 @@ import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins import com.bumble.appyx.core.plugin.plugins
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.invitepeople.api.InvitePeoplePresenter import io.element.android.features.invitepeople.api.InvitePeoplePresenter
import io.element.android.features.invitepeople.api.InvitePeopleRenderer import io.element.android.features.invitepeople.api.InvitePeopleRenderer
@ -24,7 +24,8 @@ import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class AddPeopleNode @AssistedInject constructor( @Inject
class AddPeopleNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
invitePeoplePresenterFactory: InvitePeoplePresenter.Factory, invitePeoplePresenterFactory: InvitePeoplePresenter.Factory,

View file

@ -14,8 +14,8 @@ import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins import com.bumble.appyx.core.plugin.plugins
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.plan.MobileScreen
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
@ -23,7 +23,8 @@ import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class ConfigureRoomNode @AssistedInject constructor( @Inject
class ConfigureRoomNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val presenter: ConfigureRoomPresenter, private val presenter: ConfigureRoomPresenter,

View file

@ -44,10 +44,11 @@ import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import dev.zacsweers.metro.Inject
import kotlin.jvm.optionals.getOrDefault import kotlin.jvm.optionals.getOrDefault
class ConfigureRoomPresenter @Inject constructor( @Inject
class ConfigureRoomPresenter(
private val dataStore: CreateRoomConfigStore, private val dataStore: CreateRoomConfigStore,
private val matrixClient: MatrixClient, private val matrixClient: MatrixClient,
private val mediaPickerProvider: PickerProvider, private val mediaPickerProvider: PickerProvider,

View file

@ -14,9 +14,10 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.getAndUpdate import kotlinx.coroutines.flow.getAndUpdate
import java.io.File import java.io.File
import javax.inject.Inject import dev.zacsweers.metro.Inject
class CreateRoomConfigStore @Inject constructor( @Inject
class CreateRoomConfigStore(
private val roomAliasHelper: RoomAliasHelper, private val roomAliasHelper: RoomAliasHelper,
) { ) {
private val createRoomConfigFlow: MutableStateFlow<CreateRoomConfig> = MutableStateFlow(CreateRoomConfig()) private val createRoomConfigFlow: MutableStateFlow<CreateRoomConfig> = MutableStateFlow(CreateRoomConfig())

View file

@ -12,13 +12,14 @@ import androidx.compose.ui.Modifier
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class AccountDeactivationNode @AssistedInject constructor( @Inject
class AccountDeactivationNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val presenter: AccountDeactivationPresenter, private val presenter: AccountDeactivationPresenter,

View file

@ -18,9 +18,10 @@ import io.element.android.libraries.architecture.runCatchingUpdatingState
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import dev.zacsweers.metro.Inject
class AccountDeactivationPresenter @Inject constructor( @Inject
class AccountDeactivationPresenter(
private val matrixClient: MatrixClient, private val matrixClient: MatrixClient,
) : Presenter<AccountDeactivationState> { ) : Presenter<AccountDeactivationState> {
@Composable @Composable

View file

@ -9,14 +9,15 @@ package io.element.android.features.logout.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.deactivation.api.AccountDeactivationEntryPoint import io.element.android.features.deactivation.api.AccountDeactivationEntryPoint
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import javax.inject.Inject import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultAccountDeactivationEntryPoint @Inject constructor() : AccountDeactivationEntryPoint { @Inject
class DefaultAccountDeactivationEntryPoint() : AccountDeactivationEntryPoint {
override fun createNode(parentNode: Node, buildContext: BuildContext): Node { override fun createNode(parentNode: Node, buildContext: BuildContext): Node {
return parentNode.createNode<AccountDeactivationNode>(buildContext) return parentNode.createNode<AccountDeactivationNode>(buildContext)
} }

View file

@ -7,19 +7,20 @@
package io.element.android.features.enterprise.impl package io.element.android.features.enterprise.impl
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.compound.tokens.generated.SemanticColors import io.element.android.compound.tokens.generated.SemanticColors
import io.element.android.compound.tokens.generated.compoundColorsDark import io.element.android.compound.tokens.generated.compoundColorsDark
import io.element.android.compound.tokens.generated.compoundColorsLight import io.element.android.compound.tokens.generated.compoundColorsLight
import io.element.android.features.enterprise.api.BugReportUrl import io.element.android.features.enterprise.api.BugReportUrl
import io.element.android.features.enterprise.api.EnterpriseService import io.element.android.features.enterprise.api.EnterpriseService
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.SessionId
import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOf
import javax.inject.Inject import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultEnterpriseService @Inject constructor() : EnterpriseService { @Inject
class DefaultEnterpriseService() : EnterpriseService {
override val isEnterpriseBuild = false override val isEnterpriseBuild = false
override suspend fun isEnterpriseUser(sessionId: SessionId) = false override suspend fun isEnterpriseUser(sessionId: SessionId) = false

View file

@ -7,13 +7,14 @@
package io.element.android.features.enterprise.impl package io.element.android.features.enterprise.impl
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.enterprise.api.SessionEnterpriseService import io.element.android.features.enterprise.api.SessionEnterpriseService
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import javax.inject.Inject import dev.zacsweers.metro.Inject
@ContributesBinding(SessionScope::class) @ContributesBinding(SessionScope::class)
class DefaultSessionEnterpriseService @Inject constructor() : SessionEnterpriseService { @Inject
class DefaultSessionEnterpriseService() : SessionEnterpriseService {
override suspend fun init() = Unit override suspend fun init() = Unit
override suspend fun isElementCallAvailable(): Boolean = true override suspend fun isElementCallAvailable(): Boolean = true
} }

View file

@ -10,14 +10,15 @@ package io.element.android.features.ftue.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.ftue.api.FtueEntryPoint import io.element.android.features.ftue.api.FtueEntryPoint
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import javax.inject.Inject import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultFtueEntryPoint @Inject constructor() : FtueEntryPoint { @Inject
class DefaultFtueEntryPoint() : FtueEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): FtueEntryPoint.NodeBuilder { override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): FtueEntryPoint.NodeBuilder {
val plugins = ArrayList<Plugin>() val plugins = ArrayList<Plugin>()

View file

@ -21,8 +21,8 @@ import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.newRoot import com.bumble.appyx.navmodel.backstack.operation.newRoot
import com.bumble.appyx.navmodel.backstack.operation.replace import com.bumble.appyx.navmodel.backstack.operation.replace
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.analytics.api.AnalyticsEntryPoint import io.element.android.features.analytics.api.AnalyticsEntryPoint
import io.element.android.features.ftue.impl.notifications.NotificationsOptInNode import io.element.android.features.ftue.impl.notifications.NotificationsOptInNode
@ -34,7 +34,7 @@ import io.element.android.libraries.architecture.BackstackView
import io.element.android.libraries.architecture.BaseFlowNode import io.element.android.libraries.architecture.BaseFlowNode
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
@ -45,7 +45,8 @@ import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class FtueFlowNode @AssistedInject constructor( @Inject
class FtueFlowNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val ftueState: DefaultFtueService, private val ftueState: DefaultFtueService,
@ -158,16 +159,18 @@ class FtueFlowNode @AssistedInject constructor(
BackstackView() BackstackView()
} }
@ContributesNode(AppScope::class) }
class PlaceholderNode @AssistedInject constructor(
@Assisted buildContext: BuildContext, @ContributesNode(AppScope::class)
@Assisted plugins: List<Plugin>, @Inject
) : Node(buildContext, plugins = plugins) { class PlaceholderNode(
@Composable @Assisted buildContext: BuildContext,
override fun View(modifier: Modifier) { @Assisted plugins: List<Plugin>,
Box(modifier = modifier.fillMaxSize(), contentAlignment = Alignment.Center) { ) : Node(buildContext, plugins = plugins) {
CircularProgressIndicator() @Composable
} override fun View(modifier: Modifier) {
Box(modifier = modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
CircularProgressIndicator()
} }
} }
} }

View file

@ -7,16 +7,16 @@
package io.element.android.features.ftue.impl.di package io.element.android.features.ftue.impl.di
import com.squareup.anvil.annotations.ContributesTo import dev.zacsweers.metro.BindingContainer
import dagger.Binds import dev.zacsweers.metro.Binds
import dagger.Module import dev.zacsweers.metro.ContributesTo
import io.element.android.features.ftue.impl.sessionverification.choosemode.ChooseSelfVerificationModePresenter import io.element.android.features.ftue.impl.sessionverification.choosemode.ChooseSelfVerificationModePresenter
import io.element.android.features.ftue.impl.sessionverification.choosemode.ChooseSelfVerificationModeState import io.element.android.features.ftue.impl.sessionverification.choosemode.ChooseSelfVerificationModeState
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
@ContributesTo(SessionScope::class) @ContributesTo(SessionScope::class)
@Module @BindingContainer
interface FtueModule { interface FtueModule {
@Binds @Binds
fun bindChooseSelfVerificationMethodPresenter(presenter: ChooseSelfVerificationModePresenter): Presenter<ChooseSelfVerificationModeState> fun bindChooseSelfVerificationMethodPresenter(presenter: ChooseSelfVerificationModePresenter): Presenter<ChooseSelfVerificationModeState>

View file

@ -12,15 +12,16 @@ import androidx.compose.ui.Modifier
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.libraries.architecture.NodeInputs import io.element.android.libraries.architecture.NodeInputs
import io.element.android.libraries.architecture.inputs import io.element.android.libraries.architecture.inputs
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
@ContributesNode(AppScope::class) @ContributesNode(AppScope::class)
class NotificationsOptInNode @AssistedInject constructor( @Inject
class NotificationsOptInNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
presenterFactory: NotificationsOptInPresenter.Factory, presenterFactory: NotificationsOptInPresenter.Factory,

View file

@ -12,9 +12,9 @@ import android.os.Build
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedFactory import dev.zacsweers.metro.AssistedFactory
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.di.annotations.AppCoroutineScope import io.element.android.libraries.di.annotations.AppCoroutineScope
import io.element.android.libraries.permissions.api.PermissionStateProvider import io.element.android.libraries.permissions.api.PermissionStateProvider
@ -25,7 +25,8 @@ import io.element.android.services.toolbox.api.sdk.BuildVersionSdkIntProvider
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class NotificationsOptInPresenter @AssistedInject constructor( @Inject
class NotificationsOptInPresenter(
permissionsPresenterFactory: PermissionsPresenter.Factory, permissionsPresenterFactory: PermissionsPresenter.Factory,
@Assisted private val callback: NotificationsOptInNode.Callback, @Assisted private val callback: NotificationsOptInNode.Callback,
@AppCoroutineScope @AppCoroutineScope

View file

@ -20,8 +20,8 @@ import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.newRoot import com.bumble.appyx.navmodel.backstack.operation.newRoot
import com.bumble.appyx.navmodel.backstack.operation.pop import com.bumble.appyx.navmodel.backstack.operation.pop
import com.bumble.appyx.navmodel.backstack.operation.push import com.bumble.appyx.navmodel.backstack.operation.push
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.appconfig.LearnMoreConfig import io.element.android.appconfig.LearnMoreConfig
import io.element.android.features.ftue.impl.sessionverification.choosemode.ChooseSelfVerificationModeNode import io.element.android.features.ftue.impl.sessionverification.choosemode.ChooseSelfVerificationModeNode
@ -37,7 +37,8 @@ import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class FtueSessionVerificationFlowNode @AssistedInject constructor( @Inject
class FtueSessionVerificationFlowNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val outgoingVerificationEntryPoint: OutgoingVerificationEntryPoint, private val outgoingVerificationEntryPoint: OutgoingVerificationEntryPoint,

View file

@ -13,15 +13,16 @@ import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins import com.bumble.appyx.core.plugin.plugins
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.logout.api.direct.DirectLogoutView import io.element.android.features.logout.api.direct.DirectLogoutView
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class ChooseSelfVerificationModeNode @AssistedInject constructor( @Inject
class ChooseSelfVerificationModeNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val presenter: Presenter<ChooseSelfVerificationModeState>, private val presenter: Presenter<ChooseSelfVerificationModeState>,

View file

@ -17,9 +17,10 @@ import io.element.android.features.logout.api.direct.DirectLogoutState
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.encryption.RecoveryState import io.element.android.libraries.matrix.api.encryption.RecoveryState
import javax.inject.Inject import dev.zacsweers.metro.Inject
class ChooseSelfVerificationModePresenter @Inject constructor( @Inject
class ChooseSelfVerificationModePresenter(
private val encryptionService: EncryptionService, private val encryptionService: EncryptionService,
private val directLogoutPresenter: Presenter<DirectLogoutState>, private val directLogoutPresenter: Presenter<DirectLogoutState>,
) : Presenter<ChooseSelfVerificationModeState> { ) : Presenter<ChooseSelfVerificationModeState> {

View file

@ -10,12 +10,12 @@ package io.element.android.features.ftue.impl.state
import android.Manifest import android.Manifest
import android.os.Build import android.os.Build
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.ftue.api.state.FtueService import io.element.android.features.ftue.api.state.FtueService
import io.element.android.features.ftue.api.state.FtueState import io.element.android.features.ftue.api.state.FtueState
import io.element.android.features.lockscreen.api.LockScreenService import io.element.android.features.lockscreen.api.LockScreenService
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.di.SingleIn import dev.zacsweers.metro.SingleIn
import io.element.android.libraries.di.annotations.SessionCoroutineScope import io.element.android.libraries.di.annotations.SessionCoroutineScope
import io.element.android.libraries.matrix.api.verification.SessionVerificationService import io.element.android.libraries.matrix.api.verification.SessionVerificationService
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
@ -31,11 +31,12 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import javax.inject.Inject import dev.zacsweers.metro.Inject
@ContributesBinding(SessionScope::class) @ContributesBinding(SessionScope::class)
@SingleIn(SessionScope::class) @SingleIn(SessionScope::class)
class DefaultFtueService @Inject constructor( @Inject
class DefaultFtueService(
private val sdkVersionProvider: BuildVersionSdkIntProvider, private val sdkVersionProvider: BuildVersionSdkIntProvider,
@SessionCoroutineScope sessionCoroutineScope: CoroutineScope, @SessionCoroutineScope sessionCoroutineScope: CoroutineScope,
private val analyticsService: AnalyticsService, private val analyticsService: AnalyticsService,

View file

@ -10,14 +10,15 @@ package io.element.android.features.home.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.home.api.HomeEntryPoint import io.element.android.features.home.api.HomeEntryPoint
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import javax.inject.Inject import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultHomeEntryPoint @Inject constructor() : HomeEntryPoint { @Inject
class DefaultHomeEntryPoint() : HomeEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): HomeEntryPoint.NodeBuilder { override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): HomeEntryPoint.NodeBuilder {
val plugins = ArrayList<Plugin>() val plugins = ArrayList<Plugin>()

View file

@ -25,8 +25,8 @@ import com.bumble.appyx.core.plugin.plugins
import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.pop import com.bumble.appyx.navmodel.backstack.operation.pop
import com.bumble.appyx.navmodel.backstack.operation.push import com.bumble.appyx.navmodel.backstack.operation.push
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.plan.MobileScreen
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.changeroommemberroes.api.ChangeRoomMemberRolesEntryPoint import io.element.android.features.changeroommemberroes.api.ChangeRoomMemberRolesEntryPoint
@ -56,7 +56,8 @@ import kotlinx.coroutines.withContext
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class HomeFlowNode @AssistedInject constructor( @Inject
class HomeFlowNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val matrixClient: MatrixClient, private val matrixClient: MatrixClient,

View file

@ -27,9 +27,10 @@ import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.indicator.api.IndicatorService import io.element.android.libraries.indicator.api.IndicatorService
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.sync.SyncService
import javax.inject.Inject import dev.zacsweers.metro.Inject
class HomePresenter @Inject constructor( @Inject
class HomePresenter(
private val client: MatrixClient, private val client: MatrixClient,
private val syncService: SyncService, private val syncService: SyncService,
private val snackbarDispatcher: SnackbarDispatcher, private val snackbarDispatcher: SnackbarDispatcher,

View file

@ -29,10 +29,11 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import javax.inject.Inject import dev.zacsweers.metro.Inject
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
class RoomListDataSource @Inject constructor( @Inject
class RoomListDataSource(
private val roomListService: RoomListService, private val roomListService: RoomListService,
private val roomListRoomSummaryFactory: RoomListRoomSummaryFactory, private val roomListRoomSummaryFactory: RoomListRoomSummaryFactory,
private val coroutineDispatchers: CoroutineDispatchers, private val coroutineDispatchers: CoroutineDispatchers,

View file

@ -20,9 +20,10 @@ import io.element.android.libraries.matrix.api.roomlist.RoomSummary
import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.matrix.ui.model.getAvatarData
import io.element.android.libraries.matrix.ui.model.toInviteSender import io.element.android.libraries.matrix.ui.model.toInviteSender
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import javax.inject.Inject import dev.zacsweers.metro.Inject
class RoomListRoomSummaryFactory @Inject constructor( @Inject
class RoomListRoomSummaryFactory(
private val dateFormatter: DateFormatter, private val dateFormatter: DateFormatter,
private val roomLastMessageFormatter: RoomLastMessageFormatter, private val roomLastMessageFormatter: RoomLastMessageFormatter,
) { ) {

View file

@ -7,9 +7,9 @@
package io.element.android.features.home.impl.di package io.element.android.features.home.impl.di
import com.squareup.anvil.annotations.ContributesTo import dev.zacsweers.metro.Binds
import dagger.Binds import dev.zacsweers.metro.BindingContainer
import dagger.Module import dev.zacsweers.metro.ContributesTo
import io.element.android.features.home.impl.filters.RoomListFiltersPresenter import io.element.android.features.home.impl.filters.RoomListFiltersPresenter
import io.element.android.features.home.impl.filters.RoomListFiltersState import io.element.android.features.home.impl.filters.RoomListFiltersState
import io.element.android.features.home.impl.roomlist.RoomListPresenter import io.element.android.features.home.impl.roomlist.RoomListPresenter
@ -20,7 +20,7 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
@ContributesTo(SessionScope::class) @ContributesTo(SessionScope::class)
@Module @BindingContainer
interface RoomListModule { interface RoomListModule {
@Binds @Binds
fun bindRoomListPresenter(presenter: RoomListPresenter): Presenter<RoomListState> fun bindRoomListPresenter(presenter: RoomListPresenter): Presenter<RoomListState>

View file

@ -15,10 +15,11 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.roomlist.RoomListService
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import javax.inject.Inject import dev.zacsweers.metro.Inject
import io.element.android.libraries.matrix.api.roomlist.RoomListFilter as MatrixRoomListFilter import io.element.android.libraries.matrix.api.roomlist.RoomListFilter as MatrixRoomListFilter
class RoomListFiltersPresenter @Inject constructor( @Inject
class RoomListFiltersPresenter(
private val roomListService: RoomListService, private val roomListService: RoomListService,
private val filterSelectionStrategy: FilterSelectionStrategy, private val filterSelectionStrategy: FilterSelectionStrategy,
) : Presenter<RoomListFiltersState> { ) : Presenter<RoomListFiltersState> {

View file

@ -7,14 +7,15 @@
package io.element.android.features.home.impl.filters.selection package io.element.android.features.home.impl.filters.selection
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.home.impl.filters.RoomListFilter import io.element.android.features.home.impl.filters.RoomListFilter
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import javax.inject.Inject import dev.zacsweers.metro.Inject
@ContributesBinding(SessionScope::class) @ContributesBinding(SessionScope::class)
class DefaultFilterSelectionStrategy @Inject constructor() : FilterSelectionStrategy { @Inject
class DefaultFilterSelectionStrategy() : FilterSelectionStrategy {
private val selectedFilters = LinkedHashSet<RoomListFilter>() private val selectedFilters = LinkedHashSet<RoomListFilter>()
override val filterSelectionStates = MutableStateFlow(buildFilters()) override val filterSelectionStates = MutableStateFlow(buildFilters())

View file

@ -63,12 +63,13 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.takeWhile import kotlinx.coroutines.flow.takeWhile
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import dev.zacsweers.metro.Inject
private const val EXTENDED_RANGE_SIZE = 40 private const val EXTENDED_RANGE_SIZE = 40
private const val SUBSCRIBE_TO_VISIBLE_ROOMS_DEBOUNCE_IN_MILLIS = 300L private const val SUBSCRIBE_TO_VISIBLE_ROOMS_DEBOUNCE_IN_MILLIS = 300L
class RoomListPresenter @Inject constructor( @Inject
class RoomListPresenter(
private val client: MatrixClient, private val client: MatrixClient,
private val leaveRoomPresenter: Presenter<LeaveRoomState>, private val leaveRoomPresenter: Presenter<LeaveRoomState>,
private val roomListDataSource: RoomListDataSource, private val roomListDataSource: RoomListDataSource,

View file

@ -20,11 +20,12 @@ import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import javax.inject.Inject import dev.zacsweers.metro.Inject
private const val PAGE_SIZE = 30 private const val PAGE_SIZE = 30
class RoomListSearchDataSource @Inject constructor( @Inject
class RoomListSearchDataSource(
roomListService: RoomListService, roomListService: RoomListService,
coroutineDispatchers: CoroutineDispatchers, coroutineDispatchers: CoroutineDispatchers,
private val roomSummaryFactory: RoomListRoomSummaryFactory, private val roomSummaryFactory: RoomListRoomSummaryFactory,

View file

@ -16,9 +16,10 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import javax.inject.Inject import dev.zacsweers.metro.Inject
class RoomListSearchPresenter @Inject constructor( @Inject
class RoomListSearchPresenter(
private val dataSource: RoomListSearchDataSource, private val dataSource: RoomListSearchDataSource,
) : Presenter<RoomListSearchState> { ) : Presenter<RoomListSearchState> {
@Composable @Composable

View file

@ -7,7 +7,7 @@
package io.element.android.features.invite.impl package io.element.android.features.invite.impl
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import im.vector.app.features.analytics.plan.JoinedRoom import im.vector.app.features.analytics.plan.JoinedRoom
import io.element.android.features.invite.api.SeenInvitesStore import io.element.android.features.invite.api.SeenInvitesStore
import io.element.android.libraries.core.extensions.mapFailure import io.element.android.libraries.core.extensions.mapFailure
@ -19,7 +19,7 @@ import io.element.android.libraries.matrix.api.exception.ClientException
import io.element.android.libraries.matrix.api.exception.ErrorKind import io.element.android.libraries.matrix.api.exception.ErrorKind
import io.element.android.libraries.matrix.api.room.join.JoinRoom import io.element.android.libraries.matrix.api.room.join.JoinRoom
import io.element.android.libraries.push.api.notifications.NotificationCleaner import io.element.android.libraries.push.api.notifications.NotificationCleaner
import javax.inject.Inject import dev.zacsweers.metro.Inject
interface AcceptInvite { interface AcceptInvite {
suspend operator fun invoke(roomId: RoomId): Result<RoomId> suspend operator fun invoke(roomId: RoomId): Result<RoomId>
@ -30,7 +30,8 @@ interface AcceptInvite {
} }
@ContributesBinding(SessionScope::class) @ContributesBinding(SessionScope::class)
class DefaultAcceptInvite @Inject constructor( @Inject
class DefaultAcceptInvite(
private val client: MatrixClient, private val client: MatrixClient,
private val joinRoom: JoinRoom, private val joinRoom: JoinRoom,
private val notificationCleaner: NotificationCleaner, private val notificationCleaner: NotificationCleaner,

View file

@ -7,13 +7,13 @@
package io.element.android.features.invite.impl package io.element.android.features.invite.impl
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.invite.api.SeenInvitesStore import io.element.android.features.invite.api.SeenInvitesStore
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.push.api.notifications.NotificationCleaner import io.element.android.libraries.push.api.notifications.NotificationCleaner
import javax.inject.Inject import dev.zacsweers.metro.Inject
interface DeclineInvite { interface DeclineInvite {
suspend operator fun invoke( suspend operator fun invoke(
@ -32,7 +32,8 @@ interface DeclineInvite {
} }
@ContributesBinding(SessionScope::class) @ContributesBinding(SessionScope::class)
class DefaultDeclineInvite @Inject constructor( @Inject
class DefaultDeclineInvite(
private val client: MatrixClient, private val client: MatrixClient,
private val notificationCleaner: NotificationCleaner, private val notificationCleaner: NotificationCleaner,
private val seenInvitesStore: SeenInvitesStore, private val seenInvitesStore: SeenInvitesStore,

View file

@ -8,20 +8,21 @@
package io.element.android.features.invite.impl package io.element.android.features.invite.impl
import android.content.Context import android.content.Context
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.invite.api.SeenInvitesStore import io.element.android.features.invite.api.SeenInvitesStore
import io.element.android.libraries.di.AppScope import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.di.annotations.ApplicationContext
import io.element.android.libraries.di.SingleIn import dev.zacsweers.metro.SingleIn
import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.sessionstorage.api.observer.SessionObserver import io.element.android.libraries.sessionstorage.api.observer.SessionObserver
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject import dev.zacsweers.metro.Inject
@SingleIn(AppScope::class) @SingleIn(AppScope::class)
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultSeenInvitesStoreFactory @Inject constructor( @Inject
class DefaultSeenInvitesStoreFactory(
@ApplicationContext private val context: Context, @ApplicationContext private val context: Context,
private val sessionObserver: SessionObserver, private val sessionObserver: SessionObserver,
) : SeenInvitesStoreFactory { ) : SeenInvitesStoreFactory {

View file

@ -24,9 +24,10 @@ import io.element.android.libraries.architecture.runUpdatingState
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import dev.zacsweers.metro.Inject
class AcceptDeclineInvitePresenter @Inject constructor( @Inject
class AcceptDeclineInvitePresenter(
private val acceptInvite: AcceptInvite, private val acceptInvite: AcceptInvite,
private val declineInvite: DeclineInvite, private val declineInvite: DeclineInvite,
) : Presenter<AcceptDeclineInviteState> { ) : Presenter<AcceptDeclineInviteState> {

View file

@ -9,15 +9,16 @@ package io.element.android.features.invite.impl.acceptdecline
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import com.squareup.anvil.annotations.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteView import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteView
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import javax.inject.Inject import dev.zacsweers.metro.Inject
@ContributesBinding(SessionScope::class) @ContributesBinding(SessionScope::class)
class DefaultAcceptDeclineInviteView @Inject constructor() : AcceptDeclineInviteView { @Inject
class DefaultAcceptDeclineInviteView() : AcceptDeclineInviteView {
@Composable @Composable
override fun Render( override fun Render(
state: AcceptDeclineInviteState, state: AcceptDeclineInviteState,

View file

@ -12,8 +12,8 @@ import androidx.compose.ui.Modifier
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.invite.api.InviteData import io.element.android.features.invite.api.InviteData
import io.element.android.libraries.architecture.NodeInputs import io.element.android.libraries.architecture.NodeInputs
@ -21,23 +21,24 @@ import io.element.android.libraries.architecture.inputs
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class DeclineAndBlockNode @AssistedInject constructor( @Inject
class DeclineAndBlockNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
presenterFactory: DeclineAndBlockPresenter.Factory, // presenterFactory: DeclineAndBlockPresenter.Factory,
) : Node(buildContext, plugins = plugins) { ) : Node(buildContext, plugins = plugins) {
data class Inputs(val inviteData: InviteData) : NodeInputs data class Inputs(val inviteData: InviteData) : NodeInputs
private val inviteData = inputs<Inputs>().inviteData private val inviteData = inputs<Inputs>().inviteData
private val presenter = presenterFactory.create(inviteData) // private val presenter = presenterFactory.create(inviteData)
@Composable @Composable
override fun View(modifier: Modifier) { override fun View(modifier: Modifier) {
val state = presenter.present() // val state = presenter.present()
DeclineAndBlockView( // DeclineAndBlockView(
state = state, // state = state,
onBackClick = ::navigateUp, // onBackClick = ::navigateUp,
modifier = modifier // modifier = modifier
) // )
} }
} }

View file

@ -15,9 +15,9 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import dagger.assisted.Assisted import dev.zacsweers.metro.Assisted
import dagger.assisted.AssistedFactory import dev.zacsweers.metro.AssistedFactory
import dagger.assisted.AssistedInject import dev.zacsweers.metro.Inject
import io.element.android.features.invite.api.InviteData import io.element.android.features.invite.api.InviteData
import io.element.android.features.invite.impl.DeclineInvite import io.element.android.features.invite.impl.DeclineInvite
import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncAction
@ -28,65 +28,66 @@ import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class DeclineAndBlockPresenter @AssistedInject constructor( //@Inject
@Assisted private val inviteData: InviteData, //class DeclineAndBlockPresenter(
private val declineInvite: DeclineInvite, // @Assisted private val inviteData: InviteData,
private val snackbarDispatcher: SnackbarDispatcher, // private val declineInvite: DeclineInvite,
) : Presenter<DeclineAndBlockState> { // private val snackbarDispatcher: SnackbarDispatcher,
@AssistedFactory //) : Presenter<DeclineAndBlockState> {
interface Factory { // @AssistedFactory
fun create(inviteData: InviteData): DeclineAndBlockPresenter // interface Factory {
} // fun create(inviteData: InviteData): DeclineAndBlockPresenter
// }
@Composable //
override fun present(): DeclineAndBlockState { // @Composable
var reportReason by rememberSaveable { mutableStateOf("") } // override fun present(): DeclineAndBlockState {
var blockUser by rememberSaveable { mutableStateOf(true) } // var reportReason by rememberSaveable { mutableStateOf("") }
var reportRoom by rememberSaveable { mutableStateOf(false) } // var blockUser by rememberSaveable { mutableStateOf(true) }
val declineAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) } // var reportRoom by rememberSaveable { mutableStateOf(false) }
// val declineAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
val coroutineScope = rememberCoroutineScope() //
// val coroutineScope = rememberCoroutineScope()
fun handleEvents(event: DeclineAndBlockEvents) { //
when (event) { // fun handleEvents(event: DeclineAndBlockEvents) {
DeclineAndBlockEvents.ClearDeclineAction -> declineAction.value = AsyncAction.Uninitialized // when (event) {
DeclineAndBlockEvents.Decline -> coroutineScope.decline(reportReason, blockUser, reportRoom, declineAction) // DeclineAndBlockEvents.ClearDeclineAction -> declineAction.value = AsyncAction.Uninitialized
DeclineAndBlockEvents.ToggleBlockUser -> blockUser = !blockUser // DeclineAndBlockEvents.Decline -> coroutineScope.decline(reportReason, blockUser, reportRoom, declineAction)
DeclineAndBlockEvents.ToggleReportRoom -> reportRoom = !reportRoom // DeclineAndBlockEvents.ToggleBlockUser -> blockUser = !blockUser
is DeclineAndBlockEvents.UpdateReportReason -> reportReason = event.reason // DeclineAndBlockEvents.ToggleReportRoom -> reportRoom = !reportRoom
} // is DeclineAndBlockEvents.UpdateReportReason -> reportReason = event.reason
} // }
// }
return DeclineAndBlockState( //
reportRoom = reportRoom, // return DeclineAndBlockState(
reportReason = reportReason, // reportRoom = reportRoom,
blockUser = blockUser, // reportReason = reportReason,
declineAction = declineAction.value, // blockUser = blockUser,
eventSink = ::handleEvents // declineAction = declineAction.value,
) // eventSink = ::handleEvents
} // )
// }
private fun CoroutineScope.decline( //
reason: String, // private fun CoroutineScope.decline(
blockUser: Boolean, // reason: String,
reportRoom: Boolean, // blockUser: Boolean,
action: MutableState<AsyncAction<Unit>> // reportRoom: Boolean,
) = launch { // action: MutableState<AsyncAction<Unit>>
action.value = AsyncAction.Loading // ) = launch {
declineInvite( // action.value = AsyncAction.Loading
roomId = inviteData.roomId, // declineInvite(
blockUser = blockUser, // roomId = inviteData.roomId,
reportRoom = reportRoom, // blockUser = blockUser,
reportReason = reason // reportRoom = reportRoom,
).onSuccess { // reportReason = reason
action.value = AsyncAction.Success(Unit) // ).onSuccess {
}.onFailure { error -> // action.value = AsyncAction.Success(Unit)
if (error is DeclineInvite.Exception.DeclineInviteFailed) { // }.onFailure { error ->
action.value = AsyncAction.Failure(error) // if (error is DeclineInvite.Exception.DeclineInviteFailed) {
} else { // action.value = AsyncAction.Failure(error)
action.value = AsyncAction.Uninitialized // } else {
snackbarDispatcher.post(SnackbarMessage(CommonStrings.error_unknown)) // action.value = AsyncAction.Uninitialized
} // snackbarDispatcher.post(SnackbarMessage(CommonStrings.error_unknown))
} // }
} // }
} // }
//}

Some files were not shown because too many files have changed in this diff Show more