import Foundation /// Wie die Reihen der Startseite angeordnet werden. /// /// Reine Rechnung ohne Speicher und ohne Oberfläche — die Stelle, an der die /// zwei unangenehmen Fälle entschieden werden: was mit Reihen geschieht, die /// der Server neu liefert, und was mit gespeicherten, die es nicht mehr gibt. public struct HubArrangement: Sendable, Equatable { /// Ausdrücklich ausgeblendete Reihen. public var hidden: Set /// Die gewünschte Reihenfolge. Reihen, die hier fehlen, landen am Ende. public var order: [String] public init(hidden: Set = [], order: [String] = []) { self.hidden = hidden self.order = order } /// Wendet Auswahl und Reihenfolge an. /// /// Unbekannte Reihen landen am Ende statt zu verschwinden. Sie zu /// verwerfen wäre die einfachere Regel — und der Grund dafür, dass ein /// neu angelegtes Regal auf dem Server in der App nie aufgetaucht wäre. public func apply(to hubs: [PlexHub]) -> [PlexHub] { let visible = hubs.filter { !hidden.contains($0.hubIdentifier) } guard !order.isEmpty else { return visible } let positions = Dictionary( order.enumerated().map { ($1, $0) }, // Ein doppelter Eintrag in der gespeicherten Reihenfolge — etwa // nach einem fehlgeschlagenen Schreibvorgang — soll nicht // abstürzen. Die erste Position gewinnt. uniquingKeysWith: { first, _ in first } ) return visible.enumerated().sorted { left, right in let leftPosition = positions[left.element.hubIdentifier] ?? Int.max let rightPosition = positions[right.element.hubIdentifier] ?? Int.max // Bei gleicher Position — beide unbekannt — bleibt die Reihenfolge // des Servers erhalten. Ohne diese Rückfalllinie wäre die // Anordnung neuer Reihen zufällig. if leftPosition == rightPosition { return left.offset < right.offset } return leftPosition < rightPosition }.map(\.element) } /// Die Liste für den Einstellungsbildschirm: gespeicherte Reihenfolge /// zuerst, danach alles, was der Server sonst noch liefert. /// /// Gespeicherte Reihen, die es nicht mehr gibt, fallen dabei heraus — sie /// anzuzeigen hieße, eine Reihe anzubieten, die nie erscheinen kann. public func arrangedIdentifiers(from hubs: [PlexHub]) -> [String] { var result: [String] = [] var seen = Set() for identifier in order where !seen.contains(identifier) && hubs.contains(where: { $0.hubIdentifier == identifier }) { result.append(identifier) seen.insert(identifier) } for hub in hubs where !seen.contains(hub.hubIdentifier) { result.append(hub.hubIdentifier) seen.insert(hub.hubIdentifier) } return result } }