From 6b477486c2f8ead56ef5ccdc48c12e0913f9816f Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Thu, 20 Feb 2025 23:09:16 +0800 Subject: [PATCH] fix --- dimensionhub/Core/DataModels.swift | 5 +- dimensionhub/Views/IndexView.swift | 166 +++++++++++++++++++---------- 2 files changed, 112 insertions(+), 59 deletions(-) diff --git a/dimensionhub/Core/DataModels.swift b/dimensionhub/Core/DataModels.swift index 59430cf..3c7f115 100644 --- a/dimensionhub/Core/DataModels.swift +++ b/dimensionhub/Core/DataModels.swift @@ -5,7 +5,10 @@ // Created by 安礼成 on 2025/2/20. // -// 处理数据模型 +// 首页 + + +// 日期弹出层 struct DateModel: Codable { struct Month: Codable { let name: String diff --git a/dimensionhub/Views/IndexView.swift b/dimensionhub/Views/IndexView.swift index a3bb737..ebae460 100644 --- a/dimensionhub/Views/IndexView.swift +++ b/dimensionhub/Views/IndexView.swift @@ -7,10 +7,10 @@ import SwiftUI import SwiftData +import Observation -struct IndexView: View { - @Environment(\.modelContext) private var modelContext - @Query private var items: [Item] +@Observable +final class IndexModel { struct DramaItem: Codable { struct Episode: Codable { @@ -27,29 +27,88 @@ struct IndexView: View { } } + let id: Int32 let title: String let episodes: [Episode] } - + struct UpdateDramaItem: Codable { + let id: Int let name: String let thumb: String let desc: String let datetime: String } - enum UpdateDramaShowItem { - case lable(String) - case item(UpdateDramaItem) - } - struct IndexResponse: Codable { let updateDramas: [UpdateDramaItem] let dramas: [DramaItem] } - @State var dramas: [DramaItem] = [] - @State var showUpdateDramas: [UpdateDramaShowItem] = [] + struct UpdateDramaShowItem: Identifiable { + enum Element { + case lable(String) + case item(UpdateDramaItem) + } + + let id = UUID() + let element: Element + + init(element: Element) { + self.element = element + } + } + + var dramas: [DramaItem] + var showUpdateDramas: [UpdateDramaShowItem] + + init() { + self.dramas = [] + self.showUpdateDramas = [] + } + + @MainActor + func loadData() async { + let response = await API.getIndexData(as: IndexResponse.self) + switch response { + case .error(let code, let message): + print(code) + print(message) + case .result(let result): + print(result) + self.dramas = result.dramas + self.showUpdateDramas = groupUpdateDramas(updateDramas: result.updateDramas) + } + } + + @MainActor + func loadMoreUpdateDramas() async { + let response = await API.loadMoreUpdateDramas(as: [UpdateDramaItem].self) + if case let .result(items) = response { + let showItems = groupUpdateDramas(updateDramas: items) + self.showUpdateDramas.append(contentsOf: showItems) + } + } + + private func groupUpdateDramas(updateDramas: [UpdateDramaItem]) -> [UpdateDramaShowItem] { + let groups = Dictionary(grouping: updateDramas) {$0.datetime} + var updateItems: [UpdateDramaShowItem] = [] + groups.forEach { (key, items) in + updateItems.append(.init(element: .lable(key))) + items.forEach { item in + updateItems.append(.init(element: .item(item))) + } + } + return updateItems + } + +} + +struct IndexView: View { + @Environment(\.modelContext) private var modelContext + @Query private var items: [Item] + + @State var indexModel = IndexModel() @State var isLoading: Bool = false // 是否显示日期弹出层 @@ -72,16 +131,41 @@ struct IndexView: View { .font(.system(size: 24)) } - ForEach(dramas.indices, id: \.self) { id in - DramaCellView(dramaItem: dramas[id]) + ForEach(indexModel.dramas, id: \.id) { drama in + DramaCellView(dramaItem: drama) } // 基于日期的更新列表 ScrollView(.vertical, showsIndicators: false) { LazyVStack { - ForEach(showUpdateDramas.indices, id: \.self) { index in - UpdateDramaCellView(showItem: showUpdateDramas[index], showDateNavPopover: $showDateNavPopover) + ForEach(indexModel.showUpdateDramas, id: \.id) { drama in + switch drama.element { + case .lable(let name): + Text(name) + .onTapGesture { + showDateNavPopover = true + } + case .item(let item): + VStack(alignment: .center) { + AsyncImage(url: URL(string: item.thumb)) { image in + image.resizable() + } placeholder: { + ProgressView() + } + .frame(width: 80, height: 80) + .overlay { + VStack(alignment: .leading) { + Text(item.name) + .lineLimit(1) + + Text(item.desc) + .lineLimit(1) + } + } + } + .frame(width: 100, height: 120) + } } } @@ -95,7 +179,9 @@ struct IndexView: View { if screenBounds.height - frame.minY > 50 && !isLoading { Task { - await self.loadMoreUpdateDramas() + self.isLoading = true + await self.indexModel.loadMoreUpdateDramas() + self.isLoading = false } } } @@ -110,35 +196,9 @@ struct IndexView: View { } } .task { - let response = await API.getIndexData(as: IndexResponse.self) - switch response { - case .error(let code, let message): - print(code) - print(message) - case .result(let result): - print(result) - self.dramas = result.dramas - self.showUpdateDramas = Self.yes(updateDramas: result.updateDramas) - } + await self.indexModel.loadData() } } - - @MainActor - private func loadMoreUpdateDramas() async { - guard !self.isLoading else { - return - } - - self.isLoading = true - - let response = await API.loadMoreUpdateDramas(as: [UpdateDramaItem].self) - if case let .result(items) = response { - let showItems = Self.yes(updateDramas: items) - self.showUpdateDramas.append(contentsOf: showItems) - } - - self.isLoading = false - } private func addItem() { withAnimation { @@ -155,24 +215,13 @@ struct IndexView: View { } } - private static func yes(updateDramas: [UpdateDramaItem]) -> [UpdateDramaShowItem] { - let groups = Dictionary(grouping: updateDramas) {$0.datetime} - var updateItems: [UpdateDramaShowItem] = [] - groups.forEach { (key, items) in - updateItems.append(.lable(key)) - items.forEach { item in - updateItems.append(.item(item)) - } - } - return updateItems - } } extension IndexView { // 显示剧集的列表信息 struct DramaCellView: View { - let dramaItem: DramaItem + let dramaItem: IndexModel.DramaItem var body: some View { VStack(alignment: .leading) { @@ -207,14 +256,15 @@ extension IndexView { } +/* extension IndexView { struct UpdateDramaCellView: View { - let showItem: UpdateDramaShowItem + let showItem: IndexModel.UpdateDramaShowItem @Binding var showDateNavPopover: Bool var body: some View { - switch showItem { + switch showItem.element { case .lable(let name): Text(name) .onTapGesture { @@ -243,7 +293,7 @@ extension IndexView { } } -} +}*/ #Preview { IndexView()