Merge iOS and Mac app into one

This commit is contained in:
Scarriffle
2026-05-17 21:06:59 +02:00
parent 069f8bac2d
commit ac7906f0cf
72 changed files with 1277 additions and 3408 deletions

View File

@@ -0,0 +1,86 @@
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 MediaDTO: Decodable {
let metadata: MetadataDTO?
let duration: Double?
let audioFiles: [AudioFileDTO]?
let episodes: [EpisodeDTO]?
}
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 ProgressResponseDTO: Decodable {
let id: String?
let libraryItemId: String?
let episodeId: String?
let currentTime: Double?
let duration: Double?
let isFinished: Bool?
let lastUpdate: Double?
}
struct MeResponseDTO: Decodable {
let id: String?
let username: String?
let mediaProgress: [ProgressResponseDTO]?
}

View File

@@ -0,0 +1,81 @@
import Foundation
struct Library: Codable, Identifiable, Hashable {
let id: String
let name: String
let mediaType: String?
}
struct LibraryItem: Codable, Identifiable, Hashable {
let id: String
let title: String
let author: String
let durationSeconds: Double
let audioFiles: [AudioFile]
var mediaType: String = "book"
var episodeId: String? = nil
var description: String? = nil
var isPodcast: Bool { mediaType == "podcast" }
var isPodcastContainer: Bool { isPodcast && episodeId == nil }
var isPodcastEpisode: Bool { isPodcast && episodeId != nil }
static func == (lhs: LibraryItem, rhs: LibraryItem) -> Bool {
lhs.id == rhs.id && lhs.episodeId == rhs.episodeId
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
hasher.combine(episodeId)
}
}
struct PodcastEpisode: Identifiable, Hashable, Codable {
let id: String
let title: String
let pubDate: String?
let publishedAtMillis: Double?
let season: String?
let episode: String?
let durationSeconds: Double
let audioFile: AudioFile
var formattedDate: String? {
if let ms = publishedAtMillis, ms > 0 {
let date = Date(timeIntervalSince1970: ms / 1000.0)
let df = DateFormatter()
df.dateStyle = .medium
df.timeStyle = .none
return df.string(from: date)
}
return pubDate
}
}
struct AudioFile: Codable, Hashable {
let ino: String
let filename: String
let ext: String
let durationSeconds: Double
let index: Int
}
struct PlaybackProgress: Codable, Hashable {
let itemId: String
var episodeId: String?
var currentTime: Double
var duration: Double
var isFinished: Bool
var updatedAt: Date
var syncKey: String {
if let episodeId { return "\(itemId)|\(episodeId)" }
return itemId
}
}
enum DownloadState: Equatable {
case notDownloaded
case downloading(progress: Double)
case downloaded
case failed(message: String)
}