From 746871000806845d566ca9e77ea9f75e46bf815e Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Tue, 8 Apr 2025 16:57:26 +0800 Subject: [PATCH] fix Detail --- dimensionhub/Views/Detail/DetailModel.swift | 139 +++++++++++++++ .../Views/{ => Detail}/DetailView.swift | 158 ++---------------- 2 files changed, 155 insertions(+), 142 deletions(-) create mode 100644 dimensionhub/Views/Detail/DetailModel.swift rename dimensionhub/Views/{ => Detail}/DetailView.swift (61%) diff --git a/dimensionhub/Views/Detail/DetailModel.swift b/dimensionhub/Views/Detail/DetailModel.swift new file mode 100644 index 0000000..41f1b48 --- /dev/null +++ b/dimensionhub/Views/Detail/DetailModel.swift @@ -0,0 +1,139 @@ +// +// DetailModel.swift +// dimensionhub +// +// Created by 安礼成 on 2025/4/8. +// + +import Foundation +import SwiftUI +import Observation + +@Observable +final class DetailModel { + + struct Episode: Codable, Identifiable { + let id = UUID().uuidString + let name: String + let num_name: String + let thumb: String + let play: String + + enum CodingKeys: String, CodingKey { + case name, num_name, thumb, play + } + } + + // 渠道 + struct Channel: Codable { + let name: String + let episodes: [Episode] + } + + struct DramaDetailResponse: Codable { + let name: String + let summary: String + let thumb: String + let status: [String] + let channels: [Channel] + } + + // 状态信息 + struct DramaStatus { + struct DisplayConfig { + let name: String + let bgColor: Color + let fontColor: Color + } + + let status: String + let config: DisplayConfig + + init?(_ rawValue: String) { + switch rawValue { + case "first_row": + self.status = rawValue + self.config = DisplayConfig(name: "前排占位", bgColor: .black, fontColor: .white) + case "following": + self.status = rawValue + self.config = DisplayConfig(name: "♡ 追番", bgColor: .black, fontColor: .white) + case "catching_up": + self.status = rawValue + self.config = DisplayConfig(name: "补番", bgColor: .black, fontColor: .white) + case "dropping": + self.status = rawValue + self.config = DisplayConfig(name: "弃番", bgColor: .white, fontColor: Color(hex: "#333333")) + case "finished": + self.status = rawValue + self.config = DisplayConfig(name: "补完", bgColor: .black, fontColor: .white) + default: + return nil + } + } + + } + + enum FollowResult { + case success + case error(String, String) + } + + var name: String = "" + var summary: String = "" + var thumb: String = "" + var statuses: [DramaStatus] = [] + var channels: [Channel] = [] + + // 当前选中的channel + var selectedChannelIdx: Int = 0 + var selectedEpisodes: [Episode] = [] + + func loadData(userId: String, id: Int) async { + let response = await API.getDramaDetail(userId: userId, id: id, as: DramaDetailResponse.self) + switch response { + case .error(let code, let message): + print(code) + print(message) + case .result(let detail): + await MainActor.run { + self.name = detail.name + self.summary = Utils.converHtmlToString(html: detail.summary) ?? "" + self.thumb = detail.thumb + self.statuses = detail.status.flatMap({ s in + if let status = DramaStatus(s) { + return [status] + } else { + return [] + } + }) + 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 + } + + func onTapFollowButton(userId: String, id: Int, status: String) async -> FollowResult { + let response = await API.followDrama(userId: userId, id: id, status: status, as: [String].self) + switch response { + case .error(_, let message): + return .error("错误", message) + case .result(let newStatuses): + self.statuses = newStatuses.flatMap({ s in + if let status = DramaStatus(s) { + return [status] + } else { + return [] + } + }) + return .success + } + } + +} diff --git a/dimensionhub/Views/DetailView.swift b/dimensionhub/Views/Detail/DetailView.swift similarity index 61% rename from dimensionhub/Views/DetailView.swift rename to dimensionhub/Views/Detail/DetailView.swift index 2e2627e..f29a80a 100644 --- a/dimensionhub/Views/DetailView.swift +++ b/dimensionhub/Views/Detail/DetailView.swift @@ -5,136 +5,6 @@ // Created by 安礼成 on 2025/2/21. // import SwiftUI -import Observation - -@Observable -final class DetailModel { - - struct Episode: Codable, Identifiable { - let id = UUID().uuidString - let name: String - let num_name: String - let thumb: String - let play: String - - enum CodingKeys: String, CodingKey { - case name, num_name, thumb, play - } - } - - // 渠道 - struct Channel: Codable { - let name: String - let episodes: [Episode] - } - - struct DramaDetailResponse: Codable { - let name: String - let summary: String - let thumb: String - let status: [String] - let channels: [Channel] - } - - // 状态信息 - struct DramaStatus { - struct DisplayConfig { - let name: String - let bgColor: Color - let fontColor: Color - } - - let status: String - let config: DisplayConfig - - init?(_ rawValue: String) { - switch rawValue { - case "first_row": - self.status = rawValue - self.config = DisplayConfig(name: "前排占位", bgColor: .black, fontColor: .white) - case "following": - self.status = rawValue - self.config = DisplayConfig(name: "♡ 追番", bgColor: .black, fontColor: .white) - case "catching_up": - self.status = rawValue - self.config = DisplayConfig(name: "补番", bgColor: .black, fontColor: .white) - case "dropping": - self.status = rawValue - self.config = DisplayConfig(name: "弃番", bgColor: .white, fontColor: Color(hex: "#333333")) - case "finished": - self.status = rawValue - self.config = DisplayConfig(name: "补完", bgColor: .black, fontColor: .white) - default: - return nil - } - } - - } - - enum FollowResult { - case success - case error(String, String) - } - - var name: String = "" - var summary: String = "" - var thumb: String = "" - var statuses: [DramaStatus] = [] - var channels: [Channel] = [] - - // 当前选中的channel - var selectedChannelIdx: Int = 0 - var selectedEpisodes: [Episode] = [] - - func loadData(userId: String, id: Int) async { - let response = await API.getDramaDetail(userId: userId, id: id, as: DramaDetailResponse.self) - switch response { - case .error(let code, let message): - print(code) - print(message) - case .result(let detail): - await MainActor.run { - self.name = detail.name - self.summary = Utils.converHtmlToString(html: detail.summary) ?? "" - self.thumb = detail.thumb - self.statuses = detail.status.flatMap({ s in - if let status = DramaStatus(s) { - return [status] - } else { - return [] - } - }) - 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 - } - - func onTapFollowButton(userId: String, id: Int, status: String) async -> FollowResult { - let response = await API.followDrama(userId: userId, id: id, status: status, as: [String].self) - switch response { - case .error(_, let message): - return .error("错误", message) - case .result(let newStatuses): - self.statuses = newStatuses.flatMap({ s in - if let status = DramaStatus(s) { - return [status] - } else { - return [] - } - }) - return .success - } - } - -} struct DetailView: View { @AppStorage("userId") private var userId: String = Utils.defaultUserId() @@ -191,17 +61,8 @@ struct DetailView: View { Spacer() ForEach(detailModel.statuses, id: \.status) { status in FollowButtonView(dramaStatus: status) { followStatus in - Task { - let result = await detailModel.onTapFollowButton(userId: self.userId, id: id, status: followStatus) - switch result { - case .success: - () - case .error(let title, let message): - DispatchQueue.main.async { - self.errorInfo = (title, message) - self.showAlert = true - } - } + Task.detached { + await self.clickFollowButton(followStatus: followStatus) } } } @@ -258,7 +119,20 @@ struct DetailView: View { } .task { await detailModel.loadData(userId: self.userId, id: self.id) - print(detailModel.summary) + } + } + + // 点击关注按钮 + private func clickFollowButton(followStatus: String) async { + let result = await detailModel.onTapFollowButton(userId: self.userId, id: id, status: followStatus) + switch result { + case .success: + () + case .error(let title, let message): + DispatchQueue.main.async { + self.errorInfo = (title, message) + self.showAlert = true + } } } }