diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5ff2ac75f..074e95364 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@
## Fixed
- handle double escape on Dialog #4365
- fix random crashes on quote reply #4337
+- chat not being scrolled to the very bottom upon getting opened due to images loading slowly #4406
- avoid drafts in readonly chats #4349
- fullscreen images getting cropped a little #4402, #4385
diff --git a/packages/frontend/src/components/attachment/mediaAttachment.tsx b/packages/frontend/src/components/attachment/mediaAttachment.tsx
index 1512e9c47..4135902d1 100644
--- a/packages/frontend/src/components/attachment/mediaAttachment.tsx
+++ b/packages/frontend/src/components/attachment/mediaAttachment.tsx
@@ -231,6 +231,11 @@ export function ImageAttachment({
className='attachment-content'
src={runtime.transformBlobURL(file)}
loading='lazy'
+ // Pre-setting `height` and `width` from
+ // `message.dimensionsHeight`, as we do in the message list,
+ // could be used here
+ // to prevent layout shifts, but it's not needed,
+ // because this is fixed-size anyway.
/>
)}
@@ -301,6 +306,11 @@ export function VideoAttachment({
className='attachment-content'
src={runtime.transformBlobURL(file)}
controls={false}
+ // Pre-setting `height` and `width` from
+ // `message.dimensionsHeight`, as we do in the message list,
+ // could be used here
+ // to prevent layout shifts, but it's not needed,
+ // because this is fixed-size anyway.
/>
diff --git a/packages/frontend/src/components/attachment/messageAttachment.tsx b/packages/frontend/src/components/attachment/messageAttachment.tsx
index 8004dd698..a65cd93cf 100644
--- a/packages/frontend/src/components/attachment/messageAttachment.tsx
+++ b/packages/frontend/src/components/attachment/messageAttachment.tsx
@@ -22,6 +22,7 @@ import FullscreenMedia, {
import useTranslationFunction from '../../hooks/useTranslationFunction'
import useDialog from '../../hooks/dialog/useDialog'
import AudioPlayer from '../AudioPlayer'
+import { T } from '@deltachat/jsonrpc-client'
type AttachmentProps = {
text?: string
@@ -86,6 +87,11 @@ export default function Attachment({
)
@@ -114,6 +120,11 @@ export default function Attachment({
className='attachment-content video-content'
src={runtime.transformBlobURL(message.file)}
controls={true}
+ // Pre-set width and height to prevent layout shifts
+ // when the video finally loads.
+ // This is not supposed to affect the rendered dimensions
+ // of the media _after_ it has been loaded.
+ style={getDimensions(message)}
/>
)
@@ -217,3 +228,20 @@ export function DraftAttachment({
)
}
}
+
+function getDimensions(
+ message: Pick
+): { height: number | undefined; width?: number | undefined } {
+ // With some sanity checks, in case core couldn't determine dimensions
+ // for whatever reason, but the browser might.
+ return {
+ height:
+ message.dimensionsHeight > 0 && message.dimensionsHeight < 100_000
+ ? message.dimensionsHeight
+ : undefined,
+ width:
+ message.dimensionsWidth > 0 && message.dimensionsWidth < 100_000
+ ? message.dimensionsWidth
+ : undefined,
+ }
+}