Media: rework how we get the activity context (and fix test compilation)
This commit is contained in:
parent
be009baed7
commit
092e1544ca
6 changed files with 90 additions and 24 deletions
|
|
@ -25,6 +25,9 @@ import android.os.Build
|
|||
import android.os.Environment
|
||||
import android.provider.MediaStore
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.core.net.toFile
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
|
|
@ -46,6 +49,19 @@ class AndroidLocalMediaActions @Inject constructor(
|
|||
private val buildMeta: BuildMeta,
|
||||
) : LocalMediaActions {
|
||||
|
||||
private var activityContext: Context? = null
|
||||
|
||||
@Composable
|
||||
override fun Configure() {
|
||||
val context = LocalContext.current
|
||||
return DisposableEffect(Unit) {
|
||||
activityContext = context
|
||||
onDispose {
|
||||
activityContext = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun saveOnDisk(localMedia: LocalMedia): Result<Unit> = withContext(coroutineDispatchers.io) {
|
||||
require(localMedia.uri.scheme == ContentResolver.SCHEME_FILE)
|
||||
runCatching {
|
||||
|
|
@ -61,7 +77,7 @@ class AndroidLocalMediaActions @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun share(activityContext: Context, localMedia: LocalMedia): Result<Unit> = withContext(coroutineDispatchers.io) {
|
||||
override suspend fun share(localMedia: LocalMedia): Result<Unit> = withContext(coroutineDispatchers.io) {
|
||||
require(localMedia.uri.scheme == ContentResolver.SCHEME_FILE)
|
||||
runCatching {
|
||||
val shareableUri = localMedia.toShareableUri()
|
||||
|
|
@ -71,7 +87,7 @@ class AndroidLocalMediaActions @Inject constructor(
|
|||
.setTypeAndNormalize(localMedia.info.mimeType)
|
||||
withContext(coroutineDispatchers.main) {
|
||||
val intent = Intent.createChooser(shareMediaIntent, null)
|
||||
activityContext.startActivity(intent)
|
||||
activityContext!!.startActivity(intent)
|
||||
}
|
||||
}.onSuccess {
|
||||
Timber.v("Share media succeed")
|
||||
|
|
@ -80,14 +96,14 @@ class AndroidLocalMediaActions @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun open(activityContext: Context, localMedia: LocalMedia): Result<Unit> = withContext(coroutineDispatchers.io) {
|
||||
override suspend fun open(localMedia: LocalMedia): Result<Unit> = withContext(coroutineDispatchers.io) {
|
||||
require(localMedia.uri.scheme == ContentResolver.SCHEME_FILE)
|
||||
runCatching {
|
||||
val openMediaIntent = Intent(Intent.ACTION_VIEW)
|
||||
.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
.setDataAndType(localMedia.toShareableUri(), localMedia.info.mimeType)
|
||||
withContext(coroutineDispatchers.main) {
|
||||
activityContext.startActivity(openMediaIntent)
|
||||
activityContext!!.startActivity(openMediaIntent)
|
||||
}
|
||||
}.onSuccess {
|
||||
Timber.v("Open media succeed")
|
||||
|
|
|
|||
|
|
@ -16,9 +16,13 @@
|
|||
|
||||
package io.element.android.features.messages.impl.media.local
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.runtime.Composable
|
||||
|
||||
interface LocalMediaActions {
|
||||
|
||||
@Composable
|
||||
fun Configure()
|
||||
|
||||
/**
|
||||
* Will save the current media to the Downloads directory.
|
||||
* The [LocalMedia.uri] needs to have a file scheme.
|
||||
|
|
@ -29,12 +33,12 @@ interface LocalMediaActions {
|
|||
* Will try to find a suitable application to share the media with.
|
||||
* The [LocalMedia.uri] needs to have a file scheme.
|
||||
*/
|
||||
suspend fun share(activityContext: Context, localMedia: LocalMedia): Result<Unit>
|
||||
suspend fun share(localMedia: LocalMedia): Result<Unit>
|
||||
|
||||
/**
|
||||
* Will try to find a suitable application to open the media with.
|
||||
* The [LocalMedia.uri] needs to have a file scheme.
|
||||
*/
|
||||
suspend fun open(activityContext: Context, localMedia: LocalMedia): Result<Unit>
|
||||
suspend fun open(localMedia: LocalMedia): Result<Unit>
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
package io.element.android.features.messages.impl.media.viewer
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.MutableState
|
||||
|
|
@ -26,7 +25,6 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
|
@ -50,7 +48,7 @@ class MediaViewerPresenter @AssistedInject constructor(
|
|||
@Assisted private val inputs: MediaViewerNode.Inputs,
|
||||
private val localMediaFactory: LocalMediaFactory,
|
||||
private val mediaLoader: MatrixMediaLoader,
|
||||
private val mediaActionsHandler: LocalMediaActions,
|
||||
private val localMediaActions: LocalMediaActions,
|
||||
private val snackbarDispatcher: SnackbarDispatcher,
|
||||
) : Presenter<MediaViewerState> {
|
||||
|
||||
|
|
@ -69,8 +67,8 @@ class MediaViewerPresenter @AssistedInject constructor(
|
|||
val localMedia: MutableState<Async<LocalMedia>> = remember {
|
||||
mutableStateOf(Async.Uninitialized)
|
||||
}
|
||||
val context = LocalContext.current
|
||||
val snackbarMessage = handleSnackbarMessage(snackbarDispatcher)
|
||||
localMediaActions.Configure()
|
||||
DisposableEffect(loadMediaTrigger) {
|
||||
coroutineScope.downloadMedia(mediaFile, localMedia)
|
||||
onDispose {
|
||||
|
|
@ -83,8 +81,8 @@ class MediaViewerPresenter @AssistedInject constructor(
|
|||
MediaViewerEvents.RetryLoading -> loadMediaTrigger++
|
||||
MediaViewerEvents.ClearLoadingError -> localMedia.value = Async.Uninitialized
|
||||
MediaViewerEvents.SaveOnDisk -> coroutineScope.saveOnDisk(localMedia.value)
|
||||
MediaViewerEvents.Share -> coroutineScope.share(context, localMedia.value)
|
||||
MediaViewerEvents.OpenWith -> coroutineScope.open(context, localMedia.value)
|
||||
MediaViewerEvents.Share -> coroutineScope.share(localMedia.value)
|
||||
MediaViewerEvents.OpenWith -> coroutineScope.open(localMedia.value)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -121,7 +119,7 @@ class MediaViewerPresenter @AssistedInject constructor(
|
|||
private fun CoroutineScope.saveOnDisk(localMedia: Async<LocalMedia>) = launch {
|
||||
when (localMedia) {
|
||||
is Async.Success -> {
|
||||
mediaActionsHandler.saveOnDisk(localMedia.state)
|
||||
localMediaActions.saveOnDisk(localMedia.state)
|
||||
.onSuccess {
|
||||
val snackbarMessage = SnackbarMessage(StringR.string.common_file_saved_on_disk_android)
|
||||
snackbarDispatcher.post(snackbarMessage)
|
||||
|
|
@ -131,10 +129,10 @@ class MediaViewerPresenter @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun CoroutineScope.share(activityContext: Context, localMedia: Async<LocalMedia>) = launch {
|
||||
private fun CoroutineScope.share(localMedia: Async<LocalMedia>) = launch {
|
||||
when (localMedia) {
|
||||
is Async.Success -> {
|
||||
mediaActionsHandler.share(activityContext, localMedia.state)
|
||||
localMediaActions.share(localMedia.state)
|
||||
.onFailure {
|
||||
val snackbarMessage = SnackbarMessage(openShareError(it))
|
||||
snackbarDispatcher.post(snackbarMessage)
|
||||
|
|
@ -144,10 +142,10 @@ class MediaViewerPresenter @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun CoroutineScope.open(activityContext: Context, localMedia: Async<LocalMedia>) = launch {
|
||||
private fun CoroutineScope.open(localMedia: Async<LocalMedia>) = launch {
|
||||
when (localMedia) {
|
||||
is Async.Success -> {
|
||||
mediaActionsHandler.open(activityContext, localMedia.state)
|
||||
localMediaActions.open(localMedia.state)
|
||||
.onFailure {
|
||||
val snackbarMessage = SnackbarMessage(openShareError(it))
|
||||
snackbarDispatcher.post(snackbarMessage)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue