android, desktop: constrain image sizes for previews (#6726)

* android, desktop: constrain image sizes for previews

* use correct JSON parser

* more JSON fixes

* constrain ratio in image decoder

* constrain max height in layout

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
This commit is contained in:
Evgeny
2026-03-30 12:24:16 +01:00
committed by GitHub
parent 47f82c10da
commit c3663ae285
4 changed files with 30 additions and 6 deletions
@@ -3834,7 +3834,7 @@ object MsgReactionSerializer : KSerializer<MsgReaction> {
when(val t = json["type"]?.jsonPrimitive?.content ?: "") {
"emoji" -> {
val msgReaction = try {
val emoji = Json.decodeFromString<MREmojiChar>(json["emoji"].toString())
val emoji = decoder.json.decodeFromString<MREmojiChar>(json["emoji"].toString())
MsgReaction.Emoji(emoji)
} catch (e: Throwable) {
MsgReaction.Unknown(t, json)
@@ -4276,7 +4276,7 @@ object MsgContentSerializer : KSerializer<MsgContent> {
when (t) {
"text" -> MsgContent.MCText(text)
"link" -> {
val preview = Json.decodeFromString<LinkPreview>(json["preview"].toString())
val preview = decoder.json.decodeFromString<LinkPreview>(json["preview"].toString())
MsgContent.MCLink(text, preview)
}
"image" -> {
@@ -4294,11 +4294,11 @@ object MsgContentSerializer : KSerializer<MsgContent> {
}
"file" -> MsgContent.MCFile(text)
"report" -> {
val reason = Json.decodeFromString<ReportReason>(json["reason"].toString())
val reason = decoder.json.decodeFromString<ReportReason>(json["reason"].toString())
MsgContent.MCReport(text, reason)
}
"chat" -> {
val chatLink = Json.decodeFromString<MsgChatLink>(json["chatLink"].toString())
val chatLink = decoder.json.decodeFromString<MsgChatLink>(json["chatLink"].toString())
MsgContent.MCChat(text, chatLink)
}
else -> MsgContent.MCUnknown(t, text, json)
@@ -437,7 +437,10 @@ fun PriorityLayout(
) { measureable, constraints ->
// Find important element which should tell what max width other elements can use
// Expecting only one such element. Can be less than one but not more
val imagePlaceable = measureable.firstOrNull { it.layoutId == priorityLayoutId }?.measure(constraints)
// Constrain max image height to prevent crashes and scroll issues from images with extreme aspect ratios
val maxImageHeight = (constraints.maxWidth * 2.33f).toInt().coerceAtMost(constraints.maxHeight)
val imageConstraints = constraints.copy(maxHeight = maxImageHeight)
val imagePlaceable = measureable.firstOrNull { it.layoutId == priorityLayoutId }?.measure(imageConstraints)
val placeables: List<Placeable> = measureable.map {
if (it.layoutId == priorityLayoutId)
imagePlaceable!!