Initial commit. Files are uploaded to the filesystem.
This commit is contained in:
178
components/upload/drop.vue
Normal file
178
components/upload/drop.vue
Normal file
@@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<form
|
||||
class="selector"
|
||||
:class="{ dragging }"
|
||||
@submit.prevent="upload"
|
||||
>
|
||||
<div
|
||||
ref="dropzone"
|
||||
class="dropzone"
|
||||
@drop.prevent="dropFile"
|
||||
@dragover="dragging = true"
|
||||
@dragleave="dragging = false"
|
||||
>
|
||||
<input
|
||||
type="file"
|
||||
@change="selectFile"
|
||||
>
|
||||
Drop or paste your files here
|
||||
</div>
|
||||
|
||||
<ul class="uploads nolist">
|
||||
<li
|
||||
v-for="upload in thumbs"
|
||||
class="upload"
|
||||
>
|
||||
<img
|
||||
v-if="upload.file.type.indexOf('image/') === 0"
|
||||
:src="upload.thumb"
|
||||
class="upload-thumb"
|
||||
>
|
||||
|
||||
<video
|
||||
v-if="upload.file.type.indexOf('video/') === 0"
|
||||
class="upload-thumb"
|
||||
autoplay
|
||||
muted
|
||||
loop
|
||||
>
|
||||
<source :src="upload.thumb">
|
||||
</video>
|
||||
|
||||
<span class="upload-name ellipsis">{{ upload.file.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<button
|
||||
class="button button-primary submit"
|
||||
>Upload</button>
|
||||
|
||||
<label>
|
||||
<input
|
||||
v-model="addToAlbum"
|
||||
type="checkbox"
|
||||
>Add to album
|
||||
</label>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
|
||||
import { post } from '#src/api.ts';
|
||||
|
||||
const dropzone = ref(null);
|
||||
const dragging = ref(false);
|
||||
|
||||
const uploads = ref([]);
|
||||
const thumbs = ref([]);
|
||||
|
||||
const addToAlbum = ref(true);
|
||||
|
||||
async function upload() {
|
||||
console.log('UPLOAD!', uploads.value);
|
||||
const form = new FormData();
|
||||
|
||||
uploads.value.forEach((file) => {
|
||||
form.append('files', file);
|
||||
});
|
||||
|
||||
form.append('options', JSON.stringify({
|
||||
addToAlbum: addToAlbum.value,
|
||||
}));
|
||||
|
||||
const res = await post('/files', form);
|
||||
|
||||
console.log(res);
|
||||
}
|
||||
|
||||
function addFiles(newFiles) {
|
||||
console.log('NEW FILES', newFiles);
|
||||
|
||||
uploads.value = uploads.value.concat(newFiles);
|
||||
|
||||
thumbs.value = thumbs.value.concat(newFiles.map((file) => ({
|
||||
file,
|
||||
thumb: URL.createObjectURL(file),
|
||||
})));
|
||||
}
|
||||
|
||||
function dropFile(event) {
|
||||
dragging.value = false;
|
||||
|
||||
const newFiles = Array.from(event.dataTransfer.items)
|
||||
.filter((item) => item.kind === 'file')
|
||||
.map((item) => item.getAsFile());
|
||||
|
||||
addFiles(newFiles);
|
||||
}
|
||||
|
||||
function selectFile(event) {
|
||||
const newFiles = Array.from(event.target.files);
|
||||
|
||||
addFiles(newFiles);
|
||||
|
||||
event.target.value = null;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('dragover', (event) => event.preventDefault());
|
||||
window.addEventListener('drop', (event) => event.preventDefault());
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.selector {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.dropzone {
|
||||
width: 100%;
|
||||
height: 15rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
padding: 1rem;
|
||||
border: solid 1px var(--glass-weak-20);
|
||||
|
||||
&.dragging {
|
||||
background: var(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
.uploads {
|
||||
width: 100%;
|
||||
display: grid;
|
||||
align-items: center;
|
||||
grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
|
||||
gap: .5rem;
|
||||
}
|
||||
|
||||
.upload {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.upload-thumb {
|
||||
width: 8rem;
|
||||
height: 6rem;
|
||||
object-fit: cover;
|
||||
margin-bottom: .25rem;
|
||||
}
|
||||
|
||||
.upload-name {
|
||||
font-size: .8rem;
|
||||
}
|
||||
|
||||
.submit {
|
||||
font-size: 1.2rem;
|
||||
padding: .75rem 1rem;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user