mirror of
https://github.com/romancm/gamebrary
synced 2024-11-10 05:34:15 +00:00
Refactor tags
This commit is contained in:
parent
97d7513c96
commit
d619ac9796
17 changed files with 181 additions and 274 deletions
|
@ -7,7 +7,7 @@
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||||
<link rel="manifest" href="/site.webmanifest">
|
<!-- <link rel="manifest" href="/site.webmanifest"> -->
|
||||||
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
|
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
|
||||||
<meta name="msapplication-TileColor" content="#da532c">
|
<meta name="msapplication-TileColor" content="#da532c">
|
||||||
<meta name="theme-color" content="#ffffff">
|
<meta name="theme-color" content="#ffffff">
|
||||||
|
|
|
@ -100,10 +100,6 @@ export default {
|
||||||
isGamePage() {
|
isGamePage() {
|
||||||
return this.$route.name === 'game';
|
return this.$route.name === 'game';
|
||||||
},
|
},
|
||||||
|
|
||||||
isBoard() {
|
|
||||||
return ['public.board', 'board'].includes(this.$route.name);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
|
|
|
@ -37,19 +37,19 @@
|
||||||
height="6px"
|
height="6px"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<template v-if="showGameTags">
|
<!-- TODO: use correct tags -->
|
||||||
<b-badge
|
<!-- <pre>{{ gameTags }}</pre> -->
|
||||||
v-for="({ hex, tagTextColor }, name) in gameTags"
|
<!-- <b-badge
|
||||||
:key="name"
|
v-for="({ hex, tagTextColor }, name) in gameTags"
|
||||||
pill
|
:key="name"
|
||||||
class="mr-1"
|
pill
|
||||||
variant="primary"
|
class="mr-1"
|
||||||
tag="small"
|
variant="primary"
|
||||||
:style="`background-color: ${hex}; color: ${tagTextColor}`"
|
tag="small"
|
||||||
>
|
:style="`background-color: ${hex}; color: ${tagTextColor}`"
|
||||||
<small>{{ name }}</small>
|
>
|
||||||
</b-badge>
|
<small>{{ name }}</small>
|
||||||
</template>
|
</b-badge> -->
|
||||||
</b-card-body>
|
</b-card-body>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
|
|
|
@ -42,14 +42,14 @@
|
||||||
<small v-else>{{ gameProgress }}%</small>
|
<small v-else>{{ gameProgress }}%</small>
|
||||||
</b-badge>
|
</b-badge>
|
||||||
|
|
||||||
<template v-if="showGameTags">
|
<template v-if="tagsApplied.length">
|
||||||
<b-badge
|
<b-badge
|
||||||
v-for="({ hex, tagTextColor }, name) in gameTags"
|
v-for="({ bgColor, textColor, name }) in tagsApplied"
|
||||||
:key="name"
|
:key="name"
|
||||||
pill
|
pill
|
||||||
class="mr-1"
|
class="mr-1"
|
||||||
variant="primary"
|
variant="primary"
|
||||||
:style="`background-color: ${hex}; color: ${tagTextColor}`"
|
:style="`background-color: ${bgColor}; color: ${textColor}`"
|
||||||
>
|
>
|
||||||
<small>{{ name }}</small>
|
<small>{{ name }}</small>
|
||||||
</b-badge>
|
</b-badge>
|
||||||
|
|
|
@ -21,7 +21,8 @@
|
||||||
height="6px"
|
height="6px"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<template v-if="showGameTags">
|
<!-- TODO: use correct tags -->
|
||||||
|
<!-- <template v-if="showGameTags">
|
||||||
<b-badge
|
<b-badge
|
||||||
v-for="({ hex, tagTextColor }, name) in gameTags"
|
v-for="({ hex, tagTextColor }, name) in gameTags"
|
||||||
:key="name"
|
:key="name"
|
||||||
|
@ -32,7 +33,7 @@
|
||||||
>
|
>
|
||||||
<small>{{ name }}</small>
|
<small>{{ name }}</small>
|
||||||
</b-badge>
|
</b-badge>
|
||||||
</template>
|
</template> -->
|
||||||
|
|
||||||
<b-badge variant="warning" v-if="gameNotes">
|
<b-badge variant="warning" v-if="gameNotes">
|
||||||
<i class="far fa-sticky-note fa-fw" />
|
<i class="far fa-sticky-note fa-fw" />
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
height="6px"
|
height="6px"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<template v-if="showGameTags">
|
<!-- TODO: use correct tags -->
|
||||||
|
<!-- <template v-if="showGameTags">
|
||||||
<b-badge
|
<b-badge
|
||||||
v-for="({ hex, tagTextColor }, name) in gameTags"
|
v-for="({ hex, tagTextColor }, name) in gameTags"
|
||||||
:key="name"
|
:key="name"
|
||||||
|
@ -34,7 +35,7 @@
|
||||||
>
|
>
|
||||||
<small class="font-weight-bold">{{ name }}</small>
|
<small class="font-weight-bold">{{ name }}</small>
|
||||||
</b-badge>
|
</b-badge>
|
||||||
</template>
|
</template> -->
|
||||||
</b-card-body>
|
</b-card-body>
|
||||||
</b-row>
|
</b-row>
|
||||||
</b-card>
|
</b-card>
|
||||||
|
|
|
@ -1,22 +1,16 @@
|
||||||
<template lang="html">
|
<template lang="html">
|
||||||
<b-row>
|
<b-row class="p-3">
|
||||||
<b-col
|
<b-button
|
||||||
v-for="({ hex, tagTextColor, name }, index) in tags"
|
v-for="({ textColor, bgColor, name }, index) in tags"
|
||||||
@click="$router.push({ name: 'tag.edit', params: { id: index } })"
|
@click="$router.push({ name: 'tag.edit', params: { id: index } })"
|
||||||
cols="6"
|
rounded
|
||||||
xl="4"
|
block
|
||||||
class="mb-3"
|
variant="outline-light"
|
||||||
|
:style="`background-color: ${bgColor}; color: ${textColor}`"
|
||||||
:key="name"
|
:key="name"
|
||||||
>
|
>
|
||||||
<b-button
|
{{ name }}
|
||||||
rounded
|
</b-button>
|
||||||
block
|
|
||||||
variant="outline-light"
|
|
||||||
:style="`background-color: ${hex}; color: ${tagTextColor}`"
|
|
||||||
>
|
|
||||||
{{ name }}
|
|
||||||
</b-button>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
</b-row>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -43,13 +37,5 @@ export default {
|
||||||
|
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
|
||||||
openGame(gameId) {
|
|
||||||
const { id, slug } = this.games[gameId];
|
|
||||||
|
|
||||||
this.$router.push({ name: 'game.tags', params: { id, slug } })
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -74,7 +74,7 @@ export const GENRE_ICONS = {
|
||||||
export const KEYBOARD_SHORTCUTS = {
|
export const KEYBOARD_SHORTCUTS = {
|
||||||
'MODAL_keyboard-shortcuts': ['shift', '?'],
|
'MODAL_keyboard-shortcuts': ['shift', '?'],
|
||||||
'MODAL_create-board': ['shift', 'c'],
|
'MODAL_create-board': ['shift', 'c'],
|
||||||
MODAL_devTools: ['shift', 'd'],
|
// MODAL_devTools: ['shift', 'd'],
|
||||||
ROUTE_boards: ['shift', 'b'],
|
ROUTE_boards: ['shift', 'b'],
|
||||||
ROUTE_tags: ['shift', 't'],
|
ROUTE_tags: ['shift', 't'],
|
||||||
ROUTE_notes: ['shift', 'n'],
|
ROUTE_notes: ['shift', 'n'],
|
||||||
|
|
|
@ -17,25 +17,10 @@ export default {
|
||||||
return this.gameProgress && Number(this.gameProgress) === 100;
|
return this.gameProgress && Number(this.gameProgress) === 100;
|
||||||
},
|
},
|
||||||
|
|
||||||
gameTags() {
|
|
||||||
const tagsArray = Object.entries(this.tags);
|
|
||||||
const filteredTags = tagsArray.filter(([key, value]) => {
|
|
||||||
return value.games.includes(this.gameId);
|
|
||||||
});
|
|
||||||
|
|
||||||
const filteredTagsObject = Object.fromEntries(filteredTags);
|
|
||||||
|
|
||||||
return filteredTagsObject;
|
|
||||||
},
|
|
||||||
|
|
||||||
showGameProgress() {
|
showGameProgress() {
|
||||||
return this.gameProgress > 0;
|
return this.gameProgress > 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
showGameTags() {
|
|
||||||
return this.list?.settings?.showGameTags && this.gameTags;
|
|
||||||
},
|
|
||||||
|
|
||||||
showReleaseDates() {
|
showReleaseDates() {
|
||||||
return this.list?.settings?.showReleaseDates;
|
return this.list?.settings?.showReleaseDates;
|
||||||
},
|
},
|
||||||
|
@ -48,6 +33,10 @@ export default {
|
||||||
: 0;
|
: 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tagsApplied() {
|
||||||
|
return this.tags?.filter((tag) => tag?.games?.includes(this.game?.id))
|
||||||
|
},
|
||||||
|
|
||||||
gameNotes() {
|
gameNotes() {
|
||||||
const { settings } = this.list;
|
const { settings } = this.list;
|
||||||
|
|
||||||
|
|
|
@ -4,112 +4,85 @@
|
||||||
Create tag
|
Create tag
|
||||||
</portal>
|
</portal>
|
||||||
|
|
||||||
<form
|
<form @submit.prevent="submit">
|
||||||
ref="newTagForm"
|
<label for="tagName">Tag name:</label>
|
||||||
@submit.stop.prevent="submit"
|
<b-form-input
|
||||||
>
|
id="tagName"
|
||||||
<b-form-row class="mb-3">
|
v-model.trim="tag.name"
|
||||||
<b-col cols="8" md="9">
|
class="mb-3 field"
|
||||||
<b-form-input
|
maxlength="20"
|
||||||
maxlength="20"
|
:placeholder="$t('tags.form.inputPlaceholder')"
|
||||||
:placeholder="$t('tags.form.inputPlaceholder')"
|
required
|
||||||
required
|
trim
|
||||||
v-model.trim="tagName"
|
/>
|
||||||
/>
|
|
||||||
|
|
||||||
<b-form-text v-if="tagName" tag="span">
|
<p>Background color</p>
|
||||||
{{ $t('tags.form.preview') }}
|
<v-swatches v-model="tag.bgColor" show-fallback />
|
||||||
|
|
||||||
<b-badge :style="`background-color: ${hex}; color: ${tagTextColor}`">
|
<p>Text color</p>
|
||||||
{{ tagName }}
|
<v-swatches v-model="tag.textColor" show-fallback />
|
||||||
</b-badge>
|
|
||||||
</b-form-text>
|
|
||||||
</b-col>
|
|
||||||
|
|
||||||
<b-col cols="4" md="3">
|
<p>Preview</p>
|
||||||
<b-input-group>
|
|
||||||
<b-form-input
|
|
||||||
v-model="hex"
|
|
||||||
type="color"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
|
|
||||||
<b-form-input
|
<b-button
|
||||||
v-model="tagTextColor"
|
rounded
|
||||||
type="color"
|
block
|
||||||
required
|
size="sm"
|
||||||
/>
|
class="mr-2 mb-2 field"
|
||||||
</b-input-group>
|
variant="outline-light"
|
||||||
</b-col>
|
:style="`background-color: ${tag.bgColor}; color: ${tag.textColor}`"
|
||||||
</b-form-row>
|
>
|
||||||
|
{{ tag.name || 'Tag preview' }}
|
||||||
|
</b-button>
|
||||||
|
|
||||||
<b-button
|
<b-button
|
||||||
variant="primary"
|
variant="primary"
|
||||||
class="d-flex ml-auto"
|
:disabled="saving"
|
||||||
:disabled="isDuplicate || saving || !Boolean(tagName)"
|
type="submit"
|
||||||
@click="submit"
|
|
||||||
>
|
>
|
||||||
<b-spinner small v-if="saving" />
|
<b-spinner small v-if="saving" />
|
||||||
<span v-else>{{ $t('tags.form.addTag')}}</span>
|
<span v-else>Create</span>
|
||||||
</b-button>
|
</b-button>
|
||||||
|
|
||||||
<b-alert
|
|
||||||
class="mt-3 mb-0"
|
|
||||||
:show="isDuplicate"
|
|
||||||
variant="warning"
|
|
||||||
>
|
|
||||||
{{ $t('tags.form.duplicateMessage', { tagName }) }}
|
|
||||||
<strong>{{ tagName }}</strong>
|
|
||||||
</b-alert>
|
|
||||||
</form>
|
</form>
|
||||||
</b-container>
|
</b-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapState } from 'vuex';
|
import { mapState } from 'vuex';
|
||||||
|
import VSwatches from 'vue-swatches'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
colorCombinations: [
|
tag: {
|
||||||
['#0d1137', '#e52165'],
|
name: '',
|
||||||
['#ffffff', '#000000'],
|
textColor: '#DDE6E8',
|
||||||
['#101820', '#FEE715'],
|
bgColor: '#1FBC9C',
|
||||||
['#F2AA4C', '#101820'],
|
games: [],
|
||||||
['#F93822', '#FDD20E'],
|
},
|
||||||
],
|
saving: false,
|
||||||
tagTextColor: '#F4B41A',
|
|
||||||
tagName: '',
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
components: {
|
||||||
this.setRandomColors();
|
VSwatches,
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['tags', 'platform', 'games']),
|
...mapState(['tags']),
|
||||||
// isDuplicate() {
|
|
||||||
// const { tagName, localTags } = this;
|
|
||||||
//
|
|
||||||
// const tagNames = Object.keys(localTags)
|
|
||||||
// .filter(name => name !== tagName)
|
|
||||||
// .map(name => name.toLowerCase());
|
|
||||||
//
|
|
||||||
// return tagNames.includes(tagName.toLowerCase());
|
|
||||||
// },
|
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
setRandomColors() {
|
async submit() {
|
||||||
const { colorCombinations } = this;
|
this.$store.commit('CREATE_TAG', this.tag);
|
||||||
|
this.saving = true;
|
||||||
|
|
||||||
const randomNumber = Math.floor(Math.random() * colorCombinations.length);
|
await this.$store.dispatch('SAVE_GAME_TAGS')
|
||||||
|
.catch(() => {});
|
||||||
|
|
||||||
this.tagTextColor = colorCombinations[randomNumber][0];
|
this.saving = true;
|
||||||
this.hex = colorCombinations[randomNumber][1];
|
this.$router.push({ name: 'tags' })
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -34,14 +34,6 @@
|
||||||
ref="form"
|
ref="form"
|
||||||
@submit="saveTag"
|
@submit="saveTag"
|
||||||
>
|
>
|
||||||
<b-alert
|
|
||||||
class="mt-3 mb-0"
|
|
||||||
:show="isEditedNameDuplicate && !saving"
|
|
||||||
variant="warning"
|
|
||||||
>
|
|
||||||
You already have a tag named <strong>{{ tag.name }}</strong>
|
|
||||||
</b-alert>
|
|
||||||
|
|
||||||
<label for="tagName">Tag name:</label>
|
<label for="tagName">Tag name:</label>
|
||||||
|
|
||||||
<b-form-input
|
<b-form-input
|
||||||
|
@ -57,15 +49,14 @@
|
||||||
<p>Background color</p>
|
<p>Background color</p>
|
||||||
|
|
||||||
<v-swatches
|
<v-swatches
|
||||||
v-model="tag.hex"
|
v-model="tag.bgColor"
|
||||||
show-fallback
|
show-fallback
|
||||||
popover-x="left"
|
popover-x="left"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<p>Text color</p>
|
<p>Text color</p>
|
||||||
|
|
||||||
<v-swatches
|
<v-swatches
|
||||||
v-model="tag.tagTextColor"
|
v-model="tag.textColor"
|
||||||
show-fallback
|
show-fallback
|
||||||
popover-x="left"
|
popover-x="left"
|
||||||
/>
|
/>
|
||||||
|
@ -79,7 +70,7 @@
|
||||||
size="sm"
|
size="sm"
|
||||||
class="mr-2 mb-2 field"
|
class="mr-2 mb-2 field"
|
||||||
variant="outline-light"
|
variant="outline-light"
|
||||||
:style="`background-color: ${tag.hex}; color: ${tag.tagTextColor}`"
|
:style="`background-color: ${tag.bgColor}; color: ${tag.textColor}`"
|
||||||
>
|
>
|
||||||
{{ tag.name }}
|
{{ tag.name }}
|
||||||
</b-button>
|
</b-button>
|
||||||
|
@ -88,6 +79,11 @@
|
||||||
|
|
||||||
<p>Games tagged</p>
|
<p>Games tagged</p>
|
||||||
|
|
||||||
|
<b-alert :show="tag.games.length === 0" variant="light" class="field">
|
||||||
|
No games tagged
|
||||||
|
</b-alert>
|
||||||
|
<!-- TODO: add quick game picker -->
|
||||||
|
|
||||||
<div class="tagged-games">
|
<div class="tagged-games">
|
||||||
<b-img
|
<b-img
|
||||||
v-for="game in tag.games"
|
v-for="game in tag.games"
|
||||||
|
@ -103,7 +99,7 @@
|
||||||
|
|
||||||
<b-button
|
<b-button
|
||||||
variant="primary"
|
variant="primary"
|
||||||
:disabled="isEditedNameDuplicate || saving"
|
:disabled="saving"
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
<b-spinner small v-if="saving" />
|
<b-spinner small v-if="saving" />
|
||||||
|
@ -122,7 +118,6 @@ export default {
|
||||||
return {
|
return {
|
||||||
tag: {},
|
tag: {},
|
||||||
loading: true,
|
loading: true,
|
||||||
originalTagName: '',
|
|
||||||
localTags: {},
|
localTags: {},
|
||||||
saving: false,
|
saving: false,
|
||||||
}
|
}
|
||||||
|
@ -135,18 +130,6 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['tags', 'games']),
|
...mapState(['tags', 'games']),
|
||||||
|
|
||||||
tagNames() {
|
|
||||||
const sanitizedNames = this.tags?.map(({ name }) => name.toLowerCase());
|
|
||||||
|
|
||||||
return sanitizedNames.length > 0
|
|
||||||
? sanitizedNames.filter(name => name?.toLowerCase() !== this.originalTagName?.toLowerCase())
|
|
||||||
: [];
|
|
||||||
},
|
|
||||||
|
|
||||||
isEditedNameDuplicate() {
|
|
||||||
return this.tagNames?.includes(this.tag?.name?.toLowerCase());
|
|
||||||
},
|
|
||||||
|
|
||||||
tagIndex() {
|
tagIndex() {
|
||||||
return this.$route?.params?.id;
|
return this.$route?.params?.id;
|
||||||
},
|
},
|
||||||
|
@ -172,7 +155,6 @@ export default {
|
||||||
const { tags, tagIndex } = this;
|
const { tags, tagIndex } = this;
|
||||||
|
|
||||||
this.tag = JSON.parse(JSON.stringify(tags[tagIndex]));
|
this.tag = JSON.parse(JSON.stringify(tags[tagIndex]));
|
||||||
this.originalTagName = JSON.parse(JSON.stringify(this.tag.name));
|
|
||||||
|
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
},
|
},
|
||||||
|
@ -194,20 +176,15 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteTag(tagName) {
|
deleteTag(tagName) {
|
||||||
this.$delete(this.localTags, tagName);
|
// TODO: call mutation to remove tag and save tags
|
||||||
this.saveTags(true);
|
// this.saveTags(true);
|
||||||
},
|
|
||||||
|
|
||||||
removeTag(tagName) {
|
|
||||||
this.$store.commit('REMOVE_GAME_TAG', { tagName, gameId: this.gameId });
|
|
||||||
this.saveTags();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async saveTag(e) {
|
async saveTag(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (this.$refs.form.checkValidity()) {
|
if (this.$refs.form.checkValidity()) {
|
||||||
const { tag, tags, originalTagName } = this;
|
const { tag, tags } = this;
|
||||||
|
|
||||||
tags[this.tagIndex] = tag;
|
tags[this.tagIndex] = tag;
|
||||||
|
|
||||||
|
|
|
@ -96,14 +96,12 @@
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<b-button
|
<b-button
|
||||||
v-for="({ hex, tagTextColor, name }) in tags"
|
v-for="({ bgColor, textColor, name }) in tagsApplied"
|
||||||
:key="name"
|
:key="name"
|
||||||
rounded
|
rounded
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="outline-light"
|
|
||||||
class="mr-1 my-2"
|
class="mr-1 my-2"
|
||||||
:disabled="saving"
|
:style="`background-color: ${bgColor}; color: ${textColor}`"
|
||||||
:style="`background-color: ${hex}; color: ${tagTextColor}`"
|
|
||||||
@click="$router.push({ name: 'game.tags', params: { id: game.id, slug: game.slug } })"
|
@click="$router.push({ name: 'game.tags', params: { id: game.id, slug: game.slug } })"
|
||||||
>
|
>
|
||||||
{{ name }}
|
{{ name }}
|
||||||
|
@ -335,6 +333,10 @@ export default {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tagsApplied() {
|
||||||
|
return this.tags?.filter((tag) => tag?.games?.includes(this.game?.id))
|
||||||
|
},
|
||||||
|
|
||||||
legalNotice() {
|
legalNotice() {
|
||||||
return this.game?.steam?.legal_notice;
|
return this.game?.steam?.legal_notice;
|
||||||
},
|
},
|
||||||
|
|
|
@ -51,22 +51,20 @@
|
||||||
<section>
|
<section>
|
||||||
<h3 class="mb-3">Tags applied to {{ game.name }}</h3>
|
<h3 class="mb-3">Tags applied to {{ game.name }}</h3>
|
||||||
|
|
||||||
<b-alert
|
<b-alert :show="noneSelected" variant="light">
|
||||||
v-if="tagsSelected.length === 0"
|
|
||||||
show
|
|
||||||
variant="light"
|
|
||||||
>
|
|
||||||
No tags applied
|
No tags applied
|
||||||
</b-alert>
|
</b-alert>
|
||||||
|
<!-- TODO: use correct tags -->
|
||||||
<b-button
|
<b-button
|
||||||
v-for="{ name, hex, tagTextColor } in tags"
|
v-for="({ selected, name, bgColor, textColor }, index) in formattedTags"
|
||||||
:key="name"
|
:key="name"
|
||||||
rounded
|
rounded
|
||||||
block
|
block
|
||||||
variant="outline-light"
|
variant="outline-light"
|
||||||
:style="`background-color: ${hex}; color: ${tagTextColor}`"
|
:class="{ 'd-none': !selected }"
|
||||||
@click="removeTag"
|
:disabled="saving"
|
||||||
|
:style="`background-color: ${bgColor}; color: ${textColor}`"
|
||||||
|
@click="removeTag(index)"
|
||||||
>
|
>
|
||||||
{{ name }}
|
{{ name }}
|
||||||
</b-button>
|
</b-button>
|
||||||
|
@ -76,19 +74,19 @@
|
||||||
|
|
||||||
<h3 class="my-3">Tags available</h3>
|
<h3 class="my-3">Tags available</h3>
|
||||||
|
|
||||||
<pre>{{ tags }}</pre>
|
<b-button
|
||||||
<!-- <b-button
|
v-for="({ selected, name, bgColor, textColor }, index) in formattedTags"
|
||||||
v-for="({ name, hex, tagTextColor }, index) in tags"
|
|
||||||
:key="name"
|
:key="name"
|
||||||
rounded
|
rounded
|
||||||
block
|
block
|
||||||
variant="outline-light"
|
variant="outline-light"
|
||||||
|
:class="{ 'd-none': selected }"
|
||||||
:disabled="saving"
|
:disabled="saving"
|
||||||
:style="`background-color: ${hex}; color: ${tagTextColor}`"
|
:style="`background-color: ${bgColor}; color: ${textColor}`"
|
||||||
@click="addTag(index)"
|
@click="addTag(index)"
|
||||||
>
|
>
|
||||||
{{ name }}
|
{{ name }}
|
||||||
</b-button> -->
|
</b-button>
|
||||||
</section>
|
</section>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
|
@ -131,36 +129,25 @@ export default {
|
||||||
return Object.keys(this.tags).length === 0;
|
return Object.keys(this.tags).length === 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
tagsSelected() {
|
formattedTags() {
|
||||||
return this.tags?.filter(({ games }) => {
|
return this.tags.map((tag) => ({
|
||||||
return games?.includes(this.game?.id);
|
...tag,
|
||||||
})
|
selected: tag.games.includes(Number(this.$route.params.id)),
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
tagsAvailable() {
|
noneSelected() {
|
||||||
return Object.entries(this.tags).map((t) => {
|
return !this.formattedTags.some(({ selected }) => Boolean(selected));
|
||||||
const [name, tag] = t;
|
|
||||||
|
|
||||||
return { name: name, ...tag };
|
|
||||||
})
|
|
||||||
.filter(({ games }) => {
|
|
||||||
return !games.includes(this.game.id);
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
if (this.game?.id !== this.$route.params.id) {
|
this.load();
|
||||||
this.loadGame();
|
|
||||||
} else {
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
async loadGame() {
|
async load() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.$store.commit('CLEAR_GAME');
|
|
||||||
|
|
||||||
await this.$store.dispatch('LOAD_GAME', this.$route.params.id);
|
await this.$store.dispatch('LOAD_GAME', this.$route.params.id);
|
||||||
await this.$store.dispatch('LOAD_TAGS')
|
await this.$store.dispatch('LOAD_TAGS')
|
||||||
|
@ -172,36 +159,28 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
async addTag(index) {
|
async addTag(index) {
|
||||||
console.log('add this tag');
|
this.$store.commit('APPLY_TAG_TO_GAME', index);
|
||||||
// TODO: use commit instead?
|
this.saving = true;
|
||||||
// const gameId = this.game.id;
|
|
||||||
//
|
|
||||||
// if (!gameId) return;
|
|
||||||
//
|
|
||||||
// const tags = JSON.parse(JSON.stringify(this.tags)) ;
|
|
||||||
//
|
|
||||||
// tags[index].games.push(gameId)
|
|
||||||
//
|
|
||||||
// console.log(`game id ${gameId} should be included`, tags[index].games);
|
|
||||||
|
|
||||||
// this.saving = true;
|
await this.$store.dispatch('SAVE_GAME_TAGS')
|
||||||
|
.catch(() => {
|
||||||
|
this.saving = false;
|
||||||
|
});
|
||||||
|
|
||||||
// await this.$store.dispatch('SAVE_TAGS', tags)
|
this.saving = false;
|
||||||
// .catch((e) => {
|
|
||||||
// console.log(e);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// this.saving = false;
|
|
||||||
|
|
||||||
// this.$store.commit('ADD_GAME_TAG', { tagName, gameId });
|
|
||||||
// await this.saveTags();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async removeTag(tagName) {
|
async removeTag(index) {
|
||||||
const gameId = this.game.id;
|
this.$store.commit('REMOVE_GAME_TAG', index);
|
||||||
|
|
||||||
// this.$store.commit('REMOVE_GAME_TAG', { tagName, gameId });
|
this.saving = true;
|
||||||
// await this.saveTags();
|
|
||||||
|
await this.$store.dispatch('SAVE_GAME_TAGS')
|
||||||
|
.catch(() => {
|
||||||
|
this.saving = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.saving = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
manageTags() {
|
manageTags() {
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
<portal to="headerActions">
|
<portal to="headerActions">
|
||||||
<b-button
|
<b-button
|
||||||
|
v-if="!showEmptyState"
|
||||||
class="mr-2"
|
class="mr-2"
|
||||||
variant="light"
|
variant="light"
|
||||||
:to="{ name: 'tag.create' }"
|
:to="{ name: 'tag.create' }"
|
||||||
|
@ -27,9 +28,7 @@
|
||||||
</b-button>
|
</b-button>
|
||||||
</empty-state>
|
</empty-state>
|
||||||
|
|
||||||
<b-col v-else>
|
<tags-list v-else />
|
||||||
<tags-list />
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
</b-row>
|
||||||
</b-container>
|
</b-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -581,6 +581,18 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
SAVE_GAME_TAGS({ state }) {
|
||||||
|
const db = firestore();
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
db.collection('tags')
|
||||||
|
.doc(state.user.uid)
|
||||||
|
.set({ tags: state.tags }, { merge: false })
|
||||||
|
.then(() => resolve())
|
||||||
|
.catch(reject);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
GET_TWITCH_TOKEN({ commit }) {
|
GET_TWITCH_TOKEN({ commit }) {
|
||||||
const db = firestore();
|
const db = firestore();
|
||||||
|
|
||||||
|
@ -726,14 +738,13 @@ export default {
|
||||||
const { tags } = doc.data();
|
const { tags } = doc.data();
|
||||||
|
|
||||||
if (typeof tags === 'object') {
|
if (typeof tags === 'object') {
|
||||||
console.warn('Legacy tag detected');
|
// console.warn('Legacy tag detected');
|
||||||
|
|
||||||
const formattedTags = Object.entries(tags).map(([ ,tag]) => ({ ...tag }));
|
const formattedTags = Object.entries(tags).map(([ ,tag]) => ({ ...tag }));
|
||||||
|
|
||||||
commit('SET_TAGS', formattedTags);
|
commit('SET_TAGS', formattedTags);
|
||||||
resolve(formattedTags);
|
resolve(formattedTags);
|
||||||
} else {
|
} else {
|
||||||
console.log('is type', typeof tags);
|
// console.log('is type', typeof tags);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,19 +9,6 @@ export default {
|
||||||
return board?.owner === user?.uid;
|
return board?.owner === user?.uid;
|
||||||
},
|
},
|
||||||
|
|
||||||
gameTags: ({ tags, game }) => {
|
|
||||||
if (!game?.id) return [];
|
|
||||||
// TODO: refactor architecture, don't use tag name as key
|
|
||||||
const tagsArray = Object.entries(tags);
|
|
||||||
const filteredTags = tagsArray.filter(([key, value]) => {
|
|
||||||
return value.games.includes(game.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
const filteredTagsObject = Object.fromEntries(filteredTags);
|
|
||||||
|
|
||||||
return filteredTagsObject;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Arabic is the only ltr language supported at the moment
|
// Arabic is the only ltr language supported at the moment
|
||||||
isRTL: ({ settings }) => settings && settings.language !== 'ar',
|
isRTL: ({ settings }) => settings && settings.language !== 'ar',
|
||||||
|
|
||||||
|
|
|
@ -175,21 +175,21 @@ export default {
|
||||||
state.settings = settings;
|
state.settings = settings;
|
||||||
},
|
},
|
||||||
|
|
||||||
UPDATE_TAG(state, { tagName, tagHex, tempTag }) {
|
// UPDATE_TAG(state, { tagName, tagHex, tempTag }) {
|
||||||
const updatedTag = {
|
// const updatedTag = {
|
||||||
...state.tags[tempTag.tagName],
|
// ...state.tags[tempTag.tagName],
|
||||||
hex: tagHex,
|
// hex: tagHex,
|
||||||
};
|
// };
|
||||||
|
//
|
||||||
const renaming = tagName !== tempTag.tagName;
|
// const renaming = tagName !== tempTag.tagName;
|
||||||
|
//
|
||||||
if (renaming) {
|
// if (renaming) {
|
||||||
Vue.set(state.tags, tagName, updatedTag);
|
// Vue.set(state.tags, tagName, updatedTag);
|
||||||
Vue.delete(state.tags, tempTag.tagName);
|
// Vue.delete(state.tags, tempTag.tagName);
|
||||||
} else {
|
// } else {
|
||||||
state.tags[tempTag.tagName] = updatedTag;
|
// state.tags[tempTag.tagName] = updatedTag;
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
|
|
||||||
SET_TAGS(state, tags) {
|
SET_TAGS(state, tags) {
|
||||||
state.tags = tags;
|
state.tags = tags;
|
||||||
|
@ -247,12 +247,18 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
ADD_GAME_TAG(state, { tagName, gameId }) {
|
APPLY_TAG_TO_GAME(state, tagIndex) {
|
||||||
state.tags[tagName].games.push(gameId);
|
state.tags[tagIndex].games.push(state.game.id);
|
||||||
},
|
},
|
||||||
|
|
||||||
REMOVE_GAME_TAG(state, { tagName, gameId }) {
|
CREATE_TAG(state, tag) {
|
||||||
state.tags[tagName].games.splice(state.tags[tagName].games.indexOf(gameId), 1);
|
state.tags.push(tag);
|
||||||
|
},
|
||||||
|
|
||||||
|
REMOVE_GAME_TAG(state, tagIndex) {
|
||||||
|
const gameIndex = state.tags[tagIndex].games.indexOf(state.game.id);
|
||||||
|
|
||||||
|
state.tags[tagIndex].games.splice(gameIndex, 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
SET_SEARCH_RESULTS(state, results) {
|
SET_SEARCH_RESULTS(state, results) {
|
||||||
|
|
Loading…
Reference in a new issue