From 6c4d23714a42dd59843a8fb905150eed2d5db29d Mon Sep 17 00:00:00 2001 From: taehoon 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 }" > - + @@ -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 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" /> 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)" /> 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 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)" /> From b9c281c55374bc440d0efbf33d1dd74d8ea6dfd0 Mon Sep 17 00:00:00 2001 From: taehoon 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 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]