mirror of https://github.com/zulip/zulip.git
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.
This commit is contained in:
parent
65828b20e9
commit
2ea0cc0005
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -73,15 +73,15 @@ class MarkdownThumbnailTest(ZulipTestCase):
|
|||
"<p>Test 1<br>\n"
|
||||
f'<a href="/user_uploads/{path_ids[0]}">{image_names[0]}</a> </p>\n'
|
||||
f'<div class="message_inline_image"><a href="/user_uploads/{path_ids[0]}" title="{image_names[0]}">'
|
||||
f'<img src="/user_uploads/thumbnail/{path_ids[0]}/840x560.webp"></a></div>'
|
||||
f'<img data-original-dimensions="128x128" src="/user_uploads/thumbnail/{path_ids[0]}/840x560.webp"></a></div>'
|
||||
"<p>Next image<br>\n"
|
||||
f'<a href="/user_uploads/{path_ids[1]}">{image_names[1]}</a> </p>\n'
|
||||
f'<div class="message_inline_image"><a href="/user_uploads/{path_ids[1]}" title="{image_names[1]}">'
|
||||
f'<img src="/user_uploads/thumbnail/{path_ids[1]}/840x560.webp"></a></div>'
|
||||
f'<img data-original-dimensions="128x128" src="/user_uploads/thumbnail/{path_ids[1]}/840x560.webp"></a></div>'
|
||||
"<p>Another screenshot<br>\n"
|
||||
f'<a href="/user_uploads/{path_ids[2]}">{image_names[2]}</a></p>\n'
|
||||
f'<div class="message_inline_image"><a href="/user_uploads/{path_ids[2]}" title="{image_names[2]}">'
|
||||
f'<img src="/user_uploads/thumbnail/{path_ids[2]}/840x560.webp"></a></div>'
|
||||
f'<img data-original-dimensions="128x128" src="/user_uploads/thumbnail/{path_ids[2]}/840x560.webp"></a></div>'
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -124,7 +124,7 @@ class MarkdownThumbnailTest(ZulipTestCase):
|
|||
expected = (
|
||||
f'<p><a href="/user_uploads/{path_id}">image</a></p>\n'
|
||||
f'<div class="message_inline_image"><a href="/user_uploads/{path_id}" title="image">'
|
||||
f'<img src="/user_uploads/thumbnail/{path_id}/840x560.webp"></a></div>'
|
||||
f'<img data-original-dimensions="128x128" src="/user_uploads/thumbnail/{path_id}/840x560.webp"></a></div>'
|
||||
)
|
||||
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'<p><a href="/user_uploads/{path_id}">I am 95% ± 5% certain!</a></p>\n'
|
||||
f'<div class="message_inline_image"><a href="/user_uploads/{path_id}" title="I am 95% ± 5% certain!"><img src="/user_uploads/thumbnail/{path_id}/840x560.webp"></a></div>'
|
||||
f'<div class="message_inline_image"><a href="/user_uploads/{path_id}" title="I am 95% ± 5% certain!">'
|
||||
f'<img data-original-dimensions="128x128" src="/user_uploads/thumbnail/{path_id}/840x560.webp"></a></div>'
|
||||
)
|
||||
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'<p><a href="/user_uploads/{path_id}">animated_img.gif</a></p>\n'
|
||||
f'<div class="message_inline_image"><a href="/user_uploads/{path_id}" title="animated_img.gif">'
|
||||
f'<img data-animated="true" src="/user_uploads/thumbnail/{path_id}/100x75-anim.webp"></a></div>'
|
||||
f'<p><a href="/user_uploads/{path_id}">animated_unequal_img.gif</a></p>\n'
|
||||
f'<div class="message_inline_image"><a href="/user_uploads/{path_id}" title="animated_unequal_img.gif">'
|
||||
'<img data-animated="true" data-original-dimensions="128x56"'
|
||||
f' src="/user_uploads/thumbnail/{path_id}/100x75-anim.webp"></a></div>'
|
||||
)
|
||||
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'<div class="message_inline_image"><a href="/user_uploads/{first_path_id}" title="first image">'
|
||||
'<img class="image-loading-placeholder" src="/static/images/loading/loader-black.svg"></a></div>'
|
||||
f'<div class="message_inline_image"><a href="/user_uploads/{second_path_id}" title="second image">'
|
||||
f'<img src="/user_uploads/thumbnail/{second_path_id}/840x560.webp"></a></div>'
|
||||
f'<img data-original-dimensions="128x128" src="/user_uploads/thumbnail/{second_path_id}/840x560.webp"></a></div>'
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -220,9 +222,9 @@ class MarkdownThumbnailTest(ZulipTestCase):
|
|||
f'<p><a href="/user_uploads/{first_path_id}">first image</a><br>\n'
|
||||
f'<a href="/user_uploads/{second_path_id}">second image</a></p>\n'
|
||||
f'<div class="message_inline_image"><a href="/user_uploads/{first_path_id}" title="first image">'
|
||||
f'<img src="/user_uploads/thumbnail/{first_path_id}/840x560.webp"></a></div>'
|
||||
f'<img data-original-dimensions="128x128" src="/user_uploads/thumbnail/{first_path_id}/840x560.webp"></a></div>'
|
||||
f'<div class="message_inline_image"><a href="/user_uploads/{second_path_id}" title="second image">'
|
||||
f'<img src="/user_uploads/thumbnail/{second_path_id}/840x560.webp"></a></div>'
|
||||
f'<img data-original-dimensions="128x128" src="/user_uploads/thumbnail/{second_path_id}/840x560.webp"></a></div>'
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -247,7 +249,7 @@ class MarkdownThumbnailTest(ZulipTestCase):
|
|||
expected = (
|
||||
f'<p><a href="/user_uploads/{path_id}">image</a></p>\n'
|
||||
f'<div class="message_inline_image"><a href="/user_uploads/{path_id}" title="image">'
|
||||
f'<img src="/user_uploads/thumbnail/{path_id}/840x560.webp"></a></div>'
|
||||
f'<img data-original-dimensions="128x128" src="/user_uploads/thumbnail/{path_id}/840x560.webp"></a></div>'
|
||||
)
|
||||
self.assertEqual(
|
||||
ArchivedMessage.objects.get(id=message_id).rendered_content,
|
||||
|
@ -320,7 +322,7 @@ class MarkdownThumbnailTest(ZulipTestCase):
|
|||
|
||||
rendered_thumb = (
|
||||
f'<div class="message_inline_image"><a href="/user_uploads/{path_id}" title="image">'
|
||||
f'<img src="/user_uploads/thumbnail/{path_id}/100x75.webp"></a></div>'
|
||||
f'<img data-original-dimensions="128x128" src="/user_uploads/thumbnail/{path_id}/100x75.webp"></a></div>'
|
||||
)
|
||||
|
||||
self.assert_message_content_is(
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue