This commit is contained in:
anlicheng 2025-02-20 23:09:16 +08:00
parent d2aeacd8b8
commit 6b477486c2
2 changed files with 112 additions and 59 deletions

View File

@ -5,7 +5,10 @@
// Created by on 2025/2/20.
//
//
//
//
struct DateModel: Codable {
struct Month: Codable {
let name: String

View File

@ -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()