mirror of
https://github.com/romancm/gamebrary
synced 2024-11-27 13:40:48 +00:00
Platform exclusive tags and custom colors
This commit is contained in:
parent
35bbb826f0
commit
874e018b42
8 changed files with 164 additions and 100 deletions
|
@ -37,7 +37,7 @@
|
|||
class="game-tags"
|
||||
>
|
||||
<div
|
||||
v-for="({ games, hex }, name) in tags"
|
||||
v-for="({ games, hex, tagTextColor }, name) in tags"
|
||||
v-if="games.includes(game.id)"
|
||||
:key="name"
|
||||
>
|
||||
|
@ -45,6 +45,7 @@
|
|||
v-if="games.includes(game.id)"
|
||||
:label="name"
|
||||
:hex="hex"
|
||||
:text-hex="tagTextColor"
|
||||
readonly
|
||||
@action="openTags"
|
||||
/>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
class="game-tags"
|
||||
>
|
||||
<div
|
||||
v-for="({ games, hex }, name) in tags"
|
||||
v-for="({ games, hex, tagTextColor }, name) in tags"
|
||||
v-if="games.includes(game.id)"
|
||||
:key="name"
|
||||
>
|
||||
|
@ -31,6 +31,7 @@
|
|||
v-if="games.includes(game.id)"
|
||||
:label="name"
|
||||
:hex="hex"
|
||||
:text-hex="tagTextColor"
|
||||
readonly
|
||||
@action="openTags"
|
||||
/>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
<div v-if="hasTags" class="game-tags">
|
||||
<div
|
||||
v-for="({ games, hex }, name) in tags"
|
||||
v-for="({ games, hex, tagTextColor }, name) in tags"
|
||||
v-if="games.includes(game.id)"
|
||||
:key="name"
|
||||
>
|
||||
|
@ -39,6 +39,7 @@
|
|||
v-if="games.includes(game.id)"
|
||||
:label="name"
|
||||
:hex="hex"
|
||||
:text-hex="tagTextColor"
|
||||
readonly
|
||||
@action="openTags"
|
||||
@close="removeTag(name)"
|
||||
|
|
|
@ -18,12 +18,43 @@
|
|||
type="text"
|
||||
>
|
||||
|
||||
<input
|
||||
:value="tagHex"
|
||||
type="color"
|
||||
class="color-picker"
|
||||
@change="updateColor"
|
||||
>
|
||||
<div class="color-picker-wrapper">
|
||||
<i class="fas fa-fill-drip" />
|
||||
|
||||
<input
|
||||
:value="tagHex"
|
||||
type="color"
|
||||
class="color-picker"
|
||||
@change="updateColor"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="color-picker-wrapper">
|
||||
<i class="fas fa-font" />
|
||||
<input
|
||||
:value="tagTextColor"
|
||||
type="color"
|
||||
class="color-picker"
|
||||
@change="updateTextColor"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="preview">
|
||||
<tag
|
||||
label="Preview"
|
||||
:hex="tagHex"
|
||||
:textHex="tagTextColor"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="exclusive-toggle">
|
||||
Exclusive to {{ platform.name }}
|
||||
|
||||
<toggle-switch
|
||||
id="global"
|
||||
v-model="exclusive"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tag-actions">
|
||||
|
@ -36,41 +67,51 @@
|
|||
</button>
|
||||
|
||||
<button
|
||||
:disabled="isDuplicate && !editing"
|
||||
:disabled="isDuplicate"
|
||||
class="primary"
|
||||
@click="submit"
|
||||
@click="createTag"
|
||||
>
|
||||
{{ actionLabel }}
|
||||
{{ $t('global.save') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="hasTags"
|
||||
class="tags"
|
||||
>
|
||||
<tag
|
||||
v-for="(tag, name) in localTags"
|
||||
:key="name"
|
||||
:label="name"
|
||||
:hex="tag.hex"
|
||||
@close="deleteTag(name)"
|
||||
/>
|
||||
<!-- @click.native="editTag(tag, name)" -->
|
||||
<div v-if="hasTags" class="tags">
|
||||
<!-- TODO: use computed properties for filtering out tags -->
|
||||
<section>
|
||||
<h3>All tags</h3>
|
||||
|
||||
<tag
|
||||
v-for="(tag, name) in localTags"
|
||||
v-if="!tag.platform"
|
||||
:key="name"
|
||||
:label="name"
|
||||
:hex="tag.hex"
|
||||
:text-hex="tag.tagTextColor"
|
||||
@close="deleteTag(name)"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>{{ platform.name }} tags</h3>
|
||||
|
||||
<tag
|
||||
v-for="(tag, name) in localTags"
|
||||
v-if="tag.platform && tag.platform === platform.id"
|
||||
:key="name"
|
||||
:label="name"
|
||||
:hex="tag.hex"
|
||||
:text-hex="tag.tagTextColor"
|
||||
@close="deleteTag(name)"
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <button
|
||||
class="small warning"
|
||||
:title="$t('list.delete')"
|
||||
>
|
||||
<i class="far fa-trash-alt" />
|
||||
Delete {{ platform.name }} collection
|
||||
</button> -->
|
||||
|
||||
</modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ToggleSwitch from '@/components/ToggleSwitch';
|
||||
import Tag from '@/components/Tag';
|
||||
import Modal from '@/components/Modal';
|
||||
import { mapState } from 'vuex';
|
||||
|
@ -79,6 +120,7 @@ export default {
|
|||
components: {
|
||||
Tag,
|
||||
Modal,
|
||||
ToggleSwitch,
|
||||
},
|
||||
|
||||
data() {
|
||||
|
@ -86,18 +128,19 @@ export default {
|
|||
localTags: {},
|
||||
tagName: '',
|
||||
tagHex: '',
|
||||
originalTagName: '',
|
||||
editing: false,
|
||||
defaultColor: '#ffcc00',
|
||||
tagTextColor: '#f4b41a',
|
||||
defaultColor: '#143d59',
|
||||
exclusive: false,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['tags']),
|
||||
...mapState(['tags', 'platform']),
|
||||
|
||||
newTag() {
|
||||
return {
|
||||
hex: this.tagHex,
|
||||
tagTextColor: this.tagTextColor,
|
||||
games: [],
|
||||
};
|
||||
},
|
||||
|
@ -126,12 +169,6 @@ export default {
|
|||
hasTags() {
|
||||
return Object.keys(this.localTags).length > 0;
|
||||
},
|
||||
|
||||
actionLabel() {
|
||||
return this.editing
|
||||
? this.$t('global.save')
|
||||
: this.$t('tags.createTag');
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
|
@ -140,34 +177,23 @@ export default {
|
|||
},
|
||||
|
||||
methods: {
|
||||
submit() {
|
||||
if (this.editing) {
|
||||
this.saveTag();
|
||||
} else {
|
||||
this.createTag();
|
||||
}
|
||||
},
|
||||
|
||||
saveTag() {
|
||||
const { tagName, tagHex, tempTag } = this;
|
||||
|
||||
if (tempTag.tagName !== tagName || tempTag.hex !== tagHex) {
|
||||
this.$store.commit('UPDATE_TAG', { tagName, tagHex, tempTag });
|
||||
this.$bus.$emit('SAVE_TAGS', this.tags);
|
||||
this.localTags = JSON.parse(JSON.stringify(this.tags));
|
||||
this.reset();
|
||||
}
|
||||
},
|
||||
|
||||
updateColor(e) {
|
||||
this.tagHex = e.srcElement.value;
|
||||
},
|
||||
|
||||
updateTextColor(e) {
|
||||
this.tagTextColor = e.srcElement.value;
|
||||
},
|
||||
|
||||
createTag() {
|
||||
if (!this.tagHex || !this.tagName || this.isDuplicate) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.exclusive) {
|
||||
this.newTag.platform = this.platform.id;
|
||||
}
|
||||
|
||||
this.$set(this.localTags, this.tagName, this.newTag);
|
||||
this.$bus.$emit('SAVE_TAGS', this.localTags);
|
||||
this.reset();
|
||||
|
@ -182,14 +208,9 @@ export default {
|
|||
reset() {
|
||||
this.tagName = '';
|
||||
this.tagHex = this.defaultColor;
|
||||
this.editing = false;
|
||||
},
|
||||
this.exclusive = false;
|
||||
|
||||
editTag({ hex }, tagName) {
|
||||
this.tempTag = { tagName, hex };
|
||||
this.tagName = tagName;
|
||||
this.tagHex = hex;
|
||||
this.editing = true;
|
||||
this.$forceUpdate();
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -200,7 +221,7 @@ export default {
|
|||
|
||||
.tag-input {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 40px;
|
||||
grid-template-columns: 1fr 40px 40px 60px;
|
||||
grid-gap: $gp;
|
||||
margin-bottom: $gp;
|
||||
}
|
||||
|
@ -227,4 +248,38 @@ export default {
|
|||
.tag {
|
||||
margin: 0 $gp / 2 $gp / 2 0;
|
||||
}
|
||||
|
||||
.tags {
|
||||
display: grid;
|
||||
grid-gap: $gp / 2;
|
||||
|
||||
h3 {
|
||||
margin-bottom: $gp / 2;
|
||||
}
|
||||
}
|
||||
|
||||
.exclusive-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.color-picker-wrapper {
|
||||
i {
|
||||
position: absolute;
|
||||
width: 40px;
|
||||
text-shadow: 0 1px 0 #000;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
overflow: visible;
|
||||
pointer-events: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.preview {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
|
@ -1,8 +1,8 @@
|
|||
<template lang="html">
|
||||
<span
|
||||
v-if="label && hex"
|
||||
:style="`background-color: ${hex}`"
|
||||
:class="['tag', textColor, { readonly }]"
|
||||
:style="`background-color: ${hex}; color: ${textHex}`"
|
||||
:class="['tag', { readonly }]"
|
||||
>
|
||||
<i
|
||||
v-if="!readonly"
|
||||
|
@ -31,20 +31,9 @@ export default {
|
|||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
textColor() {
|
||||
const hexColor = this.hex ? this.hex.replace('#', 0) : '#000000';
|
||||
|
||||
const r = parseInt(hexColor.substr(0, 2), 16);
|
||||
const g = parseInt(hexColor.substr(2, 2), 16);
|
||||
const b = parseInt(hexColor.substr(4, 2), 16);
|
||||
|
||||
// eslint-disable-next-line
|
||||
const yiq = ((r*299)+(g*587)+(b*114))/1000;
|
||||
|
||||
return yiq >= 128 ? 'dark' : 'light';
|
||||
textHex: {
|
||||
type: String,
|
||||
default: '#000',
|
||||
},
|
||||
},
|
||||
|
||||
|
|
|
@ -22,25 +22,40 @@
|
|||
/>
|
||||
</modal>
|
||||
|
||||
<!-- TODO: move this to its own component -->
|
||||
<modal
|
||||
ref="tag"
|
||||
:title="$t('tags.applyTag')"
|
||||
:message="$t('tags.useTags')"
|
||||
>
|
||||
<div slot="content">
|
||||
<div
|
||||
<h3>All tags</h3>
|
||||
|
||||
<tag
|
||||
v-for="(tag, name) in tags"
|
||||
v-if="!tag.platform"
|
||||
:key="name"
|
||||
class="tags"
|
||||
>
|
||||
<tag
|
||||
:label="name"
|
||||
:hex="tag.hex"
|
||||
:readonly="!tag.games.includes(gameTagsId)"
|
||||
@action="tryAdd(tag.games, name)"
|
||||
@close="removeTag(name)"
|
||||
/>
|
||||
</div>
|
||||
:label="name"
|
||||
:hex="tag.hex"
|
||||
:text-hex="tag.tagTextColor"
|
||||
:readonly="!tag.games.includes(gameTagsId)"
|
||||
@action="tryAdd(tag.games, name)"
|
||||
@close="removeTag(name)"
|
||||
/>
|
||||
|
||||
<h3>{{ platform.name }} tags</h3>
|
||||
|
||||
<tag
|
||||
v-for="(tag, name) in tags"
|
||||
v-if="tag.platform && tag.platform === platform.id"
|
||||
:key="name"
|
||||
:label="name"
|
||||
:hex="tag.hex"
|
||||
:text-hex="tag.tagTextColor"
|
||||
:readonly="!tag.games.includes(gameTagsId)"
|
||||
@action="tryAdd(tag.games, name)"
|
||||
@close="removeTag(name)"
|
||||
/>
|
||||
</div>
|
||||
</modal>
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<game-notes />
|
||||
|
||||
<section v-if="gamePlatforms && gamePlatforms.length > 0">
|
||||
|
@ -67,11 +68,12 @@
|
|||
</section>
|
||||
|
||||
<tag
|
||||
v-for="({ games, hex }, name) in tags"
|
||||
v-for="({ games, hex, tagTextColor }, name) in tags"
|
||||
v-if="games.includes(game.id)"
|
||||
:key="name"
|
||||
:label="name"
|
||||
:hex="hex"
|
||||
:text-hex="tagTextColor"
|
||||
readonly
|
||||
@action="openTags"
|
||||
@close="removeTag(name)"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
class="settings"
|
||||
>
|
||||
<game-board-settings v-model="localSettings" />
|
||||
<tags-settings v-model="localSettings" />
|
||||
<manage-tags v-model="localSettings" />
|
||||
|
||||
<div class="setting">
|
||||
<i class="fas fa-sign-out-alt" />
|
||||
|
@ -53,7 +53,7 @@ import 'firebase/auth';
|
|||
import GameBoardSettings from '@/components/Settings/GameBoardSettings';
|
||||
import SettingsGlobal from '@/components/Settings/SettingsGlobal';
|
||||
import AboutSettings from '@/components/Settings/AboutSettings';
|
||||
import TagsSettings from '@/components/Settings/TagsSettings';
|
||||
import ManageTags from '@/components/Settings/ManageTags';
|
||||
import Modal from '@/components/Modal';
|
||||
import moment from 'moment';
|
||||
import firebase from 'firebase/app';
|
||||
|
@ -66,7 +66,7 @@ export default {
|
|||
GameBoardSettings,
|
||||
SettingsGlobal,
|
||||
AboutSettings,
|
||||
TagsSettings,
|
||||
ManageTags,
|
||||
},
|
||||
|
||||
data() {
|
||||
|
|
Loading…
Reference in a new issue