diff --git a/dimensionhub/Views/IndexView.swift b/dimensionhub/Views/IndexView.swift index 013be18..ec690d8 100644 --- a/dimensionhub/Views/IndexView.swift +++ b/dimensionhub/Views/IndexView.swift @@ -67,6 +67,10 @@ final class IndexModel { var showUpdateDramas: [UpdateDramaShowItem] var selectedDate: String + // 保存原始的更新数据 + @ObservationIgnored + var updateDramaGroups: [UpdateDramaGroup] = [] + init() { self.dramas = [] self.showUpdateDramas = [] @@ -82,20 +86,34 @@ final class IndexModel { print(message) case .result(let result): self.dramas = result.dramas - self.showUpdateDramas = groupUpdateDramas(updateDramaGroups: result.update_dramas) + self.showUpdateDramas = transformGroupUpdateDramas(updateDramaGroups: result.update_dramas) + self.updateDramaGroups = result.update_dramas } } @MainActor - func loadMoreUpdateDramas(userId: Int, mode: API.LoadMode, id: Int) async { - let response = await API.loadMoreUpdateDramas(userId: userId, mode: mode, id: id, as: [UpdateDramaGroup].self) - if case let .result(groups) = response { - let showItems = groupUpdateDramas(updateDramaGroups: groups) - self.showUpdateDramas.append(contentsOf: showItems) + func loadMoreUpdateDramas(userId: Int, mode: API.LoadMode) async { + let id: Int = 8030 + // TODO 按照id来判断不一定正确,需要借助其他值 + switch mode { + case .prev: + // 查找最小的id + let response = await API.loadMoreUpdateDramas(userId: userId, mode: mode, id: id, as: [UpdateDramaGroup].self) + if case let .result(groups) = response { + self.updateDramaGroups = preappendMergeDramaGroups(groups: self.updateDramaGroups, mergeGroups: groups) + self.showUpdateDramas = transformGroupUpdateDramas(updateDramaGroups: self.updateDramaGroups) + } + case .next: + let response = await API.loadMoreUpdateDramas(userId: userId, mode: mode, id: id, as: [UpdateDramaGroup].self) + if case let .result(groups) = response { + self.updateDramaGroups = appendMergeDramaGroups(groups: self.updateDramaGroups, mergeGroups: groups) + self.showUpdateDramas = transformGroupUpdateDramas(updateDramaGroups: self.updateDramaGroups) + } } } - private func groupUpdateDramas(updateDramaGroups: [UpdateDramaGroup]) -> [UpdateDramaShowItem] { + // 格式化 + private func transformGroupUpdateDramas(updateDramaGroups: [UpdateDramaGroup]) -> [UpdateDramaShowItem] { var updateItems: [UpdateDramaShowItem] = [] updateDramaGroups.forEach { group in updateItems.append(.init(element: .group(group))) @@ -106,16 +124,53 @@ final class IndexModel { return updateItems } + // 合并groups + private func preappendMergeDramaGroups(groups: [UpdateDramaGroup], mergeGroups: [UpdateDramaGroup]) -> [UpdateDramaGroup] { + var targetGroups = groups + + for group in mergeGroups { + if let idx = targetGroups.firstIndex(where: { $0.group_id == group.group_id}) { + var newItems = group.items + newItems.append(contentsOf: targetGroups[idx].items) + + targetGroups[idx] = UpdateDramaGroup(group_id: group.group_id, group_name: group.group_name, items: newItems) + } else { + targetGroups.insert(group, at: 0) + } + } + + return targetGroups + } + + private func appendMergeDramaGroups(groups: [UpdateDramaGroup], mergeGroups: [UpdateDramaGroup]) -> [UpdateDramaGroup] { + var targetGroups = groups + + for group in mergeGroups { + if let idx = targetGroups.firstIndex(where: { $0.group_id == group.group_id}) { + var newItems = targetGroups[idx].items + newItems.append(contentsOf: group.items) + + targetGroups[idx] = UpdateDramaGroup(group_id: group.group_id, group_name: group.group_name, items: newItems) + } else { + targetGroups.append(group) + } + } + + return targetGroups + } + } struct IndexView: View { @Environment(\.modelContext) private var modelContext //@Query private var items: [Item] - @Query private var userModel: [UserModel] + //@Query private var userModel: [UserModel] = [] @State var indexModel = IndexModel() - @State var isLoading: Bool = false - + @State var isMoreLoading: Bool = false + // 前向刷新 + @State var isPrevLoading: Bool = false + // 是否显示日期弹出层 @State private var selectGroupId: String = "" @State private var showDateNavPopover: Bool = false @@ -205,17 +260,17 @@ struct IndexView: View { let frame = geometry.frame(in: .global) let screenBounds = UIScreen.main.bounds - if screenBounds.height - frame.minY > 50 && !isLoading { + if screenBounds.height - frame.minY > 50 && !isMoreLoading { Task { - self.isLoading = true - await self.indexModel.loadMoreUpdateDramas(userId: 1, mode: .next, id: 1234) - self.isLoading = false + self.isMoreLoading = true + await self.indexModel.loadMoreUpdateDramas(userId: 1, mode: .next) + self.isMoreLoading = false } } } }) - if self.isLoading { + if self.isMoreLoading { ProgressView() } } @@ -224,12 +279,23 @@ struct IndexView: View { print("new selected date: " + selectedDate) } } + .refreshable { + guard !self.isPrevLoading else { + return + } + + // 上拉刷新功能 + self.isPrevLoading = true + await self.indexModel.loadMoreUpdateDramas(userId: 1, mode: .prev) + self.isPrevLoading = false + } + } .frame(width: 370) .ignoresSafeArea(edges: .bottom) .task { - //await self.indexModel.loadData() - print(userModel) + await self.indexModel.loadData() + //print(userModel) } } @@ -252,6 +318,15 @@ struct IndexView: View { extension IndexView { + // 自定义 PreferenceKey 用于获取滚动偏移量 + struct ScrollOffsetKey: PreferenceKey { + static var defaultValue: CGFloat = 0 + + static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) { + value = nextValue() + } + } + // 显示剧集的列表信息 struct DramaCellView: View { let dramaItem: IndexModel.DramaItem diff --git a/dimensionhub/dimensionhubApp.swift b/dimensionhub/dimensionhubApp.swift index 32c60b9..a7823a7 100644 --- a/dimensionhub/dimensionhubApp.swift +++ b/dimensionhub/dimensionhubApp.swift @@ -12,7 +12,6 @@ import SwiftData struct dimensionhubApp: App { var sharedModelContainer: ModelContainer = { let schema = Schema([ - Item.self, UserModel.self ]) let modelConfiguration = ModelConfiguration( @@ -29,6 +28,7 @@ struct dimensionhubApp: App { descriptor.fetchLimit = 1 let users = try container.mainContext.fetch(descriptor) if users.isEmpty { + print("user is empty create user") container.mainContext.insert(UserModel.defaultUser()) }