From d59debd609769c191daf640ae05e450d8b0e1394 Mon Sep 17 00:00:00 2001 From: iequidoo Date: Fri, 20 Dec 2024 23:12:55 -0300 Subject: [PATCH] fix: Never change Viewtype::Sticker to Image if file has non-image extension (#6352) Even if UIs don't call `Message::force_sticker()`, they don't want conversions of `Sticker` to `Image` if it's obviously not an image, particularly, has non-image extension. Also UIs don't want conversions of `Sticker` to anything other than `Image`, so let's keep the `Sticker` viewtype in this case. --- src/blob.rs | 19 +++++++++++++++++++ src/chat.rs | 12 ++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/blob.rs b/src/blob.rs index 63c2350562..1181f1194d 100644 --- a/src/blob.rs +++ b/src/blob.rs @@ -1455,4 +1455,23 @@ mod tests { check_image_size(file_saved, width, height); Ok(()) } + + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + async fn test_send_gif_as_sticker() -> Result<()> { + let bytes = include_bytes!("../test-data/image/image100x50.gif"); + let alice = &TestContext::new_alice().await; + let file = alice.get_blobdir().join("file").with_extension("gif"); + fs::write(&file, &bytes) + .await + .context("failed to write file")?; + let mut msg = Message::new(Viewtype::Sticker); + msg.set_file(file.to_str().unwrap(), None); + let chat = alice.get_self_chat().await; + let sent = alice.send_msg(chat.id, &mut msg).await; + let msg = Message::load_from_db(alice, sent.sender_msg_id).await?; + // Message::force_sticker() wasn't used, still Viewtype::Sticker is preserved because of the + // extension. + assert_eq!(msg.get_viewtype(), Viewtype::Sticker); + Ok(()) + } } diff --git a/src/chat.rs b/src/chat.rs index 437dbff4ef..9695781224 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -2688,7 +2688,10 @@ async fn prepare_msg_blob(context: &Context, msg: &mut Message) -> Result<()> { .with_context(|| format!("attachment missing for message of type #{}", msg.viewtype))?; let send_as_is = msg.viewtype == Viewtype::File; - if msg.viewtype == Viewtype::File || msg.viewtype == Viewtype::Image { + if msg.viewtype == Viewtype::File + || msg.viewtype == Viewtype::Image + || msg.viewtype == Viewtype::Sticker && !msg.param.exists(Param::ForceSticker) + { // Correct the type, take care not to correct already very special // formats as GIF or VOICE. // @@ -2697,7 +2700,12 @@ async fn prepare_msg_blob(context: &Context, msg: &mut Message) -> Result<()> { // - from FILE/IMAGE to GIF */ if let Some((better_type, _)) = message::guess_msgtype_from_suffix(&blob.to_abs_path()) { - if better_type != Viewtype::Webxdc + if msg.viewtype == Viewtype::Sticker { + if better_type != Viewtype::Image { + // UIs don't want conversions of `Sticker` to anything other than `Image`. + msg.param.set_int(Param::ForceSticker, 1); + } + } else if better_type != Viewtype::Webxdc || context .ensure_sendable_webxdc_file(&blob.to_abs_path()) .await