mirror of
https://github.com/romancm/gamebrary
synced 2024-11-23 19:53:14 +00:00
Ground Control to Major Tom
This commit is contained in:
parent
01c8e4ff99
commit
4914c08dfa
12 changed files with 326 additions and 196 deletions
|
@ -1,8 +1,9 @@
|
|||
<!-- TODO: add speedruns -->
|
||||
<!-- TODO: use v-observe-visibility -->
|
||||
<template lang="html">
|
||||
<div class="game">
|
||||
<aside>
|
||||
<b-container fluid>
|
||||
<b-row>
|
||||
<b-col cols="3">
|
||||
<div class="position-relative">
|
||||
<b-img
|
||||
:src="gameCoverUrl"
|
||||
|
@ -26,7 +27,7 @@
|
|||
|
||||
<template v-else>
|
||||
<game-images ref="gameImages" :game="game" />
|
||||
<game-videos :videos="game.videos" v-if="game.videos" />
|
||||
<!-- <game-videos :videos="game.videos" v-if="game.videos" /> -->
|
||||
</template>
|
||||
|
||||
<game-websites :game="game" class="d-none d-md-inline" />
|
||||
|
@ -40,16 +41,16 @@
|
|||
>
|
||||
loading...
|
||||
</timeline> -->
|
||||
</b-col>
|
||||
|
||||
</aside>
|
||||
|
||||
<article>
|
||||
<portal to="pageTitle">{{ game.name }}</portal>
|
||||
|
||||
<b-col cols="7">
|
||||
<h3 class="mb-2">
|
||||
{{ game.name }}
|
||||
<b-badge variant="success" v-if="steamGame && steamGame.metacritic">{{ steamGame.metacritic.score }}</b-badge>
|
||||
</h3>
|
||||
<small>
|
||||
<pre class="text-dark">{{ steamGame }}</pre>
|
||||
</small>
|
||||
<small v-if="gog && gog.isPriceVisible">{{gog.price.symbol}}{{ gog.price.amount }}</small>
|
||||
<small><pre class="text-dark">{{ gog }}</pre></small>
|
||||
<!-- <pre class="small text-dark">{{ steamGame }}</pre> -->
|
||||
|
@ -61,7 +62,18 @@
|
|||
v-b-modal.progress
|
||||
class="my-1 w-25"
|
||||
/>
|
||||
|
||||
<!-- TODO: add icons for game modes:
|
||||
single-player
|
||||
multiplayer
|
||||
co-operative
|
||||
split-screen
|
||||
massively-multiplayer-online-mmo
|
||||
battle-royale -->
|
||||
|
||||
<game-genres :game="game" />
|
||||
<game-description :game="game" :steam-game="steamGame" />
|
||||
|
||||
<game-platforms :game="game" />
|
||||
<!-- <game-news :game="game" /> -->
|
||||
<game-details :game="game" />
|
||||
|
@ -101,20 +113,22 @@
|
|||
/>
|
||||
|
||||
<br /> -->
|
||||
</article>
|
||||
</b-col>
|
||||
|
||||
<footer>
|
||||
<b-col cols="2" sm="12" md="2">
|
||||
<similar-games
|
||||
:game="game"
|
||||
:loading="loading"
|
||||
class="mb-2"
|
||||
/>
|
||||
</footer>
|
||||
</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GameNotes from '@/components/Game/GameNotes';
|
||||
import GameGenres from '@/components/Game/GameGenres';
|
||||
// import GameNews from '@/components/Game/GameNews';
|
||||
import GameDetails from '@/components/Game/GameDetails';
|
||||
import GamePlatforms from '@/components/Game/GamePlatforms';
|
||||
|
@ -123,7 +137,7 @@ import GameDescription from '@/components/Game/GameDescription';
|
|||
import SimilarGames from '@/components/Game/SimilarGames';
|
||||
import GameWebsites from '@/components/Game/GameWebsites';
|
||||
import GameImages from '@/components/Game/GameImages';
|
||||
import GameVideos from '@/components/Game/GameVideos';
|
||||
// import GameVideos from '@/components/Game/GameVideos';
|
||||
import { mapGetters, mapState } from 'vuex';
|
||||
// import { Timeline } from 'vue-tweet-embed'
|
||||
|
||||
|
@ -136,8 +150,9 @@ export default {
|
|||
GameRating,
|
||||
GameImages,
|
||||
GameNotes,
|
||||
GameGenres,
|
||||
// GameNews,
|
||||
GameVideos,
|
||||
// GameVideos,
|
||||
GameWebsites,
|
||||
SimilarGames,
|
||||
},
|
||||
|
@ -208,39 +223,39 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
.game {
|
||||
width: calc(100% - .5rem);
|
||||
display: grid;
|
||||
grid-template-columns: 360px 2fr;
|
||||
grid-gap: 1rem;
|
||||
|
||||
@media(max-width: 1280px) {
|
||||
grid-template-columns: 360px 1fr;
|
||||
}
|
||||
|
||||
@media(max-width: 1024px) {
|
||||
grid-template-columns: 320px 1fr;
|
||||
}
|
||||
|
||||
@media(max-width: 768px) {
|
||||
width: 100%;
|
||||
grid-template-columns: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.game-cover {
|
||||
max-width: 100%;
|
||||
// position: relative;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.game-info {
|
||||
position: absolute;
|
||||
bottom: 1rem;
|
||||
right: 1rem;
|
||||
}
|
||||
|
||||
footer {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
// .game {
|
||||
// width: calc(100% - .5rem);
|
||||
// display: grid;
|
||||
// grid-template-columns: 360px 2fr;
|
||||
// grid-gap: 1rem;
|
||||
//
|
||||
// @media(max-width: 1280px) {
|
||||
// grid-template-columns: 360px 1fr;
|
||||
// }
|
||||
//
|
||||
// @media(max-width: 1024px) {
|
||||
// grid-template-columns: 320px 1fr;
|
||||
// }
|
||||
//
|
||||
// @media(max-width: 768px) {
|
||||
// width: 100%;
|
||||
// grid-template-columns: 100%;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// .game-cover {
|
||||
// max-width: 100%;
|
||||
// // position: relative;
|
||||
// height: auto;
|
||||
// }
|
||||
//
|
||||
// .game-info {
|
||||
// position: absolute;
|
||||
// bottom: 1rem;
|
||||
// right: 1rem;
|
||||
// }
|
||||
//
|
||||
// footer {
|
||||
// grid-column: 1 / -1;
|
||||
// }
|
||||
</style>
|
||||
|
|
|
@ -7,29 +7,13 @@
|
|||
/>
|
||||
</div>
|
||||
|
||||
<!-- TODO: get images from article and add them to screenshots -->
|
||||
<template v-else>
|
||||
<small class="text-muted">Source: {{ source }}</small>
|
||||
|
||||
<p>
|
||||
<span
|
||||
<p
|
||||
:class="{'break-spaces': source === 'IGDB' }"
|
||||
v-html="description"
|
||||
/>
|
||||
|
||||
<b-button v-b-modal.wikipediaArticle v-if="source === 'Wikipedia'">
|
||||
<i class="fab fa-wikipedia-w" aria-hidden />
|
||||
Read more
|
||||
</b-button>
|
||||
|
||||
|
||||
<!-- <template v-if="!trimmedDescription">
|
||||
<div
|
||||
v-html="gameDescription"
|
||||
:class="{'break-spaces': source === 'IGDB' }"
|
||||
/>
|
||||
</template> -->
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<b-modal
|
||||
|
|
|
@ -25,11 +25,6 @@
|
|||
<span class="text-wrap">{{ platforms }}</span>
|
||||
</div>
|
||||
|
||||
<div v-if="genres">
|
||||
<strong>{{ $t('board.gameModal.genres') }}:</strong>
|
||||
<span class="text-wrap">{{ genres }}</span>
|
||||
</div>
|
||||
|
||||
<div v-if="gameModes">
|
||||
<strong>{{ $t('board.gameModal.gameModes') }}:</strong>
|
||||
<span class="text-wrap">{{ gameModes }}</span>
|
||||
|
@ -78,12 +73,6 @@ export default {
|
|||
computed: {
|
||||
...mapGetters(['platformNames']),
|
||||
|
||||
genres() {
|
||||
return this.game && this.game.genres
|
||||
? this.game.genres.map(({ name }) => name).join(', ')
|
||||
: null;
|
||||
},
|
||||
|
||||
platforms() {
|
||||
return this.game && this.game.platforms
|
||||
? this.game.platforms.map(({ name }) => name).join(', ')
|
||||
|
|
41
src/components/Game/GameGenres.vue
Normal file
41
src/components/Game/GameGenres.vue
Normal file
|
@ -0,0 +1,41 @@
|
|||
<template lang="html">
|
||||
<div class="genres" v-if="gameGenres">
|
||||
<b-button
|
||||
v-for="genre in gameGenres"
|
||||
:key="genre.id"
|
||||
variant="transparent"
|
||||
>
|
||||
<i v-if="genre.icon" :class="`${genre.icon} p-0`" />
|
||||
<span v-else>{{ genre.id }}</span>
|
||||
<br />
|
||||
<small>{{ genre.name }}</small>
|
||||
</b-button>
|
||||
<!-- <pre class="text-dark">{{ genres }}</pre> -->
|
||||
<!-- <pre class="text-dark">{{ game.genres }}</pre> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
import { GENRE_ICONS } from '@/constants';
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
...mapState(['game']),
|
||||
|
||||
gameGenres() {
|
||||
const gameGenres = this.game && this.game.genres
|
||||
? this.game.genres
|
||||
: null;
|
||||
|
||||
return gameGenres.map(genre => ({
|
||||
...genre,
|
||||
icon: GENRE_ICONS[genre.id] || null,
|
||||
}));
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
</style>
|
|
@ -1,18 +1,27 @@
|
|||
<template lang="html">
|
||||
<div class="games" v-if="similarGames.length">
|
||||
<!-- <pre>{{ similarGameIds }}</pre> -->
|
||||
<!-- TODO: limit to fewer games, increase game cover, add modal to view all -->
|
||||
<!-- You may also like: -->
|
||||
<div v-if="similarGames.length">
|
||||
You may also like:
|
||||
|
||||
<!-- TODO: use array map instead -->
|
||||
<b-img
|
||||
<b-card
|
||||
v-for="game in similarGames"
|
||||
v-if="game.cover"
|
||||
:key="game.id"
|
||||
no-body
|
||||
class="overflow-hidden mb-2"
|
||||
>
|
||||
<b-row no-gutters>
|
||||
<b-col md="6">
|
||||
<b-card-img
|
||||
:src="getCoverUrl(game.cover)"
|
||||
class="rounded mr-2 mb-2 cursor-pointer"
|
||||
class="rounded m-2"
|
||||
@click="openGame(game)"
|
||||
/>
|
||||
<!-- <b-card-img src="https://picsum.photos/400/400/?image=20" alt="Image" class="rounded-0"></b-card-img> -->
|
||||
</b-col>
|
||||
<b-col md="6">
|
||||
<div class="p-2">{{ game.name }}</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -84,7 +93,7 @@ export default {
|
|||
|
||||
this.similarGames = this.similarGameIds ?
|
||||
this.similarGameIds
|
||||
.filter(game => this.games && this.games[game])
|
||||
.filter(game => this.games && this.games[game] && this.games[game].cover)
|
||||
.map(game => this.games && this.games[game])
|
||||
: [];
|
||||
},
|
||||
|
@ -93,11 +102,4 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
.games {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
overflow-x: auto;
|
||||
align-items: center;
|
||||
width: 90vw;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<template lang="html">
|
||||
<b-button
|
||||
title="Dashboard"
|
||||
size="sm"
|
||||
class="home-button"
|
||||
variant="transparent"
|
||||
@click="handleLogoClick"
|
||||
>
|
||||
<!-- <img
|
||||
src="/static/gamebrary-logo-dark.png"
|
||||
width="32"
|
||||
/> -->
|
||||
<i class="fas fa-home" />
|
||||
<img
|
||||
class="py-2"
|
||||
src="/static/logo.png"
|
||||
width="24"
|
||||
/>
|
||||
<!-- TODO: move back button to here when viewing a game that's part of a board -->
|
||||
</b-button>
|
||||
</template>
|
||||
|
@ -40,7 +40,4 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
.home-button {
|
||||
width: 50px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -47,6 +47,105 @@ export const LINKS_CATEGORIES = {
|
|||
18: { id: 'discord', svg: true },
|
||||
};
|
||||
|
||||
export const GENRE_ICONS = {
|
||||
2: 'fa-solid fa-computer-mouse',
|
||||
4: 'fa-solid fa-hand-fist',
|
||||
5: 'fa-solid fa-person-rifle',
|
||||
7: 'fa-solid fa-music',
|
||||
8: 'fa-solid fa-person-running',
|
||||
9: 'fa-solid fa-puzzle-piece',
|
||||
10: 'fa-solid fa-flag-checkered',
|
||||
12: 'fa-solid fa-shield',
|
||||
13: 'fa-solid fa-cube',
|
||||
14: 'fa-solid fa-futbol',
|
||||
15: 'fa-solid fa-chess',
|
||||
16: 'fa-solid fa-arrows-turn-to-dots',
|
||||
24: 'fa-solid fa-user-ninja',
|
||||
26: 'fa-solid fa-person-circle-question',
|
||||
30: 'fa-solid fa-table-tennis-paddle-ball',
|
||||
31: 'fa-solid fa-mountain-sun',
|
||||
32: 'fa-solid fa-gamepad',
|
||||
33: 'fa-solid fa-asterisk',
|
||||
35: 'fa-solid fa-chess-board',
|
||||
34: 'fa-solid fa-comments',
|
||||
36: 'fa-solid fa-network-wired',
|
||||
};
|
||||
|
||||
// 1.4 Beat 'em up games
|
||||
// 3.4 Interactive movie
|
||||
// 3.5 Real-time 3D adventures
|
||||
// 4 Puzzle
|
||||
// 4.1 Breakout clone game
|
||||
// 4.2 Logical game
|
||||
// 4.2.1 Physics game
|
||||
// 4.2.2 Coding game
|
||||
// 4.3 Trial-and-error / exploration
|
||||
// 4.4 Hidden object game
|
||||
// 4.5 Reveal the picture game
|
||||
// 4.6 Tile-matching game
|
||||
// 4.7 Traditional puzzle game
|
||||
// 5 Role-playing
|
||||
// 5.1 Action RPG
|
||||
// 5.2 MMORPG
|
||||
// 5.3 Roguelikes
|
||||
// 5.4 Tactical RPG
|
||||
// 5.5 Sandbox RPG
|
||||
// 5.6 First-person party-based RPG
|
||||
// 5.7 JRPG
|
||||
// 5.8 Monster Tamer
|
||||
// 6 Simulation
|
||||
// 6.1 Construction and management simulation
|
||||
// 6.2 Life simulation
|
||||
// 6.3 Vehicle simulation
|
||||
// 7 Strategy
|
||||
// 7.1 4X game
|
||||
// 7.2 Artillery game
|
||||
// 7.3 Auto battler (Auto chess)
|
||||
// 7.4 Multiplayer online battle arena (MOBA)
|
||||
// 7.5 Real-time strategy (RTS)
|
||||
// 7.6 Real-time tactics (RTT)
|
||||
// 7.7 Tower defense
|
||||
// 7.8 Turn-based strategy (TBS)
|
||||
// 7.9 Turn-based tactics (TBT)
|
||||
// 7.10 Wargame
|
||||
// 7.11 Grand strategy wargame
|
||||
// 8 Sports
|
||||
// 8.1 Racing
|
||||
// 8.2 Sports game
|
||||
// 8.3 Competitive
|
||||
// 8.4 Sports-based fighting
|
||||
// 9 MMO
|
||||
// 10 Other notable genres
|
||||
// 10.1 Board game or card game
|
||||
// 10.2 Casino game
|
||||
// 10.3 Casual games
|
||||
// 10.4 Digital collectible card game
|
||||
// 10.5 Gacha game
|
||||
// 10.6 Horror game
|
||||
// 10.7 Idle game
|
||||
// 10.8 Logic game
|
||||
// 10.9 Party game
|
||||
// 10.10 Photography game
|
||||
// 10.11 Programming game
|
||||
// 10.12 Social deduction game
|
||||
// 10.13 Trivia game
|
||||
// 10.14 Typing game
|
||||
// 11 Video game genres by purpose
|
||||
// 11.1 Advergame
|
||||
// 11.2 Art game
|
||||
// 11.3 Casual game
|
||||
// 11.4 Christian game
|
||||
// 11.5 Educational game
|
||||
// 11.6 Esports
|
||||
// 11.7 Exergame
|
||||
// 11.8 Personalized game
|
||||
// 11.9 Serious game
|
||||
// 12 Sandbox / open world games
|
||||
// 12.1 Sandbox
|
||||
// 12.2 Creative
|
||||
// 12.3 Open world
|
||||
// 13
|
||||
|
||||
export const KEYBOARD_SHORTCUTS = {
|
||||
'MODAL_keyboard-shortcuts': ['shift', '?'],
|
||||
'MODAL_create-board': ['shift', 'c'],
|
||||
|
|
|
@ -52,6 +52,8 @@ export default {
|
|||
|
||||
mounted() {
|
||||
this.loadGame();
|
||||
|
||||
this.$store.dispatch('IGDB', { path: 'game_modes', data: 'fields *;' });
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<!-- TODO: Mix media from other sources (e.g. instagram, wikipedia, youtube, twitter, etc... ) -->
|
||||
<!-- TODO: get images from article and add them to media page -->
|
||||
<template lang="html">
|
||||
<b-container fluid class="p-2">
|
||||
<b-form-row>
|
||||
|
|
|
@ -68,7 +68,7 @@ export default {
|
|||
LOAD_STEAM_GAME(context, steamGameId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// axios.get(`${API_BASE}/steam-game?gameId=${steamGameId}`)
|
||||
axios.get(`http://localhost:5001/gamebrary-8c736/us-central1/steam-game?gameId=${steamGameId}`)
|
||||
axios.get(`${API_BASE}/steam-game?gameId=${steamGameId}`)
|
||||
.then(({ data }) => {
|
||||
const steamGameData = data[steamGameId];
|
||||
|
||||
|
@ -478,7 +478,7 @@ export default {
|
|||
|
||||
LOAD_GOG_GAME(context, search) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios.get(`http://localhost:5001/gamebrary-8c736/us-central1/gog?search=${search}`)
|
||||
axios.get(`${API_BASE}/gog?search=${search}`)
|
||||
.then(({ data }) => {
|
||||
const game = data.totalGamesFound
|
||||
? data.products[0]
|
||||
|
|
|
@ -223,7 +223,7 @@ $container-max-widths: (
|
|||
// Set the number of columns and specify the width of the gutters.
|
||||
|
||||
$grid-columns: 12 !default;
|
||||
$grid-gutter-width: 30px !default;
|
||||
$grid-gutter-width: 8px !default;
|
||||
$grid-row-columns: 6 !default;
|
||||
|
||||
|
||||
|
|
BIN
static/logo.png
Normal file
BIN
static/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 78 KiB |
Loading…
Reference in a new issue