Initial Commit
linter / quality (push) Canceled after 0s
tests / ci (8.3) (push) Canceled after 0s
tests / ci (8.4) (push) Canceled after 0s
tests / ci (8.5) (push) Canceled after 0s

This commit is contained in:
2026-08-29 14:39:18 +10:00
parent d8c270fabe
commit fadbc8cd5d
3 changed files with 123 additions and 34 deletions
@@ -1,5 +1,6 @@
<script setup lang="ts">
import Avatar from '@/components/dredge/Avatar.vue';
import PostVideo from './PostVideo.vue';
import type { Post } from '@/types/dredge.types';
import { usePauseOffscreen } from '@/composables/usePauseOffScreen';
import { ComponentPublicInstance, ref } from 'vue';
@@ -76,20 +77,12 @@ usePauseOffscreen(videoRefs);
:style="{ '--slide-count': carouselSlides.length }"
>
<v-carousel-item v-for="(slide, i) in carouselSlides" :key="i">
<video
<PostVideo
v-if="slide.video_url"
:src="slide.video_url"
:aria-label="slide.alt"
:ref="registerVideo"
controls
autoplay
muted
preload="metadata"
playsinline
class="card__video"
>
Your browser doesn't support video playback.
</video>
:register-video="registerVideo"
/>
<v-img
v-else-if="slide.url"
:src="slide.url"
@@ -117,21 +110,13 @@ usePauseOffscreen(videoRefs);
</v-carousel>
<!-- Single video -->
<video
<PostVideo
v-else-if="post.is_video && post.video_url"
:src="post.video_url"
:aria-label="imageAlt"
:ref="registerVideo"
:poster="post.image_url ?? undefined"
controls
autoplay
muted
preload="metadata"
playsinline
class="card__video"
>
Your browser doesn't support video playback.
</video>
:poster="post.image_url"
:register-video="registerVideo"
/>
<!-- Single image -->
<v-img
@@ -313,14 +298,6 @@ usePauseOffscreen(videoRefs);
border-color: transparent;
}
.card__video {
width: 100%;
max-height: 600px;
object-fit: contain;
background: #000;
display: block;
}
/* Delimiter row: allow it to fit or scroll instead of clipping */
:deep(.v-carousel__controls) {
background: transparent;
@@ -0,0 +1,96 @@
<script setup lang="ts">
import { ref } from 'vue';
const props = defineProps<{
src: string;
ariaLabel: string;
poster?: string | null;
registerVideo: (el: Element | null) => void;
}>();
const videoEl = ref<HTMLVideoElement | null>(null);
const isMuted = ref(true);
function setVideoRef(el: Element | null) {
videoEl.value = el as HTMLVideoElement | null;
props.registerVideo(el);
}
function toggleMute() {
if (!videoEl.value) return;
videoEl.value.muted = !videoEl.value.muted;
isMuted.value = videoEl.value.muted;
}
function togglePlay() {
if (!videoEl.value) return;
if (videoEl.value.paused) {
videoEl.value.play().catch(() => {});
} else {
videoEl.value.pause();
}
}
</script>
<template>
<div class="post-video">
<video
:ref="setVideoRef"
:src="src"
:aria-label="ariaLabel"
:poster="poster ?? undefined"
autoplay
muted
preload="metadata"
playsinline
class="post-video__el"
@click="togglePlay"
>
Your browser doesn't support video playback.
</video>
<button
type="button"
class="post-video__mute"
:aria-label="isMuted ? 'Unmute video' : 'Mute video'"
@click.stop="toggleMute"
>
<v-icon :icon="isMuted ? 'mdi-volume-off' : 'mdi-volume-high'" size="16" />
</button>
</div>
</template>
<style scoped>
.post-video {
position: relative;
width: 100%;
height: 100%;
}
.post-video__el {
width: 100%;
height: 100%;
max-height: 600px;
object-fit: contain;
background: #000;
display: block;
cursor: pointer;
}
.post-video__mute {
position: absolute;
bottom: 0.6rem;
right: 0.6rem;
width: 1.8rem;
height: 1.8rem;
display: grid;
place-items: center;
border-radius: 999px;
border: none;
background: rgba(0, 0, 0, 0.55);
color: #fff;
cursor: pointer;
z-index: 2;
}
.post-video__mute:hover {
background: rgba(0, 0, 0, 0.75);
}
</style>