Add now playing view
This commit is contained in:
@@ -314,3 +314,90 @@ button {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.page-heading {
|
||||
margin-bottom: 22px;
|
||||
}
|
||||
|
||||
.page-heading h2 {
|
||||
margin: 0;
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
.page-heading p {
|
||||
margin: 6px 0 0;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.now-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.now-card {
|
||||
background: linear-gradient(180deg, var(--panel-2), var(--panel));
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 20px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.now-channel {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: var(--muted);
|
||||
font-weight: 800;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.now-card h3 {
|
||||
margin: 0;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.now-subtitle {
|
||||
color: #cbd5e1;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.progress-wrap {
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.progress-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: var(--muted);
|
||||
font-size: 0.85rem;
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 10px;
|
||||
background: #020617;
|
||||
border-radius: 999px;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
background: var(--accent);
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.remaining {
|
||||
color: var(--muted);
|
||||
font-size: 0.85rem;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.now-desc {
|
||||
color: #cbd5e1;
|
||||
margin: 16px 0 0;
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
.favorite-star {
|
||||
color: #facc15;
|
||||
}
|
||||
|
||||
@@ -42,9 +42,13 @@ if ($view === 'channels' && $_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
||||
[$channels, $programmes] = $xmltv->load($config);
|
||||
|
||||
$contentTemplate = $view === 'channels'
|
||||
? '/var/www/templates/channels.php'
|
||||
: '/var/www/templates/home.php';
|
||||
$currentProgrammes = $xmltv->getCurrentProgrammes($config);
|
||||
|
||||
$contentTemplate = match ($view) {
|
||||
'channels' => '/var/www/templates/channels.php',
|
||||
'now' => '/var/www/templates/now.php',
|
||||
default => '/var/www/templates/home.php',
|
||||
};
|
||||
|
||||
View::render('layout', [
|
||||
'title' => $config->get('title', 'TVGuide'),
|
||||
@@ -54,4 +58,5 @@ View::render('layout', [
|
||||
'view' => $view,
|
||||
'channelConfig' => $config->getChannels(),
|
||||
'saved' => isset($_GET['saved']),
|
||||
'currentProgrammes' => $currentProgrammes,
|
||||
]);
|
||||
|
||||
@@ -185,6 +185,56 @@ class XmlTv
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getCurrentProgrammes(?Config $config = null): array
|
||||
{
|
||||
$data = $this->getCachedData();
|
||||
$channelConfig = $config ? $config->getChannels() : [];
|
||||
$now = time();
|
||||
$items = [];
|
||||
|
||||
foreach ($data['channels'] ?? [] as $id => $channel) {
|
||||
$cfg = $channelConfig[$id] ?? [];
|
||||
|
||||
if (($cfg['enabled'] ?? true) !== true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($channel['programmes'] ?? [] as $p) {
|
||||
$start = (int)($p['start'] ?? 0);
|
||||
$stop = (int)($p['stop'] ?? 0);
|
||||
|
||||
if ($now >= $start && $now < $stop) {
|
||||
$duration = max(1, $stop - $start);
|
||||
$elapsed = max(0, $now - $start);
|
||||
$percent = min(100, round(($elapsed / $duration) * 100));
|
||||
|
||||
$items[] = [
|
||||
'channel_id' => $id,
|
||||
'channel_name' => $cfg['name'] ?? $channel['name'] ?? $id,
|
||||
'channel_number' => (int)($cfg['number'] ?? 999999),
|
||||
'favorite' => (bool)($cfg['favorite'] ?? false),
|
||||
'title' => $p['title'] ?? '',
|
||||
'subtitle' => $p['subtitle'] ?? '',
|
||||
'description' => $p['description'] ?? '',
|
||||
'category' => $p['category'] ?? '',
|
||||
'start' => $start,
|
||||
'stop' => $stop,
|
||||
'percent' => $percent,
|
||||
'remaining_minutes' => max(0, (int)ceil(($stop - $now) / 60)),
|
||||
];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
usort($items, function ($a, $b) {
|
||||
return $a['channel_number'] <=> $b['channel_number'];
|
||||
});
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
private function writeCache(array $data): void
|
||||
{
|
||||
file_put_contents(
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
<section class="page-heading">
|
||||
<h2>Jetzt läuft</h2>
|
||||
<p>Aktuelle Sendungen auf deinen aktivierten Sendern.</p>
|
||||
</section>
|
||||
|
||||
<?php if (!$currentProgrammes): ?>
|
||||
<div class="empty">Aktuell wurden keine laufenden Sendungen gefunden.</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="now-grid">
|
||||
<?php foreach ($currentProgrammes as $item): ?>
|
||||
<article class="now-card">
|
||||
<div class="now-channel">
|
||||
<span><?= htmlspecialchars($item['channel_name']) ?></span>
|
||||
<?php if ($item['favorite']): ?>
|
||||
<span class="favorite-star">⭐</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<h3><?= htmlspecialchars($item['title']) ?></h3>
|
||||
|
||||
<?php if ($item['subtitle']): ?>
|
||||
<div class="now-subtitle"><?= htmlspecialchars($item['subtitle']) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($item['category']): ?>
|
||||
<span class="category"><?= htmlspecialchars($item['category']) ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="progress-wrap">
|
||||
<div class="progress-meta">
|
||||
<span><?= date('H:i', $item['start']) ?></span>
|
||||
<span><?= date('H:i', $item['stop']) ?></span>
|
||||
</div>
|
||||
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" style="width: <?= (int)$item['percent'] ?>%"></div>
|
||||
</div>
|
||||
|
||||
<div class="remaining">
|
||||
<?= (int)$item['percent'] ?>% · noch <?= (int)$item['remaining_minutes'] ?> Minuten
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($item['description']): ?>
|
||||
<p class="now-desc"><?= htmlspecialchars($item['description']) ?></p>
|
||||
<?php endif; ?>
|
||||
</article>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
Reference in New Issue
Block a user