Zwei Fassungen dürfen gewollt sein, und die Startseite darf nicht warten

**Mehrfachfassungen lassen sich abhaken.** Zwei Dateien an einem Film sind
meist zwei Fassungen und völlig in Ordnung. In der Liste standen sie
trotzdem für immer: sie rechnet jedes Mal frisch, und es gab keinen Zustand.
Wer absichtlich zwei Fassungen hält, konnte die Gruppe nicht loswerden — und
unter den gewollten ging das Ungewollte unter.

Abgehakt wird eine Dateizahl, kein Zeitpunkt. Ein Zeitstempel müsste gegen
`MediaFile.ModifiedAt` verglichen werden, und eine alte Datei, frisch
hineinkopiert, behält ihre alte Zeit und käme nie wieder hoch. Die Anzahl
ist genau die Frage: kommt eine dritte Fassung dazu, meldet sich die Gruppe
von selbst zurück. Gerechnet wird sie auf dem Server — ein Client mit
veralteter Liste hakte sonst eine Gruppe mit zwei Dateien ab, die inzwischen
drei hat.

„Ignorierte zeigen" führt zurück, wie bei den erledigten Meldungen; ohne das
wäre das Abhaken unumkehrbar und niemand wüsste, was er weggeklickt hat.

**Die Startseite wartete dreimal nacheinander.** Erst die Serverauskunft,
dann Konto und Mediatheken, dann erst die Startseite — drei Rundreisen,
bevor das erste Bild in Auftrag ging. Liegt eine Sitzung im Speicher, laufen
die ersten beiden jetzt zugleich los. Nur dann: ohne Sitzung liefen
`/auth/me` und `/libraries` vor der Antwort auf `needsSetup` in ein 401, und
die Sitzungsprüfung kann daraufhin abmelden.

Gemessen am laufenden Server: `users/me`, `system/info` und `libraries`
starten alle bei 37 ms, die Startseitenabfragen folgen bei 73 ms. Vorher
lagen drei Runden dazwischen.

**Sieben Hintergrundbilder auf einmal waren sechs zu viel.** Jede Folie des
Aufmachers bekam sofort ihr `w1280`-Bild; sichtbar ist immer nur eine. Jetzt
lädt die sichtbare sofort und der Rest in der Leerlaufzeit — und wer
weiterschaltet, bevor das lief, bekommt sein Bild dann.

**Die Schrift kam von Google.** `display=swap` rettete den Text, nicht den
ersten Aufbau: ein Stylesheet blockiert das Zeichnen, und ein Heimserver
ohne Internet oder mit träger Namensauflösung wartete davor. Inter liegt
jetzt als zwei Dateien von zusammen sechzig Kilobyte im Projekt, variabel
für alle Schnitte, mit `unicode-range` getrennt nach latin und latin-ext.
Gemessen: null Anfragen an fonts.googleapis.com. Lizenztext liegt dabei.

**Und mein Untertitelvorrat bremste mit.** Er startete sofort beim
Hochfahren und las die ganze Mediathek — von derselben Platte, von der die
Startseite ihre Bilder holt. Jetzt beginnt er eine Minute später und stellt
zurück, solange eine Wiedergabe läuft. Die Datei bleibt dabei vorn in der
Reihe; verworfen wird nichts.

678 Tests grün, davon zwei neue.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-10-08 17:56:41 +02:00
co-authored by Claude Opus 5
parent 2809821c9b
commit 1b4784f1db
18 changed files with 1653 additions and 27 deletions
@@ -560,6 +560,98 @@ public class MetadataTests
});
}
/// <summary>Eine abgehakte Gruppe verlässt die Liste — und kommt zurück, wenn eine Datei dazukommt.</summary>
///
/// <remarks>
/// <para>
/// <b>Der Anlass.</b> Zwei Dateien an einem Film sind meist zwei
/// Fassungen und völlig in Ordnung. In der Liste standen sie trotzdem für
/// immer: sie rechnet jedes Mal frisch, und es gab keinen Zustand. Wer
/// absichtlich zwei Fassungen hält, konnte die Gruppe nicht loswerden —
/// und unter den gewollten ging das Ungewollte unter.
/// </para>
/// <para>
/// <b>Abgehakt wird eine Dateizahl, kein Zeitpunkt.</b> Kommt eine dritte
/// Fassung dazu, stimmt die Zahl nicht mehr und die Gruppe meldet sich
/// von selbst zurück. Genau das prüft der zweite Teil.
/// </para>
/// </remarks>
[Test]
public async Task Eine_abgehakte_Fassungsgruppe_meldet_sich_bei_einer_neuen_Datei_zurueck()
{
Datei("Hanni und Nanni/Hanni und Nanni.mp4");
Datei("Hanni und Nanni/Hanni und Nanni 3.mp4");
var anbieter = new VorgegebenerAnbieter
{
Film = new MovieMetadata(225313, "Hanni & Nanni 3", 2013, null, null, null),
};
using var server = MitAnbieter(anbieter);
var (client, bibliothek) = await Einrichten(server, "Movies");
await Scannen(client, bibliothek);
var vorher = await client.GetFromJsonAsync<Mehrfachbericht>(
$"/api/v1/libraries/{bibliothek}/versions");
Assert.That(vorher!.Gesamt, Is.EqualTo(1), "zwei Dateien an einem Titel");
var film = vorher.Titel[0].Id;
(await client.PostAsJsonAsync($"/api/v1/libraries/{bibliothek}/versions/acknowledge",
new FassungenRequest([film]))).EnsureSuccessStatusCode();
var offen = await client.GetFromJsonAsync<Mehrfachbericht>(
$"/api/v1/libraries/{bibliothek}/versions");
var abgehakt = await client.GetFromJsonAsync<Mehrfachbericht>(
$"/api/v1/libraries/{bibliothek}/versions?ignorierte=true");
Assert.Multiple(() =>
{
Assert.That(offen!.Gesamt, Is.Zero, "abgehakt heisst: nicht mehr in der offenen Liste");
Assert.That(abgehakt!.Gesamt, Is.EqualTo(1), "aber nachsehen muss man können");
});
// Eine dritte Fassung dazu — jetzt stimmt die abgehakte Zahl nicht mehr.
Datei("Hanni und Nanni/Hanni und Nanni 2.mp4");
await Scannen(client, bibliothek);
var wieder = await client.GetFromJsonAsync<Mehrfachbericht>(
$"/api/v1/libraries/{bibliothek}/versions");
Assert.That(wieder!.Gesamt, Is.EqualTo(1),
"eine neue Datei macht die Gruppe wieder zu einer Frage");
}
/// <summary>Zurückholen macht das Abhaken rückgängig.</summary>
[Test]
public async Task Eine_abgehakte_Gruppe_laesst_sich_zurueckholen()
{
Datei("Hanni und Nanni/Hanni und Nanni.mp4");
Datei("Hanni und Nanni/Hanni und Nanni 3.mp4");
var anbieter = new VorgegebenerAnbieter
{
Film = new MovieMetadata(225313, "Hanni & Nanni 3", 2013, null, null, null),
};
using var server = MitAnbieter(anbieter);
var (client, bibliothek) = await Einrichten(server, "Movies");
await Scannen(client, bibliothek);
var film = (await client.GetFromJsonAsync<Mehrfachbericht>(
$"/api/v1/libraries/{bibliothek}/versions"))!.Titel[0].Id;
await client.PostAsJsonAsync($"/api/v1/libraries/{bibliothek}/versions/acknowledge",
new FassungenRequest([film]));
await client.PostAsJsonAsync($"/api/v1/libraries/{bibliothek}/versions/acknowledge",
new FassungenRequest([film], Ignorieren: false));
var offen = await client.GetFromJsonAsync<Mehrfachbericht>(
$"/api/v1/libraries/{bibliothek}/versions");
Assert.That(offen!.Gesamt, Is.EqualTo(1));
}
/// <summary>Eine einzelne Datei lässt sich nicht herauslösen.</summary>
[Test]
public async Task Eine_einzelne_Datei_laesst_sich_nicht_herausloesen()