mirror of
https://github.com/simon987/sist2.git
synced 2025-04-19 02:06:46 +00:00
173 lines
4.3 KiB
Vue
173 lines
4.3 KiB
Vue
<template>
|
|
<div v-if="doc._props.hasThumbnail" class="img-wrapper" @mouseenter="onTnEnter()" @mouseleave="onTnLeave()"
|
|
@touchstart="onTouchStart()">
|
|
<div v-if="doc._props.isAudio" class="card-img-overlay" :class="{'small-badge': smallBadge}">
|
|
<span class="badge badge-resolution">{{ humanTime(doc._source.duration) }}</span>
|
|
</div>
|
|
|
|
<div
|
|
v-if="doc._props.isImage && !hover && doc._props.tnW / doc._props.tnH < 5"
|
|
class="card-img-overlay"
|
|
:class="{'small-badge': smallBadge}">
|
|
<span class="badge badge-resolution">{{ `${doc._source.width}x${doc._source.height}` }}</span>
|
|
</div>
|
|
|
|
<div v-if="(doc._props.isVideo || doc._props.isGif) && doc._source.duration > 0 && !hover"
|
|
class="card-img-overlay"
|
|
:class="{'small-badge': smallBadge}">
|
|
<span class="badge badge-resolution">{{ humanTime(doc._source.duration) }}</span>
|
|
</div>
|
|
|
|
<div v-if="doc._props.isPlayableVideo" class="play">
|
|
<svg viewBox="0 0 494.942 494.942" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="m35.353 0 424.236 247.471-424.236 247.471z"/>
|
|
</svg>
|
|
</div>
|
|
|
|
<img ref="tn"
|
|
v-if="doc._props.isPlayableImage || doc._props.isPlayableVideo"
|
|
:src="tnSrc"
|
|
alt=""
|
|
:style="{height: (doc._props.isGif && hover) ? `${tnHeight()}px` : undefined}"
|
|
class="pointer fit card-img-top" @click="onThumbnailClick()">
|
|
<img v-else :src="tnSrc" alt=""
|
|
class="fit card-img-top">
|
|
|
|
<ThumbnailProgressBar v-if="hover && doc._props.hasVidPreview"
|
|
:progress="(currentThumbnailNum + 1) / (doc._props.tnNum)"
|
|
></ThumbnailProgressBar>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import {humanTime} from "@/util";
|
|
import ThumbnailProgressBar from "@/components/ThumbnailProgressBar";
|
|
|
|
export default {
|
|
name: "FullThumbnail",
|
|
props: ["doc", "smallBadge"],
|
|
components: {ThumbnailProgressBar},
|
|
data() {
|
|
return {
|
|
hover: false,
|
|
currentThumbnailNum: 0,
|
|
timeoutId: null
|
|
}
|
|
},
|
|
created() {
|
|
this.$store.subscribe((mutation) => {
|
|
if (mutation.type === "busTnTouchStart" && mutation.payload !== this.doc._id) {
|
|
this.onTnLeave();
|
|
}
|
|
});
|
|
},
|
|
computed: {
|
|
tnSrc() {
|
|
const doc = this.doc;
|
|
const props = doc._props;
|
|
if (props.isGif && this.hover) {
|
|
return `f/${doc._id}`;
|
|
}
|
|
return (this.currentThumbnailNum === 0)
|
|
? `t/${doc._source.index}/${doc._id}`
|
|
: `t/${doc._source.index}/${doc._id}${String(this.currentThumbnailNum).padStart(4, "0")}`;
|
|
},
|
|
},
|
|
methods: {
|
|
humanTime: humanTime,
|
|
onThumbnailClick() {
|
|
this.$emit("onThumbnailClick");
|
|
},
|
|
tnHeight() {
|
|
return this.$refs.tn.height;
|
|
},
|
|
tnWidth() {
|
|
return this.$refs.tn.width;
|
|
},
|
|
onTnEnter() {
|
|
this.hover = true;
|
|
if (this.doc._props.hasVidPreview) {
|
|
this.currentThumbnailNum += 1;
|
|
this.scheduleNextTnNum();
|
|
}
|
|
},
|
|
onTnLeave() {
|
|
this.currentThumbnailNum = 0;
|
|
this.hover = false;
|
|
if (this.timeoutId !== null) {
|
|
window.clearTimeout(this.timeoutId);
|
|
this.timeoutId = null;
|
|
}
|
|
},
|
|
scheduleNextTnNum() {
|
|
const INTERVAL = this.$store.state.optVidPreviewInterval ?? 700;
|
|
this.timeoutId = window.setTimeout(() => {
|
|
if (!this.hover) {
|
|
return;
|
|
}
|
|
this.scheduleNextTnNum();
|
|
if (this.currentThumbnailNum === this.doc._props.tnNum - 1) {
|
|
this.currentThumbnailNum = 0;
|
|
} else {
|
|
this.currentThumbnailNum += 1;
|
|
}
|
|
}, INTERVAL);
|
|
},
|
|
onTouchStart() {
|
|
this.$store.commit("busTnTouchStart", this.doc._id);
|
|
if (!this.hover) {
|
|
this.onTnEnter()
|
|
}
|
|
},
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.img-wrapper {
|
|
position: relative;
|
|
}
|
|
|
|
.img-wrapper:hover svg {
|
|
fill: rgba(0, 0, 0, 1);
|
|
}
|
|
|
|
.card-img-top {
|
|
border-top-left-radius: 0;
|
|
border-top-right-radius: 0;
|
|
}
|
|
|
|
.play {
|
|
position: absolute;
|
|
width: 25px;
|
|
height: 25px;
|
|
left: 50%;
|
|
top: 50%;
|
|
transform: translate(-50%, -50%);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.play svg {
|
|
fill: rgba(0, 0, 0, 0.7);
|
|
}
|
|
|
|
.badge-resolution {
|
|
color: #212529;
|
|
background-color: #FFC107;
|
|
}
|
|
|
|
.card-img-overlay {
|
|
pointer-events: none;
|
|
padding: 0.75rem;
|
|
bottom: unset;
|
|
top: 0;
|
|
left: unset;
|
|
right: unset;
|
|
}
|
|
|
|
.small-badge {
|
|
padding: 1px 3px;
|
|
font-size: 70%;
|
|
}
|
|
|
|
</style> |