2020-08-25 23:37:33 +00:00
|
|
|
<template lang="html">
|
2021-01-20 21:21:06 +00:00
|
|
|
<b-container>
|
2020-11-23 23:15:29 +00:00
|
|
|
<empty-state
|
|
|
|
v-if="showEmptyState"
|
|
|
|
:title="$t('wallpapers.title')"
|
|
|
|
message="Upload a wallpaper to customize your boards"
|
|
|
|
action-text="Upload a wallpaper"
|
|
|
|
:busy="saving"
|
|
|
|
@action="triggerFileUpload"
|
|
|
|
/>
|
2020-11-21 06:32:14 +00:00
|
|
|
|
2020-11-23 23:15:29 +00:00
|
|
|
<template v-else>
|
|
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
|
|
<h3 class="m-0">
|
|
|
|
{{ $t('wallpapers.title') }}
|
|
|
|
</h3>
|
|
|
|
|
2021-02-03 22:57:07 +00:00
|
|
|
<div class="space-used ml-auto mr-3 pt-3">
|
|
|
|
<small class="d-block text-center" :class="{ 'text-danger': outOfSpace }">
|
|
|
|
{{ formattedSpaceUsed }} of {{ bytesToSize(maxSpace) }} used
|
|
|
|
</small>
|
|
|
|
|
|
|
|
<b-progress
|
|
|
|
:value="spaceUsed"
|
|
|
|
:max="maxSpace"
|
|
|
|
:variant="outOfSpace ? 'danger' : 'success'"
|
|
|
|
class="mb-3"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
|
2020-11-23 23:15:29 +00:00
|
|
|
<b-button
|
|
|
|
variant="primary"
|
2020-12-15 05:34:36 +00:00
|
|
|
:disabled="outOfSpace"
|
2020-11-23 23:15:29 +00:00
|
|
|
@click="triggerFileUpload"
|
|
|
|
>
|
2021-01-20 21:21:06 +00:00
|
|
|
<b-spinner small v-if="saving" />
|
|
|
|
|
|
|
|
<template v-else>
|
2020-12-28 15:22:03 +00:00
|
|
|
<i class="fas fa-upload fa-fw" aria-hidden />
|
2021-01-20 21:21:06 +00:00
|
|
|
<span class="d-none d-sm-inline">Upload</span>
|
|
|
|
</template>
|
2020-11-23 23:15:29 +00:00
|
|
|
</b-button>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<b-alert
|
|
|
|
v-if="isDuplicate && !saving && file && file.name"
|
|
|
|
show
|
|
|
|
dismissible
|
|
|
|
variant="warning"
|
|
|
|
>
|
|
|
|
{{ $t('wallpapers.form.duplicateMessage', { fileName: file.name }) }}
|
|
|
|
</b-alert>
|
|
|
|
|
2021-02-03 22:57:07 +00:00
|
|
|
<div
|
2020-11-23 23:15:29 +00:00
|
|
|
v-if="wallpapers.length"
|
2021-02-03 22:57:07 +00:00
|
|
|
class="wallpapers"
|
2020-11-23 23:15:29 +00:00
|
|
|
>
|
2021-02-03 22:57:07 +00:00
|
|
|
<b-card
|
|
|
|
v-for="wallpaper in wallpapers"
|
|
|
|
:key="wallpaper.name"
|
|
|
|
:img-src="wallpaper.url"
|
|
|
|
:img-alt="wallpaper.name"
|
|
|
|
img-top
|
|
|
|
bg-variant="transparent"
|
|
|
|
img-width="180"
|
|
|
|
class="mb-3 overflow-hidden word-wrap"
|
2020-11-23 23:15:29 +00:00
|
|
|
>
|
2021-02-03 22:57:07 +00:00
|
|
|
<h6>
|
|
|
|
{{ wallpaper.name }}
|
|
|
|
|
|
|
|
<b-badge v-if="wallpaper.metadata && wallpaper.metadata.size">
|
|
|
|
{{ bytesToSize(wallpaper.metadata.size) }}
|
|
|
|
</b-badge>
|
|
|
|
</h6>
|
|
|
|
|
|
|
|
<b-button
|
|
|
|
variant="danger"
|
|
|
|
size="sm"
|
|
|
|
@click="confirmDeleteWallpaper(wallpaper)"
|
|
|
|
>
|
|
|
|
<i class="fas fa-trash-alt fa-fw" aria-hidden />
|
|
|
|
</b-button>
|
|
|
|
</b-card>
|
|
|
|
</div>
|
2020-11-23 23:15:29 +00:00
|
|
|
|
|
|
|
<b-alert show v-else>You don't have any wallpapers.</b-alert>
|
|
|
|
</template>
|
2021-01-20 21:21:06 +00:00
|
|
|
|
|
|
|
<b-form-file
|
|
|
|
class="d-none file-input"
|
|
|
|
v-model="file"
|
|
|
|
accept="image/*"
|
|
|
|
:browse-text="$t('wallpapers.form.upload')"
|
|
|
|
:placeholder="$t('wallpapers.form.placeholder')"
|
|
|
|
@input="uploadWallpaper"
|
|
|
|
/>
|
2020-11-21 06:32:14 +00:00
|
|
|
</b-container>
|
2020-08-25 23:37:33 +00:00
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2020-10-14 00:35:40 +00:00
|
|
|
import { mapState, mapGetters } from 'vuex';
|
2020-11-23 23:15:29 +00:00
|
|
|
import EmptyState from '@/components/EmptyState';
|
2020-08-25 23:37:33 +00:00
|
|
|
|
|
|
|
export default {
|
2020-11-23 23:15:29 +00:00
|
|
|
components: {
|
|
|
|
EmptyState,
|
|
|
|
},
|
|
|
|
|
2020-08-25 23:37:33 +00:00
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
file: null,
|
|
|
|
saving: false,
|
|
|
|
loading: false,
|
2020-11-21 06:32:14 +00:00
|
|
|
isPaid: true,
|
2020-12-15 05:34:36 +00:00
|
|
|
maxSpace: '67108864', // 64mb storage limit
|
2020-08-25 23:37:33 +00:00
|
|
|
wallpaperUrls: [],
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
computed: {
|
|
|
|
...mapState(['user', 'board', 'wallpapers']),
|
2020-10-14 00:35:40 +00:00
|
|
|
...mapGetters(['nightMode']),
|
2020-08-25 23:37:33 +00:00
|
|
|
|
|
|
|
existingFiles() {
|
|
|
|
return this.wallpapers.map(({ name }) => name);
|
|
|
|
},
|
|
|
|
|
2020-11-23 23:15:29 +00:00
|
|
|
showEmptyState() {
|
|
|
|
return this.wallpapers.length === 0;
|
|
|
|
},
|
|
|
|
|
2020-08-25 23:37:33 +00:00
|
|
|
isDuplicate() {
|
|
|
|
const { file, existingFiles } = this;
|
|
|
|
|
|
|
|
return file && file.name && existingFiles.includes(file.name);
|
|
|
|
},
|
2020-11-21 06:32:14 +00:00
|
|
|
|
|
|
|
formattedSpaceUsed() {
|
|
|
|
return this.spaceUsed
|
|
|
|
? this.bytesToSize(this.spaceUsed)
|
|
|
|
: null;
|
|
|
|
},
|
|
|
|
|
2020-12-15 05:34:36 +00:00
|
|
|
spaceUsed() {
|
2021-02-01 19:31:22 +00:00
|
|
|
return this.wallpapers.reduce((total, file) => total + file.metadata.size || 0, 0);
|
2020-12-15 05:34:36 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
outOfSpace() {
|
|
|
|
return this.spaceUsed >= this.maxSpace;
|
|
|
|
},
|
2020-08-25 23:37:33 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
methods: {
|
2020-11-21 14:31:02 +00:00
|
|
|
triggerFileUpload() {
|
|
|
|
document.querySelector('.file-input input').click();
|
|
|
|
},
|
|
|
|
|
2020-11-02 20:24:11 +00:00
|
|
|
bytesToSize(bytes) {
|
|
|
|
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
|
|
|
|
|
2020-11-02 20:37:38 +00:00
|
|
|
if (bytes === 0) return '0 Byte';
|
2020-11-02 20:24:11 +00:00
|
|
|
|
2020-11-02 20:37:38 +00:00
|
|
|
const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)), 0);
|
2020-11-02 20:24:11 +00:00
|
|
|
|
2020-11-02 20:37:38 +00:00
|
|
|
return `${Math.round(bytes / (1024 ** i), 2)} ${sizes[i]}`;
|
2020-11-02 20:24:11 +00:00
|
|
|
},
|
|
|
|
|
2020-11-01 16:20:48 +00:00
|
|
|
uploadWallpaper() {
|
2020-10-31 17:43:20 +00:00
|
|
|
if (this.isDuplicate) {
|
2020-12-10 05:26:57 +00:00
|
|
|
return this.$bvToast.toast('File already exists', { variant: 'warning' });
|
2020-10-31 17:43:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!this.file) {
|
2020-11-01 16:20:48 +00:00
|
|
|
return false;
|
2020-10-31 17:43:20 +00:00
|
|
|
}
|
|
|
|
|
2020-08-25 23:37:33 +00:00
|
|
|
this.saving = true;
|
|
|
|
|
2020-11-01 16:20:48 +00:00
|
|
|
return this.$store.dispatch('UPLOAD_WALLPAPER', this.file)
|
2020-10-31 17:43:20 +00:00
|
|
|
.then(() => {
|
2020-12-10 05:26:57 +00:00
|
|
|
this.$bvToast.toast('File uploaded');
|
2020-10-31 17:43:20 +00:00
|
|
|
this.file = null;
|
|
|
|
this.saving = false;
|
|
|
|
this.$bus.$emit('WALLPAPER_UPLOADED');
|
|
|
|
})
|
2020-08-25 23:37:33 +00:00
|
|
|
.catch(() => {
|
|
|
|
this.saving = false;
|
2020-12-10 05:26:57 +00:00
|
|
|
this.$bvToast.toast('There was an error uploading wallpaper', { variant: 'danger' });
|
2020-08-25 23:37:33 +00:00
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
confirmDeleteWallpaper(file) {
|
|
|
|
this.$bvModal.msgBoxConfirm('Wallpaper will be permanently removed', {
|
|
|
|
title: 'Are you sure you want to delete this file?',
|
|
|
|
okVariant: 'danger',
|
|
|
|
okTitle: 'Yes',
|
|
|
|
})
|
|
|
|
.then((value) => {
|
|
|
|
if (value) {
|
|
|
|
this.deleteFile(file);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
async deleteFile(file) {
|
|
|
|
await this.$store.dispatch('DELETE_WALLPAPER', file)
|
|
|
|
.catch(() => {
|
2020-12-10 05:26:57 +00:00
|
|
|
this.$bvToast.toast('There was an error deleting wallpaper', { variant: 'danger' });
|
2020-08-25 23:37:33 +00:00
|
|
|
});
|
|
|
|
|
2020-12-14 21:47:33 +00:00
|
|
|
this.$bvToast.toast('File deleted');
|
2020-08-25 23:37:33 +00:00
|
|
|
|
|
|
|
// const { board } = this;
|
|
|
|
// TODO: handle wallpapers in use
|
|
|
|
// if (board.wallpaper && this.board.wallpaper === file.path) {
|
|
|
|
// this.$bus.$emit('RELOAD_WALLPAPER');
|
|
|
|
// }
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" rel="stylesheet/scss" scoped>
|
|
|
|
.delete-file {
|
|
|
|
bottom: .5rem;
|
|
|
|
right: .5rem;
|
|
|
|
}
|
2021-02-03 22:57:07 +00:00
|
|
|
|
|
|
|
.space-used {
|
|
|
|
width: 120px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.wallpapers {
|
|
|
|
display: grid;
|
|
|
|
grid-column-gap: 1rem;
|
|
|
|
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
|
|
|
|
|
|
|
|
@media(max-width: 1024px) {
|
|
|
|
grid-template-columns: 1fr 1fr 1fr;
|
|
|
|
}
|
|
|
|
|
|
|
|
@media(max-width: 720px) {
|
|
|
|
grid-template-columns: 1fr 1fr;
|
|
|
|
}
|
|
|
|
}
|
2020-08-25 23:37:33 +00:00
|
|
|
</style>
|