451 gegen 461, und ein Band für das, was noch wartet

Drei Zahlen, die alle stimmen und Verschiedenes meinen: Plex zählte 451
Filme, Flaro 449, und der Scan lief über 461 Dateien. Die
Mediathekszeile nennt sie jetzt getrennt — Titel, Folgen, Dateien,
zweite Fassungen und nicht Zugeordnetes. Damit beantwortet sich die
Frage selbst, statt offen zu bleiben.

Die Rechnung dahinter war beim ersten Versuch falsch: sie verglich
gegen alle Folgen und kam auf 1223 Titel bei 324 Dateien. Gezählt wird
jetzt, zu wie vielen Titeln überhaupt noch eine Datei daliegt — dann
geht Dateien = Titel + Fassungen + ohne auf, auch wenn etwas vermisst
wird. Nachgemessen mit einer echten Plex-Kopie: 3 Titel, 4 Dateien, 1
zweite Fassung.

Dazu trägt eine Kachel, die noch auf Freigabe wartet, jetzt ein Band —
„Wartet" oder „Geplant". Für einen Administrator standen wartende Titel
bisher mitten zwischen den freigegebenen, ohne dass etwas sie
unterschied; wer einen suchte, fand ihn nur über die Prüfliste. Dafür
reicht `PublishAt` jetzt bis in die Kachel durch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-10-04 22:04:17 +02:00
co-authored by Claude Opus 5
parent 5a5cf3d006
commit c854c4a09a
7 changed files with 180 additions and 25 deletions
+13
View File
@@ -47,6 +47,8 @@ export type Film = {
/** Leer in Listen, gefüllt beim Einzelabruf. */
genres: string[] | null;
credits: Mitwirkender[] | null;
/** `null` heisst: wartet auf Freigabe. Ein Zeitpunkt in der Zukunft: geplant. */
publishAt: string | null;
/** Der Titel in der Sprache des Originals, wenn er abweicht. */
originalTitle: string | null;
};
@@ -61,6 +63,8 @@ export type Serie = {
contentRating: string | null;
genres: string[] | null;
credits: Mitwirkender[] | null;
/** `null` heisst: wartet auf Freigabe. Ein Zeitpunkt in der Zukunft: geplant. */
publishAt: string | null;
/** Der Titel in der Sprache des Originals, wenn er abweicht. */
originalTitle: string | null;
};
@@ -91,6 +95,15 @@ export type Bibliothek = {
/** Wie viele Titel hier noch auf Freigabe warten. */
pendingCount: number;
/** Mediendateien in dieser Mediathek — ohne die vermissten. */
fileCount: number;
/** Nur bei Serien: wie viele Folgen. */
episodeCount: number | null;
/** Dateien, die an keinem Titel hängen. */
unassignedCount: number;
/** Dateien über die erste je Titel hinaus — zweite Fassungen. */
extraVersionCount: number;
};
export type Seite<T> = { items: T[]; total: number };
export type Lieferung = {
+20
View File
@@ -23,6 +23,8 @@ export type Kachel = {
stand?: Stand | null;
/** Die Zahl offener Folgen, als Plakette oben rechts. */
offen?: number | null;
/** `null` heisst: wartet auf Freigabe. Ein Zeitpunkt in der Zukunft: geplant. */
freigabe?: string | null;
};
/* ---------- Umwandlungen ---------- */
@@ -35,6 +37,7 @@ export const alsKachel = (e: Film | Serie): Kachel => ({
bild: e.posterImage,
stand: 'state' in e ? e.state : null,
offen: 'unwatchedCount' in e ? e.unwatchedCount : null,
freigabe: e.publishAt,
});
/** Eine Kachel aus „Weiterschauen" — bei Folgen dreizeilig, wie bei Plex. */
@@ -110,6 +113,23 @@ export function kachel(k: Kachel, oeffnen: (art: 'filme' | 'serien', id: string)
rahmen.appendChild(bild);
}
// **Was noch wartet, trägt ein Band.**
//
// Für einen Administrator stehen wartende Titel mitten zwischen den
// freigegebenen, ohne dass etwas sie unterscheidet — und wer einen davon
// sucht, findet ihn nur über die Prüfliste. Für alle anderen ist er gar
// nicht da, dann erscheint das Band auch nie.
if (k.freigabe === null || (k.freigabe && new Date(k.freigabe) > new Date())) {
const band = document.createElement('span');
band.className = 'wartet';
band.textContent = k.freigabe === null ? 'Wartet' : 'Geplant';
band.title = k.freigabe === null
? 'Wartet auf Freigabe — nur für Administratoren sichtbar'
: `Erscheint am ${new Date(k.freigabe).toLocaleString('de-CH',
{ dateStyle: 'medium', timeStyle: 'short' })}`;
rahmen.appendChild(band);
}
// **Der Haken sitzt in der Ecke, nicht in der Beschriftung.** So wie bei
// Plex: ein Blick über das Raster zeigt, was noch offen ist, ohne eine
// einzige Zeile zu lesen.
+10
View File
@@ -1063,6 +1063,16 @@ h2 { font-size: var(--t-abschnitt); font-weight: 700; letter-spacing: -.015em; m
* Abbrechen noch zu Bestätigen. */
.dlg-weiterer { margin-right: auto; }
/* Das Band an einer Kachel, die noch nicht freigegeben ist. Unten links,
* damit es weder dem Haken oben rechts noch dem Fortschrittsbalken am
* unteren Rand in die Quere kommt. */
.wartet {
position: absolute; left: 0; bottom: 0;
padding: 3px 8px; border-top-right-radius: var(--r-knopf);
background: color-mix(in srgb, var(--accent) 88%, black);
color: #fff; font-size: 11px; font-weight: 700; letter-spacing: .02em;
}
.bildblock { display: flex; flex-direction: column; gap: var(--s-snug); }
.bildblock h3 { margin: 0; font-size: var(--t-gross); font-weight: 600; flex: 1; }
+26 -11
View File
@@ -808,20 +808,35 @@ function bibliotheksbereich(
function kopfSchreiben(): void {
const serie = aktuell.kind === 'Shows';
// „1 Filme" ist der Satz, an dem man sieht, dass niemand hingeschaut hat.
const anzahl = aktuell.itemCount == null ? ''
: ` · ${aktuell.itemCount} ` + (aktuell.itemCount === 1
? (serie ? 'Serie' : 'Film')
: (serie ? 'Serien' : 'Filme'));
// Was wartet, gehört in dieselbe Zeile — sonst erfährt man es nur, wenn
// man bis zur Prüfliste weiterscrollt.
const wartet = aktuell.pendingCount > 0
? ` · ${aktuell.pendingCount} wartet${aktuell.pendingCount === 1 ? '' : 'en'} auf Freigabe`
: '';
// **Alle Zahlen nebeneinander, weil sie Verschiedenes meinen.**
//
// Plex zählte 451 Filme, Flaro 449, und der Scan lief über 461 Dateien.
// Keine davon war falsch — es sind Titel, Dateien und zweite Fassungen.
// Einzeln gezeigt bleibt die Frage offen, nebeneinander beantwortet sie
// sich.
const teile: string[] = [aktuell.path];
if (aktuell.itemCount != null) {
teile.push(`${aktuell.itemCount} ` + (aktuell.itemCount === 1
? (serie ? 'Serie' : 'Film')
: (serie ? 'Serien' : 'Filme')));
}
if (serie && aktuell.episodeCount != null) {
teile.push(`${aktuell.episodeCount} ${aktuell.episodeCount === 1 ? 'Folge' : 'Folgen'}`);
}
teile.push(`${aktuell.fileCount} ${aktuell.fileCount === 1 ? 'Datei' : 'Dateien'}`);
if (aktuell.extraVersionCount > 0) {
teile.push(`${aktuell.extraVersionCount} zweite Fassung`
+ (aktuell.extraVersionCount === 1 ? '' : 'en'));
}
if (aktuell.unassignedCount > 0) teile.push(`${aktuell.unassignedCount} nicht zugeordnet`);
if (aktuell.pendingCount > 0) {
teile.push(`${aktuell.pendingCount} wartet${aktuell.pendingCount === 1 ? '' : 'en'} auf Freigabe`);
}
kopf.innerHTML = `<strong>${esc(aktuell.name)}</strong>`
+ `<span class="winzig">${esc(aktuell.path)}${esc(anzahl)}${esc(wartet)}</span>`;
+ `<span class="winzig">${esc(teile.join(' · '))}</span>`;
}
kopfSchreiben();