update
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
<script setup>
|
||||
import { computed, onMounted, ref, watch } from 'vue'
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
import MovieCard from './components/MovieCard.vue'
|
||||
import FilterSidebar from './components/FilterSidebar.vue'
|
||||
import MovieDetail from './components/MovieDetail.vue'
|
||||
import SearchTab from './components/SearchTab.vue'
|
||||
import StreamTab from './components/StreamTab.vue'
|
||||
import WatchedTab from './components/WatchedTab.vue'
|
||||
import WheelTab from './components/WheelTab.vue'
|
||||
import SeriesCard from './components/SeriesCard.vue'
|
||||
|
||||
@@ -14,7 +16,13 @@ const error = ref('')
|
||||
const search = ref('')
|
||||
const sort = ref('rating')
|
||||
const selected = ref(null)
|
||||
const activeTab = ref('netflix')
|
||||
// Nach dem Neuladen soll derselbe Reiter offen sein
|
||||
const TAB_SCHLUESSEL = 'filmabend_tab'
|
||||
const TAB_IDS = ['netflix', 'canon', 'search', 'wheel', 'watched', 'stream']
|
||||
const gemerkterTab = localStorage.getItem(TAB_SCHLUESSEL)
|
||||
const activeTab = ref(TAB_IDS.includes(gemerkterTab) ? gemerkterTab : 'netflix')
|
||||
|
||||
watch(activeTab, (id) => localStorage.setItem(TAB_SCHLUESSEL, id))
|
||||
const include = ref([])
|
||||
const exclude = ref([])
|
||||
|
||||
@@ -187,13 +195,48 @@ const netflixEntries = computed(() => {
|
||||
|
||||
const tabs = computed(() => [
|
||||
{ id: 'netflix', label: 'Netflix', count: netflixMovies.value.length },
|
||||
{ id: 'canon', label: 'Kanon', count: canonGroups.value.length },
|
||||
{ id: 'canon', label: 'Horror-Kanon', count: canonGroups.value.length },
|
||||
{ id: 'search', label: 'Suche', count: null },
|
||||
{ id: 'wheel', label: 'Rad', count: null },
|
||||
{ id: 'watched', label: 'Gesehen', count: gesehenZahl.value },
|
||||
{ id: 'stream', label: 'Stream', count: null },
|
||||
])
|
||||
|
||||
const rad = ref(null)
|
||||
|
||||
// Die movie_ids der geschauten Filme — die Detailansicht zeigt damit an,
|
||||
// ob der Film schon lief
|
||||
const gesehen = ref([])
|
||||
|
||||
async function ladeGesehen() {
|
||||
try {
|
||||
const resp = await fetch('/api/watched')
|
||||
if (resp.ok) gesehen.value = await resp.json()
|
||||
} catch {
|
||||
/* dann eben ohne */
|
||||
}
|
||||
}
|
||||
|
||||
// Ausgeblendete Filme zählen für Gäste nicht mit
|
||||
const gesehenZahl = computed(
|
||||
() => gesehen.value.filter((e) => host.value || !e.hidden).length
|
||||
)
|
||||
|
||||
// Wer den Abend leitet, darf drehen und die Runde leeren. Kein Login —
|
||||
// die Tastenkombination reicht, die Seite steht ohnehin nur Freunden offen.
|
||||
const HOST_SCHLUESSEL = 'filmabend_host'
|
||||
const host = ref(localStorage.getItem(HOST_SCHLUESSEL) === '1')
|
||||
|
||||
function tastatur(e) {
|
||||
// e.code statt e.key: mit drei Zusatztasten liefert das Layout sonst
|
||||
// je nach System ein anderes Zeichen
|
||||
if (e.ctrlKey && e.shiftKey && e.altKey && e.code === 'KeyS') {
|
||||
e.preventDefault()
|
||||
host.value = !host.value
|
||||
localStorage.setItem(HOST_SCHLUESSEL, host.value ? '1' : '0')
|
||||
}
|
||||
}
|
||||
|
||||
// Wer schon vorgeschlagen hat, soll das in der Detailansicht sehen
|
||||
const meinVorschlag = ref(null)
|
||||
|
||||
@@ -326,11 +369,15 @@ async function load() {
|
||||
onMounted(() => {
|
||||
load()
|
||||
ladeVorschlag()
|
||||
ladeGesehen()
|
||||
window.addEventListener('keydown', tastatur)
|
||||
})
|
||||
|
||||
onUnmounted(() => window.removeEventListener('keydown', tastatur))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="page" :class="{ breit: activeTab === 'search' || activeTab === 'wheel' }">
|
||||
<div class="page" :class="{ breit: ['search', 'wheel', 'stream', 'watched'].includes(activeTab) }">
|
||||
<nav class="tabs">
|
||||
<button
|
||||
v-for="tab in tabs"
|
||||
@@ -342,11 +389,27 @@ onMounted(() => {
|
||||
{{ tab.label }}
|
||||
<span v-if="tab.count !== null" class="count">{{ tab.count }}</span>
|
||||
</button>
|
||||
<span v-if="host" class="host">Host</span>
|
||||
</nav>
|
||||
|
||||
<SearchTab v-if="activeTab === 'search'" @open="selected = $event" />
|
||||
|
||||
<WheelTab v-else-if="activeTab === 'wheel'" ref="rad" @open="selected = $event" />
|
||||
<WheelTab
|
||||
v-else-if="activeTab === 'wheel'"
|
||||
ref="rad"
|
||||
:host="host"
|
||||
@open="selected = $event"
|
||||
@reset="meinVorschlag = null"
|
||||
/>
|
||||
|
||||
<WatchedTab
|
||||
v-else-if="activeTab === 'watched'"
|
||||
:host="host"
|
||||
@open="selected = $event"
|
||||
@changed="ladeGesehen"
|
||||
/>
|
||||
|
||||
<StreamTab v-else-if="activeTab === 'stream'" />
|
||||
|
||||
<div v-else class="layout">
|
||||
<div class="results">
|
||||
@@ -402,7 +465,10 @@ onMounted(() => {
|
||||
@close="selected = null"
|
||||
@open="selected = $event"
|
||||
:mein-vorschlag="meinVorschlag"
|
||||
:host="host"
|
||||
:gesehen="gesehen.some((e) => e.movie_id === selected.id)"
|
||||
@suggested="nachVorschlag"
|
||||
@watched="ladeGesehen"
|
||||
/>
|
||||
|
||||
</div>
|
||||
@@ -446,6 +512,19 @@ onMounted(() => {
|
||||
border-bottom-color: var(--accent);
|
||||
}
|
||||
|
||||
.host {
|
||||
align-self: center;
|
||||
margin-left: auto;
|
||||
padding: 0.15rem 0.5rem;
|
||||
color: var(--accent);
|
||||
font-size: 0.7rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
border: 1px solid var(--accent);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.tabs .count {
|
||||
padding: 0.1rem 0.45rem;
|
||||
font-size: 0.75rem;
|
||||
|
||||
Reference in New Issue
Block a user