import Foundation /// Was Flaro über die Leitung schickt. /// /// Ein Spiegel der `Contracts.cs` auf der Serverseite, und nur das: hier wird /// nichts gerechnet und nichts gedeutet. Die Übersetzung in die neutralen /// Typen steht in `FlaroBackend+Mapping`. /// /// **Die Felder heissen wie dort.** Keine `CodingKeys`, keine Umbenennung: /// ASP.NET Core schreibt `camelCase`, Swift liest `camelCase`, und jede /// Abweichung wäre eine Stelle, an der beim nächsten Serverfeld jemand /// nachziehen müsste. enum Wire { struct Page: Decodable, Sendable { let items: [T] let total: Int } struct SystemInfo: Decodable, Sendable { let version: String? let serverName: String? let needsSetup: Bool let attributions: [Attribution]? } struct Attribution: Decodable, Sendable { let text: String let logoUrl: String let url: String } struct LoginResponse: Decodable, Sendable { let token: String let user: User } struct User: Decodable, Sendable { let id: String let userName: String let isAdministrator: Bool /// Das Profilbild, als Schlüssel in die Bildablage des Servers. let avatarImage: String? } struct Library: Decodable, Sendable { let id: String let name: String let kind: String let path: String } struct Stream: Decodable, Sendable { let index: Int let kind: String let codec: String? let language: String? let title: String? let isDefault: Bool let isForced: Bool let channels: Int? let width: Int? let height: Int? } struct File: Decodable, Sendable { let id: String let fileName: String let sizeBytes: Int64 let container: String? let durationSeconds: Double? let streams: [Stream] } struct ItemState: Decodable, Sendable { let positionSeconds: Double let runtimeSeconds: Double? let watched: Bool let playCount: Int let favourite: Bool let rating: Int? let dismissed: Bool let lastPlayedAt: Date? /// Ob der Server den Titel in „Weiterschauen" führt. /// /// **Nicht dasselbe wie „Stelle über null".** Seit es eine /// einstellbare Untergrenze gibt, sind das zwei Fragen: eine Sekunde /// wird gemerkt, zählt aber nicht als angefangen. let inProgress: Bool? } struct Movie: Decodable, Sendable { let id: String let title: String let year: Int? let overview: String? let posterImage: String? let backdropImage: String? let files: [File] let state: ItemState? /// Ab wann abspielbar. In der Zukunft heisst: noch nicht. let publishAt: Date? } struct Series: Decodable, Sendable { let id: String let title: String let year: Int? let overview: String? let posterImage: String? let backdropImage: String? let episodeCount: Int let seasons: [Int] let unwatchedCount: Int let publishAt: Date? } struct Episode: Decodable, Sendable { let id: String let season: Int let episode: Int let title: String? let overview: String? let stillImage: String? let files: [File] let state: ItemState? let publishAt: Date? /// Zu welcher Serie sie gehört — ohne das ist eine Folge für sich /// nicht darstellbar: Titel und Bild der Serie fehlten. let seriesId: String? } /// Eine Kachel aus „Weiterschauen" oder „Nächste Folge". struct Started: Decodable, Sendable { let id: String let kind: String let title: String let subTitle: String? let season: Int? let episode: Int? let year: Int? let posterImage: String? let backdropImage: String? let state: ItemState /// Zu welcher Serie die Folge gehört. let seriesId: String? /// Das breite Bild der Serie — für den Aufmacher, nicht für die /// Kachel: die will das Standbild der Folge. let seriesBackdropImage: String? let publishAt: Date? } struct CodeResponse: Decodable, Sendable { let code: String let handle: String let expiresAt: Date } /// `state` ist „pending", „approved" oder „expired". struct CodeState: Decodable, Sendable { let state: String let login: LoginResponse? } struct CodeRequest: Encodable, Sendable { let deviceName: String let deviceId: String } struct Delivery: Decodable, Sendable { let method: String let reasons: [String] let audioToEncode: [Int] let subtitlesDropped: [Int] let packageState: String let progress: Double let error: String? } // --- Was hinausgeht -------------------------------------------------- struct LoginRequest: Encodable, Sendable { let userName: String let password: String let deviceName: String let deviceId: String } struct ProgressRequest: Encodable, Sendable { let positionSeconds: Double let runtimeSeconds: Double? } struct WatchedRequest: Encodable, Sendable { let watched: Bool } struct FavouriteRequest: Encodable, Sendable { let favourite: Bool } struct RatingRequest: Encodable, Sendable { let rating: Int? } }