import SwiftUI struct HomeView: View { var viewModel: HomeViewModel @State private var searchText = "" @State private var searchViewModel = SearchViewModel() private var showingSearchResults: Bool { searchViewModel.hasSearched } var body: some View { Group { if !viewModel.hasData && viewModel.error == nil && !showingSearchResults { ProgressView() .frame(maxWidth: .infinity, maxHeight: .infinity) } else if showingSearchResults && searchViewModel.isSearching { ProgressView() .frame(maxWidth: .infinity, maxHeight: .infinity) } else { ScrollView { if showingSearchResults { searchContent } else { homeContent } } } } .navigationTitle("低端影视") .navigationDestination(for: ContentItem.self) { item in DetailView(item: item) } .searchable(text: $searchText, prompt: "搜索电影、电视剧...") .onSubmit(of: .search) { let trimmed = searchText.trimmingCharacters(in: .whitespacesAndNewlines) guard !trimmed.isEmpty else { return } Task { searchViewModel.query = trimmed await searchViewModel.search() } } .onChange(of: searchText) { _, newValue in if newValue.isEmpty { searchViewModel.clear() } } .refreshable { if showingSearchResults { await searchViewModel.search() } else { await viewModel.loadHome() } } .task { await viewModel.loadHomeIfNeeded() } } // MARK: - 首页内容 @ViewBuilder private var homeContent: some View { if let error = viewModel.error { errorView(error) } else { LazyVStack(alignment: .leading, spacing: 24) { if !viewModel.recommendedItems.isEmpty { sectionHeader("热门推荐") ScrollView(.horizontal, showsIndicators: false) { LazyHStack(spacing: 12) { ForEach(viewModel.recommendedItems) { item in NavigationLink(value: item) { ContentCardView(item: item) } .buttonStyle(.plain) } } .padding(.horizontal) } } if !viewModel.latestItems.isEmpty { sectionHeader("最新更新") ContentGridView(items: viewModel.latestItems) .padding(.horizontal) } } .padding(.vertical) } } // MARK: - 搜索结果 @ViewBuilder private var searchContent: some View { if let error = searchViewModel.error { VStack(spacing: 16) { Image(systemName: "exclamationmark.triangle") .font(.system(size: 48)) .foregroundStyle(.secondary) Text(error) .foregroundStyle(.secondary) Button("重试") { Task { await searchViewModel.search() } } } .frame(maxWidth: .infinity, minHeight: 300) } else if searchViewModel.results.isEmpty { VStack(spacing: 12) { Image(systemName: "magnifyingglass") .font(.system(size: 48)) .foregroundStyle(.secondary) Text("未找到「\(searchViewModel.query)」的相关内容") .foregroundStyle(.secondary) } .frame(maxWidth: .infinity, minHeight: 300) } else { LazyVStack(alignment: .leading, spacing: 16) { Text("搜索结果") .font(.title2) .fontWeight(.bold) .padding(.horizontal) ContentGridView(items: searchViewModel.results) { Task { await searchViewModel.loadMore() } } .padding(.horizontal) if searchViewModel.isLoadingMore { ProgressView() .frame(maxWidth: .infinity) .padding() } } .padding(.vertical) } } private func sectionHeader(_ title: String) -> some View { Text(title) .font(.title2) .fontWeight(.bold) .padding(.horizontal) } 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.loadHome() } } } .frame(maxWidth: .infinity, minHeight: 300) } }