聊天增加图片功能
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
<script setup lang="ts">
|
||||
import { onBeforeUnmount, ref, watch } from 'vue'
|
||||
import { fetchAdminFileBlob, fetchFileBlobByURL } from '@/api/files'
|
||||
|
||||
const props = defineProps<{
|
||||
source: string
|
||||
admin?: boolean
|
||||
}>()
|
||||
|
||||
const objectURL = ref('')
|
||||
const failed = ref(false)
|
||||
|
||||
function extractObjectKey(value: string) {
|
||||
try {
|
||||
const parsed = new URL(value, window.location.origin)
|
||||
return parsed.searchParams.get('key') || ''
|
||||
} catch {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
function revokeCurrentURL() {
|
||||
if (!objectURL.value) return
|
||||
URL.revokeObjectURL(objectURL.value)
|
||||
objectURL.value = ''
|
||||
}
|
||||
|
||||
async function loadImage() {
|
||||
revokeCurrentURL()
|
||||
failed.value = false
|
||||
if (!props.source) {
|
||||
failed.value = true
|
||||
return
|
||||
}
|
||||
try {
|
||||
const key = extractObjectKey(props.source)
|
||||
const blob = props.admin && key
|
||||
? await fetchAdminFileBlob(key)
|
||||
: await fetchFileBlobByURL(props.source)
|
||||
objectURL.value = URL.createObjectURL(blob)
|
||||
} catch {
|
||||
failed.value = true
|
||||
}
|
||||
}
|
||||
|
||||
function openImage() {
|
||||
if (!objectURL.value) return
|
||||
window.open(objectURL.value, '_blank')
|
||||
}
|
||||
|
||||
watch(() => [props.source, props.admin] as const, loadImage, { immediate: true })
|
||||
|
||||
onBeforeUnmount(revokeCurrentURL)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button v-if="objectURL" class="chat-image-button" type="button" @click="openImage">
|
||||
<img :src="objectURL" alt="聊天图片" loading="lazy">
|
||||
</button>
|
||||
<span v-else class="chat-image-fallback">{{ failed ? '图片加载失败' : '图片加载中' }}</span>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.chat-image-button {
|
||||
display: block;
|
||||
max-width: 220px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
border: 0;
|
||||
border-radius: 8px;
|
||||
background: transparent;
|
||||
cursor: zoom-in;
|
||||
}
|
||||
|
||||
.chat-image-button img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-height: 260px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.chat-image-fallback {
|
||||
display: inline-block;
|
||||
padding: 8px 10px;
|
||||
border-radius: 8px;
|
||||
background: #eef2f7;
|
||||
color: #6b7280;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user