dimensionhub/dimensionhub/Views/DetailView.swift
2025-02-21 23:47:55 +08:00

187 lines
5.4 KiB
Swift

//
// ListView.swift
// dimensionhub
//
// Created by on 2025/2/21.
//
import SwiftUI
import Observation
@Observable
final class DetailModel {
struct VoiceActor: Codable {
let actor_id: Int
let name: String
}
struct Episode: Codable {
let id: Int32
let name: String
let thumb: String
let numName: String
enum CodingKeys: String, CodingKey {
case id = "id"
case name = "name"
case thumb = "thumb"
case numName = "num_name"
}
}
//
struct Channel: Codable {
let name: String
let episodes: [Episode]
}
struct DramaDetailResponse: Codable {
let name: String
let voice_actors: [VoiceActor]
let status: Int
let channels: [Channel]
}
var name: String = ""
var voiceActors: [VoiceActor] = []
var status: Int = 0
var channels: [Channel] = []
// channel
var selectedChannelIdx: Int = 0
var selectedEpisodes: [Episode] = []
@MainActor
func loadData(dramaId: Int) async {
let response = await API.getDramaDetail(as: DramaDetailResponse.self)
switch response {
case .error(let code, let message):
print(code)
print(message)
case .result(let detail):
self.name = detail.name
self.voiceActors = detail.voice_actors
self.status = detail.status
self.channels = detail.channels
self.selectedChannelIdx = 0
self.selectedEpisodes = detail.channels[0].episodes
}
}
func toggleChannel(channelIdx: Int) {
self.selectedChannelIdx = channelIdx
self.selectedEpisodes = self.channels[channelIdx].episodes
}
}
struct DetailView: View {
@State var detailModel = DetailModel()
var body: some View {
VStack(alignment: .center) {
VStack(alignment: .leading, spacing: 20) {
Text(detailModel.name)
.font(.system(size: 30))
.fontWeight(.bold)
HStack(alignment: .center, spacing: 0) {
ForEach(Array(detailModel.voiceActors.enumerated()), id: \.offset) { index, actor in
if index > 0 {
Text("")
}
Text(actor.name)
.font(.system(size: 16))
}
Text("")
Spacer()
}
}
.background(Color.yellow)
HStack {
Spacer()
switch detailModel.status {
case 0:
Text("补完")
case 1:
Text("追番")
case 2:
Text("前排站位")
default:
Text("追番")
}
}
//
HStack(alignment: .center, spacing: 15) {
ForEach(Array(detailModel.channels.enumerated()), id: \.offset) { idx, channel in
Text(channel.name)
.font(.system(size: 16))
.foregroundColor(idx == detailModel.selectedChannelIdx ? .blue : .black)
.onTapGesture {
detailModel.toggleChannel(channelIdx: idx)
}
}
Spacer()
}
//
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .center) {
ForEach(detailModel.selectedEpisodes, id: \.id) { episode in
VStack(alignment: .center) {
AsyncImage(url: URL(string: episode.thumb)) { image in
image.resizable()
} placeholder: {
ProgressView()
}
.frame(width: 90, height: 70)
.overlay {
Text(episode.numName)
}
Text(episode.name)
.lineLimit(1)
}
.frame(width: 90, height: 120)
}
}
}
HStack(alignment: .center) {
Button {
print("click me")
} label: {
Rectangle()
.frame(width: 180, height: 50)
.foregroundColor(Color.yellow)
.cornerRadius(10)
.overlay {
RoundedRectangle(cornerRadius: 10)
.stroke(Color.black, lineWidth: 1)
Text("展开全部剧集")
}
}
}
Spacer()
}
.border(Color.red)
.frame(width: 370, alignment: .center)
.task {
await detailModel.loadData(dramaId: 124)
print(UIScreen.main.bounds.width)
}
}
}
#Preview {
DetailView()
}