diff --git a/dimensionhub/Views/ListView.swift b/dimensionhub/Views/ListView.swift new file mode 100644 index 0000000..427e963 --- /dev/null +++ b/dimensionhub/Views/ListView.swift @@ -0,0 +1,162 @@ +// +// ListView.swift +// dimensionhub +// +// Created by 安礼成 on 2025/2/21. +// +import SwiftUI +import Observation + +@Observable +final class ListModel { + + 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 ListView: 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) + + Text("返回") + } + .background(Color.yellow) + + // 渠道列表 + 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(.vertical, showsIndicators: false) { + VStack(alignment: .center, spacing: 20) { + ForEach(detailModel.selectedEpisodes, id: \.id) { episode in + HStack(alignment: .center) { + AsyncImage(url: URL(string: episode.thumb)) { image in + image.resizable() + } placeholder: { + ProgressView() + } + .frame(width: 90, height: 70) + + VStack(alignment: .leading, spacing: 20) { + Text(episode.numName) + + Text(episode.name) + .lineLimit(1) + } + Spacer() + } + } + } + } + + 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 { + ListView() +}