mirror of https://github.com/halo-dev/halo
feat: add support for video thumbnail preview in the attachment library (#6265)
#### What type of PR is this? /kind feature #### What this PR does / why we need it: 附件页面视频文件展示封面 #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/5945 #### Special notes for your reviewer:  #### Does this PR introduce a user-facing change? ```release-note 附件库支持预览视频封面。 ```pull/6310/head
parent
45d0a475b5
commit
66d4986531
|
@ -35,9 +35,12 @@ import AttachmentGroupList from "./components/AttachmentGroupList.vue";
|
|||
import AttachmentListItem from "./components/AttachmentListItem.vue";
|
||||
import AttachmentPoliciesModal from "./components/AttachmentPoliciesModal.vue";
|
||||
import AttachmentUploadModal from "./components/AttachmentUploadModal.vue";
|
||||
import AttachmentLoading from "./components/AttachmentLoading.vue";
|
||||
import AttachmentError from "./components/AttachmentError.vue";
|
||||
import { useAttachmentControl } from "./composables/use-attachment";
|
||||
import { useFetchAttachmentGroup } from "./composables/use-attachment-group";
|
||||
import { useFetchAttachmentPolicy } from "./composables/use-attachment-policy";
|
||||
import LazyVideo from "@/components/video/LazyVideo.vue";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@ -526,24 +529,26 @@ onMounted(() => {
|
|||
classes="pointer-events-none object-cover group-hover:opacity-75 transform-gpu"
|
||||
>
|
||||
<template #loading>
|
||||
<div
|
||||
class="flex h-full items-center justify-center object-cover"
|
||||
>
|
||||
<span class="text-xs text-gray-400">
|
||||
{{ $t("core.common.status.loading") }}...
|
||||
</span>
|
||||
</div>
|
||||
<AttachmentLoading />
|
||||
</template>
|
||||
<template #error>
|
||||
<div
|
||||
class="flex h-full items-center justify-center object-cover"
|
||||
>
|
||||
<span class="text-xs text-red-400">
|
||||
{{ $t("core.common.status.loading_error") }}
|
||||
</span>
|
||||
</div>
|
||||
<AttachmentError />
|
||||
</template>
|
||||
</LazyImage>
|
||||
<LazyVideo
|
||||
v-else-if="
|
||||
attachment?.spec.mediaType?.startsWith('video/')
|
||||
"
|
||||
:src="attachment.status?.permalink"
|
||||
classes="object-cover group-hover:opacity-75"
|
||||
>
|
||||
<template #loading>
|
||||
<AttachmentLoading />
|
||||
</template>
|
||||
<template #error>
|
||||
<AttachmentError />
|
||||
</template>
|
||||
</LazyVideo>
|
||||
<AttachmentFileTypeIcon
|
||||
v-else
|
||||
:file-name="attachment.spec.displayName"
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<div class="flex h-full items-center justify-center object-cover">
|
||||
<span class="text-xs text-red-400">
|
||||
{{ $t("core.common.status.loading_error") }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<div class="flex h-full items-center justify-center object-cover">
|
||||
<span class="text-xs text-gray-400">
|
||||
{{ $t("core.common.status.loading") }}...
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,47 @@
|
|||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from "vue";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
src: string;
|
||||
classes?: string | string[];
|
||||
}>(),
|
||||
{
|
||||
src: "",
|
||||
classes: "",
|
||||
}
|
||||
);
|
||||
|
||||
const isLoading = ref(false);
|
||||
const error = ref(false);
|
||||
|
||||
const loadVideo = async () => {
|
||||
const video = document.createElement("video");
|
||||
video.src = props.src;
|
||||
return new Promise((resolve, reject) => {
|
||||
video.onloadedmetadata = () => resolve(video);
|
||||
video.onerror = (err) => reject(err);
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
isLoading.value = true;
|
||||
try {
|
||||
await loadVideo();
|
||||
} catch (e) {
|
||||
error.value = true;
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
isLoading.value = false;
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<template v-if="isLoading">
|
||||
<slot name="loading"> loading... </slot>
|
||||
</template>
|
||||
<template v-else-if="error">
|
||||
<slot name="error"> error </slot>
|
||||
</template>
|
||||
<video v-else :src="src" preload="metadata" :class="classes" />
|
||||
</template>
|
Loading…
Reference in New Issue