MediaViewer: improve actions (save on disk and share)

This commit is contained in:
ganfra 2023-06-02 20:13:17 +02:00
parent 89d4b81f80
commit fa63ed1faf
7 changed files with 22 additions and 15 deletions

View file

@ -17,6 +17,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<!-- To be able to install APK from the application -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<application <application
android:name=".ElementXApplication" android:name=".ElementXApplication"
android:allowBackup="true" android:allowBackup="true"

View file

@ -113,16 +113,9 @@ class AndroidLocalMediaActions @Inject constructor(
} }
/** /**
* Tries to extract a file from the uri and rename it using the local media name if defined. * Tries to extract a file from the uri.
*/ */
private fun LocalMedia.toFile(): File { private fun LocalMedia.toFile(): File {
val uriAsFile = uri.toFile() return uri.toFile()
return if (name != null) {
File(uriAsFile.parentFile, name).apply {
uriAsFile.renameTo(this)
}
} else {
uriAsFile
}
} }
} }

View file

@ -94,7 +94,11 @@ class MediaViewerPresenter @AssistedInject constructor(
private fun CoroutineScope.downloadMedia(mediaFile: MutableState<MediaFile?>, localMedia: MutableState<Async<LocalMedia>>) = launch { private fun CoroutineScope.downloadMedia(mediaFile: MutableState<MediaFile?>, localMedia: MutableState<Async<LocalMedia>>) = launch {
localMedia.value = Async.Loading() localMedia.value = Async.Loading()
mediaLoader.downloadMediaFile(inputs.mediaSource, inputs.mimeType) mediaLoader.downloadMediaFile(
source = inputs.mediaSource,
mimeType = inputs.mimeType,
body = inputs.name
)
.onSuccess { .onSuccess {
mediaFile.value = it mediaFile.value = it
}.mapCatching { mediaFile -> }.mapCatching { mediaFile ->

View file

@ -104,7 +104,11 @@ fun MediaViewerView(
Scaffold(modifier, Scaffold(modifier,
topBar = { topBar = {
MediaViewerTopBar(onBackPressed, state.eventSink) MediaViewerTopBar(
actionsEnabled = state.downloadedMedia is Async.Success,
onBackPressed = onBackPressed,
eventSink = state.eventSink
)
}, },
snackbarHost = { snackbarHost = {
SnackbarHost(snackbarHostState) { data -> SnackbarHost(snackbarHostState) { data ->
@ -145,6 +149,7 @@ fun MediaViewerView(
@Composable @Composable
private fun MediaViewerTopBar( private fun MediaViewerTopBar(
actionsEnabled : Boolean,
onBackPressed: () -> Unit, onBackPressed: () -> Unit,
eventSink: (MediaViewerEvents) -> Unit, eventSink: (MediaViewerEvents) -> Unit,
) { ) {
@ -153,6 +158,7 @@ private fun MediaViewerTopBar(
navigationIcon = { BackButton(onClick = onBackPressed) }, navigationIcon = { BackButton(onClick = onBackPressed) },
actions = { actions = {
IconButton( IconButton(
enabled = actionsEnabled,
onClick = { onClick = {
eventSink(MediaViewerEvents.Share) eventSink(MediaViewerEvents.Share)
}, },
@ -160,6 +166,7 @@ private fun MediaViewerTopBar(
Icon(imageVector = Icons.Default.Share, contentDescription = stringResource(id = string.action_share)) Icon(imageVector = Icons.Default.Share, contentDescription = stringResource(id = string.action_share))
} }
IconButton( IconButton(
enabled = actionsEnabled,
onClick = { onClick = {
eventSink(MediaViewerEvents.SaveOnDisk) eventSink(MediaViewerEvents.SaveOnDisk)
}, },

View file

@ -36,5 +36,5 @@ interface MatrixMediaLoader {
* @param mimeType: optional mime type * @param mimeType: optional mime type
* @return a [Result] of [MediaFile] * @return a [Result] of [MediaFile]
*/ */
suspend fun downloadMediaFile(source: MediaSource, mimeType: String?): Result<MediaFile> suspend fun downloadMediaFile(source: MediaSource, mimeType: String?, body: String?): Result<MediaFile>
} }

View file

@ -59,13 +59,13 @@ class RustMediaLoader(
} }
} }
override suspend fun downloadMediaFile(source: MediaSource, mimeType: String?): Result<MediaFile> = override suspend fun downloadMediaFile(source: MediaSource, mimeType: String?, body: String?): Result<MediaFile> =
withContext(dispatchers.io) { withContext(dispatchers.io) {
runCatching { runCatching {
source.toRustMediaSource().use { mediaSource -> source.toRustMediaSource().use { mediaSource ->
val mediaFile = innerClient.getMediaFile( val mediaFile = innerClient.getMediaFile(
mediaSource = mediaSource, mediaSource = mediaSource,
body = null, body = body,
mimeType = mimeType ?: "application/octet-stream" mimeType = mimeType ?: "application/octet-stream"
) )
RustMediaFile(mediaFile) RustMediaFile(mediaFile)

View file

@ -44,7 +44,7 @@ class FakeMediaLoader : MatrixMediaLoader {
} }
} }
override suspend fun downloadMediaFile(source: MediaSource, mimeType: String?): Result<MediaFile> { override suspend fun downloadMediaFile(source: MediaSource, mimeType: String?, body: String?): Result<MediaFile> {
delay(FAKE_DELAY_IN_MS) delay(FAKE_DELAY_IN_MS)
return if (shouldFail) { return if (shouldFail) {
Result.failure(RuntimeException()) Result.failure(RuntimeException())