Mediatheken nach oben — und das Regal sagt endlich, was es sieht

**Die Mediatheken sind Reiter geworden.** Sie standen unten auf der
Startseite, und dorthin musste man erst scrollen — an allen Vorschlägen
vorbei, obwohl „ich will in die Filme" genau der Fall ist, in dem einem
die Vorschläge egal sind. Damit fällt die Reihe unten weg: zwei Wege zum
selben Raster sind auf einem Fernseher kein Komfort, sondern eine Frage,
welcher der richtige ist.

Die Leiste liest sich jetzt „Start · Filme · Serien · Gemischtes ·
Suchen" und wird von tvOS mittig gehalten, egal wie viele Mediatheken
dazukommen. Die Stelle der Suche bestimmt Apple, nicht diese Datei:
`role: .search` setzt sie dorthin, wo sie in jeder anderen App auch
steht, und gibt ihr die Lupe.

**Und eine Statuszeile fürs Regal.** Bleibt es leer, gibt es genau drei
Möglichkeiten: die App-Gruppe fehlt, die Datei ist nicht da, oder sie ist
da und das System fragt trotzdem nicht. Von aussen sehen alle drei gleich
aus — nämlich nach dem grossen Plakat aus dem Asset-Katalog. Nach zwei
Runden Vermuten steht unten links jetzt, welcher Fall es ist: „3 Reihen,
9 Einträge, zuletzt 21:55" oder eben „Keine App-Gruppe".

Nur im Entwicklerbau (`#if DEBUG`) und als Überlagerung, nicht als letzte
Zeile der Liste: dorthin müsste man erst an allen Reihen vorbeiscrollen,
und wer nachsieht, warum das Regal leer ist, soll es sofort sehen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-09-29 21:56:31 +02:00
co-authored by Claude Opus 5
parent 08514eb564
commit 41719595b9
4 changed files with 162 additions and 51 deletions
+85
View File
@@ -7398,6 +7398,91 @@
}
}
}
},
"topShelf.noFile": {
"extractionState": "manual",
"localizations": {
"de": {
"stringUnit": {
"state": "translated",
"value": "Noch nichts abgelegt."
}
},
"en": {
"stringUnit": {
"state": "translated",
"value": "Nothing stored yet."
}
}
}
},
"topShelf.noGroup": {
"extractionState": "manual",
"localizations": {
"de": {
"stringUnit": {
"state": "translated",
"value": "Keine App-Gruppe — das Regal kann nichts lesen."
}
},
"en": {
"stringUnit": {
"state": "translated",
"value": "No app group — the shelf cannot read anything."
}
}
}
},
"topShelf.title": {
"extractionState": "manual",
"localizations": {
"de": {
"stringUnit": {
"state": "translated",
"value": "Regal über der App"
}
},
"en": {
"stringUnit": {
"state": "translated",
"value": "Top Shelf"
}
}
}
},
"topShelf.unreadable": {
"extractionState": "manual",
"localizations": {
"de": {
"stringUnit": {
"state": "translated",
"value": "Datei liegt da, lässt sich aber nicht lesen."
}
},
"en": {
"stringUnit": {
"state": "translated",
"value": "File is there but cannot be read."
}
}
}
},
"topShelf.written %lld %lld %@": {
"extractionState": "manual",
"localizations": {
"de": {
"stringUnit": {
"state": "translated",
"value": "%lld Reihen, %lld Einträge, zuletzt %@"
}
},
"en": {
"stringUnit": {
"state": "translated",
"value": "%lld rows, %lld entries, last %@"
}
}
}
}
},
"version": "1.1"
+22
View File
@@ -86,5 +86,27 @@ enum TopShelfWriter {
// wenn sie gefragt wird.
TVTopShelfContentProvider.topShelfContentDidChange()
}
/// Was zuletzt abgelegt wurde — in einem Satz, zum Hinsehen.
///
/// **Weil man dem Regal sonst nichts ansieht.** Bleibt es leer, gibt es
/// genau drei Möglichkeiten: die App-Gruppe fehlt, die Datei ist nicht da,
/// oder sie ist da und das System fragt trotzdem nicht. Von aussen sehen
/// alle drei gleich aus — nämlich nach dem grossen Plakat aus dem
/// Asset-Katalog. Diese Zeile unterscheidet sie.
static var status: String {
guard let ort = TopShelfStore.location(group: group) else {
return String(localized: "topShelf.noGroup")
}
guard let abzug = TopShelfStore.read(group: group) else {
let daIst = FileManager.default.fileExists(atPath: ort.path)
return daIst
? String(localized: "topShelf.unreadable")
: String(localized: "topShelf.noFile")
}
let einträge = abzug.sections.reduce(0) { $0 + $1.entries.count }
let zeit = abzug.savedAt.formatted(date: .omitted, time: .shortened)
return String(localized: "topShelf.written \(abzug.sections.count) \(einträge) \(zeit)")
}
}
#endif