74 lines
1.4 KiB
Vue
74 lines
1.4 KiB
Vue
<style scoped>
|
|
img {
|
|
max-width: 100%;
|
|
max-height: 100%;
|
|
margin: auto;
|
|
display: block;
|
|
}
|
|
</style>
|
|
|
|
<template>
|
|
<div>
|
|
<div style="font-size:30vh; width: 99%" class="has-text-centered" v-if="isLoading">
|
|
<i class="fas fa-circle-notch fa-spin"></i>
|
|
</div>
|
|
<div v-else>
|
|
<img :src="image">
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { disableOpacity, enableOpacity } from '~/utils'
|
|
|
|
const toast = useNotification()
|
|
const emitter = defineEmits(['closeModel'])
|
|
|
|
const isLoading = ref<boolean>(false)
|
|
const image = ref<string>('')
|
|
|
|
const props = defineProps({
|
|
link: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
})
|
|
|
|
const handle_event = (e: KeyboardEvent) => {
|
|
if (e.key !== 'Escape') {
|
|
return
|
|
}
|
|
emitter('closeModel')
|
|
}
|
|
|
|
onMounted(async () => {
|
|
disableOpacity()
|
|
document.addEventListener('keydown', handle_event)
|
|
|
|
const url = props.link.startsWith('/') ? props.link : '/api/thumbnail?url=' + encodePath(props.link)
|
|
|
|
try {
|
|
isLoading.value = true
|
|
|
|
const imgRequest = await request(url)
|
|
if (200 !== imgRequest.status) {
|
|
return
|
|
}
|
|
|
|
image.value = URL.createObjectURL(await imgRequest.blob())
|
|
} catch (e: any) {
|
|
console.error(e)
|
|
toast.error(`Error: ${e.message}`)
|
|
} finally {
|
|
isLoading.value = false
|
|
}
|
|
})
|
|
|
|
onBeforeUnmount(() => {
|
|
document.removeEventListener('keydown', handle_event)
|
|
if (image.value) {
|
|
URL.revokeObjectURL(image.value)
|
|
}
|
|
enableOpacity()
|
|
})
|
|
</script>
|