mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-10-31 08:15:02 +00:00
Move all binding containers to a di package and normalize their method names
Every @BindingContainer now lives in a di subpackage, in a file named after it. Containers that were declared inside a shared file (SimplePlayer.kt, LockScreenConfig.kt, VoiceMessagePresenter.kt, TimelineItemPresenterFactories.kt, MediaItemPresenterFactories.kt) are extracted into their own file. Method names are made consistent too: - @Binds functions are named bind<ConcreteParameterType>, fixing three that named something else (notably RoomAliasResolverBindingContainer, whose provider was still called providesJoinRoomPresenterFactory). - @Provides functions are named after what they provide, and all use the provides prefix rather than a mix of provide and provides. ANDROID_KEYSTORE moves back to the cryptography impl package, next to KeyStoreSecretKeyRepository which uses it; it is not DI specific and would otherwise be unreachable from there. No behaviour change: Metro discovers containers via @ContributesTo and does not care about method names, so the only call site to follow was in DefaultVoiceRecorderTest. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -111,7 +111,7 @@ object AppBindingContainer {
|
||||
|
||||
@Provides
|
||||
@SingleIn(AppScope::class)
|
||||
fun provideSnackbarDispatcher(): SnackbarDispatcher {
|
||||
fun providesSnackbarDispatcher(): SnackbarDispatcher {
|
||||
return SnackbarDispatcher()
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -20,5 +20,5 @@ import io.element.android.libraries.di.SessionScope
|
||||
@BindingContainer
|
||||
interface FtueBindingContainer {
|
||||
@Binds
|
||||
fun bindChooseSelfVerificationMethodPresenter(presenter: ChooseSelfVerificationModePresenter): Presenter<ChooseSelfVerificationModeState>
|
||||
fun bindChooseSelfVerificationModePresenter(presenter: ChooseSelfVerificationModePresenter): Presenter<ChooseSelfVerificationModeState>
|
||||
}
|
||||
|
||||
+2
-2
@@ -31,10 +31,10 @@ interface RoomListBindingContainer {
|
||||
fun bindRoomListPresenter(presenter: RoomListPresenter): Presenter<RoomListState>
|
||||
|
||||
@Binds
|
||||
fun bindSearchPresenter(presenter: RoomListSearchPresenter): Presenter<RoomListSearchState>
|
||||
fun bindRoomListSearchPresenter(presenter: RoomListSearchPresenter): Presenter<RoomListSearchState>
|
||||
|
||||
@Binds
|
||||
fun bindFiltersPresenter(presenter: RoomListFiltersPresenter): Presenter<RoomListFiltersState>
|
||||
fun bindRoomListFiltersPresenter(presenter: RoomListFiltersPresenter): Presenter<RoomListFiltersState>
|
||||
|
||||
@Binds
|
||||
fun bindSpaceFiltersPresenter(presenter: SpaceFiltersPresenter): Presenter<SpaceFiltersState>
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ import io.element.android.libraries.matrix.api.MatrixClient
|
||||
@BindingContainer
|
||||
interface InviteBindingContainer {
|
||||
@Binds
|
||||
fun bindAcceptDeclinePresenter(presenter: AcceptDeclineInvitePresenter): Presenter<AcceptDeclineInviteState>
|
||||
fun bindAcceptDeclineInvitePresenter(presenter: AcceptDeclineInvitePresenter): Presenter<AcceptDeclineInviteState>
|
||||
|
||||
companion object {
|
||||
@Provides
|
||||
|
||||
+3
-2
@@ -6,7 +6,7 @@
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.knockrequests.impl.data
|
||||
package io.element.android.features.knockrequests.impl.data.di
|
||||
|
||||
import dev.zacsweers.metro.BindingContainer
|
||||
import dev.zacsweers.metro.ContributesTo
|
||||
@@ -14,6 +14,7 @@ import dev.zacsweers.metro.Provides
|
||||
import dev.zacsweers.metro.SingleIn
|
||||
import io.element.android.features.knockrequests.api.KnockRequestPermissions
|
||||
import io.element.android.features.knockrequests.api.knockRequestPermissions
|
||||
import io.element.android.features.knockrequests.impl.data.KnockRequestsService
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.permissionsFlow
|
||||
@@ -23,7 +24,7 @@ import io.element.android.libraries.matrix.api.room.powerlevels.permissionsFlow
|
||||
object KnockRequestsBindingContainer {
|
||||
@Provides
|
||||
@SingleIn(RoomScope::class)
|
||||
fun knockRequestsService(room: JoinedRoom): KnockRequestsService {
|
||||
fun providesKnockRequestsService(room: JoinedRoom): KnockRequestsService {
|
||||
return KnockRequestsService(
|
||||
knockRequestsFlow = room.knockRequestsFlow,
|
||||
permissionsFlow = room.permissionsFlow(KnockRequestPermissions.DEFAULT) { perms ->
|
||||
-20
@@ -8,12 +8,7 @@
|
||||
|
||||
package io.element.android.features.lockscreen.impl
|
||||
|
||||
import dev.zacsweers.metro.AppScope
|
||||
import dev.zacsweers.metro.BindingContainer
|
||||
import dev.zacsweers.metro.ContributesTo
|
||||
import dev.zacsweers.metro.Provides
|
||||
import kotlin.time.Duration
|
||||
import io.element.android.appconfig.LockScreenConfig as AppConfigLockScreenConfig
|
||||
|
||||
data class LockScreenConfig(
|
||||
val isPinMandatory: Boolean,
|
||||
@@ -24,18 +19,3 @@ data class LockScreenConfig(
|
||||
val isStrongBiometricsEnabled: Boolean,
|
||||
val isWeakBiometricsEnabled: Boolean,
|
||||
)
|
||||
|
||||
@ContributesTo(AppScope::class)
|
||||
@BindingContainer
|
||||
object LockScreenConfigBindingContainer {
|
||||
@Provides
|
||||
fun providesLockScreenConfig(): LockScreenConfig = LockScreenConfig(
|
||||
isPinMandatory = AppConfigLockScreenConfig.IS_PIN_MANDATORY,
|
||||
forbiddenPinCodes = AppConfigLockScreenConfig.FORBIDDEN_PIN_CODES,
|
||||
pinSize = AppConfigLockScreenConfig.PIN_SIZE,
|
||||
maxPinCodeAttemptsBeforeLogout = AppConfigLockScreenConfig.MAX_PIN_CODE_ATTEMPTS_BEFORE_LOGOUT,
|
||||
gracePeriod = AppConfigLockScreenConfig.GRACE_PERIOD,
|
||||
isStrongBiometricsEnabled = AppConfigLockScreenConfig.IS_STRONG_BIOMETRICS_ENABLED,
|
||||
isWeakBiometricsEnabled = AppConfigLockScreenConfig.IS_WEAK_BIOMETRICS_ENABLED,
|
||||
)
|
||||
}
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Element Creations 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.features.lockscreen.impl.di
|
||||
|
||||
import dev.zacsweers.metro.AppScope
|
||||
import dev.zacsweers.metro.BindingContainer
|
||||
import dev.zacsweers.metro.ContributesTo
|
||||
import dev.zacsweers.metro.Provides
|
||||
import io.element.android.features.lockscreen.impl.LockScreenConfig
|
||||
|
||||
@ContributesTo(AppScope::class)
|
||||
@BindingContainer
|
||||
object LockScreenConfigBindingContainer {
|
||||
@Provides
|
||||
fun providesLockScreenConfig(): LockScreenConfig = LockScreenConfig(
|
||||
isPinMandatory = io.element.android.appconfig.LockScreenConfig.IS_PIN_MANDATORY,
|
||||
forbiddenPinCodes = io.element.android.appconfig.LockScreenConfig.FORBIDDEN_PIN_CODES,
|
||||
pinSize = io.element.android.appconfig.LockScreenConfig.PIN_SIZE,
|
||||
maxPinCodeAttemptsBeforeLogout = io.element.android.appconfig.LockScreenConfig.MAX_PIN_CODE_ATTEMPTS_BEFORE_LOGOUT,
|
||||
gracePeriod = io.element.android.appconfig.LockScreenConfig.GRACE_PERIOD,
|
||||
isStrongBiometricsEnabled = io.element.android.appconfig.LockScreenConfig.IS_STRONG_BIOMETRICS_ENABLED,
|
||||
isWeakBiometricsEnabled = io.element.android.appconfig.LockScreenConfig.IS_WEAK_BIOMETRICS_ENABLED,
|
||||
)
|
||||
}
|
||||
+1
-1
@@ -21,5 +21,5 @@ import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||
object MessagesProvidesBindingContainer {
|
||||
@Provides
|
||||
@LiveTimeline
|
||||
fun provideLiveTimeline(joinedRoom: JoinedRoom): Timeline = joinedRoom.liveTimeline
|
||||
fun providesLiveTimeline(joinedRoom: JoinedRoom): Timeline = joinedRoom.liveTimeline
|
||||
}
|
||||
|
||||
-15
@@ -10,28 +10,13 @@ package io.element.android.features.messages.impl.timeline.di
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import dev.zacsweers.metro.BindingContainer
|
||||
import dev.zacsweers.metro.ContributesTo
|
||||
import dev.zacsweers.metro.Inject
|
||||
import dev.zacsweers.metro.Multibinds
|
||||
import dev.zacsweers.metro.SingleIn
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* Container that declares the [TimelineItemPresenterFactory] map multi binding.
|
||||
*
|
||||
* Its sole purpose is to support the case of an empty map multibinding.
|
||||
*/
|
||||
@BindingContainer
|
||||
@ContributesTo(RoomScope::class)
|
||||
interface TimelineItemPresenterFactoriesBindingContainer {
|
||||
@Multibinds
|
||||
fun multiBindTimelineItemPresenterFactories(): @JvmSuppressWildcards Map<KClass<out TimelineItemEventContent>, TimelineItemPresenterFactory<*, *>>
|
||||
}
|
||||
|
||||
/**
|
||||
* Room level caching layer for the [TimelineItemPresenterFactory] instances.
|
||||
*
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Element Creations 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.features.messages.impl.timeline.di
|
||||
|
||||
import dev.zacsweers.metro.BindingContainer
|
||||
import dev.zacsweers.metro.ContributesTo
|
||||
import dev.zacsweers.metro.Multibinds
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* Container that declares the [TimelineItemPresenterFactory] map multi binding.
|
||||
*
|
||||
* Its sole purpose is to support the case of an empty map multibinding.
|
||||
*/
|
||||
@BindingContainer
|
||||
@ContributesTo(RoomScope::class)
|
||||
interface TimelineItemPresenterFactoriesBindingContainer {
|
||||
@Multibinds
|
||||
fun multiBindTimelineItemPresenterFactories(): @JvmSuppressWildcards Map<KClass<out TimelineItemEventContent>, TimelineItemPresenterFactory<*, *>>
|
||||
}
|
||||
-15
@@ -12,27 +12,12 @@ import androidx.compose.runtime.Composable
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedFactory
|
||||
import dev.zacsweers.metro.AssistedInject
|
||||
import dev.zacsweers.metro.BindingContainer
|
||||
import dev.zacsweers.metro.Binds
|
||||
import dev.zacsweers.metro.ContributesTo
|
||||
import dev.zacsweers.metro.IntoMap
|
||||
import io.element.android.features.messages.impl.timeline.di.TimelineItemEventContentKey
|
||||
import io.element.android.features.messages.impl.timeline.di.TimelineItemPresenterFactory
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContent
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
import io.element.android.libraries.voiceplayer.api.VoiceMessagePresenterFactory
|
||||
import io.element.android.libraries.voiceplayer.api.VoiceMessageState
|
||||
|
||||
@BindingContainer
|
||||
@ContributesTo(RoomScope::class)
|
||||
interface VoiceMessagePresenterBindingContainer {
|
||||
@Binds
|
||||
@IntoMap
|
||||
@TimelineItemEventContentKey(TimelineItemVoiceContent::class)
|
||||
fun bindVoiceMessagePresenterFactory(factory: VoiceMessagePresenter.Factory): TimelineItemPresenterFactory<*, *>
|
||||
}
|
||||
|
||||
@AssistedInject
|
||||
class VoiceMessagePresenter(
|
||||
voiceMessagePresenterFactory: VoiceMessagePresenterFactory,
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Element Creations 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.features.messages.impl.voicemessages.timeline.di
|
||||
|
||||
import dev.zacsweers.metro.BindingContainer
|
||||
import dev.zacsweers.metro.Binds
|
||||
import dev.zacsweers.metro.ContributesTo
|
||||
import dev.zacsweers.metro.IntoMap
|
||||
import io.element.android.features.messages.impl.timeline.di.TimelineItemEventContentKey
|
||||
import io.element.android.features.messages.impl.timeline.di.TimelineItemPresenterFactory
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContent
|
||||
import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessagePresenter
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
|
||||
@BindingContainer
|
||||
@ContributesTo(RoomScope::class)
|
||||
interface VoiceMessagePresenterBindingContainer {
|
||||
@Binds
|
||||
@IntoMap
|
||||
@TimelineItemEventContentKey(TimelineItemVoiceContent::class)
|
||||
fun bindVoiceMessagePresenterFactory(factory: VoiceMessagePresenter.Factory): TimelineItemPresenterFactory<*, *>
|
||||
}
|
||||
+3
-1
@@ -5,11 +5,13 @@
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.preferences.impl.userstatus
|
||||
package io.element.android.features.preferences.impl.userstatus.di
|
||||
|
||||
import dev.zacsweers.metro.BindingContainer
|
||||
import dev.zacsweers.metro.Binds
|
||||
import dev.zacsweers.metro.ContributesTo
|
||||
import io.element.android.features.preferences.impl.userstatus.UserStatusPresenter
|
||||
import io.element.android.features.preferences.impl.userstatus.UserStatusState
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ import io.element.android.libraries.matrix.api.core.RoomAlias
|
||||
@ContributesTo(SessionScope::class)
|
||||
object RoomAliasResolverBindingContainer {
|
||||
@Provides
|
||||
fun providesJoinRoomPresenterFactory(
|
||||
fun providesRoomAliasResolverPresenterFactory(
|
||||
client: MatrixClient,
|
||||
): RoomAliasResolverPresenter.Factory {
|
||||
return object : RoomAliasResolverPresenter.Factory {
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||
@ContributesTo(RoomScope::class)
|
||||
object RoomMemberBindingContainer {
|
||||
@Provides
|
||||
fun provideRoomMemberDetailsPresenterFactory(
|
||||
fun providesRoomMemberDetailsPresenterFactory(
|
||||
room: JoinedRoom,
|
||||
userProfilePresenterFactory: UserProfilePresenterFactory,
|
||||
encryptionService: EncryptionService,
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ import timber.log.Timber
|
||||
object CacheStoreBindingContainer {
|
||||
@Provides
|
||||
@SingleIn(AppScope::class)
|
||||
fun provideCacheDatabase(
|
||||
fun providesCacheDatabase(
|
||||
@ApplicationContext context: Context,
|
||||
): CacheDatabase {
|
||||
val name = "cache_database"
|
||||
|
||||
+2
@@ -26,6 +26,8 @@ import java.util.concurrent.ConcurrentHashMap
|
||||
import javax.crypto.KeyGenerator
|
||||
import javax.crypto.SecretKey
|
||||
|
||||
internal const val ANDROID_KEYSTORE = "AndroidKeyStore"
|
||||
|
||||
/**
|
||||
* Default implementation of [SecretKeyRepository] that uses the Android Keystore to store the keys.
|
||||
* The generated key uses AES algorithm, with a key size of 128 bits, and the GCM block mode.
|
||||
|
||||
+2
-3
@@ -6,16 +6,15 @@
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.cryptography.impl
|
||||
package io.element.android.libraries.cryptography.impl.di
|
||||
|
||||
import dev.zacsweers.metro.AppScope
|
||||
import dev.zacsweers.metro.BindingContainer
|
||||
import dev.zacsweers.metro.ContributesTo
|
||||
import dev.zacsweers.metro.Provides
|
||||
import io.element.android.libraries.cryptography.impl.ANDROID_KEYSTORE
|
||||
import java.security.KeyStore
|
||||
|
||||
internal const val ANDROID_KEYSTORE = "AndroidKeyStore"
|
||||
|
||||
@ContributesTo(AppScope::class)
|
||||
@BindingContainer
|
||||
object CryptographyBindingContainer {
|
||||
+1
-1
@@ -27,5 +27,5 @@ object DateFormatterBindingContainer {
|
||||
fun providesLocale(): Locale = Locale.getDefault()
|
||||
|
||||
@Provides
|
||||
fun providesTimezone(): TimezoneProvider = TimezoneProvider { TimeZone.currentSystemDefault() }
|
||||
fun providesTimezoneProvider(): TimezoneProvider = TimezoneProvider { TimeZone.currentSystemDefault() }
|
||||
}
|
||||
|
||||
+2
-2
@@ -56,7 +56,7 @@ object SessionMatrixBindingContainer {
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun provideRoomMembershipObserver(matrixClient: MatrixClient): RoomMembershipObserver {
|
||||
fun providesRoomMembershipObserver(matrixClient: MatrixClient): RoomMembershipObserver {
|
||||
return matrixClient.roomMembershipObserver
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ object SessionMatrixBindingContainer {
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun providesGetUrlResolverClient(matrixClient: MatrixClient): ClientUrlContentFetcher {
|
||||
fun providesClientUrlContentFetcher(matrixClient: MatrixClient): ClientUrlContentFetcher {
|
||||
return matrixClient
|
||||
}
|
||||
|
||||
|
||||
-17
@@ -8,16 +8,8 @@
|
||||
|
||||
package io.element.android.libraries.mediaplayer.impl
|
||||
|
||||
import android.content.Context
|
||||
import androidx.media3.common.C
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.Player
|
||||
import androidx.media3.exoplayer.ExoPlayer
|
||||
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.annotations.ApplicationContext
|
||||
|
||||
/**
|
||||
* A subset of media3 [Player] that only exposes the few methods we need making it easier to mock.
|
||||
@@ -44,15 +36,6 @@ interface SimplePlayer {
|
||||
}
|
||||
}
|
||||
|
||||
@ContributesTo(RoomScope::class)
|
||||
@BindingContainer
|
||||
object SimplePlayerBindingContainer {
|
||||
@Provides
|
||||
fun simplePlayerProvider(
|
||||
@ApplicationContext context: Context,
|
||||
): SimplePlayer = DefaultSimplePlayer(ExoPlayer.Builder(context).setWakeMode(C.WAKE_MODE_LOCAL).build())
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation of [SimplePlayer] backed by a media3 [Player].
|
||||
*/
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Element Creations 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.libraries.mediaplayer.impl.di
|
||||
|
||||
import android.content.Context
|
||||
import androidx.media3.common.C
|
||||
import androidx.media3.exoplayer.ExoPlayer
|
||||
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.annotations.ApplicationContext
|
||||
import io.element.android.libraries.mediaplayer.impl.DefaultSimplePlayer
|
||||
import io.element.android.libraries.mediaplayer.impl.SimplePlayer
|
||||
|
||||
@ContributesTo(RoomScope::class)
|
||||
@BindingContainer
|
||||
object SimplePlayerBindingContainer {
|
||||
@Provides
|
||||
fun providesSimplePlayer(
|
||||
@ApplicationContext context: Context,
|
||||
): SimplePlayer = DefaultSimplePlayer(ExoPlayer.Builder(context).setWakeMode(C.WAKE_MODE_LOCAL).build())
|
||||
}
|
||||
-15
@@ -10,28 +10,13 @@ package io.element.android.libraries.mediaviewer.impl.gallery.di
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import dev.zacsweers.metro.BindingContainer
|
||||
import dev.zacsweers.metro.ContributesTo
|
||||
import dev.zacsweers.metro.Inject
|
||||
import dev.zacsweers.metro.Multibinds
|
||||
import dev.zacsweers.metro.SingleIn
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
import io.element.android.libraries.mediaviewer.impl.model.MediaItem
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* Container that declares the [MediaItemPresenterFactory] map multi binding.
|
||||
*
|
||||
* Its sole purpose is to support the case of an empty map multibinding.
|
||||
*/
|
||||
@BindingContainer
|
||||
@ContributesTo(RoomScope::class)
|
||||
interface MediaItemPresenterFactoriesBindingContainer {
|
||||
@Multibinds
|
||||
fun multiBindMediaItemPresenterFactories(): @JvmSuppressWildcards Map<KClass<out MediaItem.Event>, MediaItemPresenterFactory<*, *>>
|
||||
}
|
||||
|
||||
/**
|
||||
* Room level caching layer for the [MediaItemPresenterFactory] instances.
|
||||
*
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Element Creations 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.libraries.mediaviewer.impl.gallery.di
|
||||
|
||||
import dev.zacsweers.metro.BindingContainer
|
||||
import dev.zacsweers.metro.ContributesTo
|
||||
import dev.zacsweers.metro.Multibinds
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
import io.element.android.libraries.mediaviewer.impl.model.MediaItem
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* Container that declares the [MediaItemPresenterFactory] map multi binding.
|
||||
*
|
||||
* Its sole purpose is to support the case of an empty map multibinding.
|
||||
*/
|
||||
@BindingContainer
|
||||
@ContributesTo(RoomScope::class)
|
||||
interface MediaItemPresenterFactoriesBindingContainer {
|
||||
@Multibinds
|
||||
fun multiBindMediaItemPresenterFactories(): @JvmSuppressWildcards Map<KClass<out MediaItem.Event>, MediaItemPresenterFactory<*, *>>
|
||||
}
|
||||
-15
@@ -12,28 +12,13 @@ import androidx.compose.runtime.Composable
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedFactory
|
||||
import dev.zacsweers.metro.AssistedInject
|
||||
import dev.zacsweers.metro.BindingContainer
|
||||
import dev.zacsweers.metro.Binds
|
||||
import dev.zacsweers.metro.ContributesTo
|
||||
import dev.zacsweers.metro.IntoMap
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
import io.element.android.libraries.mediaviewer.impl.gallery.di.MediaItemEventContentKey
|
||||
import io.element.android.libraries.mediaviewer.impl.gallery.di.MediaItemPresenterFactory
|
||||
import io.element.android.libraries.mediaviewer.impl.model.MediaItem
|
||||
import io.element.android.libraries.voiceplayer.api.VoiceMessagePresenterFactory
|
||||
import io.element.android.libraries.voiceplayer.api.VoiceMessageState
|
||||
import kotlin.time.Duration
|
||||
|
||||
@BindingContainer
|
||||
@ContributesTo(RoomScope::class)
|
||||
interface VoiceMessagePresenterBindingContainer {
|
||||
@Binds
|
||||
@IntoMap
|
||||
@MediaItemEventContentKey(MediaItem.Voice::class)
|
||||
fun bindVoiceMessagePresenterFactory(factory: VoiceMessagePresenter.Factory): MediaItemPresenterFactory<*, *>
|
||||
}
|
||||
|
||||
@AssistedInject
|
||||
class VoiceMessagePresenter(
|
||||
voiceMessagePresenterFactory: VoiceMessagePresenterFactory,
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Element Creations 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.libraries.mediaviewer.impl.gallery.voice.di
|
||||
|
||||
import dev.zacsweers.metro.BindingContainer
|
||||
import dev.zacsweers.metro.Binds
|
||||
import dev.zacsweers.metro.ContributesTo
|
||||
import dev.zacsweers.metro.IntoMap
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
import io.element.android.libraries.mediaviewer.impl.gallery.di.MediaItemEventContentKey
|
||||
import io.element.android.libraries.mediaviewer.impl.gallery.di.MediaItemPresenterFactory
|
||||
import io.element.android.libraries.mediaviewer.impl.gallery.voice.VoiceMessagePresenter
|
||||
import io.element.android.libraries.mediaviewer.impl.model.MediaItem
|
||||
|
||||
@BindingContainer
|
||||
@ContributesTo(RoomScope::class)
|
||||
interface VoiceMessagePresenterBindingContainer {
|
||||
@Binds
|
||||
@IntoMap
|
||||
@MediaItemEventContentKey(MediaItem.Voice::class)
|
||||
fun bindVoiceMessagePresenterFactory(factory: VoiceMessagePresenter.Factory): MediaItemPresenterFactory<*, *>
|
||||
}
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.network
|
||||
package io.element.android.libraries.network.di
|
||||
|
||||
import dev.zacsweers.metro.AppScope
|
||||
import dev.zacsweers.metro.BindingContainer
|
||||
+2
-1
@@ -6,7 +6,7 @@
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.preferences.impl.store
|
||||
package io.element.android.libraries.preferences.impl.store.di
|
||||
|
||||
import dev.zacsweers.metro.BindingContainer
|
||||
import dev.zacsweers.metro.ContributesTo
|
||||
@@ -15,6 +15,7 @@ import io.element.android.libraries.di.SessionScope
|
||||
import io.element.android.libraries.di.annotations.SessionCoroutineScope
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
import io.element.android.libraries.preferences.api.store.SessionPreferencesStore
|
||||
import io.element.android.libraries.preferences.impl.store.DefaultSessionPreferencesStoreFactory
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
@BindingContainer
|
||||
+1
-1
@@ -25,7 +25,7 @@ import io.element.android.libraries.push.impl.battery.BatteryOptimizationPresent
|
||||
interface PushBindingContainer {
|
||||
companion object {
|
||||
@Provides
|
||||
fun provideNotificationCompatManager(@ApplicationContext context: Context): NotificationManagerCompat {
|
||||
fun providesNotificationManagerCompat(@ApplicationContext context: Context): NotificationManagerCompat {
|
||||
return NotificationManagerCompat.from(context)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ import timber.log.Timber
|
||||
object PushHistoryBindingContainer {
|
||||
@Provides
|
||||
@SingleIn(AppScope::class)
|
||||
fun providePushDatabase(
|
||||
fun providesPushDatabase(
|
||||
@ApplicationContext context: Context,
|
||||
): PushDatabase {
|
||||
val name = "push_database"
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ import timber.log.Timber
|
||||
object SessionStorageBindingContainer {
|
||||
@Provides
|
||||
@SingleIn(AppScope::class)
|
||||
fun provideMatrixDatabase(
|
||||
fun providesSessionDatabase(
|
||||
@ApplicationContext context: Context,
|
||||
): SessionDatabase {
|
||||
val name = "session_database"
|
||||
|
||||
+3
-3
@@ -24,7 +24,7 @@ import io.element.android.opusencoder.OggOpusEncoder
|
||||
@ContributesTo(RoomScope::class)
|
||||
object VoiceRecorderBindingContainer {
|
||||
@Provides
|
||||
fun provideAudioConfig(): AudioConfig {
|
||||
fun providesAudioConfig(): AudioConfig {
|
||||
val sampleRate = SampleRate
|
||||
return AudioConfig(
|
||||
format = AudioFormat.Builder()
|
||||
@@ -40,7 +40,7 @@ object VoiceRecorderBindingContainer {
|
||||
}
|
||||
|
||||
@Provides
|
||||
public fun provideVoiceFileConfig(): VoiceFileConfig =
|
||||
public fun providesVoiceFileConfig(): VoiceFileConfig =
|
||||
VoiceFileConfig(
|
||||
cacheSubdir = "voice_recordings",
|
||||
fileExt = "ogg",
|
||||
@@ -48,5 +48,5 @@ object VoiceRecorderBindingContainer {
|
||||
)
|
||||
|
||||
@Provides
|
||||
fun provideOggOpusEncoder(): OggOpusEncoder = OggOpusEncoder.create()
|
||||
fun providesOggOpusEncoder(): OggOpusEncoder = OggOpusEncoder.create()
|
||||
}
|
||||
|
||||
+1
-1
@@ -151,7 +151,7 @@ class DefaultVoiceRecorderTest {
|
||||
}
|
||||
|
||||
private fun TestScope.createDefaultVoiceRecorder(): DefaultVoiceRecorder {
|
||||
val fileConfig = VoiceRecorderBindingContainer.provideVoiceFileConfig()
|
||||
val fileConfig = VoiceRecorderBindingContainer.providesVoiceFileConfig()
|
||||
return DefaultVoiceRecorder(
|
||||
dispatchers = testCoroutineDispatchers(),
|
||||
timeSource = timeSource,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.workmanager.impl
|
||||
package io.element.android.libraries.workmanager.impl.di
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.WorkManager
|
||||
+1
-1
@@ -17,5 +17,5 @@ import io.element.android.libraries.di.identifiers.SentrySdkDsn
|
||||
@ContributesTo(AppScope::class)
|
||||
object NoopAnalyticsBindingContainer {
|
||||
@Provides
|
||||
fun provideSentrySdkDsn(): SentrySdkDsn? = null
|
||||
fun providesSentrySdkDsn(): SentrySdkDsn? = null
|
||||
}
|
||||
|
||||
+2
-2
@@ -19,8 +19,8 @@ import io.element.android.services.analyticsproviders.sentry.SentryConfig
|
||||
@ContributesTo(AppScope::class)
|
||||
object SentryBindingContainer {
|
||||
@Provides
|
||||
fun provideSentryDsn(): SentryDsn? = SentryConfig.DSN.takeIf { it.isNotBlank() }?.let(::SentryDsn)
|
||||
fun providesSentryDsn(): SentryDsn? = SentryConfig.DSN.takeIf { it.isNotBlank() }?.let(::SentryDsn)
|
||||
|
||||
@Provides
|
||||
fun provideSentrySdkDsn(): SentrySdkDsn? = SentryConfig.SDK_DSN.takeIf { it.isNotBlank() }?.let(::SentrySdkDsn)
|
||||
fun providesSentrySdkDsn(): SentrySdkDsn? = SentryConfig.SDK_DSN.takeIf { it.isNotBlank() }?.let(::SentrySdkDsn)
|
||||
}
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ import io.element.android.services.appnavstate.impl.initializer.AppForegroundSta
|
||||
@ContributesTo(AppScope::class)
|
||||
object AppNavStateBindingContainer {
|
||||
@Provides
|
||||
fun provideAppForegroundStateService(
|
||||
fun providesAppForegroundStateService(
|
||||
@ApplicationContext context: Context
|
||||
): AppForegroundStateService =
|
||||
AppInitializer.getInstance(context).initializeComponent(AppForegroundStateServiceInitializer::class.java)
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.services.toolbox.impl.systemclock
|
||||
package io.element.android.services.toolbox.impl.systemclock.di
|
||||
|
||||
import dev.zacsweers.metro.AppScope
|
||||
import dev.zacsweers.metro.BindingContainer
|
||||
@@ -18,7 +18,7 @@ import kotlin.time.TimeSource
|
||||
@ContributesTo(AppScope::class)
|
||||
object TimeBindingContainer {
|
||||
@Provides
|
||||
fun timeSource(): TimeSource {
|
||||
fun providesTimeSource(): TimeSource {
|
||||
return TimeSource.Monotonic
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user