Introduce ShareDataSender so that SharePresenter is not session scoped

Instead of creating a SharePresenter from the graph of another session, the
SharePresenter now gets the client of the selected session from the
MatrixClientProvider and uses an AppScope ShareDataSender to send the data.

To be able to send media from AppScope, MediaSenderRoomFactory is now bound in
AppScope and takes the MatrixClient as a parameter, and a new
MediaOptimizationConfigProviderFactory provides the media optimization config
of any session.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benoit Marty
2026-10-07 10:34:20 +02:00
parent ed2a553736
commit 72e3a7d92b
15 changed files with 436 additions and 264 deletions
@@ -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.libraries.mediaupload.impl
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProvider
import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProviderFactory
import io.element.android.libraries.preferences.api.store.SessionPreferencesStoreFactory
@ContributesBinding(AppScope::class)
class DefaultMediaOptimizationConfigProviderFactory(
private val sessionPreferencesStoreFactory: SessionPreferencesStoreFactory,
private val featureFlagService: FeatureFlagService,
) : MediaOptimizationConfigProviderFactory {
override fun create(client: MatrixClient): MediaOptimizationConfigProvider {
return DefaultMediaOptimizationConfigProvider(
sessionPreferencesStore = sessionPreferencesStoreFactory.get(client.sessionId, client.sessionCoroutineScope),
featureFlagsService = featureFlagService,
)
}
}
@@ -9,12 +9,13 @@
package io.element.android.libraries.mediaupload.impl
import android.net.Uri
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.androidutils.hash.hash
import io.element.android.libraries.core.extensions.flatMap
import io.element.android.libraries.core.extensions.flatMapCatching
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.media.MediaUploadHandler
import io.element.android.libraries.matrix.api.room.CreateTimelineParams
@@ -22,6 +23,7 @@ import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.mediaupload.api.MediaOptimizationConfig
import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProvider
import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProviderFactory
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
import io.element.android.libraries.mediaupload.api.MediaSender
import io.element.android.libraries.mediaupload.api.MediaSenderFactory
@@ -52,19 +54,20 @@ class DefaultMediaSenderFactory(
}
}
@ContributesBinding(SessionScope::class)
@ContributesBinding(AppScope::class)
class DefaultMediaSenderRoomFactory(
private val preProcessor: MediaPreProcessor,
private val mediaOptimizationConfigProvider: MediaOptimizationConfigProvider,
private val mediaOptimizationConfigProviderFactory: MediaOptimizationConfigProviderFactory,
) : MediaSenderRoomFactory {
override fun create(
client: MatrixClient,
room: JoinedRoom,
): MediaSender {
return DefaultMediaSender(
preProcessor = preProcessor,
room = room,
timelineMode = Timeline.Mode.Live,
mediaOptimizationConfigProvider = mediaOptimizationConfigProvider,
mediaOptimizationConfigProvider = mediaOptimizationConfigProviderFactory.create(client),
)
}
}