aboutsummaryrefslogtreecommitdiff
path: root/src/site/components/uploader
diff options
context:
space:
mode:
authorPitu <[email protected]>2018-09-16 01:09:02 -0300
committerPitu <[email protected]>2018-09-16 01:09:02 -0300
commitfe10a00ba9a3c30d8718ca004ccd19518466f5bd (patch)
tree369752f59a88dd03df1e9752be0ba166bf93c933 /src/site/components/uploader
parentFirst version of start script (diff)
downloadhost.fuwn.me-fe10a00ba9a3c30d8718ca004ccd19518466f5bd.tar.xz
host.fuwn.me-fe10a00ba9a3c30d8718ca004ccd19518466f5bd.zip
Site
Diffstat (limited to 'src/site/components/uploader')
-rw-r--r--src/site/components/uploader/Uploader.vue251
1 files changed, 251 insertions, 0 deletions
diff --git a/src/site/components/uploader/Uploader.vue b/src/site/components/uploader/Uploader.vue
new file mode 100644
index 0000000..fcb79cb
--- /dev/null
+++ b/src/site/components/uploader/Uploader.vue
@@ -0,0 +1,251 @@
+<template>
+ <div :class="{ hasFiles: files.length > 0 }"
+ class="uploader-wrapper">
+ <b-select v-if="loggedIn"
+ v-model="selectedAlbum"
+ placeholder="Upload to album"
+ size="is-medium"
+ expanded>
+ <option
+ v-for="album in albums"
+ :value="album.id"
+ :key="album.id">
+ {{ album.name }}
+ </option>
+ </b-select>
+ <dropzone v-if="showDropzone"
+ id="dropzone"
+ ref="el"
+ :options="dropzoneOptions"
+ :include-styling="false"
+ @vdropzone-success="dropzoneSuccess"
+ @vdropzone-error="dropzoneError"
+ @vdropzone-files-added="dropzoneFilesAdded" />
+
+ <div id="template"
+ ref="template">
+ <div class="dz-preview dz-file-preview">
+ <div class="dz-details">
+ <div class="dz-filename"><span data-dz-name/></div>
+ <div class="dz-size"><span data-dz-size/></div>
+ </div>
+ <div class="result">
+ <div class="copyLink">
+ <b-tooltip label="Copy link">
+ <i class="icon-web-code"/>
+ </b-tooltip>
+ </div>
+ <div class="openLink">
+ <b-tooltip label="Open file">
+ <a class="link"
+ target="_blank">
+ <i class="icon-web-url"/>
+ </a>
+ </b-tooltip>
+ </div>
+ </div>
+ <div class="error">
+ <div>
+ <span>
+ <span class="error-message"
+ data-dz-errormessage/>
+ <i class="icon-web-warning"/>
+ </span>
+ </div>
+ </div>
+ <div class="dz-progress">
+ <span class="dz-upload"
+ data-dz-uploadprogress/>
+ </div>
+ <!--
+ <div class="dz-error-message"><span data-dz-errormessage/></div>
+ <div class="dz-success-mark"><i class="fa fa-check"/></div>
+ <div class="dz-error-mark"><i class="fa fa-close"/></div>
+ -->
+ </div>
+ </div>
+ </div>
+</template>
+
+<script>
+import Dropzone from 'nuxt-dropzone';
+import '../../styles/dropzone.scss';
+
+export default {
+ components: { Dropzone },
+ data() {
+ return {
+ files: [],
+ dropzoneOptions: {},
+ showDropzone: false,
+ albums: [],
+ selectedAlbum: null
+ };
+ },
+ computed: {
+ config() {
+ return this.$store.state.config;
+ },
+ token() {
+ return this.$store.state.token;
+ },
+ loggedIn() {
+ return this.$store.state.loggedIn;
+ }
+ },
+ watch: {
+ loggedIn() {
+ this.getAlbums();
+ },
+ selectedAlbum() {
+ this.updateDropzoneConfig();
+ }
+ },
+ mounted() {
+ this.dropzoneOptions = {
+ url: `${this.$config.baseURL}/upload`,
+ autoProcessQueue: true,
+ addRemoveLinks: false,
+ parallelUploads: 5,
+ uploadMultiple: false,
+ maxFiles: 1000,
+ createImageThumbnails: false,
+ paramName: 'file',
+ chunking: true,
+ retryChunks: true,
+ retryChunksLimit: 3,
+ parallelChunkUploads: false,
+ chunkSize: this.config.chunkSize * 1000000,
+ chunksUploaded: this.dropzoneChunksUploaded,
+ maxFilesize: this.config.maxFileSize,
+ previewTemplate: this.$refs.template.innerHTML,
+ dictDefaultMessage: 'Drag & Drop your files or click to browse',
+ headers: { Accept: 'application/vnd.lolisafe.json' }
+ };
+ this.showDropzone = true;
+ if (this.loggedIn) this.getAlbums();
+ },
+ methods: {
+ /*
+ Get all available albums so the user can upload directly to one (or several soon™) of them.
+ */
+ async getAlbums() {
+ try {
+ const response = await this.axios.get(`${this.$config.baseURL}/albums/dropdown`);
+ this.albums = response.data.albums;
+ this.updateDropzoneConfig();
+ } catch (error) {
+ this.$onPromiseError(error);
+ }
+ },
+
+ /*
+ This method needs to be called after the token or selectedAlbum changes
+ since dropzone doesn't seem to update the config values unless you force it.
+ Tch.
+ */
+ updateDropzoneConfig() {
+ this.$refs.el.setOption('headers', {
+ Accept: 'application/vnd.lolisafe.json',
+ Authorization: this.token ? `Bearer ${this.token}` : '',
+ albumId: this.selectedAlbum ? this.selectedAlbum : null
+ });
+ },
+
+ /*
+ Dropzone stuff
+ */
+ dropzoneFilesAdded(files) {
+ // console.log(files);
+ },
+ dropzoneSuccess(file, response) {
+ this.processResult(file, response);
+ },
+ dropzoneError(file, message, xhr) {
+ this.$showToast('There was an error uploading this file. Check the console.', true, 5000);
+ console.error(file, message, xhr);
+ },
+ dropzoneChunksUploaded(file, done) {
+ const response = JSON.parse(file.xhr.response);
+ if (!response.url) {
+ console.error('There was a problem uploading the file?');
+ return done();
+ }
+
+ this.processResult(file, response);
+ this.$forceUpdate();
+ return done();
+ },
+
+ /*
+ If upload/s was/were successfull we modify the template so that the buttons for
+ copying the returned url or opening it in a new window appear.
+ */
+ processResult(file, response) {
+ if (!response.url) return;
+ file.previewTemplate.querySelector('.link').setAttribute('href', response.url);
+ file.previewTemplate.querySelector('.copyLink').addEventListener('click', () => {
+ this.$showToast('Link copied!', false, 1000);
+ this.$clipboard(response.url);
+ });
+ }
+ }
+};
+</script>
+<style lang="scss" scoped>
+ #template { display: none; }
+ .uploader-wrapper {
+ display: block;
+ width: 400px;
+ margin: 0 auto;
+ max-width: 100%;
+ transition-duration: 86ms;
+ transition-property: box-shadow,-webkit-transform;
+ transition-property: box-shadow,transform;
+ transition-property: box-shadow,transform,-webkit-transform;
+ will-change: box-shadow,transform;
+
+ &:hover, &.hasFiles {
+ box-shadow: 0 1rem 3rem 0rem rgba(10, 10, 10, 0.25);
+ -webkit-transform: translateY(-.5rem);
+ transform: translateY(-.5rem);
+ }
+ }
+</style>
+<style lang="scss">
+ @import '../../styles/colors.scss';
+ .filepond--panel-root {
+ background: transparent;
+ border: 2px solid #2c3340;
+ }
+ .filepond--drop-label {
+ color: #c7ccd8;
+ pointer-events: none;
+ }
+
+ .filepond--item-panel {
+ background-color: #767b8b;
+ }
+
+ .filepond--root .filepond--drip-blob {
+ background-color: #7f8a9a
+ }
+
+ .filepond--drip {
+ background: black;
+ }
+
+ div.uploader-wrapper {
+ div.control {
+ margin-bottom: 5px;
+ span.select {
+ select {
+ border: 2px solid #2c3340;
+ background: rgba(0, 0, 0, 0.15);
+ border-radius: .3em;
+ color: $uploaderDropdownColor;
+ }
+ }
+ }
+ }
+</style>