Files
ddys-client/DDYSClient/Views/Browse/BrowseView.swift
2026-02-26 22:15:35 +08:00

85 lines
2.8 KiB
Swift

import SwiftUI
struct BrowseView: View {
let category: ContentCategory
@Bindable var viewModel: BrowseViewModel
var body: some View {
Group {
if !viewModel.hasData && viewModel.error == nil {
VStack(spacing: 0) {
FilterBarView(filter: $viewModel.filter) {
Task { await viewModel.applyFilter(viewModel.filter) }
}
.padding(.vertical, 8)
ProgressView()
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
} else {
ScrollView {
VStack(spacing: 0) {
FilterBarView(filter: $viewModel.filter) {
Task { await viewModel.applyFilter(viewModel.filter) }
}
.padding(.vertical, 8)
if let error = viewModel.error {
errorView(error)
} else if viewModel.items.isEmpty {
emptyView
} else {
ContentGridView(items: viewModel.items) {
Task { await viewModel.loadMore() }
}
.padding(.horizontal)
.padding(.top, 8)
if viewModel.isLoadingMore {
ProgressView()
.padding()
}
}
}
}
}
}
.navigationTitle(category.displayName)
.navigationDestination(for: ContentItem.self) { item in
DetailView(item: item)
}
.refreshable {
await viewModel.loadContent()
}
.task {
viewModel.category = category
await viewModel.loadContentIfNeeded()
}
}
private func errorView(_ message: String) -> some View {
VStack(spacing: 16) {
Image(systemName: "exclamationmark.triangle")
.font(.system(size: 48))
.foregroundStyle(.secondary)
Text(message)
.foregroundStyle(.secondary)
Button("重试") {
Task { await viewModel.loadContent() }
}
}
.frame(maxWidth: .infinity, minHeight: 300)
}
private var emptyView: some View {
VStack(spacing: 12) {
Image(systemName: "film.stack")
.font(.system(size: 48))
.foregroundStyle(.secondary)
Text("暂无内容")
.foregroundStyle(.secondary)
}
.frame(maxWidth: .infinity, minHeight: 300)
}
}