- Chapter navigation with auto-scroll to current chapter and end-of-chapter sleep timer - Opt-in listening history (local-only) with XML export and per-item quick menu - Bookmarks with server sync via Audiobookshelf API - Live MB counter during downloads via URLSessionDownloadTask delegate - In-progress downloads shown in "Heruntergeladen" with dimmed cover + ring overlay - Cover image cache (50 MB memory / 500 MB disk URLCache) - German/English localization (de.lproj, en.lproj) - Loading spinner now triggers immediately on view switch instead of waiting for the network Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
102 lines
2.0 KiB
Swift
102 lines
2.0 KiB
Swift
import Foundation
|
|
|
|
struct LoginResponseDTO: Decodable {
|
|
let user: UserDTO
|
|
}
|
|
|
|
struct UserDTO: Decodable {
|
|
let id: String
|
|
let username: String?
|
|
let token: String
|
|
}
|
|
|
|
struct LibrariesResponseDTO: Decodable {
|
|
let libraries: [LibraryDTO]
|
|
}
|
|
|
|
struct LibraryDTO: Decodable {
|
|
let id: String
|
|
let name: String
|
|
let mediaType: String?
|
|
}
|
|
|
|
struct LibraryItemsResponseDTO: Decodable {
|
|
let results: [LibraryItemDTO]
|
|
let total: Int?
|
|
}
|
|
|
|
struct LibraryItemDTO: Decodable {
|
|
let id: String
|
|
let mediaType: String?
|
|
let media: MediaDTO?
|
|
}
|
|
|
|
struct ChapterDTO: Decodable {
|
|
let id: Int?
|
|
let start: Double?
|
|
let end: Double?
|
|
let title: String?
|
|
}
|
|
|
|
struct MediaDTO: Decodable {
|
|
let metadata: MetadataDTO?
|
|
let duration: Double?
|
|
let audioFiles: [AudioFileDTO]?
|
|
let episodes: [EpisodeDTO]?
|
|
let chapters: [ChapterDTO]?
|
|
}
|
|
|
|
struct MetadataDTO: Decodable {
|
|
let title: String?
|
|
let authorName: String?
|
|
let author: String?
|
|
let description: String?
|
|
}
|
|
|
|
struct EpisodeDTO: Decodable {
|
|
let id: String
|
|
let title: String?
|
|
let subtitle: String?
|
|
let pubDate: String?
|
|
let publishedAt: Double?
|
|
let season: String?
|
|
let episode: String?
|
|
let duration: Double?
|
|
let audioFile: AudioFileDTO?
|
|
}
|
|
|
|
struct AudioFileDTO: Decodable {
|
|
let ino: String
|
|
let index: Int?
|
|
let metadata: AudioFileMetadataDTO?
|
|
let duration: Double?
|
|
|
|
struct AudioFileMetadataDTO: Decodable {
|
|
let filename: String?
|
|
let ext: String?
|
|
}
|
|
}
|
|
|
|
struct BookmarkDTO: Decodable {
|
|
let title: String?
|
|
let time: Double?
|
|
let createdAt: Double?
|
|
}
|
|
|
|
struct ProgressResponseDTO: Decodable {
|
|
let id: String?
|
|
let libraryItemId: String?
|
|
let episodeId: String?
|
|
let currentTime: Double?
|
|
let duration: Double?
|
|
let isFinished: Bool?
|
|
let lastUpdate: Double?
|
|
let bookmarks: [BookmarkDTO]?
|
|
}
|
|
|
|
struct MeResponseDTO: Decodable {
|
|
let id: String?
|
|
let username: String?
|
|
let mediaProgress: [ProgressResponseDTO]?
|
|
}
|