Merge pull request #2133 from davotoula/fix-image-sharing-error
Fix image sharing error
This commit is contained in:
@@ -85,11 +85,11 @@ object ShareHelper {
|
|||||||
} ?: throw IOException("Unable to open snapshot for: $imageUrl")
|
} ?: throw IOException("Unable to open snapshot for: $imageUrl")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getImageExtension(file: File): String = getMediaExtension(file, isVideo = false)
|
internal fun getImageExtension(file: File): String = getMediaExtension(file, isVideo = false)
|
||||||
|
|
||||||
private fun getVideoExtension(file: File): String = getMediaExtension(file, isVideo = true)
|
internal fun getVideoExtension(file: File): String = getMediaExtension(file, isVideo = true)
|
||||||
|
|
||||||
private fun getMediaExtension(
|
internal fun getMediaExtension(
|
||||||
file: File,
|
file: File,
|
||||||
isVideo: Boolean,
|
isVideo: Boolean,
|
||||||
): String {
|
): String {
|
||||||
|
|||||||
+4
-5
@@ -762,8 +762,6 @@ fun ShareMediaAction(
|
|||||||
content: BaseMediaContent? = null,
|
content: BaseMediaContent? = null,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
) {
|
) {
|
||||||
val scope = accountViewModel.viewModelScope
|
|
||||||
|
|
||||||
// Track if video is downloading - hoisted here to block menu dismiss during download
|
// Track if video is downloading - hoisted here to block menu dismiss during download
|
||||||
val isDownloadingVideo = remember { mutableStateOf(false) }
|
val isDownloadingVideo = remember { mutableStateOf(false) }
|
||||||
|
|
||||||
@@ -817,7 +815,7 @@ fun ShareMediaAction(
|
|||||||
videoUri?.let {
|
videoUri?.let {
|
||||||
if (videoUri.isNotEmpty()) {
|
if (videoUri.isNotEmpty()) {
|
||||||
M3ActionRow(icon = Icons.Outlined.Share, text = stringRes(R.string.share_image)) {
|
M3ActionRow(icon = Icons.Outlined.Share, text = stringRes(R.string.share_image)) {
|
||||||
scope.launch { shareImageFile(context, videoUri, mimeType) }
|
accountViewModel.viewModelScope.launch { shareImageFile(context, videoUri, mimeType) }
|
||||||
onDismiss()
|
onDismiss()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -834,7 +832,7 @@ fun ShareMediaAction(
|
|||||||
) {
|
) {
|
||||||
isDownloadingVideo.value = true
|
isDownloadingVideo.value = true
|
||||||
accountViewModel.toastManager.toast(R.string.share_video, R.string.downloading_video_for_sharing)
|
accountViewModel.toastManager.toast(R.string.share_video, R.string.downloading_video_for_sharing)
|
||||||
scope.launch {
|
accountViewModel.viewModelScope.launch {
|
||||||
shareVideoFile(
|
shareVideoFile(
|
||||||
context = context,
|
context = context,
|
||||||
videoUrl = videoUri,
|
videoUrl = videoUri,
|
||||||
@@ -859,7 +857,7 @@ fun ShareMediaAction(
|
|||||||
is MediaLocalVideo -> {
|
is MediaLocalVideo -> {
|
||||||
content.localFile?.let { localFile ->
|
content.localFile?.let { localFile ->
|
||||||
M3ActionRow(icon = Icons.Outlined.Share, text = stringRes(R.string.share_video)) {
|
M3ActionRow(icon = Icons.Outlined.Share, text = stringRes(R.string.share_video)) {
|
||||||
scope.launch { shareLocalVideoFile(context, localFile, mimeType) }
|
accountViewModel.viewModelScope.launch { shareLocalVideoFile(context, localFile, mimeType) }
|
||||||
onDismiss()
|
onDismiss()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -895,6 +893,7 @@ private suspend fun shareImageFile(
|
|||||||
|
|
||||||
context.startActivity(Intent.createChooser(shareIntent, null))
|
context.startActivity(Intent.createChooser(shareIntent, null))
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
if (e is CancellationException) throw e
|
||||||
Log.w("ZoomableContentView", "Failed to share image: $videoUri", e)
|
Log.w("ZoomableContentView", "Failed to share image: $videoUri", e)
|
||||||
Toast.makeText(context, context.getString(R.string.unable_to_share_image), Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, context.getString(R.string.unable_to_share_image), Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,4 +49,118 @@ class ShareHelperTest {
|
|||||||
targetFile.delete()
|
targetFile.delete()
|
||||||
tempDir.delete()
|
tempDir.delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getImageExtension_jpeg() {
|
||||||
|
val file = createTempFileWithBytes(byteArrayOf(0xFF.toByte(), 0xD8.toByte(), 0x00, 0x00))
|
||||||
|
assertEquals("jpg", ShareHelper.getImageExtension(file))
|
||||||
|
file.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getImageExtension_png() {
|
||||||
|
val file = createTempFileWithBytes(byteArrayOf(0x89.toByte(), 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A))
|
||||||
|
assertEquals("png", ShareHelper.getImageExtension(file))
|
||||||
|
file.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getImageExtension_gif() {
|
||||||
|
val file = createTempFileWithBytes("GIF89a".toByteArray())
|
||||||
|
assertEquals("gif", ShareHelper.getImageExtension(file))
|
||||||
|
file.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getImageExtension_webp() {
|
||||||
|
// RIFF....WEBP
|
||||||
|
val header = ByteArray(12)
|
||||||
|
"RIFF".toByteArray().copyInto(header, 0)
|
||||||
|
"WEBP".toByteArray().copyInto(header, 8)
|
||||||
|
val file = createTempFileWithBytes(header)
|
||||||
|
assertEquals("webp", ShareHelper.getImageExtension(file))
|
||||||
|
file.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getImageExtension_unknownDefaultsToJpg() {
|
||||||
|
val file = createTempFileWithBytes(byteArrayOf(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07))
|
||||||
|
assertEquals("jpg", ShareHelper.getImageExtension(file))
|
||||||
|
file.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getImageExtension_tooShortDefaultsToJpg() {
|
||||||
|
val file = createTempFileWithBytes(byteArrayOf(0x00, 0x01))
|
||||||
|
assertEquals("jpg", ShareHelper.getImageExtension(file))
|
||||||
|
file.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getVideoExtension_webm() {
|
||||||
|
val file = createTempFileWithBytes(byteArrayOf(0x1A, 0x45, 0xDF.toByte(), 0xA3.toByte(), 0x00, 0x00))
|
||||||
|
assertEquals("webm", ShareHelper.getVideoExtension(file))
|
||||||
|
file.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getVideoExtension_avi() {
|
||||||
|
// RIFF....AVI
|
||||||
|
val header = ByteArray(12)
|
||||||
|
"RIFF".toByteArray().copyInto(header, 0)
|
||||||
|
"AVI ".toByteArray().copyInto(header, 8)
|
||||||
|
val file = createTempFileWithBytes(header)
|
||||||
|
assertEquals("avi", ShareHelper.getVideoExtension(file))
|
||||||
|
file.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getVideoExtension_mp4Isom() {
|
||||||
|
// ....ftypisom
|
||||||
|
val header = ByteArray(12)
|
||||||
|
"ftyp".toByteArray().copyInto(header, 4)
|
||||||
|
"isom".toByteArray().copyInto(header, 8)
|
||||||
|
val file = createTempFileWithBytes(header)
|
||||||
|
assertEquals("mp4", ShareHelper.getVideoExtension(file))
|
||||||
|
file.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getVideoExtension_mov() {
|
||||||
|
// ....ftypqt__
|
||||||
|
val header = ByteArray(12)
|
||||||
|
"ftyp".toByteArray().copyInto(header, 4)
|
||||||
|
"qt ".toByteArray().copyInto(header, 8)
|
||||||
|
val file = createTempFileWithBytes(header)
|
||||||
|
assertEquals("mov", ShareHelper.getVideoExtension(file))
|
||||||
|
file.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getVideoExtension_unknownDefaultsToMp4() {
|
||||||
|
val file = createTempFileWithBytes(byteArrayOf(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07))
|
||||||
|
assertEquals("mp4", ShareHelper.getVideoExtension(file))
|
||||||
|
file.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getMediaExtension_emptyFileDefaultsToImage() {
|
||||||
|
val file = createTempFileWithBytes(byteArrayOf())
|
||||||
|
assertEquals("jpg", ShareHelper.getMediaExtension(file, isVideo = false))
|
||||||
|
file.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getMediaExtension_emptyFileDefaultsToVideo() {
|
||||||
|
val file = createTempFileWithBytes(byteArrayOf())
|
||||||
|
assertEquals("mp4", ShareHelper.getMediaExtension(file, isVideo = true))
|
||||||
|
file.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createTempFileWithBytes(bytes: ByteArray): File {
|
||||||
|
val file = File.createTempFile("sharehelpertest", ".tmp")
|
||||||
|
file.deleteOnExit()
|
||||||
|
file.writeBytes(bytes)
|
||||||
|
return file
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user