Merge branch 'improve-gallery-sizing-logic' into 'develop'

Improve gallery sizing logic

See merge request pleroma/pleroma-fe!975
This commit is contained in:
HJ 2019-10-23 16:17:56 +00:00
commit f5c37231e1
5 changed files with 57 additions and 37 deletions

View file

@ -10,7 +10,8 @@ const Attachment = {
'statusId', 'statusId',
'size', 'size',
'allowPlay', 'allowPlay',
'setMedia' 'setMedia',
'naturalSizeLoad'
], ],
data () { data () {
return { return {
@ -88,6 +89,11 @@ const Attachment = {
} else { } else {
this.showHidden = !this.showHidden this.showHidden = !this.showHidden
} }
},
onImageLoad (image) {
const width = image.naturalWidth
const height = image.naturalHeight
this.naturalSizeLoad && this.naturalSizeLoad({ width, height })
} }
} }
} }

View file

@ -58,6 +58,7 @@
:referrerpolicy="referrerpolicy" :referrerpolicy="referrerpolicy"
:mimetype="attachment.mimetype" :mimetype="attachment.mimetype"
:src="attachment.large_thumb_url || attachment.url" :src="attachment.large_thumb_url || attachment.url"
:image-load-handler="onImageLoad"
/> />
</a> </a>

View file

@ -1,23 +1,18 @@
import Attachment from '../attachment/attachment.vue' import Attachment from '../attachment/attachment.vue'
import { chunk, last, dropRight } from 'lodash' import { chunk, last, dropRight, sumBy } from 'lodash'
const Gallery = { const Gallery = {
data: () => ({
width: 500
}),
props: [ props: [
'attachments', 'attachments',
'nsfw', 'nsfw',
'setMedia' 'setMedia'
], ],
data () {
return {
sizes: {}
}
},
components: { Attachment }, components: { Attachment },
mounted () {
this.resize()
window.addEventListener('resize', this.resize)
},
destroyed () {
window.removeEventListener('resize', this.resize)
},
computed: { computed: {
rows () { rows () {
if (!this.attachments) { if (!this.attachments) {
@ -33,21 +28,24 @@ const Gallery = {
} }
return rows return rows
}, },
rowHeight () {
return itemsPerRow => ({ 'height': `${(this.width / (itemsPerRow + 0.6))}px` })
},
useContainFit () { useContainFit () {
return this.$store.state.config.useContainFit return this.$store.state.config.useContainFit
} }
}, },
methods: { methods: {
resize () { onNaturalSizeLoad (id, size) {
// Quick optimization to make resizing not always trigger state change, this.$set(this.sizes, id, size)
// only update attachment size in 10px steps },
const width = Math.floor(this.$el.getBoundingClientRect().width / 10) * 10 rowStyle (itemsPerRow) {
if (this.width !== width) { return { 'padding-bottom': `${(100 / (itemsPerRow + 0.6))}%` }
this.width = width },
} itemStyle (id, row) {
const total = sumBy(row, item => this.getAspectRatio(item.id))
return { flex: `${this.getAspectRatio(id) / total} 1 0%` }
},
getAspectRatio (id) {
const size = this.sizes[id]
return size ? size.width / size.height : 1
} }
} }
} }

View file

@ -7,17 +7,21 @@
v-for="(row, index) in rows" v-for="(row, index) in rows"
:key="index" :key="index"
class="gallery-row" class="gallery-row"
:style="rowHeight(row.length)" :style="rowStyle(row.length)"
:class="{ 'contain-fit': useContainFit, 'cover-fit': !useContainFit }" :class="{ 'contain-fit': useContainFit, 'cover-fit': !useContainFit }"
> >
<attachment <div class="gallery-row-inner">
v-for="attachment in row" <attachment
:key="attachment.id" v-for="attachment in row"
:set-media="setMedia" :key="attachment.id"
:nsfw="nsfw" :set-media="setMedia"
:attachment="attachment" :nsfw="nsfw"
:allow-play="false" :attachment="attachment"
/> :allow-play="false"
:natural-size-load="onNaturalSizeLoad.bind(null, attachment.id)"
:style="itemStyle(attachment.id, row)"
/>
</div>
</div> </div>
</div> </div>
</template> </template>
@ -28,15 +32,24 @@
@import '../../_variables.scss'; @import '../../_variables.scss';
.gallery-row { .gallery-row {
height: 200px; position: relative;
height: 0;
width: 100%; width: 100%;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: stretch;
flex-grow: 1; flex-grow: 1;
margin-top: 0.5em; 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 // FIXME: specificity problem with this and .attachments.attachment
// we shouldn't have the need for .image here // we shouldn't have the need for .image here
.attachment.image { .attachment.image {

View file

@ -3,7 +3,8 @@ const StillImage = {
'src', 'src',
'referrerpolicy', 'referrerpolicy',
'mimetype', 'mimetype',
'imageLoadError' 'imageLoadError',
'imageLoadHandler'
], ],
data () { data () {
return { return {
@ -17,6 +18,7 @@ const StillImage = {
}, },
methods: { methods: {
onLoad () { onLoad () {
this.imageLoadHandler && this.imageLoadHandler(this.$refs.src)
const canvas = this.$refs.canvas const canvas = this.$refs.canvas
if (!canvas) return if (!canvas) return
const width = this.$refs.src.naturalWidth const width = this.$refs.src.naturalWidth