2025-04-08 15:39:28 +08:00

215 lines
7.4 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// IndexModel.swift
// dimensionhub
//
// Created by on 2025/4/8.
//
import Foundation
import Observation
@Observable
final class IndexModel {
struct DramaItem: Codable {
struct Episode: Codable, Identifiable {
let id = UUID().uuidString
let name: String
let thumb: String
let num_name: String
let play: String
enum CodingKeys: String, CodingKey {
case name, thumb, num_name, play
}
}
let id: Int
let title: String
let episodes: [Episode]
}
struct UpdateDramaGroup: Codable {
struct Item: Codable {
let id: Int
let name: String
let time: Int
let thumb: String
let status: String
}
let group_id: String
let group_name: String
let items: [Item]
}
struct IndexResponse: Codable {
let update_dramas: [UpdateDramaGroup]
let follow_num: Int
}
var selectedDate: String
//
var updateDramaGroups: [UpdateDramaGroup] = []
var follow_num: String = "0"
// group_name
var fixedDramaGroup: UpdateDramaGroup? = nil
@ObservationIgnored
private var isLoaded = false
init() {
self.selectedDate = ""
}
func loadData(userId: String) async {
guard !isLoaded else {
return
}
let response = await API.getIndexData(userId: userId, as: IndexResponse.self)
switch response {
case .error(let code, let message):
print("index load data get error_code: \(code), message: \(message)")
case .result(let result):
await MainActor.run {
self.updateDramaGroups = result.update_dramas
self.fixedDramaGroup = result.update_dramas.first
self.follow_num = result.follow_num >= 100 ? "99+" : "\(result.follow_num)"
}
}
self.isLoaded = true
}
func setFixedDrameGroup(groupId: String) {
if let newFixedDramaGroup = self.updateDramaGroups.first(where: {$0.group_id == groupId}),
newFixedDramaGroup.group_id != self.fixedDramaGroup?.group_id {
self.fixedDramaGroup = newFixedDramaGroup
}
}
func loadMoreUpdateDramas(userId: String, mode: API.LoadMode) async {
// id
let dramaIds = self.getDramaIds(self.updateDramaGroups)
print("current ids: \(dramaIds)")
switch mode {
case .prev:
// id
if let firstId = dramaIds.first {
let response = await API.loadMoreUpdateDramas(userId: userId, mode: mode, id: firstId, as: [UpdateDramaGroup].self)
if case let .result(groups) = response {
if groups.count > 0 {
print("--------- before ------------")
displayDramaGroups(self.updateDramaGroups)
await MainActor.run {
self.updateDramaGroups = preappendMergeDramaGroups(groups: self.updateDramaGroups, mergeGroups: groups)
}
print("--------- after ------------")
displayDramaGroups(self.updateDramaGroups)
print("--------- ------------")
}
}
}
case .next:
if let lastId = dramaIds.last {
let response = await API.loadMoreUpdateDramas(userId: userId, mode: mode, id: lastId, as: [UpdateDramaGroup].self)
if case let .result(groups) = response {
if groups.count > 0 {
print("--------- before ------------")
displayDramaGroups(self.updateDramaGroups)
await MainActor.run {
self.updateDramaGroups = appendMergeDramaGroups(groups: self.updateDramaGroups, mergeGroups: groups)
}
print("----------after-----------")
displayDramaGroups(self.updateDramaGroups)
print("---------------------")
}
}
}
}
}
//
func loadDateUpdateDramas(userId: String, date: String) async {
self.updateDramaGroups.removeAll()
let response = await API.loadDateUpdateDramas(userId: userId, date: date, as: [UpdateDramaGroup].self)
if case let .result(groups) = response {
await MainActor.run {
self.updateDramaGroups = groups
self.fixedDramaGroup = groups.first
}
}
}
// 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 sortDramaGroups(groups: 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 sortDramaGroups(groups: targetGroups)
}
//
private func sortDramaGroups(groups: [UpdateDramaGroup]) -> [UpdateDramaGroup] {
return groups.sorted { g0, g1 in
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM"
if let date0 = dateFormatter.date(from: g0.group_id),
let date1 = dateFormatter.date(from: g1.group_id) {
return date0 > date1
} else {
return g0.group_id > g1.group_id
}
}
}
private func getDramaIds(_ updateDramaGroups: [UpdateDramaGroup]) -> [Int] {
return self.updateDramaGroups.flatMap { group in
return group.items.map { item in
return item.id
}
}
}
private func displayDramaGroups(_ groups: [UpdateDramaGroup]) {
for group in groups {
let ids = group.items.map { $0.id}
print("group_id: \(group.group_id), items: \(ids)")
}
}
}