Files
ddys-client/DDYSClient/ViewModels/BrowseViewModel.swift
2026-02-26 22:15:35 +08:00

99 lines
2.8 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.

import Foundation
@Observable
final class BrowseViewModel {
var items: [ContentItem] = []
var category: ContentCategory = .movie
var filter = FilterState()
var currentPage = 1
var totalPages = 1
var isLoading = false
var isLoadingMore = false
var error: String?
private var cacheKey: String {
"\(category.rawValue)_\(filter.sort)_\(filter.genre)_\(filter.region)_\(filter.year)"
}
var hasData: Bool {
!items.isEmpty
}
@MainActor
func loadContentIfNeeded() async {
if hasData && !ContentCache.shared.isExpired(key: cacheKey) {
return
}
await loadContent()
}
@MainActor
func loadContent() async {
isLoading = true
error = nil
currentPage = 1
totalPages = 1
items = []
do {
let html = try await APIClient.shared.fetchCategoryPage(
category: category,
page: 1,
filter: filter
)
let newItems = try HTMLParser.parseContentList(html: html, defaultCategory: category)
let pagination = try HTMLParser.parsePagination(html: html)
self.items = newItems
self.currentPage = pagination.current
self.totalPages = pagination.total
ContentCache.shared.markFresh(key: cacheKey)
} catch is CancellationError {
} catch let error as URLError where error.code == .cancelled {
} catch {
self.error = error.localizedDescription
}
isLoading = false
}
@MainActor
func loadMore() async {
guard !isLoadingMore, !isLoading, currentPage < totalPages else { return }
isLoadingMore = true
let nextPage = currentPage + 1
do {
let html = try await APIClient.shared.fetchCategoryPage(
category: category,
page: nextPage,
filter: filter
)
let newItems = try HTMLParser.parseContentList(html: html, defaultCategory: category)
let pagination = try HTMLParser.parsePagination(html: html)
self.items.append(contentsOf: newItems)
self.currentPage = pagination.current
self.totalPages = pagination.total
} catch is CancellationError {
} catch let error as URLError where error.code == .cancelled {
} catch {
//
}
isLoadingMore = false
}
func changeCategory(_ newCategory: ContentCategory) async {
category = newCategory
filter = FilterState()
await loadContentIfNeeded()
}
func applyFilter(_ newFilter: FilterState) async {
filter = newFilter
await loadContent()
}
}