Luminate/Sources/LuminateUI/Components/TVShowView.swift

102 lines
3.4 KiB
Swift

import Adwaita
import Foundation
import LuminateCore
struct TVShowView: View {
var item: Components.Schemas.BaseItemDto
var client: JellyfinClient
var userId: String
@State private var seasons: [Components.Schemas.BaseItemDto] = []
@State private var selectedSeasonId: String?
@State private var backdropData: Data?
var view: Body {
ScrollView {
VStack {
if let data = backdropData {
Picture()
.data(data)
.frame(minHeight: 300)
.frame(maxHeight: 300)
.hexpand(true)
}
HStack {
PosterCell(item: item, client: client)
.frame(minWidth: 200)
.frame(maxWidth: 200)
VStack {
Text(item.name ?? "")
.title1()
.halign(.start)
if let status = item.status {
Text(status)
.caption()
.halign(.start)
}
if let overview = item.overview {
Text(overview)
.body()
.halign(.start)
.padding(10, .vertical)
}
}
.hexpand(true)
}
.padding()
if !seasons.isEmpty {
VStack {
Text("Season")
.caption()
.halign(.start)
HStack {
ForEach(seasons) { season in
Button(season.name ?? "?") {
selectedSeasonId = season.id
}
.suggested(selectedSeasonId == season.id)
.flat(selectedSeasonId != season.id)
}
}
}
.padding(10, .horizontal)
}
if let seasonId = selectedSeasonId {
EpisodeList(
seriesId: item.id ?? "",
seasonId: seasonId,
client: client,
userId: userId
)
}
}
}
.onAppear {
loadSeasons()
loadBackdrop()
}
}
private func loadBackdrop() {
guard let tag = item.backdropImageTag, let itemId = item.id else { return }
Task {
guard
let url = await client.imageURL(
itemId: itemId, imageType: .backdrop, tag: tag, maxWidth: 1920
)
else { return }
let service = ImageService()
backdropData = try? await service.loadImage(url: url)
}
}
private func loadSeasons() {
Task {
let result = try? await client.getSeasons(seriesId: item.id ?? "", userId: userId)
await MainActor.run {
seasons = result?.items ?? []
selectedSeasonId = seasons.first?.id
}
}
}
}