You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
1.7 KiB
Vue
62 lines
1.7 KiB
Vue
<template>
|
|
<button class="btn btn-secondary" @click.prevent="$refs.fileInput.click()">
|
|
<slot><i class="bi-plus"></i></slot>
|
|
</button>
|
|
<input
|
|
type="file"
|
|
ref="fileInput"
|
|
class="d-none"
|
|
@change="setFile($refs.fileInput.files[0])"
|
|
/>
|
|
<div v-if="info">{{ info }}</div>
|
|
<div v-if="progressRef">
|
|
<ByteCalc :bytes="progressRef.loaded" /><span> of </span
|
|
><ByteCalc :bytes="progressRef.total" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import ByteCalc from '@/components/helpers/ByteCalc.vue';
|
|
import { defineEmits, defineProps, ref } from 'vue';
|
|
import { readFileBuffer } from '@/lib/readFileBlob';
|
|
import { useWebdavStore } from '@/store/webdav';
|
|
import type { ProgressEvent } from 'webdav';
|
|
|
|
const props = defineProps({ path: String });
|
|
const emit = defineEmits(['started', 'finished', 'failed', 'progress']);
|
|
const store = useWebdavStore();
|
|
|
|
const progressRef = ref(null as null | ProgressEvent);
|
|
const info = ref('');
|
|
|
|
const setFile = async (file: File) => {
|
|
emit('started');
|
|
const buffer = await readFileBuffer(file);
|
|
try {
|
|
await store.currentSession?.client.putFileContents(
|
|
`${props.path}/${file.name}`,
|
|
buffer,
|
|
{
|
|
onUploadProgress: (progress) => {
|
|
progressRef.value = progress;
|
|
emit('progress', progress);
|
|
console.log(`Uploaded ${progress.loaded} bytes of ${progress.total}`);
|
|
},
|
|
}
|
|
);
|
|
info.value = 'upload completed';
|
|
emit('finished');
|
|
} catch (e) {
|
|
info.value = 'upload failed';
|
|
emit('failed', e);
|
|
console.error(e);
|
|
}
|
|
setTimeout(() => {
|
|
progressRef.value = null;
|
|
info.value = '';
|
|
}, 2000);
|
|
};
|
|
</script>
|
|
|
|
<style scoped></style>
|