Dashboard Live

This commit is contained in:
Gogs
2026-07-09 15:26:41 +02:00
parent 574b344d1e
commit 558bd4ff6f
3 changed files with 113 additions and 2 deletions
+8
View File
@@ -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(),
+103
View File
@@ -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 = `
<img src="${item.logo_url || '/assets/logos/default.svg'}" alt="">
<strong></strong>
<span></span>
<div class="dashboard-progress">
<div></div>
</div>
`;
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 = '<div class="empty compact">Aktuell keine Sendungen.</div>';
}
}
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);
});
+2 -2
View File
@@ -110,7 +110,7 @@ $favoritesNow = array_values(array_filter($currentProgrammes, fn($item) => !empt
<section class="dashboard-panel">
<h3>🔥 Jetzt läuft</h3>
<div class="dashboard-card-grid">
<div class="dashboard-card-grid" data-dashboard-now>
<?php foreach (array_slice($currentProgrammes, 0, 6) as $item): ?>
<?php $id = dashboardProgrammeId($item['channel_id'], $item['start'], $item['title'] ?? ''); ?>
<button class="dashboard-programme-card dashboard-programme" type="button" data-programme-id="<?= htmlspecialchars($id) ?>">
@@ -128,7 +128,7 @@ $favoritesNow = array_values(array_filter($currentProgrammes, fn($item) => !empt
<section class="dashboard-panel">
<h3>⏰ Beginnt gleich</h3>
<div class="dashboard-card-grid">
<div class="dashboard-card-grid" data-dashboard-favorites>
<?php foreach (array_slice($upcoming, 0, 6) as $item): ?>
<button class="dashboard-programme-card dashboard-programme" type="button" data-programme-id="<?= htmlspecialchars($item['id']) ?>">
<img src="<?= htmlspecialchars(LogoService::getLogoUrl($item['channel_id'])) ?>" alt="">