Errungenschaften: Abzeichen fuer erreichte Meilensteine
CI / pruefen (pull_request) Canceled after 0s
CI / pruefen (pull_request) Canceled after 0s
Zwanzig feste Abzeichen plus dynamische fuer vollstaendig gesehene Filmreihen und abgeschlossene Universen. Sie tauchen auf, wenn etwas erreicht ist, und bleiben — auch wenn die Bedingung spaeter wegfaellt. Eine zurueckgenommene Sichtung soll kein Abzeichen kosten. Alle Regeln arbeiten auf *einem* Datensatz, der einmal geholt wird. Sonst stellte jede Regel ihre eigene Abfrage, und aus zwanzig Abzeichen wuerden zwanzig Abfragen bei jedem Abhaken. Ausgewertet wird nach Sichtungsaktionen und einmal taeglich; der erste Lauf eines Kontos ist stumm, weil eine gewachsene Bibliothek sonst zwei Dutzend Meldungen auf einmal ausloest. Fuer Filmreihen braucht es keine gepflegte Liste: TMDB gruppiert sie selbst, und tmdbCollectionId liegt beim Import schon am Titel. Eigennamen wie "Spider Bro" kommen aus einer kleinen Datendatei obendrauf; fehlt ein Eintrag, greift der generische Name. Die kuratierten Eintraege tragen jeweils ein Stueck des erwarteten TMDB-Namens. Ich habe die Collection-Kennungen aus dem Gedaechtnis geschrieben und kann sie hier nicht gegen TMDB pruefen — passt der Name nicht, wird der Eintrag ignoriert und der generische greift. Eine falsch abgeschriebene Kennung bleibt damit folgenlos statt jemandem das falsche Abzeichen zu geben. Die Uhrzeit-Regel liest die Stunde ueber formatToParts statt ueber die formatierte Zeichenkette: auf Deutsch liefert Intl fuer eine einzelne Stunde "03 Uhr", und daraus wird beim Umwandeln NaN. Ein Test hat das aufgedeckt. Beim ersten Oeffnen der Uebersicht wird einmal ausgewertet — sonst bliebe sie bei einem Bestandskonto leer, bis nachts der Hintergrundlauf kommt. Zehn Tests, Anleitung mit Screenshot. Symbole als eigene SVG auf einem gemeinsamen Raster; erreicht und offen unterscheiden sich nicht nur durch Farbe, sondern auch im Text. Refs #15
This commit is contained in:
@@ -16,7 +16,7 @@ import type { ActionResult } from "@/app/actions/library";
|
||||
type Toast = {
|
||||
id: number;
|
||||
message: string;
|
||||
tone: "info" | "error";
|
||||
tone: "info" | "error" | "erfolg";
|
||||
undo?: () => Promise<void> | void;
|
||||
};
|
||||
|
||||
@@ -58,6 +58,12 @@ export function ToastProvider({ children }: { children: React.ReactNode }) {
|
||||
show(result.message, {
|
||||
undo: undo && ids.length > 0 ? () => void undo(ids) : undefined,
|
||||
});
|
||||
|
||||
// Errungenschaften bekommen eine eigene Einblendung — sie sollen nicht
|
||||
// in der Meldung über das Abhaken untergehen.
|
||||
for (const name of result.achievements ?? []) {
|
||||
show(`Errungenschaft: ${name}`, { tone: "erfolg" });
|
||||
}
|
||||
},
|
||||
[show],
|
||||
);
|
||||
@@ -96,8 +102,15 @@ function ToastItem({ toast, onDismiss }: { toast: Toast; onDismiss: () => void }
|
||||
borderColor:
|
||||
toast.tone === "error"
|
||||
? "color-mix(in oklab, var(--fl-danger) 50%, transparent)"
|
||||
: "var(--fl-border)",
|
||||
color: toast.tone === "error" ? "var(--fl-danger)" : "var(--fl-text)",
|
||||
: toast.tone === "erfolg"
|
||||
? "color-mix(in oklab, var(--fl-success) 50%, transparent)"
|
||||
: "var(--fl-border)",
|
||||
color:
|
||||
toast.tone === "error"
|
||||
? "var(--fl-danger)"
|
||||
: toast.tone === "erfolg"
|
||||
? "var(--fl-success)"
|
||||
: "var(--fl-text)",
|
||||
}}
|
||||
>
|
||||
<span className="flex-1">{toast.message}</span>
|
||||
|
||||
Reference in New Issue
Block a user