Save action added to bottom sheet.

This commit is contained in:
onurays 2020-04-17 15:27:42 +03:00
parent ab3cc90ed5
commit 8434f9326e
5 changed files with 103 additions and 1 deletions

View File

@ -29,6 +29,8 @@ import androidx.core.content.FileProvider
import androidx.fragment.app.Fragment
import im.vector.riotx.BuildConfig
import im.vector.riotx.R
import okio.buffer
import okio.sink
import timber.log.Timber
import java.io.File
import java.text.SimpleDateFormat
@ -258,6 +260,58 @@ fun shareMedia(context: Context, file: File, mediaMimeType: String?) {
}
}
fun saveMedia(context: Context, file: File, title: String, mediaMimeType: String?) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val externalContentUri: Uri
val values = ContentValues()
when {
mediaMimeType?.startsWith("image/") == true -> {
externalContentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
values.put(MediaStore.Images.Media.TITLE, title)
values.put(MediaStore.Images.Media.DISPLAY_NAME, title)
values.put(MediaStore.Images.Media.MIME_TYPE, mediaMimeType)
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis())
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis())
}
mediaMimeType?.startsWith("video/") == true -> {
externalContentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
values.put(MediaStore.Video.Media.TITLE, title)
values.put(MediaStore.Video.Media.DISPLAY_NAME, title)
values.put(MediaStore.Video.Media.MIME_TYPE, mediaMimeType)
values.put(MediaStore.Video.Media.DATE_ADDED, System.currentTimeMillis())
values.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis())
}
mediaMimeType?.startsWith("audio/") == true -> {
externalContentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
values.put(MediaStore.Audio.Media.TITLE, title)
values.put(MediaStore.Audio.Media.DISPLAY_NAME, title)
values.put(MediaStore.Audio.Media.MIME_TYPE, mediaMimeType)
values.put(MediaStore.Audio.Media.DATE_ADDED, System.currentTimeMillis())
values.put(MediaStore.Audio.Media.DATE_TAKEN, System.currentTimeMillis())
}
else -> {
externalContentUri = MediaStore.Downloads.EXTERNAL_CONTENT_URI
values.put(MediaStore.Downloads.TITLE, title)
values.put(MediaStore.Downloads.DISPLAY_NAME, title)
values.put(MediaStore.Downloads.MIME_TYPE, mediaMimeType)
values.put(MediaStore.Downloads.DATE_ADDED, System.currentTimeMillis())
values.put(MediaStore.Downloads.DATE_TAKEN, System.currentTimeMillis())
}
}
context.contentResolver.insert(externalContentUri, values)?.let { uri ->
context.contentResolver.openOutputStream(uri)?.use { outputStream ->
outputStream.sink().buffer().write(file.inputStream().use { it.readBytes() })
}
}
} else {
@Suppress("DEPRECATION")
Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE).also { mediaScanIntent ->
mediaScanIntent.data = Uri.fromFile(file)
context.sendBroadcast(mediaScanIntent)
}
}
}
/**
* Open the play store to the provided application Id, default to this app
*/

View File

@ -115,6 +115,7 @@ import im.vector.riotx.core.utils.createUIHandler
import im.vector.riotx.core.utils.getColorFromUserId
import im.vector.riotx.core.utils.jsonViewerStyler
import im.vector.riotx.core.utils.openUrlInExternalBrowser
import im.vector.riotx.core.utils.saveMedia
import im.vector.riotx.core.utils.shareMedia
import im.vector.riotx.core.utils.toast
import im.vector.riotx.features.attachments.AttachmentTypeSelectorView
@ -1153,6 +1154,28 @@ class RoomDetailFragment @Inject constructor(
)
}
private fun onSaveActionClicked(action: EventSharedAction.Save) {
session.downloadFile(
FileService.DownloadMode.FOR_EXTERNAL_SHARE,
action.eventId,
action.messageContent.body,
action.messageContent.getFileUrl(),
action.messageContent.encryptedFileInfo?.toElementToDecrypt(),
object : MatrixCallback<File> {
override fun onSuccess(data: File) {
if (isAdded) {
saveMedia(
context = requireContext(),
file = data,
title = action.messageContent.body,
mediaMimeType = getMimeTypeFromUri(requireContext(), data.toUri())
)
}
}
}
)
}
private fun handleActions(action: EventSharedAction) {
when (action) {
is EventSharedAction.OpenUserProfile -> {
@ -1176,6 +1199,9 @@ class RoomDetailFragment @Inject constructor(
is EventSharedAction.Share -> {
onShareActionClicked(action)
}
is EventSharedAction.Save -> {
onSaveActionClicked(action)
}
is EventSharedAction.ViewEditHistory -> {
onEditedDecorationClicked(action.messageInformationData)
}

View File

@ -50,6 +50,9 @@ sealed class EventSharedAction(@StringRes val titleRes: Int,
data class Share(val eventId: String, val messageContent: MessageWithAttachmentContent) :
EventSharedAction(R.string.share, R.drawable.ic_share)
data class Save(val eventId: String, val messageContent: MessageWithAttachmentContent) :
EventSharedAction(R.string.save, R.drawable.ic_material_save)
data class Resend(val eventId: String) :
EventSharedAction(R.string.global_retry, R.drawable.ic_refresh_cw)

View File

@ -30,11 +30,11 @@ import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.isTextMessage
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.message.MessageContent
import im.vector.matrix.android.api.session.room.model.message.MessageWithAttachmentContent
import im.vector.matrix.android.api.session.room.model.message.MessageFormat
import im.vector.matrix.android.api.session.room.model.message.MessageTextContent
import im.vector.matrix.android.api.session.room.model.message.MessageType
import im.vector.matrix.android.api.session.room.model.message.MessageVerificationRequestContent
import im.vector.matrix.android.api.session.room.model.message.MessageWithAttachmentContent
import im.vector.matrix.android.api.session.room.send.SendState
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent
@ -290,6 +290,10 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted
add(EventSharedAction.Share(timelineEvent.eventId, messageContent))
}
if (canSave(msgType) && messageContent is MessageWithAttachmentContent) {
add(EventSharedAction.Save(timelineEvent.eventId, messageContent))
}
if (timelineEvent.root.sendState == SendState.SENT) {
// TODO Can be redacted
@ -413,4 +417,14 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted
else -> false
}
}
private fun canSave(msgType: String?): Boolean {
return when (msgType) {
MessageType.MSGTYPE_IMAGE,
MessageType.MSGTYPE_AUDIO,
MessageType.MSGTYPE_VIDEO,
MessageType.MSGTYPE_FILE -> true
else -> false
}
}
}

View File

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM12,19c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM15,9L5,9L5,5h10v4z"/>
</vector>