fix Detail

This commit is contained in:
anlicheng 2025-04-08 16:57:26 +08:00
parent 6dc1c3c6eb
commit 7468710008
2 changed files with 155 additions and 142 deletions

View File

@ -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
}
}
}

View File

@ -5,136 +5,6 @@
// Created by on 2025/2/21. // Created by on 2025/2/21.
// //
import SwiftUI 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 { struct DetailView: View {
@AppStorage("userId") private var userId: String = Utils.defaultUserId() @AppStorage("userId") private var userId: String = Utils.defaultUserId()
@ -191,17 +61,8 @@ struct DetailView: View {
Spacer() Spacer()
ForEach(detailModel.statuses, id: \.status) { status in ForEach(detailModel.statuses, id: \.status) { status in
FollowButtonView(dramaStatus: status) { followStatus in FollowButtonView(dramaStatus: status) { followStatus in
Task { Task.detached {
let result = await detailModel.onTapFollowButton(userId: self.userId, id: id, status: followStatus) await self.clickFollowButton(followStatus: followStatus)
switch result {
case .success:
()
case .error(let title, let message):
DispatchQueue.main.async {
self.errorInfo = (title, message)
self.showAlert = true
}
}
} }
} }
} }
@ -258,7 +119,20 @@ struct DetailView: View {
} }
.task { .task {
await detailModel.loadData(userId: self.userId, id: self.id) 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
}
} }
} }
} }