Start migrating Anvil KSP to Metro

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

View file

@ -14,16 +14,17 @@ import androidx.compose.ui.Modifier
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.appconfig.AnalyticsConfig
import io.element.android.compound.theme.ElementTheme
import io.element.android.libraries.androidutils.browser.openUrlInChromeCustomTab
import io.element.android.libraries.di.AppScope
import dev.zacsweers.metro.AppScope
@ContributesNode(AppScope::class)
class AnalyticsOptInNode @AssistedInject constructor(
@Inject
class AnalyticsOptInNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
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 kotlinx.coroutines.CoroutineScope
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 analyticsService: AnalyticsService,
) : 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.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.libraries.architecture.createNode
import io.element.android.libraries.di.AppScope
import javax.inject.Inject
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class)
class DefaultAnalyticsEntryPoint @Inject constructor() : AnalyticsEntryPoint {
@Inject
class DefaultAnalyticsEntryPoint() : AnalyticsEntryPoint {
override fun createNode(parentNode: Node, buildContext: BuildContext): Node {
return parentNode.createNode<AnalyticsOptInNode>(buildContext)
}

View file

@ -7,16 +7,16 @@
package io.element.android.features.analytics.impl.di
import com.squareup.anvil.annotations.ContributesTo
import dagger.Binds
import dagger.Module
import dev.zacsweers.metro.BindingContainer
import dev.zacsweers.metro.Binds
import dev.zacsweers.metro.ContributesTo
import io.element.android.features.analytics.api.preferences.AnalyticsPreferencesState
import io.element.android.features.analytics.impl.preferences.AnalyticsPreferencesPresenter
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.di.AppScope
import dev.zacsweers.metro.AppScope
@ContributesTo(AppScope::class)
@Module
@BindingContainer
interface AnalyticsModule {
@Binds
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 kotlinx.coroutines.CoroutineScope
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 buildMeta: BuildMeta,
) : Presenter<AnalyticsPreferencesState> {

View file

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

View file

@ -7,28 +7,30 @@
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.libraries.core.coroutine.CoroutineDispatchers
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.annotations.AppCoroutineScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import timber.log.Timber
import java.io.File
import javax.inject.Inject
import dev.zacsweers.metro.Inject
import dev.zacsweers.metro.Named
/**
* Default implementation of [CacheCleaner].
*/
@ContributesBinding(AppScope::class)
class DefaultCacheCleaner @Inject constructor(
@Inject
class DefaultCacheCleaner(
@AppCoroutineScope
private val coroutineScope: CoroutineScope,
private val dispatchers: CoroutineDispatchers,
@CacheDirectory private val cacheDir: File,
@Named("cacheDirectory") private val cacheDir: File,
) : CacheCleaner {
companion object {
val SUBDIRS_TO_CLEANUP = listOf("temp/media", "temp/voice")

View file

@ -8,20 +8,21 @@
package io.element.android.features.call.impl
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.ElementCallEntryPoint
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.IntentProvider
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import dev.zacsweers.metro.AppScope
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.UserId
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class)
class DefaultElementCallEntryPoint @Inject constructor(
@Inject
class DefaultElementCallEntryPoint(
@ApplicationContext private val context: Context,
private val activeCallManager: ActiveCallManager,
) : ElementCallEntryPoint {

View file

@ -7,11 +7,11 @@
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.ui.ElementCallActivity
import io.element.android.features.call.impl.ui.IncomingCallActivity
import io.element.android.libraries.di.AppScope
import dev.zacsweers.metro.AppScope
@ContributesTo(AppScope::class)
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.utils.IntentProvider
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.core.EventId
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.ui.media.ImageLoaderHolder
import io.element.android.libraries.push.api.notifications.NotificationBitmapLoader
import javax.inject.Inject
import dev.zacsweers.metro.Inject
import kotlin.time.Duration.Companion.seconds
/**
* Creates a notification for a ringing call.
*/
class RingingCallNotificationCreator @Inject constructor(
@Inject
class RingingCallNotificationCreator(
@ApplicationContext private val context: Context,
private val matrixClientProvider: MatrixClientProvider,
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 kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
import dev.zacsweers.metro.Inject
private val loggerTag = LoggerTag("PiP")
class PictureInPicturePresenter @Inject constructor(
@Inject
class PictureInPicturePresenter(
pipSupportProvider: PipSupportProvider,
) : Presenter<PictureInPictureState> {
private val isPipSupported = pipSupportProvider.isPipSupported()

View file

@ -11,11 +11,11 @@ import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
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.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import javax.inject.Inject
import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.annotations.ApplicationContext
import dev.zacsweers.metro.Inject
interface PipSupportProvider {
@ChecksSdkIntAtLeast(Build.VERSION_CODES.O)
@ -23,7 +23,8 @@ interface PipSupportProvider {
}
@ContributesBinding(AppScope::class)
class DefaultPipSupportProvider @Inject constructor(
@Inject
class DefaultPipSupportProvider(
@ApplicationContext private val context: Context,
) : PipSupportProvider {
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 kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import javax.inject.Inject
import dev.zacsweers.metro.Inject
/**
* 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.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.AssistedFactory
import dev.zacsweers.metro.Inject
import im.vector.app.features.analytics.plan.MobileScreen
import io.element.android.compound.theme.ElementTheme
import io.element.android.features.call.api.CallType
@ -49,7 +49,8 @@ import timber.log.Timber
import java.util.UUID
import kotlin.time.Duration.Companion.seconds
class CallScreenPresenter @AssistedInject constructor(
@Inject
class CallScreenPresenter(
@Assisted private val callType: CallType,
@Assisted private val navigator: CallScreenNavigator,
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.preferences.api.store.AppPreferencesStore
import timber.log.Timber
import javax.inject.Inject
import dev.zacsweers.metro.Inject
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.onEach
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.

View file

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

View file

@ -15,16 +15,16 @@ import androidx.core.app.NotificationManagerCompat
import androidx.core.content.getSystemService
import coil3.SingletonImageLoader
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.features.call.api.CallType
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.RingingCallNotificationCreator
import io.element.android.libraries.core.extensions.runCatchingExceptions
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import io.element.android.libraries.di.SingleIn
import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.annotations.ApplicationContext
import dev.zacsweers.metro.SingleIn
import io.element.android.libraries.di.annotations.AppCoroutineScope
import io.element.android.libraries.matrix.api.MatrixClientProvider
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.withLock
import timber.log.Timber
import javax.inject.Inject
import dev.zacsweers.metro.Inject
import kotlin.time.Duration.Companion.seconds
/**
@ -86,7 +86,8 @@ interface ActiveCallManager {
@SingleIn(AppScope::class)
@ContributesBinding(AppScope::class)
class DefaultActiveCallManager @Inject constructor(
@Inject
class DefaultActiveCallManager(
@ApplicationContext context: Context,
@AppCoroutineScope
private val coroutineScope: CoroutineScope,

View file

@ -9,9 +9,10 @@ package io.element.android.features.call.impl.utils
import android.net.Uri
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 knownHosts = sequenceOf(
"call.element.io",

View file

@ -7,14 +7,15 @@
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.libraries.di.AppScope
import dev.zacsweers.metro.AppScope
import io.element.android.libraries.matrix.api.widget.CallAnalyticCredentialsProvider
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@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 posthogApiHost: String? = BuildConfig.POSTHOG_API_HOST.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
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
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.core.RoomId
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.services.appnavstate.api.ActiveRoomsHolder
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"
@ContributesBinding(AppScope::class)
class DefaultCallWidgetProvider @Inject constructor(
@Inject
class DefaultCallWidgetProvider(
private val matrixClientsProvider: MatrixClientProvider,
private val appPreferencesStore: AppPreferencesStore,
private val callWidgetSettingsProvider: CallWidgetSettingsProvider,

View file

@ -7,17 +7,18 @@
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.CurrentCallService
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.SingleIn
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.SingleIn
import kotlinx.coroutines.flow.MutableStateFlow
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@SingleIn(AppScope::class)
@ContributesBinding(AppScope::class)
class DefaultCurrentCallService @Inject constructor() : CurrentCallService {
@Inject
class DefaultCurrentCallService() : CurrentCallService {
override val currentCall = MutableStateFlow<CurrentCall>(CurrentCall.None)
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.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.changeroommemberroes.api.ChangeRoomMemberRolesListType
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
@ContributesNode(RoomScope::class)
class ChangeRolesNode @AssistedInject constructor(
@Inject
class ChangeRolesNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
presenterFactory: ChangeRolesPresenter.Factory,

View file

@ -18,9 +18,9 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.AssistedFactory
import dev.zacsweers.metro.Inject
import im.vector.app.features.analytics.plan.RoomModeration
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.Presenter
@ -47,7 +47,8 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
class ChangeRolesPresenter @AssistedInject constructor(
@Inject
class ChangeRolesPresenter(
@Assisted private val role: RoomMember.Role,
private val room: JoinedRoom,
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.ParentNode
import com.bumble.appyx.core.plugin.Plugin
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.appnav.di.RoomComponentFactory
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
@ContributesNode(SessionScope::class)
class ChangeRoomMemberRolesRootNode @AssistedInject constructor(
@Inject
class ChangeRoomMemberRolesRootNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
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.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.ChangeRoomMemberRolesListType
import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.room.JoinedRoom
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(SessionScope::class)
class DefaultChangeRoomMemberRolesEntyPoint @Inject constructor() : ChangeRoomMemberRolesEntryPoint {
@Inject
class DefaultChangeRoomMemberRolesEntyPoint() : ChangeRoomMemberRolesEntryPoint {
override fun builder(parentNode: Node, buildContext: BuildContext): ChangeRoomMemberRolesEntryPoint.Builder {
return object : ChangeRoomMemberRolesEntryPoint.Builder {
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.roomMembers
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 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.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.replace
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.createroom.api.CreateRoomEntryPoint
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
@ContributesNode(SessionScope::class)
class CreateRoomFlowNode @AssistedInject constructor(
@Inject
class CreateRoomFlowNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
) : 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.node.Node
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.libraries.architecture.createNode
import io.element.android.libraries.di.SessionScope
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(SessionScope::class)
class DefaultCreateRoomEntryPoint @Inject constructor() : CreateRoomEntryPoint {
@Inject
class DefaultCreateRoomEntryPoint() : CreateRoomEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): CreateRoomEntryPoint.NodeBuilder {
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.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.invitepeople.api.InvitePeoplePresenter
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
@ContributesNode(SessionScope::class)
class AddPeopleNode @AssistedInject constructor(
@Inject
class AddPeopleNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
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.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import im.vector.app.features.analytics.plan.MobileScreen
import io.element.android.anvilannotations.ContributesNode
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
@ContributesNode(SessionScope::class)
class ConfigureRoomNode @AssistedInject constructor(
@Inject
class ConfigureRoomNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
private val presenter: ConfigureRoomPresenter,

View file

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

View file

@ -14,9 +14,10 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.getAndUpdate
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 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.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.libraries.di.SessionScope
@ContributesNode(SessionScope::class)
class AccountDeactivationNode @AssistedInject constructor(
@Inject
class AccountDeactivationNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
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 kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import javax.inject.Inject
import dev.zacsweers.metro.Inject
class AccountDeactivationPresenter @Inject constructor(
@Inject
class AccountDeactivationPresenter(
private val matrixClient: MatrixClient,
) : Presenter<AccountDeactivationState> {
@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.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.libraries.architecture.createNode
import io.element.android.libraries.di.AppScope
import javax.inject.Inject
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class)
class DefaultAccountDeactivationEntryPoint @Inject constructor() : AccountDeactivationEntryPoint {
@Inject
class DefaultAccountDeactivationEntryPoint() : AccountDeactivationEntryPoint {
override fun createNode(parentNode: Node, buildContext: BuildContext): Node {
return parentNode.createNode<AccountDeactivationNode>(buildContext)
}

View file

@ -7,19 +7,20 @@
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.compoundColorsDark
import io.element.android.compound.tokens.generated.compoundColorsLight
import io.element.android.features.enterprise.api.BugReportUrl
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 kotlinx.coroutines.flow.flowOf
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class)
class DefaultEnterpriseService @Inject constructor() : EnterpriseService {
@Inject
class DefaultEnterpriseService() : EnterpriseService {
override val isEnterpriseBuild = false
override suspend fun isEnterpriseUser(sessionId: SessionId) = false

View file

@ -7,13 +7,14 @@
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.libraries.di.SessionScope
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(SessionScope::class)
class DefaultSessionEnterpriseService @Inject constructor() : SessionEnterpriseService {
@Inject
class DefaultSessionEnterpriseService() : SessionEnterpriseService {
override suspend fun init() = Unit
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.node.Node
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.libraries.architecture.createNode
import io.element.android.libraries.di.AppScope
import javax.inject.Inject
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class)
class DefaultFtueEntryPoint @Inject constructor() : FtueEntryPoint {
@Inject
class DefaultFtueEntryPoint() : FtueEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): FtueEntryPoint.NodeBuilder {
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.operation.newRoot
import com.bumble.appyx.navmodel.backstack.operation.replace
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.analytics.api.AnalyticsEntryPoint
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.createNode
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.services.analytics.api.AnalyticsService
import kotlinx.coroutines.flow.distinctUntilChanged
@ -45,7 +45,8 @@ import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize
@ContributesNode(SessionScope::class)
class FtueFlowNode @AssistedInject constructor(
@Inject
class FtueFlowNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
private val ftueState: DefaultFtueService,
@ -158,16 +159,18 @@ class FtueFlowNode @AssistedInject constructor(
BackstackView()
}
@ContributesNode(AppScope::class)
class PlaceholderNode @AssistedInject constructor(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
) : Node(buildContext, plugins = plugins) {
@Composable
override fun View(modifier: Modifier) {
Box(modifier = modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
CircularProgressIndicator()
}
}
@ContributesNode(AppScope::class)
@Inject
class PlaceholderNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
) : Node(buildContext, plugins = plugins) {
@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
import com.squareup.anvil.annotations.ContributesTo
import dagger.Binds
import dagger.Module
import dev.zacsweers.metro.BindingContainer
import dev.zacsweers.metro.Binds
import dev.zacsweers.metro.ContributesTo
import io.element.android.features.ftue.impl.sessionverification.choosemode.ChooseSelfVerificationModePresenter
import io.element.android.features.ftue.impl.sessionverification.choosemode.ChooseSelfVerificationModeState
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.di.SessionScope
@ContributesTo(SessionScope::class)
@Module
@BindingContainer
interface FtueModule {
@Binds
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.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.libraries.architecture.NodeInputs
import io.element.android.libraries.architecture.inputs
import io.element.android.libraries.di.AppScope
import dev.zacsweers.metro.AppScope
@ContributesNode(AppScope::class)
class NotificationsOptInNode @AssistedInject constructor(
@Inject
class NotificationsOptInNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
presenterFactory: NotificationsOptInPresenter.Factory,

View file

@ -12,9 +12,9 @@ import android.os.Build
import androidx.annotation.RequiresApi
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.AssistedFactory
import dev.zacsweers.metro.Inject
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.di.annotations.AppCoroutineScope
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.launch
class NotificationsOptInPresenter @AssistedInject constructor(
@Inject
class NotificationsOptInPresenter(
permissionsPresenterFactory: PermissionsPresenter.Factory,
@Assisted private val callback: NotificationsOptInNode.Callback,
@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.pop
import com.bumble.appyx.navmodel.backstack.operation.push
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.appconfig.LearnMoreConfig
import io.element.android.features.ftue.impl.sessionverification.choosemode.ChooseSelfVerificationModeNode
@ -37,7 +37,8 @@ import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize
@ContributesNode(SessionScope::class)
class FtueSessionVerificationFlowNode @AssistedInject constructor(
@Inject
class FtueSessionVerificationFlowNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
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.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.logout.api.direct.DirectLogoutView
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.di.SessionScope
@ContributesNode(SessionScope::class)
class ChooseSelfVerificationModeNode @AssistedInject constructor(
@Inject
class ChooseSelfVerificationModeNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
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.matrix.api.encryption.EncryptionService
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 directLogoutPresenter: Presenter<DirectLogoutState>,
) : Presenter<ChooseSelfVerificationModeState> {

View file

@ -10,12 +10,12 @@ package io.element.android.features.ftue.impl.state
import android.Manifest
import android.os.Build
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.FtueState
import io.element.android.features.lockscreen.api.LockScreenService
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.matrix.api.verification.SessionVerificationService
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.map
import kotlinx.coroutines.flow.onEach
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(SessionScope::class)
@SingleIn(SessionScope::class)
class DefaultFtueService @Inject constructor(
@Inject
class DefaultFtueService(
private val sdkVersionProvider: BuildVersionSdkIntProvider,
@SessionCoroutineScope sessionCoroutineScope: CoroutineScope,
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.node.Node
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.libraries.architecture.createNode
import io.element.android.libraries.di.AppScope
import javax.inject.Inject
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class)
class DefaultHomeEntryPoint @Inject constructor() : HomeEntryPoint {
@Inject
class DefaultHomeEntryPoint() : HomeEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): HomeEntryPoint.NodeBuilder {
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.operation.pop
import com.bumble.appyx.navmodel.backstack.operation.push
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import im.vector.app.features.analytics.plan.MobileScreen
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.changeroommemberroes.api.ChangeRoomMemberRolesEntryPoint
@ -56,7 +56,8 @@ import kotlinx.coroutines.withContext
import kotlinx.parcelize.Parcelize
@ContributesNode(SessionScope::class)
class HomeFlowNode @AssistedInject constructor(
@Inject
class HomeFlowNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
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.matrix.api.MatrixClient
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 syncService: SyncService,
private val snackbarDispatcher: SnackbarDispatcher,

View file

@ -29,10 +29,11 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import javax.inject.Inject
import dev.zacsweers.metro.Inject
import kotlin.time.Duration.Companion.seconds
class RoomListDataSource @Inject constructor(
@Inject
class RoomListDataSource(
private val roomListService: RoomListService,
private val roomListRoomSummaryFactory: RoomListRoomSummaryFactory,
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.toInviteSender
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 roomLastMessageFormatter: RoomLastMessageFormatter,
) {

View file

@ -7,9 +7,9 @@
package io.element.android.features.home.impl.di
import com.squareup.anvil.annotations.ContributesTo
import dagger.Binds
import dagger.Module
import dev.zacsweers.metro.Binds
import dev.zacsweers.metro.BindingContainer
import dev.zacsweers.metro.ContributesTo
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.roomlist.RoomListPresenter
@ -20,7 +20,7 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.di.SessionScope
@ContributesTo(SessionScope::class)
@Module
@BindingContainer
interface RoomListModule {
@Binds
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 kotlinx.collections.immutable.toPersistentList
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
class RoomListFiltersPresenter @Inject constructor(
@Inject
class RoomListFiltersPresenter(
private val roomListService: RoomListService,
private val filterSelectionStrategy: FilterSelectionStrategy,
) : Presenter<RoomListFiltersState> {

View file

@ -7,14 +7,15 @@
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.libraries.di.SessionScope
import kotlinx.coroutines.flow.MutableStateFlow
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(SessionScope::class)
class DefaultFilterSelectionStrategy @Inject constructor() : FilterSelectionStrategy {
@Inject
class DefaultFilterSelectionStrategy() : FilterSelectionStrategy {
private val selectedFilters = LinkedHashSet<RoomListFilter>()
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.takeWhile
import kotlinx.coroutines.launch
import javax.inject.Inject
import dev.zacsweers.metro.Inject
private const val EXTENDED_RANGE_SIZE = 40
private const val SUBSCRIBE_TO_VISIBLE_ROOMS_DEBOUNCE_IN_MILLIS = 300L
class RoomListPresenter @Inject constructor(
@Inject
class RoomListPresenter(
private val client: MatrixClient,
private val leaveRoomPresenter: Presenter<LeaveRoomState>,
private val roomListDataSource: RoomListDataSource,

View file

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

View file

@ -16,9 +16,10 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import io.element.android.libraries.architecture.Presenter
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,
) : Presenter<RoomListSearchState> {
@Composable

View file

@ -7,7 +7,7 @@
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 io.element.android.features.invite.api.SeenInvitesStore
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.room.join.JoinRoom
import io.element.android.libraries.push.api.notifications.NotificationCleaner
import javax.inject.Inject
import dev.zacsweers.metro.Inject
interface AcceptInvite {
suspend operator fun invoke(roomId: RoomId): Result<RoomId>
@ -30,7 +30,8 @@ interface AcceptInvite {
}
@ContributesBinding(SessionScope::class)
class DefaultAcceptInvite @Inject constructor(
@Inject
class DefaultAcceptInvite(
private val client: MatrixClient,
private val joinRoom: JoinRoom,
private val notificationCleaner: NotificationCleaner,

View file

@ -7,13 +7,13 @@
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.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.push.api.notifications.NotificationCleaner
import javax.inject.Inject
import dev.zacsweers.metro.Inject
interface DeclineInvite {
suspend operator fun invoke(
@ -32,7 +32,8 @@ interface DeclineInvite {
}
@ContributesBinding(SessionScope::class)
class DefaultDeclineInvite @Inject constructor(
@Inject
class DefaultDeclineInvite(
private val client: MatrixClient,
private val notificationCleaner: NotificationCleaner,
private val seenInvitesStore: SeenInvitesStore,

View file

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

View file

@ -24,9 +24,10 @@ import io.element.android.libraries.architecture.runUpdatingState
import io.element.android.libraries.matrix.api.core.RoomId
import kotlinx.coroutines.CoroutineScope
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 declineInvite: DeclineInvite,
) : Presenter<AcceptDeclineInviteState> {

View file

@ -9,15 +9,16 @@ package io.element.android.features.invite.impl.acceptdecline
import androidx.compose.runtime.Composable
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.AcceptDeclineInviteView
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.core.RoomId
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(SessionScope::class)
class DefaultAcceptDeclineInviteView @Inject constructor() : AcceptDeclineInviteView {
@Inject
class DefaultAcceptDeclineInviteView() : AcceptDeclineInviteView {
@Composable
override fun Render(
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.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.invite.api.InviteData
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
@ContributesNode(SessionScope::class)
class DeclineAndBlockNode @AssistedInject constructor(
@Inject
class DeclineAndBlockNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
presenterFactory: DeclineAndBlockPresenter.Factory,
// presenterFactory: DeclineAndBlockPresenter.Factory,
) : Node(buildContext, plugins = plugins) {
data class Inputs(val inviteData: InviteData) : NodeInputs
private val inviteData = inputs<Inputs>().inviteData
private val presenter = presenterFactory.create(inviteData)
// private val presenter = presenterFactory.create(inviteData)
@Composable
override fun View(modifier: Modifier) {
val state = presenter.present()
DeclineAndBlockView(
state = state,
onBackClick = ::navigateUp,
modifier = modifier
)
// val state = presenter.present()
// DeclineAndBlockView(
// state = state,
// onBackClick = ::navigateUp,
// modifier = modifier
// )
}
}

View file

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

View file

@ -9,15 +9,16 @@ package io.element.android.features.invite.impl.declineandblock
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.invite.api.InviteData
import io.element.android.features.invite.api.declineandblock.DeclineInviteAndBlockEntryPoint
import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.AppScope
import javax.inject.Inject
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class)
class DefaultDeclineAndBlockEntryPoint @Inject constructor() : DeclineInviteAndBlockEntryPoint {
@Inject
class DefaultDeclineAndBlockEntryPoint() : DeclineInviteAndBlockEntryPoint {
override fun createNode(parentNode: Node, buildContext: BuildContext, inviteData: InviteData): Node {
val inputs = DeclineAndBlockNode.Inputs(inviteData)
return parentNode.createNode<DeclineAndBlockNode>(buildContext, plugins = listOf(inputs))

View file

@ -7,10 +7,10 @@
package io.element.android.features.invite.impl.di
import com.squareup.anvil.annotations.ContributesTo
import dagger.Binds
import dagger.Module
import dagger.Provides
import dev.zacsweers.metro.Binds
import dev.zacsweers.metro.BindingContainer
import dev.zacsweers.metro.ContributesTo
import dev.zacsweers.metro.Provides
import io.element.android.features.invite.api.SeenInvitesStore
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
import io.element.android.features.invite.impl.SeenInvitesStoreFactory
@ -20,7 +20,7 @@ import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.MatrixClient
@ContributesTo(SessionScope::class)
@Module
@BindingContainer
interface InviteModule {
@Binds
fun bindAcceptDeclinePresenter(presenter: AcceptDeclineInvitePresenter): Presenter<AcceptDeclineInviteState>

View file

@ -16,10 +16,10 @@ import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import com.squareup.anvil.annotations.ContributesBinding
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.ContributesBinding
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.AssistedFactory
import dev.zacsweers.metro.Inject
import io.element.android.features.invitepeople.api.InvitePeopleEvents
import io.element.android.features.invitepeople.api.InvitePeoplePresenter
import io.element.android.features.invitepeople.api.InvitePeopleState
@ -49,7 +49,8 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class DefaultInvitePeoplePresenter @AssistedInject constructor(
@Inject
class DefaultInvitePeoplePresenter(
@Assisted private val joinedRoom: JoinedRoom?,
@Assisted private val roomId: RoomId,
private val userRepository: UserRepository,

View file

@ -9,14 +9,15 @@ package io.element.android.features.invitepeople.impl
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.invitepeople.api.InvitePeopleRenderer
import io.element.android.features.invitepeople.api.InvitePeopleState
import io.element.android.libraries.di.SessionScope
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(SessionScope::class)
class DefaultInvitePeopleRenderer @Inject constructor() : InvitePeopleRenderer {
@Inject
class DefaultInvitePeopleRenderer() : InvitePeopleRenderer {
@Composable
override fun Render(state: InvitePeopleState, modifier: Modifier) {
if (state is DefaultInvitePeopleState) {

View file

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

View file

@ -16,8 +16,8 @@ import com.bumble.appyx.core.node.node
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.push
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.invite.api.InviteData
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteView
@ -30,7 +30,8 @@ import io.element.android.libraries.di.SessionScope
import kotlinx.parcelize.Parcelize
@ContributesNode(SessionScope::class)
class JoinRoomFlowNode @AssistedInject constructor(
@Inject
class JoinRoomFlowNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
presenterFactory: JoinRoomPresenter.Factory,

View file

@ -20,8 +20,8 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import im.vector.app.features.analytics.plan.JoinedRoom
import io.element.android.features.invite.api.SeenInvitesStore
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents
@ -54,7 +54,8 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import java.util.Optional
class JoinRoomPresenter @AssistedInject constructor(
@Inject
class JoinRoomPresenter(
@Assisted private val roomId: RoomId,
@Assisted private val roomIdOrAlias: RoomIdOrAlias,
@Assisted private val roomDescription: Optional<RoomDescription>,

View file

@ -7,18 +7,19 @@
package io.element.android.features.joinroom.impl.di
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
import javax.inject.Inject
import dev.zacsweers.metro.Inject
interface CancelKnockRoom {
suspend operator fun invoke(roomId: RoomId): Result<Unit>
}
@ContributesBinding(SessionScope::class)
class DefaultCancelKnockRoom @Inject constructor(private val client: MatrixClient) : CancelKnockRoom {
@Inject
class DefaultCancelKnockRoom(private val client: MatrixClient) : CancelKnockRoom {
override suspend fun invoke(roomId: RoomId): Result<Unit> {
return client
.getRoom(roomId)

View file

@ -7,18 +7,19 @@
package io.element.android.features.joinroom.impl.di
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
import javax.inject.Inject
import dev.zacsweers.metro.Inject
interface ForgetRoom {
suspend operator fun invoke(roomId: RoomId): Result<Unit>
}
@ContributesBinding(SessionScope::class)
class DefaultForgetRoom @Inject constructor(private val client: MatrixClient) : ForgetRoom {
@Inject
class DefaultForgetRoom(private val client: MatrixClient) : ForgetRoom {
override suspend fun invoke(roomId: RoomId): Result<Unit> {
return client.getRoom(roomId)?.use { it.forget() }
?: Result.failure(IllegalStateException("Room not found"))

View file

@ -7,9 +7,9 @@
package io.element.android.features.joinroom.impl.di
import com.squareup.anvil.annotations.ContributesTo
import dagger.Module
import dagger.Provides
import dev.zacsweers.metro.BindingContainer
import dev.zacsweers.metro.ContributesTo
import dev.zacsweers.metro.Provides
import im.vector.app.features.analytics.plan.JoinedRoom
import io.element.android.features.invite.api.SeenInvitesStore
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
@ -24,7 +24,7 @@ import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
import io.element.android.libraries.matrix.api.room.join.JoinRoom
import java.util.Optional
@Module
@BindingContainer
@ContributesTo(SessionScope::class)
object JoinRoomModule {
@Provides

View file

@ -7,11 +7,11 @@
package io.element.android.features.joinroom.impl.di
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
import javax.inject.Inject
import dev.zacsweers.metro.Inject
interface KnockRoom {
suspend operator fun invoke(
@ -22,7 +22,8 @@ interface KnockRoom {
}
@ContributesBinding(SessionScope::class)
class DefaultKnockRoom @Inject constructor(private val client: MatrixClient) : KnockRoom {
@Inject
class DefaultKnockRoom(private val client: MatrixClient) : KnockRoom {
override suspend fun invoke(
roomIdOrAlias: RoomIdOrAlias,
message: String,

View file

@ -9,13 +9,14 @@ package io.element.android.features.knockrequests.impl.banner
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.knockrequests.api.banner.KnockRequestsBannerRenderer
import io.element.android.libraries.di.RoomScope
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(RoomScope::class)
class DefaultKnockRequestsBannerRenderer @Inject constructor(
@Inject
class DefaultKnockRequestsBannerRenderer(
private val presenter: KnockRequestsBannerPresenter,
) : KnockRequestsBannerRenderer {
@Composable

View file

@ -23,11 +23,12 @@ import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import javax.inject.Inject
import dev.zacsweers.metro.Inject
private const val ACCEPT_ERROR_DISPLAY_DURATION = 1500L
class KnockRequestsBannerPresenter @Inject constructor(
@Inject
class KnockRequestsBannerPresenter(
private val knockRequestsService: KnockRequestsService,
@SessionCoroutineScope
private val sessionCoroutineScope: CoroutineScope,

View file

@ -7,16 +7,16 @@
package io.element.android.features.knockrequests.impl.data
import com.squareup.anvil.annotations.ContributesTo
import dagger.Module
import dagger.Provides
import dev.zacsweers.metro.BindingContainer
import dev.zacsweers.metro.ContributesTo
import dev.zacsweers.metro.Provides
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.di.SingleIn
import dev.zacsweers.metro.SingleIn
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.matrix.api.room.JoinedRoom
@Module
@BindingContainer
@ContributesTo(RoomScope::class)
object KnockRequestsModule {
@Provides

View file

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

View file

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

View file

@ -22,9 +22,10 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runUpdatingState
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import javax.inject.Inject
import dev.zacsweers.metro.Inject
class KnockRequestsListPresenter @Inject constructor(
@Inject
class KnockRequestsListPresenter(
private val knockRequestsService: KnockRequestsService,
) : Presenter<KnockRequestsListState> {
@Composable

View file

@ -9,15 +9,16 @@ package io.element.android.features.leaveroom.impl
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.leaveroom.api.LeaveRoomRenderer
import io.element.android.features.leaveroom.api.LeaveRoomState
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.core.RoomId
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(SessionScope::class)
class InternalLeaveRoomRenderer @Inject constructor() : LeaveRoomRenderer {
@Inject
class InternalLeaveRoomRenderer() : LeaveRoomRenderer {
@Composable
override fun Render(state: LeaveRoomState, onSelectNewOwners: (RoomId) -> Unit, modifier: Modifier) {
if (state is InternalLeaveRoomState) {

View file

@ -29,9 +29,10 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
import dev.zacsweers.metro.Inject
class LeaveRoomPresenter @Inject constructor(
@Inject
class LeaveRoomPresenter(
private val client: MatrixClient,
private val dispatchers: CoroutineDispatchers,
private val notificationConversationService: NotificationConversationService,

View file

@ -7,16 +7,16 @@
package io.element.android.features.leaveroom.impl.di
import com.squareup.anvil.annotations.ContributesTo
import dagger.Binds
import dagger.Module
import dev.zacsweers.metro.Binds
import dev.zacsweers.metro.BindingContainer
import dev.zacsweers.metro.ContributesTo
import io.element.android.features.leaveroom.api.LeaveRoomState
import io.element.android.features.leaveroom.impl.LeaveRoomPresenter
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.di.SessionScope
@ContributesTo(SessionScope::class)
@Module
@BindingContainer
interface LeaveRoomModule {
@Binds
fun bindLeaveRoomPresenter(presenter: LeaveRoomPresenter): Presenter<LeaveRoomState>

View file

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

View file

@ -15,8 +15,8 @@ import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.push
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.licenses.impl.details.DependenciesDetailsNode
import io.element.android.features.licenses.impl.list.DependencyLicensesListNode
@ -24,11 +24,12 @@ import io.element.android.features.licenses.impl.model.DependencyLicenseItem
import io.element.android.libraries.architecture.BackstackView
import io.element.android.libraries.architecture.BaseFlowNode
import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.AppScope
import dev.zacsweers.metro.AppScope
import kotlinx.parcelize.Parcelize
@ContributesNode(AppScope::class)
class DependenciesFlowNode @AssistedInject constructor(
@Inject
class DependenciesFlowNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
) : BaseFlowNode<DependenciesFlowNode.NavTarget>(

View file

@ -8,23 +8,24 @@
package io.element.android.features.licenses.impl
import android.content.Context
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.licenses.impl.model.DependencyLicenseItem
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.annotations.ApplicationContext
import kotlinx.coroutines.withContext
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import javax.inject.Inject
import dev.zacsweers.metro.Inject
interface LicensesProvider {
suspend fun provides(): List<DependencyLicenseItem>
}
@ContributesBinding(AppScope::class)
class AssetLicensesProvider @Inject constructor(
@Inject
class AssetLicensesProvider(
@ApplicationContext private val context: Context,
private val dispatchers: CoroutineDispatchers,
) : LicensesProvider {

View file

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

View file

@ -13,14 +13,15 @@ import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.licenses.impl.model.DependencyLicenseItem
import io.element.android.libraries.di.AppScope
import dev.zacsweers.metro.AppScope
@ContributesNode(AppScope::class)
class DependencyLicensesListNode @AssistedInject constructor(
@Inject
class DependencyLicensesListNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
private val presenter: DependencyLicensesListPresenter,

View file

@ -20,9 +20,10 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.extensions.runCatchingExceptions
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList
import javax.inject.Inject
import dev.zacsweers.metro.Inject
class DependencyLicensesListPresenter @Inject constructor(
@Inject
class DependencyLicensesListPresenter(
private val licensesProvider: LicensesProvider,
) : Presenter<DependencyLicensesListState> {
@Composable

View file

@ -7,14 +7,15 @@
package io.element.android.features.location.impl
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.location.api.BuildConfig
import io.element.android.features.location.api.LocationService
import io.element.android.libraries.di.AppScope
import javax.inject.Inject
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class)
class DefaultLocationService @Inject constructor() : LocationService {
@Inject
class DefaultLocationService() : LocationService {
override fun isServiceAvailable(): Boolean {
return BuildConfig.MAPTILER_API_KEY.isNotEmpty()
}

View file

@ -12,18 +12,19 @@ import android.content.Intent
import android.net.Uri
import androidx.annotation.VisibleForTesting
import androidx.core.net.toUri
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.location.api.Location
import io.element.android.libraries.androidutils.system.openAppSettingsPage
import io.element.android.libraries.core.extensions.runCatchingExceptions
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import dev.zacsweers.metro.AppScope
import io.element.android.libraries.di.annotations.ApplicationContext
import timber.log.Timber
import java.util.Locale
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class)
class AndroidLocationActions @Inject constructor(
@Inject
class AndroidLocationActions(
@ApplicationContext private val context: Context
) : LocationActions {
override fun share(location: Location, label: String?) {

View file

@ -11,14 +11,15 @@ import androidx.compose.runtime.Composable
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.isGranted
import com.google.accompanist.permissions.rememberMultiplePermissionsState
import com.squareup.anvil.annotations.ContributesBinding
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import io.element.android.libraries.di.AppScope
import dev.zacsweers.metro.ContributesBinding
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.AssistedFactory
import dev.zacsweers.metro.Inject
import dev.zacsweers.metro.AppScope
@Suppress("unused")
class DefaultPermissionsPresenter @AssistedInject constructor(
@Inject
class DefaultPermissionsPresenter(
@Assisted private val permissions: List<String>
) : PermissionsPresenter {
@AssistedFactory

View file

@ -9,15 +9,16 @@ package io.element.android.features.location.impl.send
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.location.api.SendLocationEntryPoint
import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.AppScope
import dev.zacsweers.metro.AppScope
import io.element.android.libraries.matrix.api.timeline.Timeline
import javax.inject.Inject
import dev.zacsweers.metro.Inject
@ContributesBinding(AppScope::class)
class DefaultSendLocationEntryPoint @Inject constructor() : SendLocationEntryPoint {
@Inject
class DefaultSendLocationEntryPoint() : SendLocationEntryPoint {
override fun builder(timelineMode: Timeline.Mode): SendLocationEntryPoint.Builder {
return Builder(timelineMode)
}

View file

@ -13,8 +13,8 @@ import com.bumble.appyx.core.lifecycle.subscribe
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import im.vector.app.features.analytics.plan.MobileScreen
import io.element.android.anvilannotations.ContributesNode
import io.element.android.libraries.architecture.NodeInputs
@ -24,7 +24,8 @@ import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.services.analytics.api.AnalyticsService
@ContributesNode(RoomScope::class)
class SendLocationNode @AssistedInject constructor(
@Inject
class SendLocationNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
presenterFactory: SendLocationPresenter.Factory,

View file

@ -15,9 +15,9 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.AssistedFactory
import dev.zacsweers.metro.Inject
import im.vector.app.features.analytics.plan.Composer
import io.element.android.features.location.impl.common.MapDefaults
import io.element.android.features.location.impl.common.actions.LocationActions
@ -36,7 +36,8 @@ import io.element.android.libraries.textcomposer.model.MessageComposerMode
import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.coroutines.launch
class SendLocationPresenter @AssistedInject constructor(
@Inject
class SendLocationPresenter(
permissionsPresenterFactory: PermissionsPresenter.Factory,
private val room: JoinedRoom,
@Assisted private val timelineMode: Timeline.Mode,

View file

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

View file

@ -13,8 +13,8 @@ import com.bumble.appyx.core.lifecycle.subscribe
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.Inject
import im.vector.app.features.analytics.plan.MobileScreen
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.location.api.ShowLocationEntryPoint
@ -23,7 +23,8 @@ import io.element.android.libraries.di.RoomScope
import io.element.android.services.analytics.api.AnalyticsService
@ContributesNode(RoomScope::class)
class ShowLocationNode @AssistedInject constructor(
@Inject
class ShowLocationNode(
presenterFactory: ShowLocationPresenter.Factory,
analyticsService: AnalyticsService,
@Assisted buildContext: BuildContext,

View file

@ -14,9 +14,9 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.AssistedFactory
import dev.zacsweers.metro.Inject
import io.element.android.features.location.api.Location
import io.element.android.features.location.impl.common.MapDefaults
import io.element.android.features.location.impl.common.actions.LocationActions
@ -26,7 +26,8 @@ import io.element.android.features.location.impl.common.permissions.PermissionsS
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.meta.BuildMeta
class ShowLocationPresenter @AssistedInject constructor(
@Inject
class ShowLocationPresenter(
permissionsPresenterFactory: PermissionsPresenter.Factory,
private val locationActions: LocationActions,
private val buildMeta: BuildMeta,

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