Refine live controls and compact show cards

This commit is contained in:
hnzio committed 2026-10-24 19:09:44 +02:00
1 parent 01b5606a3b
commit fd47910d09
5 files changed
+211 -64

No files matched your search

+72 -11
View File
@@ -1057,6 +1057,13 @@ textarea:focus {
text-transform: uppercase;
}
.timer-label {
display: flex;
align-items: center;
justify-content: center;
gap: 0.25rem;
}
.live-output-state strong {
overflow: hidden;
font-size: 0.75rem;
@@ -1151,6 +1158,39 @@ textarea:focus {
text-align: center;
}
.section-timer-control {
display: flex;
align-items: stretch;
gap: 0.3rem;
}
.section-timer-control form {
display: flex;
}
.live-timer-toggle {
display: grid;
width: 2.15rem;
padding: 0;
place-items: center;
border: 1px solid var(--line);
border-radius: 0.65rem;
background: color-mix(in srgb, #d65c55 12%, var(--panel-soft));
color: #d65c55;
cursor: pointer;
font-size: 0.85rem;
}
.live-timer-toggle.paused {
background: color-mix(in srgb, var(--accent) 10%, var(--panel-soft));
color: var(--accent-strong);
}
.live-timer-toggle:hover,
.live-timer-toggle:focus-visible {
border-color: currentColor;
}
.total-countdown {
color: var(--text);
cursor: pointer;
@@ -1185,17 +1225,20 @@ textarea:focus {
color: #d24d45;
}
.live-output-state > span {
width: 0.5rem;
height: 0.5rem;
.live-output-state > .live-output-icon {
display: grid;
width: 1.5rem;
height: 1.5rem;
flex: 0 0 auto;
border-radius: 50%;
background: var(--text-faint);
place-items: center;
border-radius: 0.45rem;
background: var(--panel-soft);
color: var(--text-faint);
}
.live-output-control.active .live-output-state > span {
background: var(--accent);
box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--accent) 12%, transparent);
.live-output-control.active .live-output-icon {
background: color-mix(in srgb, var(--accent) 12%, var(--panel-soft));
color: var(--accent-strong);
}
.live-output-control {
@@ -1256,7 +1299,10 @@ textarea:focus {
}
.live-menu-trigger {
display: flex;
width: fit-content;
align-items: center;
gap: 0.32rem;
padding: 0.48rem 0.65rem;
border: 1px solid var(--line);
border-radius: 0.65rem;
@@ -2093,6 +2139,16 @@ textarea:focus {
}
}
@media (max-width: 30rem) {
.live-status-row {
grid-template-columns: minmax(0, 1fr) auto auto;
}
.live-output-control {
grid-column: 1 / -1;
}
}
@media (max-width: 23rem) {
.live-context-summary {
display: grid;
@@ -6296,11 +6352,16 @@ textarea:focus {
.show-card,
.show-card-facts {
align-items: flex-start;
flex-direction: column;
}
.show-card-facts {
width: 100%;
gap: 0.4rem;
flex-direction: row;
align-items: center;
gap: 0.7rem;
}
.show-card-facts span {
display: flex;
align-items: baseline;
gap: 0.25rem;
}
.show-settings-form .wide-field,
.usage-edit-form .wide-field {
+90 -32
View File
@@ -431,14 +431,15 @@
aria-expanded={menuOpen}
onclick={toggleLiveMenu}
>
Menü
<AppIcon name="bars" />
<span>Menü</span>
</button>
</div>
<div class="live-status-row">
<div class:active={Boolean(presentedUsage)} class="live-output-control">
<div class="live-output-state" aria-live="polite">
<span aria-hidden="true"></span>
<span class="live-output-icon" aria-hidden="true"><AppIcon name="display" /></span>
<div>
<small>Ausgabe</small>
<strong title={presentedUsage?.title ?? undefined}
@@ -455,7 +456,9 @@
<input type="hidden" name="usageId" value="" />
<input type="hidden" name="revision" value={data.live.liveRevision} />
<input type="hidden" name="commandId" value={data.commandId} />
<button class="text-button" type="submit" disabled={Boolean(data.live.endedAtUtc)}>Präsentation leeren</button>
<button class="text-button" type="submit" disabled={Boolean(data.live.endedAtUtc)}
>Präsentation leeren</button
>
</form>{/if}
</div>
@@ -467,8 +470,14 @@
? 'Gelaufene Gesamtzeit, zu Restzeit wechseln'
: 'Geschätzte Restzeit, zu gelaufener Zeit wechseln'}
>
<span>{timerDisplay === 'elapsed' ? 'Gelaufen' : 'Restzeit'}</span>
<strong>{formatCountdown(timerDisplay === 'elapsed' ? totalElapsedSeconds : remainingSeconds)}</strong>
<span class="timer-label"
><AppIcon name="timer" /> {timerDisplay === 'elapsed' ? 'Gelaufen' : 'Restzeit'}</span
>
<strong
>{formatCountdown(
timerDisplay === 'elapsed' ? totalElapsedSeconds : remainingSeconds
)}</strong
>
{#if timerDisplay === 'remaining' && data.live.remainingEstimate.unplannedSectionCount}
<small title="Verbleibende Abschnitte ohne geplante Abschnittsdauer"
>+ {data.live.remainingEstimate.unplannedSectionCount} ungeplant</small
@@ -476,22 +485,42 @@
{/if}
</button>
<div
class:warning={hasActiveSectionTimer &&
sectionRemainingSeconds <= 120 &&
sectionRemainingSeconds >= 0}
class:overrun={hasActiveSectionTimer && sectionRemainingSeconds < 0}
class="section-countdown"
aria-live="off"
>
<span>Abschnitt</span>
<strong>
{#if hasActiveSectionTimer}
{sectionRemainingSeconds < 0
? `+${formatCountdown(Math.abs(sectionRemainingSeconds))}`
: formatCountdown(sectionRemainingSeconds)}
{:else}Kein Countdown{/if}
</strong>
<div class="section-timer-control">
<div
class:warning={hasActiveSectionTimer &&
sectionRemainingSeconds <= 120 &&
sectionRemainingSeconds >= 0}
class:overrun={hasActiveSectionTimer && sectionRemainingSeconds < 0}
class="section-countdown"
aria-live="off"
>
<span class="timer-label"><AppIcon name="timer" /> Abschnitt</span>
<strong>
{#if hasActiveSectionTimer}
{sectionRemainingSeconds < 0
? `+${formatCountdown(Math.abs(sectionRemainingSeconds))}`
: formatCountdown(sectionRemainingSeconds)}
{:else}Kein Countdown{/if}
</strong>
</div>
{#if data.live.startedAtUtc && !data.live.endedAtUtc}<form
method="POST"
action={liveAction(data.live.isPaused ? 'resume' : 'pause')}
use:enhance={enhanceCommand}
>
<input type="hidden" name="showId" value={data.live.show.id} />
<input type="hidden" name="revision" value={data.live.liveRevision} />
<input type="hidden" name="commandId" value={data.commandId} />
<button
class:paused={data.live.isPaused}
class="live-timer-toggle"
type="submit"
aria-label={data.live.isPaused ? 'Sendung fortsetzen' : 'Sendung pausieren'}
title={data.live.isPaused ? 'Sendung fortsetzen' : 'Sendung pausieren'}
>
<AppIcon name={data.live.isPaused ? 'play' : 'pause'} />
</button>
</form>{/if}
</div>
<button
@@ -561,7 +590,11 @@
{#if !data.live.startedAtUtc}
<form method="POST" action={liveAction('setStatus')} use:enhance={enhanceCommand}>
<input type="hidden" name="showId" value={data.live.show.id} />
<input type="hidden" name="status" value={data.live.show.status === 'ready' ? 'draft' : 'ready'} />
<input
type="hidden"
name="status"
value={data.live.show.status === 'ready' ? 'draft' : 'ready'}
/>
<input type="hidden" name="revision" value={data.live.liveRevision} />
<input type="hidden" name="showRevision" value={data.live.show.revision} />
<input type="hidden" name="commandId" value={data.commandId} />
@@ -573,30 +606,45 @@
<input type="hidden" name="showId" value={data.live.show.id} />
<input type="hidden" name="revision" value={data.live.liveRevision} />
<input type="hidden" name="commandId" value={data.commandId} />
<button class="secondary-button" type="submit"><AppIcon name="play" /> Sendung starten</button>
<button class="secondary-button" type="submit"
><AppIcon name="play" /> Sendung starten</button
>
</form>
{:else if data.live.endedAtUtc}
<form method="POST" action={liveAction('resumeEnded')} use:enhance={enhanceCommand}>
<input type="hidden" name="showId" value={data.live.show.id} />
<input type="hidden" name="revision" value={data.live.liveRevision} />
<input type="hidden" name="commandId" value={data.commandId} />
<button class="secondary-button" type="submit"><AppIcon name="play" /> Lauf fortsetzen</button>
<button class="secondary-button" type="submit"
><AppIcon name="play" /> Lauf fortsetzen</button
>
</form>
<form
method="POST"
action={liveAction('startNewRun')}
use:enhance={enhanceCommand}
onsubmit={(event) => {
if (!confirm('Neuen Durchlauf starten? Fortschritt und Zeitmessungen werden zurückgesetzt.')) event.preventDefault();
if (
!confirm(
'Neuen Durchlauf starten? Fortschritt und Zeitmessungen werden zurückgesetzt.'
)
)
event.preventDefault();
}}
>
<input type="hidden" name="showId" value={data.live.show.id} />
<input type="hidden" name="revision" value={data.live.liveRevision} />
<input type="hidden" name="commandId" value={data.commandId} />
<button class="text-button" type="submit"><AppIcon name="arrow-rotate-left" /> Neuer Durchlauf</button>
<button class="text-button" type="submit"
><AppIcon name="arrow-rotate-left" /> Neuer Durchlauf</button
>
</form>
{:else}
<form method="POST" action={liveAction(data.live.isPaused ? 'resume' : 'pause')} use:enhance={enhanceCommand}>
<form
method="POST"
action={liveAction(data.live.isPaused ? 'resume' : 'pause')}
use:enhance={enhanceCommand}
>
<input type="hidden" name="showId" value={data.live.show.id} />
<input type="hidden" name="revision" value={data.live.liveRevision} />
<input type="hidden" name="commandId" value={data.commandId} />
@@ -616,7 +664,9 @@
<input type="hidden" name="showId" value={data.live.show.id} />
<input type="hidden" name="revision" value={data.live.liveRevision} />
<input type="hidden" name="commandId" value={data.commandId} />
<button class="text-button" type="submit"><AppIcon name="arrow-rotate-left" /> Abschnittszeit zurücksetzen</button>
<button class="text-button" type="submit"
><AppIcon name="arrow-rotate-left" /> Abschnittszeit zurücksetzen</button
>
</form>{/if}
<form
method="POST"
@@ -629,20 +679,25 @@
<input type="hidden" name="showId" value={data.live.show.id} />
<input type="hidden" name="revision" value={data.live.liveRevision} />
<input type="hidden" name="commandId" value={data.commandId} />
<button class="text-button" type="submit"><AppIcon name="timer" /> Gesamtzeit zurücksetzen</button>
<button class="text-button" type="submit"
><AppIcon name="timer" /> Gesamtzeit zurücksetzen</button
>
</form>
<form
method="POST"
action={liveAction('end')}
use:enhance={enhanceCommand}
onsubmit={(event) => {
if (!confirm('Sendung wirklich beenden? Offene Pieces bleiben offen.')) event.preventDefault();
if (!confirm('Sendung wirklich beenden? Offene Pieces bleiben offen.'))
event.preventDefault();
}}
>
<input type="hidden" name="showId" value={data.live.show.id} />
<input type="hidden" name="revision" value={data.live.liveRevision} />
<input type="hidden" name="commandId" value={data.commandId} />
<button class="text-button danger-text" type="submit"><AppIcon name="stop" /> Sendung beenden</button>
<button class="text-button danger-text" type="submit"
><AppIcon name="stop" /> Sendung beenden</button
>
</form>
{/if}
{#if needsResume && !data.live.endedAtUtc}<form
@@ -924,7 +979,10 @@
<input type="hidden" name="usageId" value={usage.id} />
<input type="hidden" name="revision" value={data.live.liveRevision} />
<input type="hidden" name="commandId" value={data.commandId} />
<button type="submit" disabled={Boolean(data.live.endedAtUtc)} aria-label={`${usage.title} präsentieren`}
<button
type="submit"
disabled={Boolean(data.live.endedAtUtc)}
aria-label={`${usage.title} präsentieren`}
><AppIcon name="display" /></button
>
</form>