mirror of
https://github.com/romancm/gamebrary
synced 2024-11-24 20:23:06 +00:00
file management and board settings
This commit is contained in:
parent
a84be79a9a
commit
3a43d2eafb
13 changed files with 470 additions and 268 deletions
|
@ -22,6 +22,7 @@
|
|||
<b-form-input
|
||||
id="name"
|
||||
v-model="board.name"
|
||||
autofocus
|
||||
required
|
||||
/>
|
||||
</b-form-group>
|
||||
|
@ -74,6 +75,7 @@
|
|||
|
||||
<b-button
|
||||
variant="primary"
|
||||
:disabled="saving"
|
||||
@click="submit"
|
||||
>
|
||||
<b-spinner small v-if="saving" />
|
||||
|
@ -131,7 +133,7 @@ export default {
|
|||
name: null,
|
||||
description: null,
|
||||
theme: null,
|
||||
backgroundColor: '#ccc',
|
||||
wallpaper: null,
|
||||
platforms: [],
|
||||
lists: [],
|
||||
};
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
<create-board />
|
||||
</div>
|
||||
|
||||
<!-- <pre>{{ platforms }}</pre> -->
|
||||
|
||||
<b-overlay :show="loading && !platforms.length" rounded="sm" variant="transparent">
|
||||
<b-row cols="3" no-gutters>
|
||||
<b-col v-for="board in boards" :key="board.id">
|
||||
|
@ -20,12 +18,6 @@
|
|||
{{ board.description }}
|
||||
</b-card-text>
|
||||
|
||||
<div v-for="platform in board.platforms" :key="platform">
|
||||
{{ platforms[platform].name }}
|
||||
</div>
|
||||
|
||||
{{ board.lists.length }} lists
|
||||
|
||||
<b-button
|
||||
variant="danger"
|
||||
@click="confirmDelete(board.id)"
|
||||
|
@ -39,6 +31,10 @@
|
|||
>
|
||||
Open board
|
||||
</b-button>
|
||||
|
||||
<!-- <b-button v-b-modal:board-settings>
|
||||
<b-icon-gear-fill />
|
||||
</b-button> -->
|
||||
</b-card>
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<b-list-group flush>
|
||||
|
||||
<b-list-group-item>
|
||||
<wallpaper-upload />
|
||||
<legacy-wallpaper-upload />
|
||||
</b-list-group-item>
|
||||
|
||||
<b-list-group-item>
|
||||
|
@ -52,11 +52,11 @@
|
|||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
import themes from '@/themes';
|
||||
import WallpaperUpload from '@/components/WallpaperUpload';
|
||||
import LegacyWallpaperUpload from '@/components/LegacyBoard/LegacyWallpaperUpload';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
WallpaperUpload,
|
||||
LegacyWallpaperUpload,
|
||||
},
|
||||
|
||||
data() {
|
||||
|
|
|
@ -14,10 +14,8 @@
|
|||
|
||||
<h5>Platforms (Deprecated)</h5>
|
||||
|
||||
<platforms-header />
|
||||
|
||||
<platforms-list
|
||||
:platforms="sortedPlatforms"
|
||||
:platforms="ownedPlatforms"
|
||||
/>
|
||||
|
||||
<platforms-footer />
|
||||
|
@ -26,15 +24,12 @@
|
|||
<script>
|
||||
import platforms from '@/platforms';
|
||||
import PlatformsFooter from '@/components/LegacyBoard/LegacyPlatformsFooter';
|
||||
import PlatformsHeader from '@/components/LegacyBoard/LegacyPlatformsHeader';
|
||||
import PlatformsList from '@/components/LegacyBoard/LegacyPlatformsList';
|
||||
import sortby from 'lodash.sortby';
|
||||
import { mapState } from 'vuex';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
PlatformsFooter,
|
||||
PlatformsHeader,
|
||||
PlatformsList,
|
||||
},
|
||||
|
||||
|
@ -47,48 +42,13 @@ export default {
|
|||
computed: {
|
||||
...mapState(['gameLists', 'settings']),
|
||||
|
||||
// TODO: move to getter and replace other instances
|
||||
hasLists() {
|
||||
return Object.keys(this.gameLists).length > 0;
|
||||
},
|
||||
|
||||
listView() {
|
||||
return this.settings && this.settings.platformsView
|
||||
? this.settings.platformsView
|
||||
: 'grid';
|
||||
},
|
||||
|
||||
platformsFilterField() {
|
||||
return this.settings && this.settings.platformsFilterField
|
||||
? this.settings.platformsFilterField
|
||||
: null;
|
||||
},
|
||||
|
||||
ownedPlatforms() {
|
||||
return this.platforms.filter(({ code }) => this.gameLists[code]);
|
||||
},
|
||||
|
||||
platformsSortField() {
|
||||
return this.settings && this.settings.platformsSortField
|
||||
? this.settings.platformsSortField
|
||||
: 'releaseYear';
|
||||
},
|
||||
|
||||
filteredPlatforms() {
|
||||
return this.platformsFilterField
|
||||
? this.ownedPlatforms.filter(({ type }) => type === this.platformsFilterField)
|
||||
: this.ownedPlatforms;
|
||||
},
|
||||
|
||||
sortedPlatforms() {
|
||||
const sortedPlatforms = this.platformsSortField
|
||||
? sortby(this.filteredPlatforms, this.platformsSortField)
|
||||
: this.filteredPlatforms;
|
||||
|
||||
return this.platformsSortField === 'releaseYear'
|
||||
? sortedPlatforms.reverse()
|
||||
: sortedPlatforms;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -1,116 +0,0 @@
|
|||
<template lang="html">
|
||||
<header>
|
||||
<b-button-toolbar aria-label="Filter and sort platforms">
|
||||
<strong class="py-2 pr-1">Filter:</strong>
|
||||
<b-button-group class="mx-1">
|
||||
<b-button
|
||||
v-for="filter in filters"
|
||||
:key="filter"
|
||||
:variant="filterField === filter ? 'primary' : null"
|
||||
size="sm"
|
||||
@click="setFilter(filter)"
|
||||
>
|
||||
{{ filter ? $t(`platforms.${filter}`) : $t('platforms.all') }}
|
||||
</b-button>
|
||||
</b-button-group>
|
||||
|
||||
<strong class="py-2 pr-1 mx-1">Sort:</strong>
|
||||
<b-button-group>
|
||||
<b-button
|
||||
v-for="field in availableSortFields"
|
||||
:key="field"
|
||||
:variant="sortField === field ? 'primary' : null"
|
||||
size="sm"
|
||||
@click="setSortField(field)"
|
||||
>
|
||||
{{ $t(`platforms.${field}`) }}
|
||||
</b-button>
|
||||
</b-button-group>
|
||||
</b-button-toolbar>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
filters: [
|
||||
null,
|
||||
'consoles',
|
||||
'handheld',
|
||||
'computer',
|
||||
],
|
||||
availableSortFields: [
|
||||
'releaseYear',
|
||||
'name',
|
||||
'type',
|
||||
],
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['settings']),
|
||||
|
||||
filterField() {
|
||||
return this.settings && this.settings.platformsFilterField
|
||||
? this.settings.platformsFilterField
|
||||
: null;
|
||||
},
|
||||
|
||||
sortField() {
|
||||
return this.settings && this.settings.platformsSortField
|
||||
? this.settings.platformsSortField
|
||||
: 'releaseYear';
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
saveSettings() {
|
||||
this.$store.dispatch('SAVE_SETTINGS_LEGACY', this.settings)
|
||||
.then(() => {
|
||||
this.$bvToast.toast('Settings saved', { title: 'Success', variant: 'success' });
|
||||
})
|
||||
.catch(() => {
|
||||
this.$bvToast.toast('There was an error saving your settings', { title: 'Error', variant: 'danger' });
|
||||
});
|
||||
},
|
||||
|
||||
setFilter(value) {
|
||||
this.$store.commit('UPDATE_SETTING', { key: 'platformsFilterField', value });
|
||||
this.saveSettings();
|
||||
},
|
||||
|
||||
setSortField(value) {
|
||||
this.$store.commit('UPDATE_SETTING', { key: 'platformsSortField', value });
|
||||
this.saveSettings();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
// @import "~styles/styles";
|
||||
|
||||
header {
|
||||
// display: inline-grid;
|
||||
// align-items: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 1rem;
|
||||
grid-gap: 1rem;
|
||||
}
|
||||
|
||||
.filter-active {
|
||||
color: var(--success-background);
|
||||
}
|
||||
|
||||
section {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
</style>
|
|
@ -81,7 +81,7 @@ export default {
|
|||
wallpapers: this.wallpapers,
|
||||
};
|
||||
|
||||
this.$store.dispatch('SAVE_SETTINGS_LEGACY', settings)
|
||||
this.$store.dispatch('SAVE_SETTINGS', settings)
|
||||
.then(() => {
|
||||
this.$bvToast.toast('Settings saved', { title: 'Success', variant: 'success' });
|
||||
this.loading = false;
|
|
@ -14,13 +14,9 @@
|
|||
/>
|
||||
</template>
|
||||
|
||||
<template v-if="isBoard">
|
||||
<board-settings />
|
||||
<b-dropdown-divider />
|
||||
</template>
|
||||
|
||||
<tags-settings />
|
||||
<account-settings />
|
||||
<file-settings />
|
||||
<releases />
|
||||
<about />
|
||||
<b-dropdown-divider />
|
||||
|
@ -34,8 +30,8 @@
|
|||
<script>
|
||||
import TagsSettings from '@/components/Settings/TagsSettings';
|
||||
import AccountSettings from '@/components/Settings/AccountSettings';
|
||||
import FileSettings from '@/components/Settings/FileSettings';
|
||||
import Releases from '@/components/Settings/Releases';
|
||||
import BoardSettings from '@/components/Settings/BoardSettings';
|
||||
import SignOut from '@/components/Settings/SignOut';
|
||||
import About from '@/components/Settings/About';
|
||||
import { mapState } from 'vuex';
|
||||
|
@ -44,18 +40,14 @@ export default {
|
|||
components: {
|
||||
TagsSettings,
|
||||
AccountSettings,
|
||||
FileSettings,
|
||||
Releases,
|
||||
BoardSettings,
|
||||
SignOut,
|
||||
About,
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
|
||||
isBoard() {
|
||||
return this.$route.name === 'board';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -1,25 +1,48 @@
|
|||
<template lang="html">
|
||||
<b-dropdown-item v-b-modal:board-settings>
|
||||
<b-icon-kanban class="mr-1" />
|
||||
Board settings
|
||||
<b-button
|
||||
v-b-modal:board-settings
|
||||
class="mt-3"
|
||||
ref="addList"
|
||||
>
|
||||
<b-icon-gear-fill />
|
||||
|
||||
<b-modal
|
||||
id="board-settings"
|
||||
title="Board settings"
|
||||
body-class="p-0"
|
||||
@show="getSettings"
|
||||
scrollable
|
||||
@show="init"
|
||||
>
|
||||
<b-list-group flush>
|
||||
<form ref="boardSettingsForm" @submit.stop.prevent="submit">
|
||||
<b-form-group
|
||||
label="Board name"
|
||||
label-for="name"
|
||||
>
|
||||
<b-form-input
|
||||
id="name"
|
||||
v-model="name"
|
||||
required
|
||||
/>
|
||||
</b-form-group>
|
||||
|
||||
<b-list-group-item>
|
||||
<wallpaper-upload />
|
||||
</b-list-group-item>
|
||||
<b-form-group
|
||||
label="Board descriptiopn"
|
||||
label-for="description"
|
||||
>
|
||||
<b-form-textarea
|
||||
id="description"
|
||||
v-model="description"
|
||||
maxlength="280"
|
||||
rows="3"
|
||||
/>
|
||||
</b-form-group>
|
||||
|
||||
<b-list-group-item>
|
||||
<label for="theme">Theme</label>
|
||||
<b-form-group
|
||||
label="Board theme"
|
||||
label-for="theme"
|
||||
>
|
||||
<b-form-select
|
||||
id="theme"
|
||||
disabled
|
||||
v-model="theme"
|
||||
>
|
||||
<b-form-select-option
|
||||
v-for="{ id, name } in themes"
|
||||
|
@ -29,60 +52,155 @@
|
|||
{{ name }}
|
||||
</b-form-select-option>
|
||||
</b-form-select>
|
||||
</b-form-group>
|
||||
|
||||
<b-alert show variant="warning" class="mt-3">
|
||||
Themes are temporarily disabled
|
||||
</b-alert>
|
||||
</b-list-group-item>
|
||||
</b-list-group>
|
||||
<b-form-group
|
||||
label="Board wallpaper"
|
||||
label-for="wallpaper"
|
||||
>
|
||||
<b-dropdown
|
||||
v-if="wallpapers.length"
|
||||
id="wallpaper"
|
||||
text="Select wallpaper"
|
||||
boundary="viewport"
|
||||
class="m-md-2"
|
||||
>
|
||||
<b-dropdown-item variant="danger" v-if="wallpaper" @click="removeWallpaper">
|
||||
Remove wallpaper
|
||||
</b-dropdown-item>
|
||||
<b-dropdown-item
|
||||
v-for="file in wallpapers"
|
||||
:key="file.name"
|
||||
@click="setWallpaper(file)"
|
||||
>
|
||||
<b-img
|
||||
thumbnail
|
||||
width="200px"
|
||||
:src="file.url"
|
||||
:alt="file.name"
|
||||
fluid
|
||||
/>
|
||||
</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
</b-form-group>
|
||||
|
||||
<b-img
|
||||
v-if="wallpaper"
|
||||
thumbnail
|
||||
width="200px"
|
||||
:src="wallpaperUrl"
|
||||
fluid
|
||||
/>
|
||||
|
||||
<platform-picker
|
||||
v-model="board.platforms"
|
||||
/>
|
||||
</form>
|
||||
|
||||
<template v-slot:modal-footer>
|
||||
<b-button
|
||||
:title="$t('list.delete')"
|
||||
variant="danger"
|
||||
@click="promptDeleteBoard"
|
||||
@click="confirmDelete"
|
||||
>
|
||||
Delete board
|
||||
</b-button>
|
||||
|
||||
<b-button
|
||||
variant="primary"
|
||||
:disabled="saving"
|
||||
@click="saveSettings"
|
||||
>
|
||||
<b-spinner small v-if="saving" />
|
||||
<span v-else>Save</span>
|
||||
</b-button>
|
||||
</template>
|
||||
</b-modal>
|
||||
</b-dropdown-item>
|
||||
</b-button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
import themes from '@/themes';
|
||||
import WallpaperUpload from '@/components/WallpaperUpload';
|
||||
import PlatformPicker from '@/components/Board/PlatformPicker';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
WallpaperUpload,
|
||||
PlatformPicker,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
themes,
|
||||
saving: false,
|
||||
description: null,
|
||||
name: null,
|
||||
platforms: null,
|
||||
theme: null,
|
||||
wallpaper: null,
|
||||
wallpaperUrl: null,
|
||||
wallpapers: [],
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user', 'platform', 'gameLists']),
|
||||
...mapState(['board', 'user']),
|
||||
},
|
||||
|
||||
methods: {
|
||||
getSettings() {
|
||||
// console.log('get settings bitdch!');
|
||||
// const { sortOrder } = this.gameLists[this.platform.code][this.listIndex];
|
||||
//
|
||||
// this.sortOrder = sortOrder || 'sortByCustom';
|
||||
async loadWallpapers() {
|
||||
this.wallpapers = [];
|
||||
|
||||
const files = await this.$store.dispatch('LOAD_WALLPAPERS');
|
||||
|
||||
// TODO: use promise all instead
|
||||
files.forEach(async (path) => {
|
||||
const url = await this.$store.dispatch('LOAD_FIRESTORE_FILE', path);
|
||||
|
||||
const name = path.split(`${this.user.uid}/wallpapers/`)[1];
|
||||
|
||||
this.wallpapers.push({ name, url, path });
|
||||
});
|
||||
},
|
||||
|
||||
promptDeleteBoard() {
|
||||
this.$bvModal.msgBoxConfirm('All your data will be removed', {
|
||||
title: 'Are you sure you want to delete this board?',
|
||||
removeWallpaper() {
|
||||
this.wallpaper = null;
|
||||
this.wallpaperUrl = null;
|
||||
},
|
||||
|
||||
async setWallpaper(file) {
|
||||
this.wallpaper = file.path;
|
||||
|
||||
this.wallpaperUrl = await this.$store.dispatch('LOAD_FIRESTORE_FILE', file.path);
|
||||
},
|
||||
|
||||
submit(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (this.$refs.createBoardForm.checkValidity()) {
|
||||
this.createBoard();
|
||||
}
|
||||
},
|
||||
|
||||
async init() {
|
||||
const { board } = this;
|
||||
|
||||
this.description = board.description;
|
||||
this.name = board.name;
|
||||
this.platforms = board.platforms;
|
||||
this.theme = board.theme || 'default';
|
||||
this.wallpaper = board.wallpaper;
|
||||
this.wallpaperUrl = board.wallpaper
|
||||
? await this.$store.dispatch('LOAD_FIRESTORE_FILE', board.wallpaper)
|
||||
: null;
|
||||
|
||||
this.loadWallpapers();
|
||||
},
|
||||
|
||||
confirmDelete() {
|
||||
this.$bvModal.msgBoxConfirm('Are you sure you want to delete this board?', {
|
||||
title: 'Delete board',
|
||||
okVariant: 'danger',
|
||||
okTitle: 'Yes, delete board! Hahaha!',
|
||||
okTitle: 'Yes, delete board',
|
||||
})
|
||||
.then((value) => {
|
||||
if (value) {
|
||||
|
@ -91,47 +209,60 @@ export default {
|
|||
});
|
||||
},
|
||||
|
||||
deleteBoard() {
|
||||
this.$store.commit('REMOVE_PLATFORM_LEGACY');
|
||||
async deleteBoard() {
|
||||
this.loading = true;
|
||||
|
||||
this.$store.dispatch('SAVE_LIST_NO_MERGE_LEGACY', this.gameLists)
|
||||
.then(() => {
|
||||
this.$router.push({ name: 'platforms' });
|
||||
})
|
||||
await this.$store.dispatch('DELETE_BOARD', this.board.id)
|
||||
.catch(() => {
|
||||
this.$bvToast.toast('Authentication error', { title: 'Error', variant: 'danger' });
|
||||
this.loading = false;
|
||||
this.$bvToast.toast('There was an error deleting board', { title: 'Error', variant: 'error' });
|
||||
});
|
||||
|
||||
this.loading = false;
|
||||
this.$bvToast.toast('Board removed', { title: 'Success', variant: 'success' });
|
||||
this.$router.push({ name: 'home' });
|
||||
},
|
||||
|
||||
// async save() {
|
||||
// this.saving = true;
|
||||
//
|
||||
// const gameLists = JSON.parse(JSON.stringify(this.gameLists));
|
||||
//
|
||||
// gameLists[this.platform.code][this.listIndex].sortOrder = this.sortOrder;
|
||||
//
|
||||
// await this.$store.dispatch('SAVE_LIST_LEGACY', gameLists)
|
||||
// .catch(() => {
|
||||
// this.saving = false;
|
||||
//
|
||||
// this.$bvToast.toast('There was an error renaming list', {
|
||||
// title: 'Error',
|
||||
// variant: 'danger',
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// this.saving = false;
|
||||
//
|
||||
// this.$bvToast.toast('List renamed', {
|
||||
// title: 'Saved',
|
||||
// variant: 'success',
|
||||
// });
|
||||
//
|
||||
// this.$bvModal.hide('board-settings');
|
||||
// },
|
||||
async saveSettings() {
|
||||
this.saving = true;
|
||||
const wallpaperChanged = this.board.wallpaper !== this.wallpaper;
|
||||
|
||||
const { board } = this;
|
||||
|
||||
const payload = {
|
||||
...board,
|
||||
description: this.description,
|
||||
name: this.name,
|
||||
platforms: this.platforms,
|
||||
theme: this.theme,
|
||||
wallpaper: this.wallpaper,
|
||||
};
|
||||
|
||||
this.$store.commit('SET_BOARD', payload);
|
||||
|
||||
await this.$store.dispatch('SAVE_BOARD')
|
||||
.catch(() => {
|
||||
this.saving = false;
|
||||
|
||||
this.$bvToast.toast('There was an error renaming list', { title: 'Error', variant: 'danger' });
|
||||
});
|
||||
|
||||
this.saving = false;
|
||||
this.$bvToast.toast('Board settings saved', { title: 'Saved', variant: 'success' });
|
||||
this.$bvModal.hide('board-settings');
|
||||
|
||||
if (wallpaperChanged) {
|
||||
this.$bus.$emit('RELOAD_WALLPAPER');
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
<style lang="scss" rel="stylesheet/scss">
|
||||
.dropdown-menu {
|
||||
max-height: 400px;
|
||||
max-width: 360px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
|
|
153
src/components/Settings/FileSettings.vue
Normal file
153
src/components/Settings/FileSettings.vue
Normal file
|
@ -0,0 +1,153 @@
|
|||
<template lang="html">
|
||||
<b-dropdown-item v-b-modal:file-settings>
|
||||
<b-icon-tags class="mr-1" />
|
||||
Manage files
|
||||
|
||||
<b-modal
|
||||
id="file-settings"
|
||||
title="Manage Files"
|
||||
hide-footer
|
||||
size="xl"
|
||||
@show="loadWallpapers"
|
||||
>
|
||||
<h5>Wallpapers</h5>
|
||||
|
||||
<b-form-file
|
||||
v-model="file"
|
||||
accept="image/*"
|
||||
class="mb-3"
|
||||
placeholder="Choose a file or drop it here..."
|
||||
drop-placeholder="Drop file here..."
|
||||
/>
|
||||
|
||||
<b-button @click="uploadFile" :disabled="!Boolean(file)">
|
||||
Upload
|
||||
</b-button>
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
Files
|
||||
<div class="wallpapers">
|
||||
<b-card
|
||||
v-for="(file, index) in wallpapers"
|
||||
:key="file.name"
|
||||
:header="file.name"
|
||||
header-class="py-0 px-2"
|
||||
body-class="d-flex p-0 text-center justify-content-center align-items-center"
|
||||
header-tag="small"
|
||||
>
|
||||
<b-img
|
||||
:src="file.url"
|
||||
:alt="file.name"
|
||||
fluid
|
||||
/>
|
||||
|
||||
<b-button
|
||||
class="delete-file"
|
||||
variant="danger"
|
||||
size="sm"
|
||||
@click="confirmDeleteFile({ file, index })"
|
||||
>
|
||||
<b-icon-trash />
|
||||
</b-button>
|
||||
</b-card>
|
||||
</div>
|
||||
</b-modal>
|
||||
</b-dropdown-item>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import firebase from 'firebase/app';
|
||||
import 'firebase/firestore';
|
||||
import { mapState } from 'vuex';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
file: null,
|
||||
saving: false,
|
||||
loading: false,
|
||||
wallpapers: [],
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user', 'board']),
|
||||
},
|
||||
|
||||
methods: {
|
||||
async loadWallpapers() {
|
||||
this.wallpapers = [];
|
||||
this.loading = true;
|
||||
|
||||
const files = await this.$store.dispatch('LOAD_WALLPAPERS');
|
||||
|
||||
// TODO: use promise all instead
|
||||
files.forEach(async (path) => {
|
||||
const url = await this.$store.dispatch('LOAD_FIRESTORE_FILE', path);
|
||||
|
||||
const name = path.split(`${this.user.uid}/wallpapers/`)[1];
|
||||
|
||||
this.wallpapers.push({ name, url, path });
|
||||
});
|
||||
},
|
||||
|
||||
uploadFile() {
|
||||
const { file, user } = this;
|
||||
|
||||
this.saving = true;
|
||||
|
||||
firebase.storage().ref(`${user.uid}/wallpapers/${file.name}`).put(file)
|
||||
.then(({ state }) => {
|
||||
if (state === 'success') {
|
||||
this.$bvToast.toast(file.name, { title: 'File uploaded', variant: 'success' });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
confirmDeleteFile({ file, index }) {
|
||||
this.$bvModal.msgBoxConfirm(`${file.name} 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, index });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
async deleteFile({ file, index }) {
|
||||
await this.$store.dispatch('DELETE_FIRESTORE_FILE', file.path);
|
||||
|
||||
this.$bvToast.toast(file.name, { title: 'File deleted', variant: 'success' });
|
||||
|
||||
this.wallpapers.splice(index, 1);
|
||||
|
||||
if (this.board && this.board.wallpaper && this.board.wallpaper === file.path) {
|
||||
this.$bus.$emit('RELOAD_WALLPAPER');
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
.wallpapers {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
grid-gap: 1rem;
|
||||
|
||||
img {
|
||||
max-height: 140px;
|
||||
}
|
||||
|
||||
.delete-file {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,3 +1,5 @@
|
|||
export const POPULAR_PLATFORMS = [169, 167, 130, 48, 49, 41];
|
||||
|
||||
export const PLATFORM_CATEGORIES = {
|
||||
1: 'console',
|
||||
2: 'arcade',
|
||||
|
@ -7,6 +9,22 @@ export const PLATFORM_CATEGORIES = {
|
|||
6: 'computer',
|
||||
};
|
||||
|
||||
export const PLATFORM_FILTER_FIELDS = [
|
||||
null,
|
||||
'popular',
|
||||
'console',
|
||||
// 'arcade',
|
||||
// 'platform',
|
||||
'operating_system',
|
||||
'portable_console',
|
||||
'computer',
|
||||
];
|
||||
|
||||
export const PLATFORM_SORT_FILEDS = [
|
||||
'generation',
|
||||
'name',
|
||||
];
|
||||
|
||||
export const PLATFORM_BG_HEX = {
|
||||
167: '#222',
|
||||
166: '#000',
|
||||
|
@ -56,6 +74,7 @@ export const EXCLUDED_PLATFORMS = [
|
|||
151,
|
||||
152,
|
||||
52, // Arcade
|
||||
79, // Neogeo
|
||||
153,
|
||||
154,
|
||||
155,
|
||||
|
|
|
@ -25,11 +25,15 @@
|
|||
"reportBugs": "reporting bugs",
|
||||
"submitFeedback": "submitting feedback",
|
||||
"all": "All",
|
||||
"consoles": "Consoles",
|
||||
"handheld": "Handhelds",
|
||||
"console": "Consoles",
|
||||
"platform": "Digital",
|
||||
"operating_system": "PC / Other",
|
||||
"portable_console": "Handhelds",
|
||||
"computer": "Home Computers",
|
||||
"popular": "Popular",
|
||||
"releaseYear": "Year released",
|
||||
"name": "Alphabetically",
|
||||
"generation": "Generation / Date relased",
|
||||
"type": "Type"
|
||||
},
|
||||
"gameBoard": {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template lang="html">
|
||||
<div class="board" :class="{ dragging }" >
|
||||
<div :class="['board', { dragging }]" :style="wallpaper" >
|
||||
<board-placeholder v-if="loading" />
|
||||
|
||||
<template v-else>
|
||||
|
@ -11,12 +11,17 @@
|
|||
/>
|
||||
</template>
|
||||
|
||||
<add-list />
|
||||
<div class="d-flex flex-column pr-3">
|
||||
<add-list />
|
||||
<board-settings />
|
||||
</div>
|
||||
|
||||
<game-modal />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BoardSettings from '@/components/Settings/BoardSettings';
|
||||
import BoardPlaceholder from '@/components/Board/BoardPlaceholder';
|
||||
import AddList from '@/components/Board/AddList';
|
||||
import GameModal from '@/components/Game/GameModal';
|
||||
|
@ -31,24 +36,38 @@ export default {
|
|||
List,
|
||||
BoardPlaceholder,
|
||||
AddList,
|
||||
BoardSettings,
|
||||
GameModal,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
gameData: null,
|
||||
gameDetailListIndex: null,
|
||||
queryLimit: 500,
|
||||
wallpaperUrl: null,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user', 'dragging', 'board']),
|
||||
|
||||
wallpaper() {
|
||||
const { wallpaperUrl } = this;
|
||||
|
||||
return wallpaperUrl
|
||||
? `background-image: url('${wallpaperUrl}');`
|
||||
: '';
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.load();
|
||||
this.$bus.$on('RELOAD_WALLPAPER', this.loadBoardWallpaper);
|
||||
},
|
||||
|
||||
destroyed() {
|
||||
this.$store.commit('CLEAR_BOARD');
|
||||
this.$bus.$off('RELOAD_WALLPAPER', this.loadBoardWallpaper);
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
@ -70,6 +89,13 @@ export default {
|
|||
});
|
||||
|
||||
this.loadBoardGames();
|
||||
this.loadBoardWallpaper();
|
||||
},
|
||||
|
||||
async loadBoardWallpaper() {
|
||||
this.wallpaperUrl = this.board.wallpaper
|
||||
? await this.$store.dispatch('LOAD_FIRESTORE_FILE', this.board.wallpaper)
|
||||
: null;
|
||||
},
|
||||
|
||||
loadBoardGames() {
|
||||
|
@ -118,9 +144,10 @@ export default {
|
|||
.board {
|
||||
user-select: none;
|
||||
display: flex;
|
||||
background-size: cover;
|
||||
align-items: flex-start;
|
||||
height: calc(100vh - 58px);
|
||||
padding: 0 1rem;
|
||||
height: 100vh;
|
||||
padding: 58px 1rem 0;
|
||||
box-sizing: border-box;
|
||||
overflow-x: auto;
|
||||
overflow-x: overlay;
|
||||
|
|
|
@ -94,6 +94,40 @@ export default {
|
|||
});
|
||||
},
|
||||
|
||||
|
||||
DELETE_FIRESTORE_FILE(context, path) {
|
||||
return new Promise((resolve, reject) => {
|
||||
firebase.storage().ref(path).delete()
|
||||
.then(() => {
|
||||
resolve();
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
},
|
||||
|
||||
LOAD_FIRESTORE_FILE(context, path) {
|
||||
const storage = firebase.storage().ref();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
storage.child(path).getDownloadURL()
|
||||
.then((url) => {
|
||||
resolve(url);
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
},
|
||||
|
||||
async LOAD_WALLPAPERS({ state }) {
|
||||
const storage = firebase.storage().ref(`${state.user.uid}/wallpapers`);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
storage
|
||||
.listAll()
|
||||
.then(({ items }) => resolve(items.map(({ fullPath }) => fullPath)))
|
||||
.catch(reject);
|
||||
});
|
||||
},
|
||||
|
||||
// set merge to true when deleting lists
|
||||
SAVE_BOARD({ state }, merge = false) {
|
||||
const db = firebase.firestore();
|
||||
|
@ -197,19 +231,6 @@ export default {
|
|||
});
|
||||
},
|
||||
|
||||
SAVE_SETTINGS_LEGACY({ commit, state }, settings) {
|
||||
const db = firebase.firestore();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
db.collection('settings').doc(state.user.uid).set(settings, { merge: true })
|
||||
.then(() => {
|
||||
commit('SET_SETTINGS', settings);
|
||||
resolve();
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
},
|
||||
|
||||
SEARCH_LEGACY({ commit, state }, searchText) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios.get(`${API_BASE}/search?search=${searchText}&platform=${state.platform.id}`)
|
||||
|
@ -225,6 +246,19 @@ export default {
|
|||
// STUFF THAT REMAINS THE SAME
|
||||
//
|
||||
|
||||
SAVE_SETTINGS({ commit, state }, settings) {
|
||||
const db = firebase.firestore();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
db.collection('settings').doc(state.user.uid).set(settings, { merge: true })
|
||||
.then(() => {
|
||||
commit('SET_SETTINGS', settings);
|
||||
resolve();
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
},
|
||||
|
||||
// TODO: combine into single action
|
||||
SAVE_NOTES({ state }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
|
Loading…
Reference in a new issue