fix(android): skip reactions for temp messages and fallback gif upload
This commit is contained in:
@@ -2,6 +2,8 @@ package ru.daemonlord.messenger.data.media.repository
|
|||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.Movie
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
@@ -96,7 +98,26 @@ class NetworkMediaRepository @Inject constructor(
|
|||||||
return UploadPayload(fileName = fileName, mimeType = mimeType, bytes = bytes)
|
return UploadPayload(fileName = fileName, mimeType = mimeType, bytes = bytes)
|
||||||
}
|
}
|
||||||
if (mimeType.equals("image/gif", ignoreCase = true)) {
|
if (mimeType.equals("image/gif", ignoreCase = true)) {
|
||||||
return UploadPayload(fileName = fileName, mimeType = mimeType, bytes = bytes)
|
val still = gifToPngPayload(fileName = fileName, bytes = bytes)
|
||||||
|
if (still != null) return still
|
||||||
|
val bitmapFallback = runCatching { BitmapFactory.decodeByteArray(bytes, 0, bytes.size) }.getOrNull()
|
||||||
|
if (bitmapFallback != null) {
|
||||||
|
val output = ByteArrayOutputStream()
|
||||||
|
val compressed = bitmapFallback.compress(Bitmap.CompressFormat.PNG, 100, output)
|
||||||
|
bitmapFallback.recycle()
|
||||||
|
if (compressed) {
|
||||||
|
val pngBytes = output.toByteArray()
|
||||||
|
if (pngBytes.isNotEmpty()) {
|
||||||
|
val baseName = fileName.substringBeforeLast('.').ifBlank { "gif" }
|
||||||
|
return UploadPayload(
|
||||||
|
fileName = "${baseName}-still.png",
|
||||||
|
mimeType = "image/png",
|
||||||
|
bytes = pngBytes,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return UploadPayload(fileName = fileName, mimeType = "application/octet-stream", bytes = bytes)
|
||||||
}
|
}
|
||||||
val source = runCatching { BitmapFactory.decodeByteArray(bytes, 0, bytes.size) }.getOrNull()
|
val source = runCatching { BitmapFactory.decodeByteArray(bytes, 0, bytes.size) }.getOrNull()
|
||||||
?: return UploadPayload(fileName = fileName, mimeType = mimeType, bytes = bytes)
|
?: return UploadPayload(fileName = fileName, mimeType = mimeType, bytes = bytes)
|
||||||
@@ -140,4 +161,32 @@ class NetworkMediaRepository @Inject constructor(
|
|||||||
val mimeType: String,
|
val mimeType: String,
|
||||||
val bytes: ByteArray,
|
val bytes: ByteArray,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private fun gifToPngPayload(
|
||||||
|
fileName: String,
|
||||||
|
bytes: ByteArray,
|
||||||
|
): UploadPayload? {
|
||||||
|
val movie = runCatching { Movie.decodeByteArray(bytes, 0, bytes.size) }.getOrNull() ?: return null
|
||||||
|
val width = movie.width().coerceAtLeast(1)
|
||||||
|
val height = movie.height().coerceAtLeast(1)
|
||||||
|
val bitmap = runCatching { Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) }.getOrNull() ?: return null
|
||||||
|
return try {
|
||||||
|
val canvas = Canvas(bitmap)
|
||||||
|
movie.setTime(0)
|
||||||
|
movie.draw(canvas, 0f, 0f)
|
||||||
|
val output = ByteArrayOutputStream()
|
||||||
|
val compressed = bitmap.compress(Bitmap.CompressFormat.PNG, 100, output)
|
||||||
|
if (!compressed) return null
|
||||||
|
val pngBytes = output.toByteArray()
|
||||||
|
if (pngBytes.isEmpty()) return null
|
||||||
|
val baseName = fileName.substringBeforeLast('.').ifBlank { "gif" }
|
||||||
|
UploadPayload(
|
||||||
|
fileName = "${baseName}-still.png",
|
||||||
|
mimeType = "image/png",
|
||||||
|
bytes = pngBytes,
|
||||||
|
)
|
||||||
|
} finally {
|
||||||
|
bitmap.recycle()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -650,6 +650,7 @@ class ChatViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadReactions(messageId: Long) {
|
private fun loadReactions(messageId: Long) {
|
||||||
|
if (messageId <= 0L) return
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
when (val result = listMessageReactionsUseCase(messageId = messageId)) {
|
when (val result = listMessageReactionsUseCase(messageId = messageId)) {
|
||||||
is AppResult.Success -> {
|
is AppResult.Success -> {
|
||||||
@@ -666,6 +667,7 @@ class ChatViewModel @Inject constructor(
|
|||||||
val toRequest = messages
|
val toRequest = messages
|
||||||
.asReversed()
|
.asReversed()
|
||||||
.map { it.id }
|
.map { it.id }
|
||||||
|
.filter { it > 0L }
|
||||||
.filter { reactionsRequestedMessageIds.add(it) }
|
.filter { reactionsRequestedMessageIds.add(it) }
|
||||||
|
|
||||||
if (toRequest.isEmpty()) return
|
if (toRequest.isEmpty()) return
|
||||||
|
|||||||
Reference in New Issue
Block a user