mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-09-25 06:55:57 +00:00
ui: send dropped .webm as video only when it has a video track (#7354)
* ui: send dropped .webm as video only when it has a video track .webm is as commonly an audio-only container as a video one, so the extension alone cannot tell whether there is a frame to embed. Read the container to decide: files with a video track are sent as video, the rest as files. Only done for files attached without the user saying how to send them (drag & drop, paste). An explicitly picked video is still sent as one, so .webm is now listed in the video file picker too. * plan: send dropped .webm as video only when it has a video track
This commit is contained in:
+20
-2
@@ -285,7 +285,22 @@ expect fun AttachmentSelection(
|
||||
)
|
||||
|
||||
fun MutableState<ComposeState>.onFilesAttached(uris: List<URI>) {
|
||||
val groups = uris.groupBy { isImage(it) || isVideoUri(it) }
|
||||
// The extension is enough to classify every format except .webm, which is just as commonly an
|
||||
// audio-only container as a video one. An audio-only file has no frame to embed and is sent as a file,
|
||||
// but that can only be told from the content, so reading it is deferred to a background thread.
|
||||
// Only done here, where files arrive without the user saying how to send them (drag & drop, paste) -
|
||||
// an explicitly picked video is still sent as one.
|
||||
if (uris.none { isWebmUri(it) }) {
|
||||
attachFiles(uris, emptySet())
|
||||
} else {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
attachFiles(uris, uris.filter { isWebmUri(it) && hasVideoTrack(it) }.toSet())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableState<ComposeState>.attachFiles(uris: List<URI>, webmVideos: Set<URI>) {
|
||||
val groups = uris.groupBy { isImage(it) || (isVideoUri(it) && (!isWebmUri(it) || it in webmVideos)) }
|
||||
val media = groups[true] ?: emptyList()
|
||||
val files = groups[false] ?: emptyList()
|
||||
if (media.isNotEmpty()) {
|
||||
@@ -298,9 +313,12 @@ fun MutableState<ComposeState>.onFilesAttached(uris: List<URI>) {
|
||||
private fun isVideoUri(uri: URI): Boolean {
|
||||
val name = getFileName(uri)?.lowercase() ?: return false
|
||||
return name.endsWith(".mov") || name.endsWith(".avi") || name.endsWith(".mp4") ||
|
||||
name.endsWith(".mpg") || name.endsWith(".mpeg") || name.endsWith(".mkv")
|
||||
name.endsWith(".mpg") || name.endsWith(".mpeg") || name.endsWith(".mkv") ||
|
||||
name.endsWith(".webm")
|
||||
}
|
||||
|
||||
private fun isWebmUri(uri: URI): Boolean = getFileName(uri)?.lowercase()?.endsWith(".webm") == true
|
||||
|
||||
fun MutableState<ComposeState>.processPickedFile(uri: URI?, text: String?) {
|
||||
if (uri != null) {
|
||||
val maxFileSize = value.maxFileSize
|
||||
|
||||
+3
@@ -495,6 +495,9 @@ fun ciSenderProfile(ci: ChatItem, chatInfo: ChatInfo): LocalProfile? = when (val
|
||||
|
||||
expect suspend fun getBitmapFromVideo(uri: URI, timestamp: Long? = null, random: Boolean = true, withAlertOnException: Boolean = true): VideoPlayerInterface.PreviewAndDuration
|
||||
|
||||
// Whether the file really contains a video track. Reads container metadata only, without decoding a frame.
|
||||
expect suspend fun hasVideoTrack(uri: URI): Boolean
|
||||
|
||||
fun showWrongUriAlert() {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title = generalGetString(MR.strings.non_content_uri_alert_title),
|
||||
|
||||
Reference in New Issue
Block a user