From 558bd4ff6f1f2ab6b576352d0a89e517b3e27f36 Mon Sep 17 00:00:00 2001 From: Gogs Date: Thu, 9 Jul 2026 15:26:41 +0200 Subject: [PATCH] Dashboard Live --- app/public/api/live-now.php | 8 +++ app/public/assets/js/live-now.js | 103 +++++++++++++++++++++++++++++++ app/templates/home.php | 4 +- 3 files changed, 113 insertions(+), 2 deletions(-) diff --git a/app/public/api/live-now.php b/app/public/api/live-now.php index ea5d99b..aac8c8e 100644 --- a/app/public/api/live-now.php +++ b/app/public/api/live-now.php @@ -25,6 +25,14 @@ $items = $service->getCurrentProgrammes($data, $config); $now = new DateTimeImmutable('now', new DateTimeZone($timezone)); +require_once '/var/www/src/Services/LogoService.php'; + +foreach ($items as &$item) { + $item['logo_url'] = LogoService::getLogoUrl($item['channel_id']); +} + +unset($item); + ApiResponse::json([ 'ok' => true, 'timestamp' => $now->getTimestamp(), diff --git a/app/public/assets/js/live-now.js b/app/public/assets/js/live-now.js index e2aad63..1c962e8 100644 --- a/app/public/assets/js/live-now.js +++ b/app/public/assets/js/live-now.js @@ -160,3 +160,106 @@ document.addEventListener('DOMContentLoaded', () => { liveNow.start(); }); + +function dashboardCreateCard(item) { + const button = document.createElement('button'); + button.className = 'dashboard-programme-card dashboard-programme'; + button.type = 'button'; + button.dataset.programmeId = `${item.channel_id}-${item.start}-${item.title}`; + button.dataset.dashboardKey = item.channel_id; + + button.innerHTML = ` + + + +
+
+
+ `; + + dashboardUpdateCard(button, item); + return button; +} + +function dashboardUpdateCard(card, item) { + card.querySelector('img').src = item.logo_url || '/assets/logos/default.svg'; + card.querySelector('strong').textContent = item.title || ''; + card.querySelector('span').textContent = + `${item.channel_name || ''} · noch ${TVGuideLive.calcRemainingMinutes(item.stop)} Min.`; + + const bar = card.querySelector('.dashboard-progress div'); + if (bar) { + bar.style.width = `${TVGuideLive.calcPercent(item.start, item.stop)}%`; + } + + card.dataset.programmeId = `${item.channel_id}-${item.start}-${item.title}`; +} + +function dashboardRender(grid, items) { + if (!grid) return; + + // Beim ersten Live-Refresh vorhandene serverseitige Karten entfernen + if (!grid.dataset.dashboardInitialized) { + grid.innerHTML = ''; + grid.dataset.dashboardInitialized = '1'; + } + + const seen = new Set(); + + items.slice(0, 6).forEach(item => { + const key = item.channel_id; + seen.add(key); + + let card = grid.querySelector(`[data-dashboard-key="${CSS.escape(key)}"]`); + + if (!card) { + card = dashboardCreateCard(item); + grid.appendChild(card); + } else { + dashboardUpdateCard(card, item); + } + }); + + grid.querySelectorAll('[data-dashboard-key]').forEach(card => { + if (!seen.has(card.dataset.dashboardKey)) { + card.remove(); + } + }); + + if (items.length === 0) { + grid.innerHTML = '
Aktuell keine Sendungen.
'; + } +} + +async function dashboardRefreshNow() { + const nowGrid = document.querySelector('[data-dashboard-now]'); + const favGrid = document.querySelector('[data-dashboard-favorites]'); + + if (!nowGrid && !favGrid) return; + + try { + const data = await TVGuideLive.fetchJson('/api/live-now.php'); + const items = data.items || []; + + dashboardRender(nowGrid, items); + + dashboardRender( + favGrid, + items.filter(item => item.favorite) + ); + } catch (error) { + console.error('Dashboard konnte nicht aktualisiert werden:', error); + } +} + +function dashboardTick() { + document.querySelectorAll('[data-dashboard-key]').forEach(card => { + const key = card.dataset.dashboardKey; + // vollständiger Refresh kommt alle 30 Sekunden; hier nur Balken/Restzeit über vorhandene DOM-Daten nicht möglich + }); +} + +document.addEventListener('DOMContentLoaded', () => { + dashboardRefreshNow(); + setInterval(dashboardRefreshNow, 30000); +}); diff --git a/app/templates/home.php b/app/templates/home.php index 5398a0e..f06b4ad 100644 --- a/app/templates/home.php +++ b/app/templates/home.php @@ -110,7 +110,7 @@ $favoritesNow = array_values(array_filter($currentProgrammes, fn($item) => !empt

🔥 Jetzt läuft

-
+