ytptube/ui/app/components/ImageView.vue
2025-08-29 19:00:26 +03:00

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>