66 lines
1.8 KiB
Swift
66 lines
1.8 KiB
Swift
import Foundation
|
|
|
|
@Observable
|
|
final class HomeViewModel {
|
|
var recommendedItems: [ContentItem] = []
|
|
var latestItems: [ContentItem] = []
|
|
var hotMovies: [HotMovieItem] = []
|
|
var isLoading = false
|
|
var error: String?
|
|
|
|
private let cacheKey = "home"
|
|
|
|
var hasData: Bool {
|
|
!recommendedItems.isEmpty || !latestItems.isEmpty
|
|
}
|
|
|
|
@MainActor
|
|
func loadHomeIfNeeded() async {
|
|
if hasData && !ContentCache.shared.isExpired(key: cacheKey) {
|
|
return
|
|
}
|
|
await loadHome()
|
|
}
|
|
|
|
@MainActor
|
|
func loadHome() async {
|
|
isLoading = true
|
|
error = nil
|
|
|
|
await withTaskGroup(of: Void.self) { group in
|
|
group.addTask { await self.loadHomePage() }
|
|
group.addTask { await self.loadHotMovies() }
|
|
}
|
|
|
|
if error == nil && hasData {
|
|
ContentCache.shared.markFresh(key: cacheKey)
|
|
}
|
|
|
|
isLoading = false
|
|
}
|
|
|
|
private func loadHomePage() async {
|
|
do {
|
|
let html = try await APIClient.shared.fetchHomePage()
|
|
let sections = try HTMLParser.parseHomeSections(html: html)
|
|
await MainActor.run {
|
|
if sections.count > 0 { self.recommendedItems = sections[0] }
|
|
if sections.count > 1 { self.latestItems = sections[1] }
|
|
}
|
|
} catch is CancellationError {
|
|
} catch let error as URLError where error.code == .cancelled {
|
|
} catch {
|
|
await MainActor.run { self.error = error.localizedDescription }
|
|
}
|
|
}
|
|
|
|
private func loadHotMovies() async {
|
|
do {
|
|
let movies = try await APIClient.shared.fetchHotMovies()
|
|
await MainActor.run { self.hotMovies = movies }
|
|
} catch {
|
|
// 热门 API 失败不影响主页显示
|
|
}
|
|
}
|
|
}
|