Files
2025-05-28 09:55:51 +08:00

72 lines
2.0 KiB
Vue

<script setup>
import { ref, toRefs, watch } from 'vue'
import { supabase } from '../supabase'
const prop = defineProps(['path', 'size'])
const { path, size } = toRefs(prop)
const emit = defineEmits(['upload', 'update:path'])
const uploading = ref(false)
const src = ref('')
const files = ref()
const downloadImage = async () => {
try {
const { data, error } = await supabase.storage
.from('avatars')
.download(path.value)
if (error) throw error
src.value = URL.createObjectURL(data)
} catch (error) {
console.error('Error downloading image: ', error.message)
}
}
const uploadAvatar = async (evt) => {
files.value = evt.target.files
try {
uploading.value = true
if (!files.value || files.value.length === 0) {
throw new Error('You must select an image to upload.')
}
const file = files.value[0]
const fileExt = file.name.split('.').pop()
const filePath = `${Math.random()}.${fileExt}`
let { error: uploadError } = await supabase.storage
.from('avatars')
.upload(filePath, file)
if (uploadError) throw uploadError
emit('update:path', filePath)
emit('upload')
} catch (error) {
alert(error.message)
} finally {
uploading.value = false
}
}
watch(path, () => {
if (path.value) downloadImage()
})
</script>
<template>
<div>
<img v-if="src" :src="src" alt="Avatar" class="avatar image"
:style="{ height: size + 'em', width: size + 'em' }" />
<div v-else class="avatar no-image" :style="{ height: size + 'em', width: size + 'em' }" />
<div :style="{ width: size + 'em' }">
<label class="button primary block" for="single">
{{ uploading ? "Uploading ..." : "Upload" }}
</label>
<input style="visibility: hidden; position: absolute" type="file" id="single" accept="image/*"
@change="uploadAvatar" :disabled="uploading" />
</div>
</div>
</template>