mirror of
https://github.com/romancm/gamebrary
synced 2024-11-23 19:53:14 +00:00
wip
This commit is contained in:
parent
94b9b855d2
commit
145d7c3a13
18 changed files with 306 additions and 79 deletions
34
src/App.vue
34
src/App.vue
|
@ -2,18 +2,18 @@
|
|||
<div
|
||||
id="app"
|
||||
:dir="dir"
|
||||
:class="`dock-${dockPosition}`"
|
||||
v-shortkey="KEYBOARD_SHORTCUTS"
|
||||
@shortkey="handleShortcutAction"
|
||||
>
|
||||
<dock />
|
||||
|
||||
<global-modals />
|
||||
|
||||
<main :class="{
|
||||
'authorizing': !user,
|
||||
'is-board': isBoard,
|
||||
}"
|
||||
>
|
||||
<global-modals />
|
||||
<router-view />
|
||||
</main>
|
||||
</div>
|
||||
|
@ -59,6 +59,10 @@ export default {
|
|||
return settings && settings.language === 'ar' ? 'rtl' : 'ltr';
|
||||
},
|
||||
|
||||
dockPosition() {
|
||||
return this.settings && this.settings.dockPosition;
|
||||
},
|
||||
|
||||
isPublicRoute() {
|
||||
return this.$route.meta && this.$route.meta.public;
|
||||
},
|
||||
|
@ -116,16 +120,36 @@ export default {
|
|||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
main {
|
||||
overflow-y: auto;
|
||||
height: calc(100vh - 54px);
|
||||
height: calc(100vh - 46px);
|
||||
|
||||
&.authorizing {
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-board {
|
||||
height: 100vh;
|
||||
.dock-left,
|
||||
.dock-right {
|
||||
height: 100vh;
|
||||
display: grid;
|
||||
grid-template-columns: 54px auto;
|
||||
}
|
||||
|
||||
.dock-right {
|
||||
grid-template-columns: auto 54px;
|
||||
|
||||
main {
|
||||
grid-row: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.dock-bottom {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
|
||||
main {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,13 +1,22 @@
|
|||
<template lang="html">
|
||||
<portal to="logo" v-if="boards.length">
|
||||
<b-dropdown
|
||||
class="ml-2"
|
||||
:class="{ 'ml-2': isHorizontal }"
|
||||
toggle-class="px-0"
|
||||
variant="transparent"
|
||||
>
|
||||
<template v-slot:button-content>
|
||||
{{ board.name }}
|
||||
<i class="fas fa-caret-down fa-fw" aria-hidden />
|
||||
<template v-if="isHorizontal">
|
||||
{{ board.name }}
|
||||
<i class="fas fa-caret-down fa-fw" aria-hidden />
|
||||
</template>
|
||||
|
||||
<b-avatar
|
||||
v-else
|
||||
variant="primary"
|
||||
:text="boardInitials"
|
||||
rounded
|
||||
/>
|
||||
</template>
|
||||
|
||||
<b-dropdown-item-button
|
||||
|
@ -62,7 +71,7 @@ import { mapState } from 'vuex';
|
|||
|
||||
export default {
|
||||
computed: {
|
||||
...mapState(['board', 'wallpapers', 'boards']),
|
||||
...mapState(['board', 'wallpapers', 'boards', 'settings']),
|
||||
|
||||
filteredBoards() {
|
||||
return this.boards
|
||||
|
@ -76,6 +85,18 @@ export default {
|
|||
};
|
||||
});
|
||||
},
|
||||
|
||||
dockPosition() {
|
||||
return this.settings && this.settings.dockPosition;
|
||||
},
|
||||
|
||||
boardInitials() {
|
||||
return this.board.name.split(' ').map(n => n[0]).join('').slice(0, 2);
|
||||
},
|
||||
|
||||
isHorizontal() {
|
||||
return !this.dockPosition || this.dockPosition === 'bottom';
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
|
|
@ -1,54 +1,45 @@
|
|||
<template lang="html">
|
||||
<nav
|
||||
:class="[{ 'position-fixed': isBoard }, 'd-flex align-items-center justify-content-between w-100 py-2 px-3 z-index-1']"
|
||||
>
|
||||
<div class="d-flex">
|
||||
<router-link :to="{ name: 'home' }">
|
||||
<img
|
||||
src="/static/gamebrary-logo.png"
|
||||
width="32"
|
||||
/>
|
||||
</router-link>
|
||||
<component
|
||||
v-if="user"
|
||||
:is="userDockComponent"
|
||||
/>
|
||||
|
||||
<!-- Gamebrary -->
|
||||
|
||||
<portal-target name="logo" />
|
||||
|
||||
<span v-if="!isBoard" class="m-2">
|
||||
<portal-target name="pageTitle" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="d-flex">
|
||||
|
||||
<!-- <global-search class="ml-2" /> -->
|
||||
<portal-target name="dock" multiple />
|
||||
|
||||
<user-menu v-if="user" />
|
||||
<public-menu v-else />
|
||||
</div>
|
||||
</nav>
|
||||
<public-dock v-else />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
import PinnedBoards from '@/components/Board/PinnedBoards';
|
||||
import UserMenu from '@/components/UserMenu';
|
||||
import PublicDock from '@/components/Dock/PublicDock';
|
||||
import HorizontalDock from '@/components/Dock/HorizontalDock';
|
||||
import VerticalDock from '@/components/Dock/VerticalDock';
|
||||
import PublicMenu from '@/components/PublicMenu';
|
||||
import GlobalSearch from '@/components/GlobalSearch';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
PinnedBoards,
|
||||
UserMenu,
|
||||
PublicDock,
|
||||
HorizontalDock,
|
||||
VerticalDock,
|
||||
PublicMenu,
|
||||
GlobalSearch,
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['board', 'user', 'publicBoards']),
|
||||
...mapState(['board', 'user', 'publicBoards', 'settings']),
|
||||
...mapGetters(['isBoardOwner']),
|
||||
|
||||
dockPosition() {
|
||||
return this.settings && this.settings.dockPosition;
|
||||
},
|
||||
|
||||
userDockComponent() {
|
||||
const isVertical = ['left', 'right'].includes(this.dockPosition);
|
||||
|
||||
return isVertical ? 'VerticalDock' : 'HorizontalDock';
|
||||
},
|
||||
|
||||
isBoard() {
|
||||
return ['public-board', 'board'].includes(this.$route.name);
|
||||
},
|
||||
|
@ -91,3 +82,19 @@ export default {
|
|||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
.dock {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
padding: .25rem 1rem;
|
||||
align-items: center;
|
||||
background: #ccf;
|
||||
|
||||
&.left {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
35
src/components/Dock/HorizontalDock.vue
Normal file
35
src/components/Dock/HorizontalDock.vue
Normal file
|
@ -0,0 +1,35 @@
|
|||
<template lang="html">
|
||||
<nav class="d-flex align-items-center justify-content-between p-2">
|
||||
<div class="d-flex">
|
||||
<router-link :to="{ name: 'home' }">
|
||||
<img
|
||||
src="/static/gamebrary-logo.png"
|
||||
width="32"
|
||||
/>
|
||||
</router-link>
|
||||
|
||||
<portal-target name="logo" />
|
||||
</div>
|
||||
|
||||
<div class="d-flex">
|
||||
<global-search class="ml-2" />
|
||||
<portal-target name="dock" multiple />
|
||||
<user-menu />
|
||||
</div>
|
||||
|
||||
|
||||
<!-- <span v-if="!isBoard" class="m-2">
|
||||
<portal-target name="pageTitle" />
|
||||
</span> -->
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UserMenu from '@/components/UserMenu';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
UserMenu,
|
||||
},
|
||||
};
|
||||
</script>
|
40
src/components/Dock/PublicDock.vue
Normal file
40
src/components/Dock/PublicDock.vue
Normal file
|
@ -0,0 +1,40 @@
|
|||
<template lang="html">
|
||||
<nav>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
<img
|
||||
src="/static/gamebrary-logo.png"
|
||||
width="32"
|
||||
/>
|
||||
</router-link>
|
||||
|
||||
<public-menu />
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
import PublicMenu from '@/components/PublicMenu';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
PublicMenu,
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['settings']),
|
||||
|
||||
dockPosition() {
|
||||
return this.settings && this.settings.dockPosition;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
nav {
|
||||
padding: .25rem 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
39
src/components/Dock/VerticalDock.vue
Normal file
39
src/components/Dock/VerticalDock.vue
Normal file
|
@ -0,0 +1,39 @@
|
|||
<template lang="html">
|
||||
<nav class="bg-danger py-2">
|
||||
<router-link :to="{ name: 'home' }">
|
||||
<img
|
||||
src="/static/gamebrary-logo.png"
|
||||
width="32"
|
||||
/>
|
||||
</router-link>
|
||||
|
||||
<aside>
|
||||
<portal-target name="logo" />
|
||||
<!-- <global-search class="ml-2" /> -->
|
||||
<portal-target name="dock" multiple />
|
||||
<user-menu vertical />
|
||||
<span v-if="!isBoard" class="m-2">
|
||||
<portal-target name="pageTitle" />
|
||||
</span>
|
||||
</aside>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UserMenu from '@/components/UserMenu';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
UserMenu,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
|
@ -1,5 +1,5 @@
|
|||
<template lang="html">
|
||||
<b-container v-if="game.name">
|
||||
<b-container v-if="game.name" fluid>
|
||||
<b-row>
|
||||
<b-col cols="12" md="4" lg="4">
|
||||
<b-img
|
||||
|
|
|
@ -70,6 +70,7 @@ export default {
|
|||
|
||||
methods: {
|
||||
openGame(gameId) {
|
||||
// TODO: handle game detail view setting
|
||||
this.$store.commit('SET_GAME_MODAL_DATA', { gameId });
|
||||
this.$bvModal.show('game-modal');
|
||||
},
|
||||
|
|
|
@ -213,7 +213,13 @@ export default {
|
|||
this.$store.commit('SET_GAME_MODAL_DATA', { gameId, list });
|
||||
|
||||
if (gameDetailView === 'new') {
|
||||
this.$router.push({ name: 'game', params: { gameId } });
|
||||
this.$router.push({
|
||||
name: 'game',
|
||||
params: {
|
||||
gameId,
|
||||
gameSlug: 'molesta-la-bresta',
|
||||
},
|
||||
});
|
||||
} else if (gameDetailView === 'side') {
|
||||
// TODO: find a way to open sidebar programatically, open defect in gh?
|
||||
} else {
|
||||
|
@ -274,9 +280,7 @@ export default {
|
|||
.games {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
max-height: calc(100vh - 116px);
|
||||
// TODO: detect mobile and use variable height
|
||||
// max-height: calc(100vh - 200px);
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
padding: 0 .5rem;
|
||||
width: 100%;
|
||||
|
|
|
@ -1,20 +1,14 @@
|
|||
<template lang="html">
|
||||
<header>
|
||||
<portal to="pageTitle">{{ title }}</portal>
|
||||
<header class="my-4 d-flex align-items-center justify-content-between">
|
||||
<h3>{{ title }}</h3>
|
||||
|
||||
<portal to="dock">
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<slot />
|
||||
|
||||
<b-button
|
||||
v-if="actionText"
|
||||
variant="primary"
|
||||
@click="$emit('action')"
|
||||
>
|
||||
{{ actionText }}
|
||||
</b-button>
|
||||
</div>
|
||||
</portal>
|
||||
<b-button
|
||||
v-if="actionText"
|
||||
variant="primary"
|
||||
@click="$emit('action')"
|
||||
>
|
||||
{{ actionText }}
|
||||
</b-button>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<template lang="html">
|
||||
<footer class="text-white container ml-auto mr-auto">
|
||||
<h3>© {{ year }} Gamebrary</h3>
|
||||
|
||||
<footer class="text-muted text-center container ml-auto mr-auto">
|
||||
<div class="pt-4 pb-24 flex items-center justify-center">
|
||||
<ul>
|
||||
<a class="px-1" href="/about">About</a>
|
||||
|
@ -14,7 +12,9 @@
|
|||
</ul>
|
||||
</div>
|
||||
|
||||
<small>
|
||||
<small class="text-muted">
|
||||
<small>©{{ year }} Gamebrary</small>
|
||||
|
||||
{{ $t('global.donateMessage') }}
|
||||
<a href="https://www.paypal.me/RomanCervantes/5" target="_blank">
|
||||
{{ $t('global.donating') }}
|
||||
|
|
60
src/components/Settings/DockSettings.vue
Normal file
60
src/components/Settings/DockSettings.vue
Normal file
|
@ -0,0 +1,60 @@
|
|||
<template lang="html">
|
||||
<div>
|
||||
<b-form-group label="Dock position:">
|
||||
<b-form-select
|
||||
v-model="dockPosition"
|
||||
style="max-width: 200px"
|
||||
@change="save"
|
||||
>
|
||||
<b-form-select-option
|
||||
v-for="{ name, value } in $options.DOCK_POSITIONS"
|
||||
:key="value"
|
||||
:value="value"
|
||||
>
|
||||
{{ name }}
|
||||
</b-form-select-option>
|
||||
</b-form-select>
|
||||
</b-form-group>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
import { DOCK_POSITIONS } from '@/constants';
|
||||
|
||||
export default {
|
||||
DOCK_POSITIONS,
|
||||
|
||||
data() {
|
||||
return {
|
||||
dockPosition: null,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['settings']),
|
||||
},
|
||||
|
||||
mounted() {
|
||||
const { settings } = this;
|
||||
|
||||
this.dockPosition = settings.dockPosition || null;
|
||||
},
|
||||
|
||||
methods: {
|
||||
async save() {
|
||||
const { dockPosition, settings } = this;
|
||||
|
||||
const payload = {
|
||||
...settings,
|
||||
dockPosition,
|
||||
};
|
||||
|
||||
await this.$store.dispatch('SAVE_SETTINGS', payload)
|
||||
.catch(() => {
|
||||
this.$bvToast.toast('There was an error saving your settings', { variant: 'danger' });
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -1,5 +1,5 @@
|
|||
<template lang="html">
|
||||
<b-dropdown right toggle-class="p-0 ml-2">
|
||||
<b-dropdown right toggle-class="p-0">
|
||||
<template #button-content>
|
||||
<b-avatar
|
||||
rounded
|
||||
|
|
|
@ -226,3 +226,10 @@ export const GAME_DETAIL_RATING = [
|
|||
{ name: 'ESRB', value: 'esrb' },
|
||||
{ name: 'PEGI', value: 'pegi' },
|
||||
];
|
||||
|
||||
export const DOCK_POSITIONS = [
|
||||
{ name: 'Top', value: null },
|
||||
{ name: 'Left', value: 'left' },
|
||||
{ name: 'Bottom', value: 'bottom' },
|
||||
{ name: 'Right', value: 'right' },
|
||||
];
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template lang="html">
|
||||
<b-container>
|
||||
<b-alert
|
||||
v-if="!showExpiredAlert"
|
||||
v-if="showExpiredAlert"
|
||||
show
|
||||
variant="danger"
|
||||
dismissible
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<template lang="html">
|
||||
<div
|
||||
:class="[
|
||||
'board px-3',
|
||||
'board p-3',
|
||||
{ dragging, empty },
|
||||
]"
|
||||
:style="boardStyles"
|
||||
|
@ -11,14 +11,14 @@
|
|||
<boards-dropdown />
|
||||
|
||||
<portal to="dock">
|
||||
<b-button
|
||||
<!-- <b-button
|
||||
v-if="user && user.uid && user.uid === board.owner"
|
||||
variant="secondary"
|
||||
v-b-modal:edit-board
|
||||
>
|
||||
<i class="fas fa-pencil-alt fa-fw" aria-hidden />
|
||||
Edit board
|
||||
</b-button>
|
||||
</b-button> -->
|
||||
<!-- TODO: add board filtering -->
|
||||
<!-- <b-button
|
||||
variant="warning"
|
||||
|
@ -43,7 +43,7 @@
|
|||
|
||||
<div
|
||||
v-else-if="user && user.uid && user.uid === board.owner"
|
||||
class="d-flex flex-column pr-2"
|
||||
class="d-flex flex-column"
|
||||
>
|
||||
<b-button
|
||||
variant="secondary"
|
||||
|
@ -257,8 +257,7 @@ export default {
|
|||
display: flex;
|
||||
background-size: cover;
|
||||
align-items: flex-start;
|
||||
height: 100vh;
|
||||
padding-top: 54px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow-x: auto;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<template lang="html">
|
||||
<b-container fluid>
|
||||
Dashboard
|
||||
<page-title
|
||||
title="Boards"
|
||||
action-text="Create board"
|
||||
|
@ -8,11 +7,6 @@
|
|||
/>
|
||||
|
||||
<boards />
|
||||
|
||||
<h5>public boards</h5>
|
||||
<h5>news feeds</h5>
|
||||
<h5>deals</h5>
|
||||
<h5>newsletter signup</h5>
|
||||
</b-container>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<div class="d-inline-flex flex-column align-items-start">
|
||||
<language-selector />
|
||||
<game-detail-settings />
|
||||
<!-- <game-detail-view-selector /> -->
|
||||
<dock-settings />
|
||||
|
||||
<!-- <provider-card /> -->
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
|||
<script>
|
||||
import LanguageSelector from '@/components/Settings/LanguageSelector';
|
||||
import GameDetailSettings from '@/components/Settings/GameDetailSettings';
|
||||
import DockSettings from '@/components/Settings/DockSettings';
|
||||
// import GameDetailViewSelector from '@/components/Settings/GameDetailViewSelector';
|
||||
// import ProviderCard from '@/components/ProviderCard';
|
||||
import DeleteAccountModal from '@/components/Settings/DeleteAccountModal';
|
||||
|
@ -42,6 +43,7 @@ export default {
|
|||
components: {
|
||||
LanguageSelector,
|
||||
GameDetailSettings,
|
||||
DockSettings,
|
||||
// GameDetailViewSelector,
|
||||
// ProviderCard,
|
||||
DeleteAccountModal,
|
||||
|
|
Loading…
Reference in a new issue