From f0397f8af82eab0c65bc54de68d681b8d06a095b Mon Sep 17 00:00:00 2001
From: bree <me@bree.dev>
Date: Thu, 8 Jul 2021 10:22:42 -0400
Subject: [PATCH] remove content jumping when loading image and video
 attachments

---
 .../attachments/Attachment.module.scss        | 34 ++++++++++++-------
 .../messaging/attachments/Attachment.tsx      | 27 ++++++++++++---
 2 files changed, 43 insertions(+), 18 deletions(-)

diff --git a/src/components/common/messaging/attachments/Attachment.module.scss b/src/components/common/messaging/attachments/Attachment.module.scss
index b7bf8c3..9c030ac 100644
--- a/src/components/common/messaging/attachments/Attachment.module.scss
+++ b/src/components/common/messaging/attachments/Attachment.module.scss
@@ -17,18 +17,26 @@
         margin-top: 4px;
     }
 
-    &.image {
-        cursor: pointer;
+    &.image, &.video > video {
+        cursor: pointer;   
         
-        max-height: 640px;
-        max-width: min(480px, 100%);
+        aspect-ratio: var(--width) / var(--height);
+        max-height: min(640px, var(--height-px));
+        max-width: min(480px, 100%, var(--width-px));
         
         object-fit: contain;
+    }
 
-        &.loaded {
-            width: auto;
+    &.image {
+        &.long {
+            width: min(100%, var(--width-px));
             height: auto;
         }
+
+        &.tall {
+            height: min(100%, var(--height-px));
+            width: auto;
+        }
     }
 
     &.video {
@@ -39,14 +47,14 @@
 
         video {
             border-radius: 0 0 6px 6px;
-            
-            max-height: 640px;
-            max-width: min(480px, 100%);
-        }
 
-        video.loaded {
-            width: auto;
-            height: auto;
+            &.long {
+                height: auto;
+            }
+    
+            &.tall {
+                width: auto;
+            }
         }
     }
 
diff --git a/src/components/common/messaging/attachments/Attachment.tsx b/src/components/common/messaging/attachments/Attachment.tsx
index a19eea4..d3df72f 100644
--- a/src/components/common/messaging/attachments/Attachment.tsx
+++ b/src/components/common/messaging/attachments/Attachment.tsx
@@ -24,7 +24,6 @@ export default function Attachment({ attachment, hasContent }: Props) {
     const { openScreen } = useIntermediate();
     const { filename, metadata } = attachment;
     const [spoiler, setSpoiler] = useState(filename.startsWith("SPOILER_"));
-    const [loaded, setLoaded] = useState(false);
 
     const url = client.generateFileURL(
         attachment,
@@ -50,20 +49,28 @@ export default function Attachment({ attachment, hasContent }: Props) {
                         alt={filename}
                         width={metadata.width}
                         height={metadata.height}
+                        loading="lazy"
                         data-spoiler={spoiler}
                         data-has-content={hasContent}
                         className={classNames(
                             styles.attachment,
                             styles.image,
-                            loaded && styles.loaded,
+                            metadata.width > metadata.height
+                                ? styles.long
+                                : styles.tall,
                         )}
+                        style={{
+                            "--width": metadata.width,
+                            "--height": metadata.height,
+                            "--width-px": metadata.width + "px",
+                            "--height-px": metadata.height + "px",
+                        }}
                         onClick={() =>
                             openScreen({ id: "image_viewer", attachment })
                         }
                         onMouseDown={(ev) =>
                             ev.button === 1 && window.open(url, "_blank")
                         }
-                        onLoad={() => setLoaded(true)}
                     />
                 </div>
             );
@@ -99,12 +106,22 @@ export default function Attachment({ attachment, hasContent }: Props) {
                             src={url}
                             width={metadata.width}
                             height={metadata.height}
-                            className={classNames(loaded && styles.loaded)}
+                            loading="lazy"
+                            className={classNames(
+                                metadata.width > metadata.height
+                                    ? styles.long
+                                    : styles.tall,
+                            )}
+                            style={{
+                                "--width": metadata.width,
+                                "--height": metadata.height,
+                                "--width-px": metadata.width + "px",
+                                "--height-px": metadata.height + "px",
+                            }}
                             controls
                             onMouseDown={(ev) =>
                                 ev.button === 1 && window.open(url, "_blank")
                             }
-                            onLoadedMetadata={() => setLoaded(true)}
                         />
                     </div>
                 </div>
-- 
GitLab