Skip to content

Commit

Permalink
feat: support loading moment media images with thumbnails (#124)
Browse files Browse the repository at this point in the history
支持使用缩略图加载瞬间图片,减少网络传输。

/kind feature

```release-note
支持使用缩略图加载瞬间图片,减少网络传输。
```
  • Loading branch information
ruibaby authored Sep 3, 2024
1 parent 4db48c9 commit 587f24c
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 36 deletions.
32 changes: 19 additions & 13 deletions console/src/components/MediaCard.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts" setup>
import type { MomentMedia } from "@/api/generated";
import { computed } from "vue";
import LucideFileAudio from "~icons/lucide/file-audio";
import LucideFileVideo from "~icons/lucide/file-video";
import MingCloseCircle from "~icons/mingcute/close-circle-fill";
Expand All @@ -8,9 +9,7 @@ const props = withDefaults(
defineProps<{
media: MomentMedia;
}>(),
{
media: undefined,
}
{}
);
const emit = defineEmits<{
Expand Down Expand Up @@ -46,54 +45,61 @@ const getExtname = (type?: string) => {
}
return "";
};
const imageThumbnailUrl = computed(() => {
const { url } = props.media || {};
return `/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=${encodeURI(
url || ""
)}&size=s`;
});
</script>
<template>
<div class="relative overflow-hidden">
<template v-if="props.media.type == 'PHOTO'">
<template v-if="media.type == 'PHOTO'">
<div class="aspect-square">
<img
:src="props.media.url"
:src="imageThumbnailUrl"
class="size-full object-cover"
loading="lazy"
/>
</div>
</template>
<template v-else-if="props.media.type == 'VIDEO'">
<template v-else-if="media.type == 'VIDEO'">
<div class="aspect-square">
<video
v-if="canPlayType(props.media.originType)"
v-if="canPlayType(media.originType)"
class="size-full object-cover"
preload="metadata"
>
<source :src="props.media.url" :type="props.media.originType" />
<source :src="media.url" :type="media.originType" />
</video>
<div
v-else
class="size-full flex flex-col items-center justify-center bg-gray-100 space-y-1"
>
<LucideFileVideo />
<span class="text-xs text-gray-500 font-sans">
{{ getExtname(props.media.originType) }}
{{ getExtname(media.originType) }}
</span>
</div>
</div>
</template>
<template v-else-if="props.media.type == 'AUDIO'">
<template v-else-if="media.type == 'AUDIO'">
<div class="aspect-square">
<audio
v-if="audioType(props.media.originType)"
v-if="audioType(media.originType)"
class="object-cover"
preload="metadata"
>
<source :src="props.media.url" :type="props.media.originType" />
<source :src="media.url" :type="media.originType" />
</audio>
<div
v-else
class="size-full flex flex-col items-center justify-center bg-gray-100 space-y-1"
>
<LucideFileAudio />
<span class="text-xs text-gray-500 font-sans">
{{ getExtname(props.media.originType) }}
{{ getExtname(media.originType) }}
</span>
</div>
</div>
Expand Down
16 changes: 11 additions & 5 deletions console/src/components/MomentPreview.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts" setup>
import type { Moment } from "@/api/generated";
import type { Moment, MomentMedia } from "@/api/generated";
import { IconArrowLeft, IconArrowRight } from "@halo-dev/components";
import hljs from "highlight.js/lib/common";
import xml from "highlight.js/lib/languages/xml";
Expand Down Expand Up @@ -99,13 +99,19 @@ const getExtname = (type?: string) => {
}
return "";
};
function getImageThumbnailUrl(media: MomentMedia) {
const { url } = media || {};
return `/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=${encodeURI(
url || ""
)}&size=s`;
}
</script>
<template>
<PreviewDetailModal
v-if="selectedMedia"
v-model:visible="detailVisible"
v-if="detailVisible && selectedMedia"
:media="selectedMedia"
@close="(selectedMedia = undefined) && (selectedIndex = 0)"
@close="detailVisible = false"
>
<template #actions>
<span
Expand Down Expand Up @@ -145,7 +151,7 @@ const getExtname = (type?: string) => {
<div class="aspect-square" @click="handleClickMedium(index)">
<template v-if="media.type == 'PHOTO'">
<img
:src="media.url"
:src="getImageThumbnailUrl(media)"
class="size-full object-cover"
loading="lazy"
/>
Expand Down
24 changes: 6 additions & 18 deletions console/src/components/PreviewDetailModal.vue
Original file line number Diff line number Diff line change
@@ -1,38 +1,31 @@
<script setup lang="ts">
import type { MomentMedia } from "@/api/generated";
import { VButton, VModal, VSpace } from "@halo-dev/components";
import { VButton, VModal } from "@halo-dev/components";
import { ref } from "vue";
const props = withDefaults(
defineProps<{
visible: boolean;
media: MomentMedia;
}>(),
{
visible: false,
media: undefined,
}
);
const emit = defineEmits<{
(event: "update:visible", visible: boolean): void;
(event: "close"): void;
}>();
const onVisibleChange = (visible: boolean) => {
emit("update:visible", visible);
if (!visible) {
emit("close");
}
};
const modal = ref<InstanceType<typeof VModal> | null>(null);
</script>
<template>
<VModal
ref="modal"
title="预览"
:visible="visible"
:width="1000"
:layer-closable="true"
height="80vh"
@update:visible="onVisibleChange"
@close="emit('close')"
>
<template #actions>
<slot name="actions"></slot>
Expand All @@ -50,12 +43,7 @@ const onVisibleChange = (visible: boolean) => {
</template>
</div>
<template #footer>
<VSpace>
<VButton type="default" @click="onVisibleChange(false)"
>关闭 Esc</VButton
>
<slot name="footer" />
</VSpace>
<VButton type="default" @click="modal?.close()">关闭 Esc</VButton>
</template>
</VModal>
</template>

0 comments on commit 587f24c

Please sign in to comment.