95 lines
2.7 KiB
Vue
95 lines
2.7 KiB
Vue
<template>
|
|
<div class="flex h-screen w-screen text-white">
|
|
<div class="flex flex-1 overflow-hidden" :style="backgroundStyle">
|
|
<!-- Sidebar -->
|
|
<Sidebar
|
|
v-if="showSidebar"
|
|
:tags="tags"
|
|
:selectedTag="selectedTag"
|
|
@selectTag="store.selectTag"
|
|
@openOptions="optionsOpen = true"
|
|
/>
|
|
|
|
<!-- Main Content -->
|
|
<div class="flex flex-col flex-1 overflow-hidden">
|
|
<GamePreview
|
|
:game="selectedGame"
|
|
@qr="store.showQr"
|
|
/>
|
|
<GameCarousel
|
|
:games="store.filteredGames"
|
|
:selectedGame="selectedGame"
|
|
:selectedTag="selectedTag"
|
|
:direction="transitionDirection"
|
|
@selectGame="store.selectGame"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<OptionsModal v-if="optionsOpen" @close="optionsOpen = false"/>
|
|
<QrModal v-if="qrLink" :link="qrLink" @close="qrLink = ''"/>
|
|
<LoadingModal v-if="gameIsStarting"/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { onMounted, computed } from 'vue';
|
|
import Sidebar from './components/Sidebar.vue';
|
|
import GamePreview from './components/GamePreview.vue';
|
|
import GameCarousel from './components/GameCarousel.vue';
|
|
import OptionsModal from './components/OptionsModal.vue';
|
|
import QrModal from './components/QrModal.vue';
|
|
import LoadingModal from './components/LoadingModal.vue';
|
|
import { useKeyboardNavigation } from './utils/use-keyboard-navigation';
|
|
import { fetchGames } from './services/game-service';
|
|
import { useAppStore } from "./stores/app-store";
|
|
import { storeToRefs } from "pinia";
|
|
import { KeyboardManager } from "./utils/keyboard-manager";
|
|
|
|
const store = useAppStore();
|
|
const {
|
|
selectedTag,
|
|
selectedGame,
|
|
tags,
|
|
games,
|
|
transitionDirection,
|
|
qrLink,
|
|
gameIsStarting,
|
|
optionsOpen,
|
|
showSidebar
|
|
} = storeToRefs(store);
|
|
|
|
onMounted(async () => {
|
|
games.value = await fetchGames();
|
|
tags.value = [...new Set(games.value.flatMap(game => game.genres.split(",")))];
|
|
store.selectTag(tags.value[0])
|
|
});
|
|
|
|
// Create the gradient background style
|
|
const backgroundStyle = computed(() => {
|
|
const primary = selectedGame?.value?.color_scheme?.primary ?? "#4d97f8";
|
|
const secondary = selectedGame?.value?.color_scheme?.secondary ?? "#100a7d";
|
|
|
|
const backgroundImage = `linear-gradient(135deg, ${primary}, ${secondary})`;
|
|
// const backgroundImage = !!bgImage ? `url(${bgImage})` : `linear-gradient(135deg, ${primary}, ${secondary})`;
|
|
|
|
return {
|
|
backgroundImage
|
|
};
|
|
|
|
});
|
|
|
|
if (showSidebar) {
|
|
KeyboardManager.switchContext("sidebar")
|
|
} else {
|
|
KeyboardManager.switchContext("carousel")
|
|
}
|
|
useKeyboardNavigation();
|
|
</script>
|
|
|
|
<style scoped>
|
|
body {
|
|
overflow: hidden;
|
|
}
|
|
</style>
|