Improved MIME type related code

This commit is contained in:
Sylvain Berfini 2023-05-25 11:10:24 +02:00
parent 855f8c11c1
commit 83dc8a7b13
7 changed files with 84 additions and 78 deletions

View file

@ -35,10 +35,11 @@ class ChatMessageAttachmentData(
init { init {
val extension = FileUtils.getExtensionFromFileName(path) val extension = FileUtils.getExtensionFromFileName(path)
val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
isImage = FileUtils.isMimeImage(mime) val mimeType = FileUtils.getMimeType(mime)
isVideo = FileUtils.isMimeVideo(mime) isImage = mimeType == FileUtils.MimeType.Image
isAudio = FileUtils.isMimeAudio(mime) isVideo = mimeType == FileUtils.MimeType.Video
isPdf = FileUtils.isMimePdf(mime) isAudio = mimeType == FileUtils.MimeType.Audio
isPdf = mimeType == FileUtils.MimeType.Pdf
} }
fun delete() { fun delete() {

View file

@ -275,18 +275,26 @@ class ChatMessageContentData(
filePath.value = path filePath.value = path
val extension = FileUtils.getExtensionFromFileName(path) val extension = FileUtils.getExtensionFromFileName(path)
val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
isImage.value = FileUtils.isMimeImage(mime) val type = when (FileUtils.getMimeType(mime)) {
isVideo.value = FileUtils.isMimeVideo(mime) && !isVoiceRecord FileUtils.MimeType.Image -> {
isAudio.value = FileUtils.isMimeAudio(mime) && !isVoiceRecord isImage.value = true
isPdf.value = FileUtils.isMimePdf(mime) "image"
val type = when { }
isImage.value == true -> "image" FileUtils.MimeType.Video -> {
isVideo.value == true -> "video" isVideo.value = !isVoiceRecord
isAudio.value == true -> "audio" if (isVoiceRecord) "voice recording" else "video"
isPdf.value == true -> "pdf" }
isVoiceRecord -> "voice recording" FileUtils.MimeType.Audio -> {
isConferenceIcs -> "conference invitation" isAudio.value = !isVoiceRecord
else -> "unknown" if (isVoiceRecord) "voice recording" else "audio"
}
FileUtils.MimeType.Pdf -> {
isPdf.value = true
"pdf"
}
else -> {
if (isConferenceIcs) "conference invitation" else "unknown"
}
} }
Log.i( Log.i(
"[Content] Extension for file [$path] is [$extension], deduced type from MIME is [$type]" "[Content] Extension for file [$path] is [$extension], deduced type from MIME is [$type]"
@ -311,23 +319,26 @@ class ChatMessageContentData(
Log.w( Log.w(
"[Content] Found ${if (content.isFile) "file" else "file transfer"} content with empty path..." "[Content] Found ${if (content.isFile) "file" else "file transfer"} content with empty path..."
) )
isImage.value = false
isVideo.value = false
isAudio.value = false
isPdf.value = false
isVoiceRecording.value = false
isConferenceSchedule.value = false
} }
} else if (content.isFileTransfer) { } else if (content.isFileTransfer) {
downloadable.value = true downloadable.value = true
val extension = FileUtils.getExtensionFromFileName(fileName.value!!) val extension = FileUtils.getExtensionFromFileName(fileName.value!!)
val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
isImage.value = FileUtils.isMimeImage(mime) when (FileUtils.getMimeType(mime)) {
isVideo.value = FileUtils.isMimeVideo(mime) FileUtils.MimeType.Image -> {
isAudio.value = FileUtils.isMimeAudio(mime) isImage.value = true
isPdf.value = FileUtils.isMimePdf(mime) }
isVoiceRecording.value = false FileUtils.MimeType.Video -> {
isConferenceSchedule.value = false isVideo.value = true
}
FileUtils.MimeType.Audio -> {
isAudio.value = true
}
FileUtils.MimeType.Pdf -> {
isPdf.value = true
}
else -> {}
}
} else if (content.isIcalendar) { } else if (content.isIcalendar) {
Log.i("[Content] Found content with icalendar body") Log.i("[Content] Found content with icalendar body")
isConferenceSchedule.value = true isConferenceSchedule.value = true

View file

@ -478,8 +478,8 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
"[Chat Room] Content file path was empty, created file from buffer at $path" "[Chat Room] Content file path was empty, created file from buffer at $path"
) )
} else if (content.isIcalendar) { } else if (content.isIcalendar) {
val name = "conference.ics" val filename = "conference.ics"
val file = FileUtils.getFileStoragePath(name) val file = FileUtils.getFileStoragePath(filename)
FileUtils.writeIntoFile(content.buffer, file) FileUtils.writeIntoFile(content.buffer, file)
path = file.absolutePath path = file.absolutePath
content.filePath = path content.filePath = path
@ -498,20 +498,20 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
val extension = FileUtils.getExtensionFromFileName(path) val extension = FileUtils.getExtensionFromFileName(path)
val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
when { when (FileUtils.getMimeType(mime)) {
FileUtils.isMimeImage(mime) -> navigateToImageFileViewer( FileUtils.MimeType.Image -> navigateToImageFileViewer(
preventScreenshots preventScreenshots
) )
FileUtils.isMimeVideo(mime) -> navigateToVideoFileViewer( FileUtils.MimeType.Video -> navigateToVideoFileViewer(
preventScreenshots preventScreenshots
) )
FileUtils.isMimeAudio(mime) -> navigateToAudioFileViewer( FileUtils.MimeType.Audio -> navigateToAudioFileViewer(
preventScreenshots preventScreenshots
) )
FileUtils.isMimePdf(mime) -> navigateToPdfFileViewer( FileUtils.MimeType.Pdf -> navigateToPdfFileViewer(
preventScreenshots preventScreenshots
) )
FileUtils.isMimePlainText(mime) -> navigateToTextFileViewer( FileUtils.MimeType.PlainText -> navigateToTextFileViewer(
preventScreenshots preventScreenshots
) )
else -> { else -> {
@ -584,9 +584,9 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
viewLifecycleOwner viewLifecycleOwner
) { ) {
it.consume { chatMessage -> it.consume { chatMessage ->
var index = 0 var index: Int
var retryCount = 0 var loadSteps = 0
var expectedChildCount = 0 var expectedChildCount: Int
do { do {
val events = listViewModel.events.value.orEmpty() val events = listViewModel.events.value.orEmpty()
expectedChildCount = events.size expectedChildCount = events.size
@ -600,18 +600,17 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
} }
index = events.indexOf(eventLog) index = events.indexOf(eventLog)
if (index == -1) { if (index == -1) {
retryCount += 1 loadSteps += 1
listViewModel.loadMoreData(events.size) listViewModel.loadMoreData(events.size)
} }
} while (index == -1 && retryCount < 5) } while (index == -1 && loadSteps < 5)
if (index != -1) { if (index != -1) {
if (retryCount == 0) { if (loadSteps == 0) {
scrollTo(index, true) scrollTo(index, true)
} else { } else {
lifecycleScope.launch { lifecycleScope.launch {
withContext(Dispatchers.Default) { withContext(Dispatchers.Default) {
val layoutManager = binding.chatMessagesList.layoutManager as LinearLayoutManager
var retryCount = 0 var retryCount = 0
do { do {
// We have to wait for newly loaded items to be added to list before being able to scroll // We have to wait for newly loaded items to be added to list before being able to scroll
@ -684,7 +683,7 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
} }
} }
binding.setVoiceRecordingTouchListener { view, event -> binding.setVoiceRecordingTouchListener { _, event ->
if (corePreferences.holdToRecordVoiceMessage) { if (corePreferences.holdToRecordVoiceMessage) {
when (event.action) { when (event.action) {
MotionEvent.ACTION_DOWN -> { MotionEvent.ACTION_DOWN -> {

View file

@ -92,8 +92,8 @@ class TopBarFragment : GenericFragment<FileViewerTopBarFragmentBinding>() {
val extension = FileUtils.getExtensionFromFileName(filePath) val extension = FileUtils.getExtensionFromFileName(filePath)
val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
when { when (FileUtils.getMimeType(mime)) {
FileUtils.isMimeImage(mime) -> { FileUtils.MimeType.Image -> {
val export = lifecycleScope.async { val export = lifecycleScope.async {
Compatibility.addImageToMediaStore(requireContext(), content) Compatibility.addImageToMediaStore(requireContext(), content)
} }
@ -108,7 +108,7 @@ class TopBarFragment : GenericFragment<FileViewerTopBarFragmentBinding>() {
) )
} }
} }
FileUtils.isMimeVideo(mime) -> { FileUtils.MimeType.Video -> {
val export = lifecycleScope.async { val export = lifecycleScope.async {
Compatibility.addVideoToMediaStore(requireContext(), content) Compatibility.addVideoToMediaStore(requireContext(), content)
} }
@ -123,7 +123,7 @@ class TopBarFragment : GenericFragment<FileViewerTopBarFragmentBinding>() {
) )
} }
} }
FileUtils.isMimeAudio(mime) -> { FileUtils.MimeType.Audio -> {
val export = lifecycleScope.async { val export = lifecycleScope.async {
Compatibility.addAudioToMediaStore(requireContext(), content) Compatibility.addAudioToMediaStore(requireContext(), content)
} }

View file

@ -1048,8 +1048,8 @@ class CoreContext(
val extension = FileUtils.getExtensionFromFileName(filePath) val extension = FileUtils.getExtensionFromFileName(filePath)
val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
when { when (FileUtils.getMimeType(mime)) {
FileUtils.isMimeImage(mime) -> { FileUtils.MimeType.Image -> {
if (Compatibility.addImageToMediaStore(context, content)) { if (Compatibility.addImageToMediaStore(context, content)) {
Log.i( Log.i(
"[Context] Successfully exported image [${content.name}] to Media Store" "[Context] Successfully exported image [${content.name}] to Media Store"
@ -1060,7 +1060,7 @@ class CoreContext(
) )
} }
} }
FileUtils.isMimeVideo(mime) -> { FileUtils.MimeType.Video -> {
if (Compatibility.addVideoToMediaStore(context, content)) { if (Compatibility.addVideoToMediaStore(context, content)) {
Log.i( Log.i(
"[Context] Successfully exported video [${content.name}] to Media Store" "[Context] Successfully exported video [${content.name}] to Media Store"
@ -1071,7 +1071,7 @@ class CoreContext(
) )
} }
} }
FileUtils.isMimeAudio(mime) -> { FileUtils.MimeType.Audio -> {
if (Compatibility.addAudioToMediaStore(context, content)) { if (Compatibility.addAudioToMediaStore(context, content)) {
Log.i( Log.i(
"[Context] Successfully exported audio [${content.name}] to Media Store" "[Context] Successfully exported audio [${content.name}] to Media Store"

View file

@ -547,7 +547,7 @@ fun loadAvatarWithCoil(imageView: ImageView, path: String?) {
@BindingAdapter("coilVideoPreview") @BindingAdapter("coilVideoPreview")
fun loadVideoPreview(imageView: ImageView, path: String?) { fun loadVideoPreview(imageView: ImageView, path: String?) {
if (!path.isNullOrEmpty() && FileUtils.isExtensionVideo(path)) { if (!path.isNullOrEmpty()) {
imageView.load(path) { imageView.load(path) {
videoFrameMillis(0) videoFrameMillis(0)
listener( listener(

View file

@ -42,6 +42,15 @@ import org.linphone.R
import org.linphone.core.tools.Log import org.linphone.core.tools.Log
class FileUtils { class FileUtils {
enum class MimeType {
PlainText,
Pdf,
Image,
Video,
Audio,
Unknown
}
companion object { companion object {
fun getNameFromFilePath(filePath: String): String { fun getNameFromFilePath(filePath: String): String {
var name = filePath var name = filePath
@ -64,36 +73,22 @@ class FileUtils {
return extension.lowercase(Locale.getDefault()) return extension.lowercase(Locale.getDefault())
} }
fun isMimePlainText(type: String?): Boolean { fun getMimeType(type: String?): MimeType {
return type?.startsWith("text/plain") ?: false if (type.isNullOrEmpty()) return MimeType.Unknown
return when {
type.startsWith("image/") -> MimeType.Image
type.startsWith("text/plain") -> MimeType.PlainText
type.startsWith("video/") -> MimeType.Video
type.startsWith("audio/") -> MimeType.Audio
type.startsWith("application/pdf") -> MimeType.Pdf
else -> MimeType.Unknown
} }
fun isMimePdf(type: String?): Boolean {
return type?.startsWith("application/pdf") ?: false
}
fun isMimeImage(type: String?): Boolean {
return type?.startsWith("image/") ?: false
}
fun isMimeVideo(type: String?): Boolean {
return type?.startsWith("video/") ?: false
}
fun isMimeAudio(type: String?): Boolean {
return type?.startsWith("audio/") ?: false
} }
fun isExtensionImage(path: String): Boolean { fun isExtensionImage(path: String): Boolean {
val extension = getExtensionFromFileName(path) val extension = getExtensionFromFileName(path)
val type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) val type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
return isMimeImage(type) return getMimeType(type) == MimeType.Image
}
fun isExtensionVideo(path: String): Boolean {
val extension = getExtensionFromFileName(path)
val type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
return isMimeVideo(type)
} }
fun clearExistingPlainFiles() { fun clearExistingPlainFiles() {