This commit is contained in:
Gamebrary 2021-09-10 16:04:00 -07:00
parent 94b9b855d2
commit 145d7c3a13
18 changed files with 306 additions and 79 deletions

View file

@ -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>

View file

@ -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: {

View file

@ -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>

View 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>

View 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>

View 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>

View file

@ -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

View file

@ -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');
},

View file

@ -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%;

View file

@ -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>

View file

@ -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') }}

View 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>

View file

@ -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

View file

@ -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' },
];

View file

@ -1,7 +1,7 @@
<template lang="html">
<b-container>
<b-alert
v-if="!showExpiredAlert"
v-if="showExpiredAlert"
show
variant="danger"
dismissible

View file

@ -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;

View file

@ -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>

View file

@ -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,