This commit is contained in:
anlicheng 2025-02-25 12:03:51 +08:00
parent cd34006635
commit 1ef90a8972
4 changed files with 86 additions and 74 deletions

View File

@ -61,13 +61,13 @@ struct API {
}
static func getDateIndex<T: Codable>(as: T.Type) async -> APIResponse<T> {
let request = URLRequest(url: URL(string: url + "date_index")!)
let request = URLRequest(url: URL(string: baseUrl + "date_index")!)
return await doRequest(request: request, as: T.self)
}
static func getDramaDetail<T: Codable>(as: T.Type) async -> APIResponse<T> {
let request = URLRequest(url: URL(string: url + "detail")!)
static func getDramaDetail<T: Codable>(userId: Int, id: Int, as: T.Type) async -> APIResponse<T> {
let request = URLRequest(url: URL(string: baseUrl + "/api/detail?user_id=\(userId)&id=\(id)")!)
return await doRequest(request: request, as: T.self)
}

View File

@ -10,22 +10,15 @@ import Observation
@Observable
final class DetailModel {
struct VoiceActor: Codable {
let actor_id: Int
let name: String
}
struct Episode: Codable {
let id: Int32
struct Episode: Codable, Identifiable {
let id = UUID().uuidString
let name: String
let num_name: String
let thumb: String
let numName: String
let play: String
enum CodingKeys: String, CodingKey {
case id = "id"
case name = "name"
case thumb = "thumb"
case numName = "num_name"
case name, num_name, thumb, play
}
}
@ -37,14 +30,51 @@ final class DetailModel {
struct DramaDetailResponse: Codable {
let name: String
let voice_actors: [VoiceActor]
let status: Int
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: .white, fontColor: Color(hex: "#333333"))
case "catching_up":
self.status = rawValue
self.config = DisplayConfig(name: "补番", bgColor: .black, fontColor: .white)
case "dropping":
self.status = rawValue
self.config = DisplayConfig(name: "弃番", bgColor: .black, fontColor: .white)
case "finished":
self.status = rawValue
self.config = DisplayConfig(name: "补完", bgColor: .black, fontColor: .white)
default:
return nil
}
}
}
var name: String = ""
var voiceActors: [VoiceActor] = []
var status: Int = 0
var summary: String = ""
var thumb: String = ""
var statuses: [DramaStatus] = []
var channels: [Channel] = []
// channel
@ -52,16 +82,21 @@ final class DetailModel {
var selectedEpisodes: [Episode] = []
@MainActor
func loadData(dramaId: Int) async {
let response = await API.getDramaDetail(as: DramaDetailResponse.self)
func loadData(userId: Int, 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):
self.name = detail.name
self.voiceActors = detail.voice_actors
self.status = detail.status
self.statuses = detail.status.flatMap({ s in
if let status = DramaStatus(s) {
return [status]
} else {
return []
}
})
self.channels = detail.channels
self.selectedChannelIdx = 0
@ -78,6 +113,7 @@ final class DetailModel {
struct DetailView: View {
@State var detailModel = DetailModel()
let id: Int32
var body: some View {
VStack(alignment: .center) {
@ -88,6 +124,7 @@ struct DetailView: View {
.fontWeight(.bold)
.foregroundColor(Color(hex: "#333333"))
/*
HStack(alignment: .center, spacing: 0) {
ForEach(Array(detailModel.voiceActors.enumerated()), id: \.offset) { index, actor in
if index > 0 {
@ -105,33 +142,16 @@ struct DetailView: View {
Spacer()
}
*/
}
.padding([.top, .leading], 10)
.background(Color(hex: "#F2F2F2"), ignoresSafeAreaEdges: [.bottom])
HStack {
HStack(alignment: .center, spacing: 10) {
Spacer()
switch detailModel.status {
case 0:
FollowButtonView(title: "补完", bgColor: .black, fontColor: .white) {
}
case 1:
FollowButtonView(title: "追番", bgColor: .black, fontColor: .white) {
}
case 2:
FollowButtonView(title: "前排站位", bgColor: .black, fontColor: .white) {
}
case 3:
FollowButtonView(title: "弃番", bgColor: .black, fontColor: .white) {
}
default:
FollowButtonView(title: "追番", bgColor: .white, fontColor: Color(hex: "#333333")) {
ForEach(detailModel.statuses, id: \.status) { status in
FollowButtonView(title: status.config.name, bgColor: status.config.bgColor, fontColor: status.config.fontColor) {
print("call me follow button clicked")
}
}
}
@ -206,8 +226,7 @@ struct DetailView: View {
}
.frame(width: 370, alignment: .center)
.task {
await detailModel.loadData(dramaId: 124)
print(UIScreen.main.bounds.width)
await detailModel.loadData(userId: 1, id: self.id)
}
}
@ -244,5 +263,5 @@ extension DetailView {
}
#Preview {
DetailView()
DetailView(id: 19625)
}

View File

@ -338,7 +338,7 @@ extension IndexView {
var body: some View {
VStack(alignment: .leading) {
NavigationLink(destination: DetailView()) {
NavigationLink(destination: DetailView(id: dramaItem.id)) {
Text(dramaItem.title)
.font(.system(size: 20))
.foregroundColor(Color(hex: "#333333"))

View File

@ -10,22 +10,15 @@ import Observation
@Observable
final class ListModel {
struct VoiceActor: Codable {
let actor_id: Int
let name: String
}
struct Episode: Codable {
let id: Int32
struct Episode: Codable, Identifiable {
let id = UUID().uuidString
let name: String
let num_name: String
let thumb: String
let numName: String
let play: String
enum CodingKeys: String, CodingKey {
case id = "id"
case name = "name"
case thumb = "thumb"
case numName = "num_name"
case name, num_name, thumb, play
}
}
@ -37,14 +30,15 @@ final class ListModel {
struct DramaDetailResponse: Codable {
let name: String
let voice_actors: [VoiceActor]
let status: Int
let summary: String
let thumb: String
let status: [String]
let channels: [Channel]
}
var name: String = ""
var voiceActors: [VoiceActor] = []
var status: Int = 0
var summary: String = ""
var thumb: String = ""
var channels: [Channel] = []
// channel
@ -52,16 +46,14 @@ final class ListModel {
var selectedEpisodes: [Episode] = []
@MainActor
func loadData(dramaId: Int) async {
let response = await API.getDramaDetail(as: DramaDetailResponse.self)
func loadData(userId: Int, 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):
self.name = detail.name
self.voiceActors = detail.voice_actors
self.status = detail.status
self.channels = detail.channels
self.selectedChannelIdx = 0
@ -78,7 +70,8 @@ final class ListModel {
struct ListView: View {
@Environment(\.presentationMode) var presentationMode
@State var detailModel = DetailModel()
@State var detailModel = ListModel()
let id: Int
var body: some View {
VStack(alignment: .center, spacing: 20) {
@ -117,7 +110,7 @@ struct ListView: View {
//
ScrollView(.vertical, showsIndicators: false) {
VStack(alignment: .center, spacing: 15) {
ForEach(detailModel.selectedEpisodes, id: \.id) { episode in
ForEach(detailModel.selectedEpisodes) { episode in
HStack(alignment: .center) {
AsyncImage(url: URL(string: episode.thumb)) { image in
image.resizable()
@ -127,7 +120,7 @@ struct ListView: View {
.frame(width: 90, height: 60)
VStack(alignment: .leading, spacing: 20) {
Text(episode.numName)
Text(episode.num_name)
.font(.system(size: 12))
.foregroundColor(Color(hex: "#333333"))
@ -165,12 +158,12 @@ struct ListView: View {
}
.frame(width: 370, alignment: .center)
.task {
await detailModel.loadData(dramaId: 124)
await detailModel.loadData(userId: 1, id: self.id)
}
}
}
#Preview {
ListView()
ListView(id: 19625)
}