Release 0.5.9

This commit is contained in:
hnzio committed 2026-10-23 13:16:32 +02:00
1 parent 2851c7d936
commit c3033479b5
32 files changed
+1598 -50

No files matched your search

+75 -1
View File
@@ -13,6 +13,7 @@
let now = $state(Date.now());
let loadedAt = $state(Date.now());
let currentId = $state(untrack(() => data.live.current?.id ?? null));
let loadedRevision = $state(untrack(() => data.live.liveRevision));
let outputWindow: Window | null = null;
let progress = $derived(
data.live.totalCount ? Math.round((data.live.completedCount / data.live.totalCount) * 100) : 0
@@ -21,11 +22,21 @@
(data.live.current?.actualDurationSeconds ?? 0) +
(data.live.current ? Math.max(0, Math.floor((now - loadedAt) / 1000)) : 0)
);
let sectionElapsedSeconds = $derived(
(data.live.sectionTimer?.elapsedSeconds ?? 0) +
(data.live.sectionTimer?.runningSinceUtc
? Math.max(0, Math.floor((now - loadedAt) / 1000))
: 0)
);
let sectionRemainingSeconds = $derived(
(data.live.sectionTimer?.plannedDurationSeconds ?? 0) - sectionElapsedSeconds
);
$effect(() => {
const nextCurrentId = data.live.current?.id ?? null;
if (nextCurrentId !== currentId) {
if (nextCurrentId !== currentId || data.live.liveRevision !== loadedRevision) {
currentId = nextCurrentId;
loadedRevision = data.live.liveRevision;
loadedAt = Date.now();
}
});
@@ -73,6 +84,15 @@
persistSettings();
}
function formatCountdown(totalSeconds: number) {
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = Math.floor(totalSeconds % 60);
return hours > 0
? `${hours}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
: `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
}
function liveAction(name: string) {
return `?show=${encodeURIComponent(data.live.show.id)}&/${name}`;
}
@@ -187,6 +207,21 @@
style={`--prompt-size: ${promptSize}rem`}
aria-labelledby="current-title"
>
{#if data.live.sectionTimer?.sectionId === data.live.current.sectionId}
<section
class:warning={sectionRemainingSeconds <= 120 && sectionRemainingSeconds >= 0}
class:overrun={sectionRemainingSeconds < 0}
class="section-countdown"
aria-live="off"
>
<span>{data.live.sectionTimer.sectionName} · Abschnitt</span>
<strong
>{sectionRemainingSeconds < 0
? `Überzogen +${formatCountdown(Math.abs(sectionRemainingSeconds))}`
: `Noch ${formatCountdown(sectionRemainingSeconds)}`}</strong
>
</section>
{/if}
<div class="live-kicker">
<span>Aktuell · {data.live.current.sectionName}</span>
{#if showTimes}<strong
@@ -209,6 +244,45 @@
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
<div class="live-markdown">{@html data.live.current.researchHtml}</div>
</details>
{#if data.live.current.sources.length || data.live.current.tools.length}
<!-- eslint-disable svelte/no-navigation-without-resolve -->
<section class="live-materials" aria-labelledby="live-materials-title">
<div>
<span>Nur Redaktion</span>
<h3 id="live-materials-title">Materialien</h3>
</div>
{#if data.live.current.sources.length}<div class="live-material-group">
<strong>Quellen</strong>
<ul>
{#each data.live.current.sources as source (source.id)}<li>
<!-- The URL is a server-validated private HTTP(S) snapshot. -->
<!-- eslint-disable-next-line svelte/no-navigation-without-resolve -->
<a href={source.url} target="_blank" rel="noopener noreferrer"
>{source.label}</a
>{#if source.timecodeSeconds !== null}<small
>ab {formatClock(source.timecodeSeconds)}</small
>{/if}
</li>{/each}
</ul>
</div>{/if}
{#if data.live.current.tools.length}<div class="live-material-group">
<strong>Werkzeuge</strong>
<ul>
{#each data.live.current.tools as tool (tool.id)}<li>
{#if tool.workUrl || tool.startUrl}<!-- The URL is a server-validated private HTTP(S) snapshot. -->
<!-- eslint-disable-next-line svelte/no-navigation-without-resolve -->
<a
href={tool.workUrl || tool.startUrl}
target="_blank"
rel="noopener noreferrer">{tool.name}</a
>{:else}<span>{tool.name}</span><small>Kein Link hinterlegt</small>{/if}
{#if tool.note}<small>{tool.note}</small>{/if}
</li>{/each}
</ul>
</div>{/if}
</section>
<!-- eslint-enable svelte/no-navigation-without-resolve -->
{/if}
{#if data.live.current.transitionHtml}<section class="transition-card">
<span>Überleitung</span>
<!-- eslint-disable-next-line svelte/no-at-html-tags -->