feat: 绘画功能本地图片存储优化

ui: 优化字体
This commit is contained in:
2024-03-20 18:00:04 +08:00
parent e69774679a
commit 75f431d7bf
9 changed files with 181 additions and 59 deletions

View File

@@ -2,6 +2,7 @@
import type {ResultBlockMeta} from '~/components/aigc/drawing/index';
import type {PropType} from 'vue';
import dayjs from 'dayjs';
import {get} from 'idb-keyval';
const props = defineProps({
icon: {
@@ -14,17 +15,62 @@ const props = defineProps({
prompt: {
type: String,
},
fid: {
type: String,
required: true,
},
images: {
type: Array,
default: (): Array<string> => [],
},
meta: {
type: Object as PropType<ResultBlockMeta>,
},
})
const toast = useToast()
const expand_prompt = ref(false)
const show_meta = ref(true)
const cachedImages = ref<string[]>([])
const cachedImagesInterval = ref<NodeJS.Timeout | null>(null)
onMounted(async () => {
cachedImagesInterval.value = setInterval(async () => {
cachedImages.value = await get(props.fid) as string[] || []
}, 1000)
})
onUnmounted(() => {
if (cachedImagesInterval.value) {
clearInterval(cachedImagesInterval.value)
}
})
const handle_download = (url: string) => {
const a = document.createElement('a')
a.href = url
a.download = `xsh_ai_drawing-${dayjs(props.meta?.datetime! * 1000).format('YYYY-MM-DD-HH-mm-ss')}.png`
a.click()
}
const copyToClipboard = (text: string) => {
navigator.clipboard.writeText(text).then(() => {
toast.add({
title: '复制成功',
description: '已将内容复制到剪贴板',
color: 'primary',
icon: 'i-tabler-copy',
})
}).catch(() => {
toast.add({
title: '复制失败',
description: '无法复制到剪贴板',
color: 'red',
icon: 'i-tabler-circle-x',
})
})
}
</script>
<template>
@@ -47,13 +93,30 @@ const show_meta = ref(true)
@click="expand_prompt = !expand_prompt">
{{ prompt }}
</p>
<UButton color="gray" size="xs" icon="i-tabler-copy" variant="ghost" class="-mt-1"></UButton>
<UButton color="gray" size="xs" icon="i-tabler-copy" variant="ghost" class="-mt-1"
@click="copyToClipboard(prompt)"></UButton>
</div>
<div v-if="images.length > 0" class="flex items-center overflow-x-auto h-64 gap-2 pb-2 snap-x">
<img v-for="(url, i) in images" class="result-image" :src="useBlobUrlFromB64(url)" alt="AI Generated" :key="i"/>
<div v-if="cachedImages.length > 0" class="flex items-center overflow-x-auto h-64 gap-2 pb-2 snap-x">
<div class="h-full aspect-auto relative rounded-lg shadow-md overflow-hidden group"
v-for="(url, i) in cachedImages" :key="`${fid}-${i}`">
<div class="absolute inset-0 bg-gradient-to-t from-neutral-800/40 to-transparent w-full h-full flex items-end
scale-105 opacity-0 group-hover:scale-100 group-hover:opacity-100 transition">
<div class="w-full flex justify-end gap-1 p-1">
<UTooltip text="以此图为参考创作">
<UButton color="indigo" variant="soft" size="2xs" icon="i-tabler-copy" square></UButton>
</UTooltip>
<UTooltip text="下载">
<UButton color="indigo" variant="soft" size="2xs" icon="i-tabler-download" square
@click="handle_download(url)"></UButton>
</UTooltip>
</div>
</div>
<img class="result-image" :src="useBlobUrlFromB64(url)" alt="AI Generated"/>
</div>
</div>
<div v-else class="h-64 aspect-[3/4] mb-4 rounded-lg placeholder-gradient flex justify-center items-center">
<UIcon name="i-svg-spinners-tadpole" class="text-3xl" />
<UIcon name="i-svg-spinners-tadpole" class="text-3xl"/>
</div>
<Transition v-if="meta" name="meta">
<div v-if="show_meta" class="w-full flex items-center gap-2 flex-wrap whitespace-nowrap pb-2 mt-2">
@@ -95,7 +158,7 @@ const show_meta = ref(true)
.result-image {
@apply snap-start;
@apply h-full aspect-auto object-cover rounded-lg shadow-md;
@apply w-full h-full object-cover;
}
.placeholder-gradient {