mirror of
https://github.com/romancm/gamebrary
synced 2024-11-12 22:47:14 +00:00
WIP stuff
This commit is contained in:
parent
74f484ec27
commit
91d1a1bde8
10 changed files with 147 additions and 176 deletions
|
@ -1,79 +1,54 @@
|
|||
<template lang="html">
|
||||
<div class="standard-board pb-5">
|
||||
GRID!@@
|
||||
<!-- TODO: clean this up, remove all isGrid references -->
|
||||
<!-- TODO: update isGrid to use board?.grid -->
|
||||
<div class="standard-list" :class="{ 'grid': isGrid }">
|
||||
<p v-if="isEmpty">
|
||||
This board is empty.
|
||||
</p>
|
||||
<div class="grid-board pb-5">
|
||||
<p v-if="isEmpty">
|
||||
This board is empty.
|
||||
</p>
|
||||
|
||||
<draggable
|
||||
class="games"
|
||||
:class="{ 'game-grid': isGrid }"
|
||||
handle=".card"
|
||||
ghost-class="card-placeholder"
|
||||
drag-class="border-success"
|
||||
chosen-class="border-primary"
|
||||
filter=".drag-filter"
|
||||
delay="50"
|
||||
animation="500"
|
||||
:list="list.games"
|
||||
:move="validateMove"
|
||||
:disabled="draggingDisabled"
|
||||
:group="{ name: 'games' }"
|
||||
@end="dragEnd"
|
||||
@start="dragStart"
|
||||
<draggable
|
||||
class="game-grid"
|
||||
v-bind="draggableProps"
|
||||
:list="list.games"
|
||||
:disabled="draggingDisabled"
|
||||
:move="validateMove"
|
||||
@end="dragEnd"
|
||||
@start="dragStart"
|
||||
>
|
||||
<GameCard
|
||||
v-for="(gameId, index) in listGames"
|
||||
:key="index"
|
||||
:list="list"
|
||||
:ref="gameId"
|
||||
:game-id="gameId"
|
||||
:ranked="board.ranked"
|
||||
:rank="index + 1"
|
||||
vertical
|
||||
hide-platforms
|
||||
@click.native="openGame(gameId, list)"
|
||||
/>
|
||||
|
||||
<b-card
|
||||
v-if="isBoardOwner"
|
||||
slot="footer"
|
||||
body-class="align-content-center text-center"
|
||||
:bg-variant="darkTheme ? 'dark' : 'light'"
|
||||
:text-variant="darkTheme ? 'light' : 'dark'"
|
||||
@click="openGameSelectorSidebar"
|
||||
>
|
||||
<GameCard
|
||||
v-for="(game, index) in listGames"
|
||||
:key="index"
|
||||
:list="list"
|
||||
:ref="game.id"
|
||||
:game-id="game.id"
|
||||
:ranked="board.ranked"
|
||||
:rank="index + 1"
|
||||
:vertical="isGrid"
|
||||
:hide-platforms="isGrid"
|
||||
:class="isGrid ? null: 'mb-3'"
|
||||
@click.native="openGame(game.id, list)"
|
||||
/>
|
||||
Expand your collection!
|
||||
|
||||
<template v-if="isBoardOwner">
|
||||
<b-card
|
||||
v-if="isGrid"
|
||||
body-class="align-content-center text-center"
|
||||
:bg-variant="darkTheme ? 'dark' : 'light'"
|
||||
:text-variant="darkTheme ? 'light' : 'dark'"
|
||||
@click="openGameSelectorSidebar"
|
||||
>
|
||||
Expand your collection!
|
||||
|
||||
<b-button
|
||||
class="mt-2"
|
||||
:variant="darkTheme ? 'success' : 'primary'"
|
||||
>
|
||||
Add games
|
||||
</b-button>
|
||||
</b-card>
|
||||
|
||||
<b-button
|
||||
v-else
|
||||
class="py-3"
|
||||
block
|
||||
:variant="darkTheme ? 'success' : 'primary'"
|
||||
@click="openGameSelectorSidebar"
|
||||
>
|
||||
Add games
|
||||
</b-button>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
<b-button
|
||||
class="mt-2"
|
||||
:variant="darkTheme ? 'success' : 'primary'"
|
||||
>
|
||||
Add games
|
||||
</b-button>
|
||||
</b-card>
|
||||
</draggable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { HIGHLIGHTED_GAME_TIMEOUT, BOARD_TYPE_GRID } from '@/constants';
|
||||
import { HIGHLIGHTED_GAME_TIMEOUT } from '@/constants';
|
||||
import draggable from 'vuedraggable';
|
||||
import slugify from 'slugify'
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
|
@ -87,7 +62,7 @@ export default {
|
|||
|
||||
computed: {
|
||||
...mapState(['cachedGames', 'dragging', 'progresses', 'board', 'user', 'settings', 'highlightedGame']),
|
||||
...mapGetters(['isBoardOwner', 'darkTheme']),
|
||||
...mapGetters(['isBoardOwner', 'darkTheme', 'draggableProps']),
|
||||
|
||||
list() {
|
||||
const [firstList] = this.board?.lists;
|
||||
|
@ -99,10 +74,6 @@ export default {
|
|||
return this.board?.lists?.length > 0;
|
||||
},
|
||||
|
||||
isGrid() {
|
||||
return this.board?.type === BOARD_TYPE_GRID;
|
||||
},
|
||||
|
||||
filter() {
|
||||
return this.listGames || [];
|
||||
},
|
||||
|
@ -112,9 +83,7 @@ export default {
|
|||
},
|
||||
|
||||
listGames() {
|
||||
return this.list?.games
|
||||
?.map((id) => this.cachedGames?.[id])
|
||||
?.filter(({ id }) => Boolean(id));
|
||||
return this.list?.games;
|
||||
},
|
||||
|
||||
isEmpty() {
|
||||
|
@ -160,9 +129,9 @@ export default {
|
|||
}
|
||||
});
|
||||
|
||||
// setTimeout(() => {
|
||||
// this.$store.commit('SET_HIGHLIGHTED_GAME', null);
|
||||
// }, HIGHLIGHTED_GAME_TIMEOUT);
|
||||
setTimeout(() => {
|
||||
this.$store.commit('SET_HIGHLIGHTED_GAME', null);
|
||||
}, HIGHLIGHTED_GAME_TIMEOUT);
|
||||
},
|
||||
|
||||
async flattenAndSaveBoard() {
|
||||
|
@ -221,7 +190,7 @@ export default {
|
|||
await this.$store.dispatch('SAVE_GAME_BOARD', board);
|
||||
await this.$store.dispatch('LOAD_BOARD', board?.id)
|
||||
} catch (e) {
|
||||
// this.$bvToast.toast(`There was an error removing "${this.game.name}"`, { title: list.name, variant: 'danger' });
|
||||
this.$bvToast.toast(`There was an error removing "${this.game.name}"`, { title: list.name, variant: 'danger' });
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -266,11 +235,13 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.standard-board {
|
||||
.grid-board {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow-y: auto;
|
||||
flex-direction: column;
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
filter=".drag-filter"
|
||||
delay="50"
|
||||
animation="500"
|
||||
:list="list.games"
|
||||
:list="listGames"
|
||||
:move="validateMove"
|
||||
:disabled="draggingDisabled"
|
||||
:group="{ name: 'games' }"
|
||||
|
@ -227,3 +227,17 @@ export default {
|
|||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.standard-board {
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
overflow-x: hidden;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow-y: auto;
|
||||
flex-direction: column;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -164,19 +164,3 @@ export default {
|
|||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" rel="stylesheet/scss">
|
||||
.game-cover {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.standard-list {
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
overflow-x: hidden;
|
||||
|
||||
&.grid {
|
||||
max-width: 1280px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
<!-- TODO: fix Lists will be merged into a single list. -->
|
||||
<!-- TODO: allow to upload and set wallpaper from here -->
|
||||
<template lang="html">
|
||||
<b-sidebar
|
||||
id="edit-board-sidebar"
|
||||
|
@ -143,7 +145,13 @@
|
|||
|
||||
<script>
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
import { BOARD_TYPES, BOARD_TYPE_STANDARD, BOARD_TYPE_KANBAN, LIST_SORT_OPTIONS } from '@/constants';
|
||||
import {
|
||||
BOARD_TYPES,
|
||||
BOARD_TYPE_STANDARD,
|
||||
BOARD_TYPE_GRID,
|
||||
BOARD_TYPE_KANBAN,
|
||||
LIST_SORT_OPTIONS,
|
||||
} from '@/constants';
|
||||
import WallpapersList from '@/components/WallpapersList';
|
||||
import UploadWallpaperButton from '@/components/UploadWallpaperButton';
|
||||
import SidebarHeader from '@/components/SidebarHeader';
|
||||
|
@ -153,6 +161,7 @@ import VSwatches from 'vue-swatches';
|
|||
export default {
|
||||
BOARD_TYPES,
|
||||
BOARD_TYPE_STANDARD,
|
||||
BOARD_TYPE_GRID,
|
||||
LIST_SORT_OPTIONS,
|
||||
|
||||
components: {
|
||||
|
@ -183,7 +192,9 @@ export default {
|
|||
needsFlattening() {
|
||||
const listCount = this.board?.lists?.length || 0;
|
||||
|
||||
return listCount > 1 && this.board.type === 'standard';
|
||||
if (!listCount) return
|
||||
|
||||
return [BOARD_TYPE_STANDARD, BOARD_TYPE_GRID].includes(this.board.type);
|
||||
},
|
||||
|
||||
mergedGamesList() {
|
||||
|
|
|
@ -234,9 +234,32 @@ export default {
|
|||
display: grid;
|
||||
grid-template-columns: 140px auto;
|
||||
grid-gap: 1rem;
|
||||
transition: background-color 300ms linear;
|
||||
transition: background-color 300ms linear, transform 0.3s ease, box-shadow 0.3s ease, opacity 0.2s ease;
|
||||
padding: 0.5rem;
|
||||
|
||||
&.dragging {
|
||||
// cursor: grabbing;
|
||||
display: block;
|
||||
transform: rotate(1deg) !important;
|
||||
// box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); /* Stronger shadow when dragged */
|
||||
// transition: transform 0.2s ease, box-shadow 0.2s ease; /* Faster transition while dragging */
|
||||
}
|
||||
|
||||
&.ghost {
|
||||
.like-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
aside {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
img {
|
||||
opacity: 0.2;
|
||||
filter: grayscale(90%);
|
||||
}
|
||||
}
|
||||
|
||||
&.highlighted {
|
||||
border: 3px dotted var(--danger);
|
||||
}
|
||||
|
|
|
@ -348,54 +348,9 @@ export default {
|
|||
|
||||
.games {
|
||||
overflow: hidden;
|
||||
max-height: calc(100vh - 200px);
|
||||
max-height: calc(100vh - 209px);
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
|
||||
@media(max-width: 768px) {
|
||||
max-height: 70vh;
|
||||
}
|
||||
}
|
||||
|
||||
&.grid {
|
||||
.games {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-column-gap: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
&.covers {
|
||||
.games {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
grid-column-gap: .5rem;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
padding-bottom: .5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-settings {
|
||||
padding: 1rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" rel="stylesheet/scss">
|
||||
.card-placeholder {
|
||||
> div {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
img {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
height: 100px;
|
||||
opacity: .1;
|
||||
background: #000;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -79,35 +79,31 @@
|
|||
</div>
|
||||
|
||||
<div :class="['game-description pb-4', source]">
|
||||
<b-spinner v-if="loading" class="spinner-centered" />
|
||||
<p v-html="description" />
|
||||
|
||||
<template v-else>
|
||||
<p v-html="description" />
|
||||
<p class="small">
|
||||
<template>
|
||||
Developed by
|
||||
<b-link
|
||||
v-for="(developer, index) in gameDevelopers"
|
||||
:key="index"
|
||||
:to="{ name: 'company', params: { id: developer.id, slug: developer.slug }}"
|
||||
class="mr-2 mb-2 align-items-center"
|
||||
>
|
||||
<span>{{ developer.name }}</span>
|
||||
</b-link>
|
||||
</template>
|
||||
|
||||
<p class="small">
|
||||
<template>
|
||||
Developed by
|
||||
<b-link
|
||||
v-for="(developer, index) in gameDevelopers"
|
||||
:key="index"
|
||||
:to="{ name: 'company', params: { id: developer.id, slug: developer.slug }}"
|
||||
class="mr-2 mb-2 align-items-center"
|
||||
>
|
||||
<span>{{ developer.name }}</span>
|
||||
</b-link>
|
||||
</template>
|
||||
|
||||
Published by
|
||||
<b-link
|
||||
v-for="publisher in gamePublishers"
|
||||
:key="publisher.id"
|
||||
:to="{ name: 'company', params: { id: publisher.id, slug: publisher.slug }}"
|
||||
>
|
||||
{{ publisher.name }}
|
||||
</b-link>
|
||||
</p>
|
||||
<small class="text-muted mb-3 text-capitalize">Source: {{ source }}</small>
|
||||
</template>
|
||||
Published by
|
||||
<b-link
|
||||
v-for="publisher in gamePublishers"
|
||||
:key="publisher.id"
|
||||
:to="{ name: 'company', params: { id: publisher.id, slug: publisher.slug }}"
|
||||
>
|
||||
{{ publisher.name }}
|
||||
</b-link>
|
||||
</p>
|
||||
<small class="text-muted mb-3 text-capitalize">Source: {{ source }}</small>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
|
|
@ -79,6 +79,20 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
// TODO: use this extensively
|
||||
draggableProps(state, getters) {
|
||||
return {
|
||||
handle: '.game-card',
|
||||
ghostClass: 'ghost',
|
||||
dragClass: 'dragging',
|
||||
chosenClass: 'border-primary',
|
||||
filter: '.drag-filter',
|
||||
delay: '50',
|
||||
animation: '500',
|
||||
group: { name: 'games' },
|
||||
}
|
||||
},
|
||||
|
||||
// Arabic is the only ltr language supported at the moment
|
||||
isRTL: ({ settings }) => settings?.language !== 'ar',
|
||||
|
||||
|
|
|
@ -258,8 +258,11 @@ export default {
|
|||
Vue.set(state.notes, gameId, note);
|
||||
},
|
||||
|
||||
// TODO: refactor dragging in general
|
||||
// TODO: rename this to reflect that it's the dragging game id only
|
||||
// TODO: replace all instances of SET_DRAGGING_STATUS
|
||||
SET_DRAGGING_STATUS(state, status) {
|
||||
state.dragging = status;
|
||||
state.draggingGameId = status;
|
||||
},
|
||||
|
||||
REMOVE_GAME_NOTE(state, gameId) {
|
||||
|
|
|
@ -3,7 +3,7 @@ export default {
|
|||
highlightedGame: null,
|
||||
boards: [],
|
||||
games: {},
|
||||
dragging: false,
|
||||
draggingGameId: null,
|
||||
game: {},
|
||||
cachedGames: {},
|
||||
notes: {},
|
||||
|
|
Loading…
Reference in a new issue