From 2ea0cc0005eb85f8e019e54edbe84960e35df86d Mon Sep 17 00:00:00 2001 From: Alex Vandiver Date: Mon, 22 Jul 2024 21:16:03 +0000 Subject: [PATCH] thumbnail: Add a data-original-dimensions attribute. This allows clients to potentially lay out the thumbnails more intelligently, or to provide a better "progressive-load" experience when enlarging the thumbnail. --- api_docs/changelog.md | 6 +++++ version.py | 2 +- zerver/lib/thumbnail.py | 7 ++++++ zerver/tests/test_markdown_thumbnail.py | 32 +++++++++++++------------ zerver/worker/thumbnail.py | 2 ++ 5 files changed, 33 insertions(+), 16 deletions(-) diff --git a/api_docs/changelog.md b/api_docs/changelog.md index dba6d76e08..7e4161582c 100644 --- a/api_docs/changelog.md +++ b/api_docs/changelog.md @@ -20,6 +20,12 @@ format used by the Zulip server that they are interacting with. ## Changes in Zulip 9.0 +**Feature level 276** + +* [Markdown message formatting](/api/message-formatting#image-previews): + Image preview elements not contain a `data-original-dimensions` + attribute containing the dimensions of the original image. + **Feature level 275** * [`POST /register`](/api/register-queue), [`PATCH diff --git a/version.py b/version.py index cdc2fce7a0..6d8b2deaa4 100644 --- a/version.py +++ b/version.py @@ -34,7 +34,7 @@ DESKTOP_WARNING_VERSION = "5.9.3" # new level means in api_docs/changelog.md, as well as "**Changes**" # entries in the endpoint's documentation in `zulip.yaml`. -API_FEATURE_LEVEL = 275 # Last bumped for `web_animate_image_previews` setting. +API_FEATURE_LEVEL = 276 # Last bumped for data-original-dimensions # Bump the minor PROVISION_VERSION to indicate that folks should provision diff --git a/zerver/lib/thumbnail.py b/zerver/lib/thumbnail.py index 7718fc02bd..fd18392fe0 100644 --- a/zerver/lib/thumbnail.py +++ b/zerver/lib/thumbnail.py @@ -329,6 +329,8 @@ def split_thumbnail_path(file_path: str) -> tuple[str, BaseThumbnailFormat]: class MarkdownImageMetadata: url: str is_animated: bool + original_width_px: int + original_height_px: int def get_user_upload_previews( @@ -347,6 +349,8 @@ def get_user_upload_previews( upload_preview_data[image_attachment.path_id] = MarkdownImageMetadata( url=url, is_animated=is_animated, + original_width_px=image_attachment.original_width_px, + original_height_px=image_attachment.original_height_px, ) return upload_preview_data @@ -421,6 +425,9 @@ def rewrite_thumbnailed_images( changed = True del image_tag["class"] image_tag["src"] = image_data.url + image_tag["data-original-dimensions"] = ( + f"{image_data.original_width_px}x{image_data.original_height_px}" + ) if image_data.is_animated: image_tag["data-animated"] = "true" diff --git a/zerver/tests/test_markdown_thumbnail.py b/zerver/tests/test_markdown_thumbnail.py index b352b1c0eb..b68d4a3e21 100644 --- a/zerver/tests/test_markdown_thumbnail.py +++ b/zerver/tests/test_markdown_thumbnail.py @@ -73,15 +73,15 @@ class MarkdownThumbnailTest(ZulipTestCase): "

Test 1
\n" f'{image_names[0]}

\n' f'
' - f'
' + f'' "

Next image
\n" f'{image_names[1]}

\n' f'
' - f'
' + f'' "

Another screenshot
\n" f'{image_names[2]}

\n' f'
' - f'
' + f'' ), ) @@ -124,7 +124,7 @@ class MarkdownThumbnailTest(ZulipTestCase): expected = ( f'

image

\n' f'
' - f'
' + f'' ) self.assert_message_content_is(message_id, expected) @@ -142,7 +142,8 @@ class MarkdownThumbnailTest(ZulipTestCase): message_id = self.send_message_content(f"[I am 95% ± 5% certain!](/user_uploads/{path_id})") expected = ( f'

I am 95% ± 5% certain!

\n' - f'
' + f'
' + f'
' ) self.assert_message_content_is(message_id, expected) @@ -157,12 +158,13 @@ class MarkdownThumbnailTest(ZulipTestCase): ThumbnailFormat("webp", 100, 75, animated=True), ThumbnailFormat("webp", 100, 75, animated=False), ): - path_id = self.upload_and_thumbnail_image("animated_img.gif") - content = f"[animated_img.gif](/user_uploads/{path_id})" + path_id = self.upload_and_thumbnail_image("animated_unequal_img.gif") + content = f"[animated_unequal_img.gif](/user_uploads/{path_id})" expected = ( - f'

animated_img.gif

\n' - f'
' - f'
' + f'

animated_unequal_img.gif

\n' + f'
' + '
' ) message_id = self.send_message_content(content, do_thumbnail=True) self.assert_message_content_is(message_id, expected) @@ -208,7 +210,7 @@ class MarkdownThumbnailTest(ZulipTestCase): f'
' '
' f'
' - f'
' + f'' ), ) @@ -220,9 +222,9 @@ class MarkdownThumbnailTest(ZulipTestCase): f'

first image
\n' f'second image

\n' f'
' - f'
' + f'' f'
' - f'
' + f'' ), ) @@ -247,7 +249,7 @@ class MarkdownThumbnailTest(ZulipTestCase): expected = ( f'

image

\n' f'
' - f'
' + f'' ) self.assertEqual( ArchivedMessage.objects.get(id=message_id).rendered_content, @@ -320,7 +322,7 @@ class MarkdownThumbnailTest(ZulipTestCase): rendered_thumb = ( f'
' - f'
' + f'' ) self.assert_message_content_is( diff --git a/zerver/worker/thumbnail.py b/zerver/worker/thumbnail.py index aef0a50e7b..9e5854e06c 100644 --- a/zerver/worker/thumbnail.py +++ b/zerver/worker/thumbnail.py @@ -147,6 +147,8 @@ def ensure_thumbnails(image_attachment: ImageAttachment) -> int: MarkdownImageMetadata( url=url, is_animated=is_animated, + original_width_px=image_attachment.original_width_px, + original_height_px=image_attachment.original_height_px, ), ) return written_images