Trigger re-layout on media load events

Loading media changes dimensions of the containing cards,
so we need to re-layout the grid.
This commit is contained in:
Marcel Hellkamp 2023-08-15 16:13:49 +02:00
parent 20dcbe74d4
commit 4bcf7c73d3
2 changed files with 14 additions and 10 deletions

View File

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, inject, onBeforeUnmount, onMounted, onUpdated, ref, watch } from 'vue'; import { computed, inject, onBeforeUnmount, onMounted, onUpdated, provide, ref, watch } from 'vue';
import { createFilterWrapper, debounceFilter, useDocumentVisibility, usePreferredDark, useWindowSize } from '@vueuse/core' import { createFilterWrapper, debounceFilter, useDocumentVisibility, usePreferredDark, useWindowSize } from '@vueuse/core'
import { type Config, type Post } from '@/types'; import { type Config, type Post } from '@/types';
@ -42,12 +42,14 @@ watch(visibilityState, () => {
}) })
// Fix Masonry layout on updates, config changes or window resize events // Fix Masonry layout on updates, config changes or window resize events
const fixLayout = inject('redrawVueMasonry') as () => void const fixLayoutNow = inject('redrawVueMasonry') as () => void
const windowSize = useWindowSize() const fixLayout = createFilterWrapper(debounceFilter(500, { maxWait: 500 }), ()=>{
const layoutDebounce = debounceFilter(500, { maxWait: 500 }) console.debug("Updating masonry layout")
const doFixLayoput = createFilterWrapper(layoutDebounce, () => fixLayout()) fixLayoutNow()
watch([windowSize.width, config, allPosts], doFixLayoput, { deep: true }) })
onUpdated(doFixLayoput) provide("fixLayout", fixLayout)
onUpdated(fixLayout)
watch([useWindowSize().width, config, allPosts], fixLayout, { deep: true })
// Watch for a theme changes // Watch for a theme changes
const isDarkPrefered = usePreferredDark() const isDarkPrefered = usePreferredDark()

View File

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { useElementVisibility, useIntervalFn } from '@vueuse/core' import { useElementVisibility, useIntervalFn } from '@vueuse/core'
import { computed, ref } from 'vue'; import { computed, inject, ref } from 'vue';
import moment from 'moment' import moment from 'moment'
import { type Config, type Post } from '@/types'; import { type Config, type Post } from '@/types';
@ -25,6 +25,8 @@ const playVideo = computed(() => {
return media.value?.type === "video" && props.config.playVideos && videoIsVisible.value return media.value?.type === "video" && props.config.playVideos && videoIsVisible.value
}) })
const onMediaLoad = inject('fixLayout', () => undefined)
</script> </script>
<template> <template>
@ -42,9 +44,9 @@ const playVideo = computed(() => {
</div> </div>
<div class="card-body"> <div class="card-body">
<div v-if="config.showMedia" class="wall-media mb-3"> <div v-if="config.showMedia" class="wall-media mb-3">
<img v-if="media?.type === 'image'" :src="media.url" :alt="media.alt" :title="media.alt"> <img v-if="media?.type === 'image'" :src="media.url" :alt="media.alt" :title="media.alt" @load="onMediaLoad">
<video v-else-if="media?.type === 'video'" ref="videoElement" muted loop :autoplay="playVideo" <video v-else-if="media?.type === 'video'" ref="videoElement" muted loop :autoplay="playVideo"
:poster="media.preview" :alt="media.alt" :title="media.alt"> :poster="media.preview" :alt="media.alt" :title="media.alt" @loadedmetadata="onMediaLoad">
<source v-if="playVideo" :src="media.url"> <source v-if="playVideo" :src="media.url">
</video> </video>
</div> </div>