From 6c4d23714a42dd59843a8fb905150eed2d5db29d Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Fri, 18 Oct 2019 15:27:51 -0400
Subject: [PATCH 1/5] populate gallery row height without getting width

---
 src/components/gallery/gallery.js  | 24 ++----------------
 src/components/gallery/gallery.vue | 39 +++++++++++++++++++-----------
 2 files changed, 27 insertions(+), 36 deletions(-)

diff --git a/src/components/gallery/gallery.js b/src/components/gallery/gallery.js
index 7f33a81b..3610f53d 100644
--- a/src/components/gallery/gallery.js
+++ b/src/components/gallery/gallery.js
@@ -2,22 +2,12 @@ import Attachment from '../attachment/attachment.vue'
 import { chunk, last, dropRight } from 'lodash'
 
 const Gallery = {
-  data: () => ({
-    width: 500
-  }),
   props: [
     'attachments',
     'nsfw',
     'setMedia'
   ],
   components: { Attachment },
-  mounted () {
-    this.resize()
-    window.addEventListener('resize', this.resize)
-  },
-  destroyed () {
-    window.removeEventListener('resize', this.resize)
-  },
   computed: {
     rows () {
       if (!this.attachments) {
@@ -33,22 +23,12 @@ const Gallery = {
       }
       return rows
     },
-    rowHeight () {
-      return itemsPerRow => ({ 'height': `${(this.width / (itemsPerRow + 0.6))}px` })
+    rowStyle () {
+      return itemsPerRow => ({ 'padding-bottom': `${(100 / (itemsPerRow + 0.6))}%` })
     },
     useContainFit () {
       return this.$store.state.config.useContainFit
     }
-  },
-  methods: {
-    resize () {
-      // Quick optimization to make resizing not always trigger state change,
-      // only update attachment size in 10px steps
-      const width = Math.floor(this.$el.getBoundingClientRect().width / 10) * 10
-      if (this.width !== width) {
-        this.width = width
-      }
-    }
   }
 }
 
diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index 6169d294..3877987a 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -7,17 +7,19 @@
       v-for="(row, index) in rows"
       :key="index"
       class="gallery-row"
-      :style="rowHeight(row.length)"
+      :style="rowStyle(row.length)"
       :class="{ 'contain-fit': useContainFit, 'cover-fit': !useContainFit }"
     >
-      <attachment
-        v-for="attachment in row"
-        :key="attachment.id"
-        :set-media="setMedia"
-        :nsfw="nsfw"
-        :attachment="attachment"
-        :allow-play="false"
-      />
+      <div class="gallery-row-inner">
+        <attachment
+          v-for="attachment in row"
+          :key="attachment.id"
+          :set-media="setMedia"
+          :nsfw="nsfw"
+          :attachment="attachment"
+          :allow-play="false"
+        />
+      </div>
     </div>
   </div>
 </template>
@@ -28,15 +30,24 @@
 @import '../../_variables.scss';
 
 .gallery-row {
-  height: 200px;
+  position: relative;
+  height: 0;
   width: 100%;
-  display: flex;
-  flex-direction: row;
-  flex-wrap: nowrap;
-  align-content: stretch;
   flex-grow: 1;
   margin-top: 0.5em;
 
+  .gallery-row-inner {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    display: flex;
+    flex-direction: row;
+    flex-wrap: nowrap;
+    align-content: stretch;
+  }
+
   // FIXME: specificity problem with this and .attachments.attachment
   // we shouldn't have the need for .image here
   .attachment.image {

From 0396c6f29d29f3c9d743e00955a25e2d844b02da Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Fri, 18 Oct 2019 16:04:17 -0400
Subject: [PATCH 2/5] keep image natural ratio in gallery row

---
 src/components/attachment/attachment.js   |  8 +++++++-
 src/components/attachment/attachment.vue  |  1 +
 src/components/gallery/gallery.js         | 24 ++++++++++++++++++++---
 src/components/gallery/gallery.vue        |  2 ++
 src/components/still-image/still-image.js |  4 +++-
 5 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/src/components/attachment/attachment.js b/src/components/attachment/attachment.js
index e93921fe..0880bd7f 100644
--- a/src/components/attachment/attachment.js
+++ b/src/components/attachment/attachment.js
@@ -10,7 +10,8 @@ const Attachment = {
     'statusId',
     'size',
     'allowPlay',
-    'setMedia'
+    'setMedia',
+    'naturalSizeLoad'
   ],
   data () {
     return {
@@ -88,6 +89,11 @@ const Attachment = {
       } else {
         this.showHidden = !this.showHidden
       }
+    },
+    onImageLoad (image) {
+      const width = image.naturalWidth
+      const height = image.naturalHeight
+      this.naturalSizeLoad && this.naturalSizeLoad({ width, height })
     }
   }
 }
diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue
index af16e302..0748b2f0 100644
--- a/src/components/attachment/attachment.vue
+++ b/src/components/attachment/attachment.vue
@@ -58,6 +58,7 @@
         :referrerpolicy="referrerpolicy"
         :mimetype="attachment.mimetype"
         :src="attachment.large_thumb_url || attachment.url"
+        :image-load-handler="onImageLoad"
       />
     </a>
 
diff --git a/src/components/gallery/gallery.js b/src/components/gallery/gallery.js
index 3610f53d..e8cbb526 100644
--- a/src/components/gallery/gallery.js
+++ b/src/components/gallery/gallery.js
@@ -7,6 +7,11 @@ const Gallery = {
     'nsfw',
     'setMedia'
   ],
+  data () {
+    return {
+      sizes: {}
+    }
+  },
   components: { Attachment },
   computed: {
     rows () {
@@ -23,12 +28,25 @@ const Gallery = {
       }
       return rows
     },
-    rowStyle () {
-      return itemsPerRow => ({ 'padding-bottom': `${(100 / (itemsPerRow + 0.6))}%` })
-    },
     useContainFit () {
       return this.$store.state.config.useContainFit
     }
+  },
+  methods: {
+    onNaturalSizeLoad (id, size) {
+      this.$set(this.sizes, id, size)
+    },
+    rowStyle (itemsPerRow) {
+      return { 'padding-bottom': `${(100 / (itemsPerRow + 0.6))}%` }
+    },
+    itemStyle (id) {
+      const size = this.sizes[id]
+      if (size) {
+        return { flex: size.width / size.height }
+      } else {
+        return {}
+      }
+    }
   }
 }
 
diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index 3877987a..803ec471 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -18,6 +18,8 @@
           :nsfw="nsfw"
           :attachment="attachment"
           :allow-play="false"
+          :natural-size-load="onNaturalSizeLoad.bind(null, attachment.id)"
+          :style="itemStyle(attachment.id)"
         />
       </div>
     </div>
diff --git a/src/components/still-image/still-image.js b/src/components/still-image/still-image.js
index 02e98f19..9c2d446b 100644
--- a/src/components/still-image/still-image.js
+++ b/src/components/still-image/still-image.js
@@ -3,7 +3,8 @@ const StillImage = {
     'src',
     'referrerpolicy',
     'mimetype',
-    'imageLoadError'
+    'imageLoadError',
+    'imageLoadHandler'
   ],
   data () {
     return {
@@ -17,6 +18,7 @@ const StillImage = {
   },
   methods: {
     onLoad () {
+      this.imageLoadHandler && this.imageLoadHandler(this.$refs.src)
       const canvas = this.$refs.canvas
       if (!canvas) return
       const width = this.$refs.src.naturalWidth

From ad0452220619960f4f19c4557691d2f8f3438df9 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Mon, 21 Oct 2019 15:13:11 -0400
Subject: [PATCH 3/5] update flex-grow calculation logic

---
 src/components/gallery/gallery.js  | 14 +++++++-------
 src/components/gallery/gallery.vue |  2 +-
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/components/gallery/gallery.js b/src/components/gallery/gallery.js
index e8cbb526..4037da98 100644
--- a/src/components/gallery/gallery.js
+++ b/src/components/gallery/gallery.js
@@ -1,5 +1,5 @@
 import Attachment from '../attachment/attachment.vue'
-import { chunk, last, dropRight } from 'lodash'
+import { chunk, last, dropRight, sumBy } from 'lodash'
 
 const Gallery = {
   props: [
@@ -39,13 +39,13 @@ const Gallery = {
     rowStyle (itemsPerRow) {
       return { 'padding-bottom': `${(100 / (itemsPerRow + 0.6))}%` }
     },
-    itemStyle (id) {
+    itemStyle (id, row) {
+      const total = sumBy(row, item => this.getAspectRatio(item.id))
+      return { flexGrow: this.getAspectRatio(id) / total }
+    },
+    getAspectRatio (id) {
       const size = this.sizes[id]
-      if (size) {
-        return { flex: size.width / size.height }
-      } else {
-        return {}
-      }
+      return size ? size.width / size.height : 1
     }
   }
 }
diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index 803ec471..7abc2161 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -19,7 +19,7 @@
           :attachment="attachment"
           :allow-play="false"
           :natural-size-load="onNaturalSizeLoad.bind(null, attachment.id)"
-          :style="itemStyle(attachment.id)"
+          :style="itemStyle(attachment.id, row)"
         />
       </div>
     </div>

From b9c281c55374bc440d0efbf33d1dd74d8ea6dfd0 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Tue, 22 Oct 2019 07:10:52 -0400
Subject: [PATCH 4/5] set flex amount correctly

---
 src/components/gallery/gallery.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/gallery/gallery.js b/src/components/gallery/gallery.js
index 4037da98..9281d41b 100644
--- a/src/components/gallery/gallery.js
+++ b/src/components/gallery/gallery.js
@@ -41,7 +41,7 @@ const Gallery = {
     },
     itemStyle (id, row) {
       const total = sumBy(row, item => this.getAspectRatio(item.id))
-      return { flexGrow: this.getAspectRatio(id) / total }
+      return { flex: this.getAspectRatio(id) / total }
     },
     getAspectRatio (id) {
       const size = this.sizes[id]

From d76b83efc801cfc4bfd7cb0afa7d7289a16ec667 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Tue, 22 Oct 2019 14:47:21 -0400
Subject: [PATCH 5/5] set flex-shrink and flex-basis explicitly

---
 src/components/gallery/gallery.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/gallery/gallery.js b/src/components/gallery/gallery.js
index 9281d41b..bd0de608 100644
--- a/src/components/gallery/gallery.js
+++ b/src/components/gallery/gallery.js
@@ -41,7 +41,7 @@ const Gallery = {
     },
     itemStyle (id, row) {
       const total = sumBy(row, item => this.getAspectRatio(item.id))
-      return { flex: this.getAspectRatio(id) / total }
+      return { flex: `${this.getAspectRatio(id) / total} 1 0%` }
     },
     getAspectRatio (id) {
       const size = this.sizes[id]