perf: add pagination to game selection view
Fixes lag and color inconsistency in trip creation game selection. - Add pagination with 50 games per page to TripCreationViewModel - Add displayedAvailableGames, loadInitialAvailableGames, loadMoreAvailableGames - Update GamePickerSheet to use paginated data with infinite scroll trigger - Show "Load more games" button with progress indicator and count Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -114,8 +114,11 @@ struct TripCreationView: View {
|
||||
}
|
||||
.sheet(isPresented: $showGamePicker) {
|
||||
GamePickerSheet(
|
||||
games: viewModel.availableGames,
|
||||
selectedIds: $viewModel.mustSeeGameIds
|
||||
games: viewModel.displayedAvailableGames,
|
||||
selectedIds: $viewModel.mustSeeGameIds,
|
||||
hasMoreGames: viewModel.hasMoreAvailableGames,
|
||||
totalGamesCount: viewModel.availableGames.count,
|
||||
loadMoreGames: { viewModel.loadMoreAvailableGames() }
|
||||
)
|
||||
}
|
||||
.sheet(isPresented: $showCityInput) {
|
||||
@@ -452,6 +455,12 @@ struct TripCreationView: View {
|
||||
.font(.subheadline)
|
||||
.foregroundStyle(Theme.textSecondary(colorScheme))
|
||||
}
|
||||
.onAppear {
|
||||
// Ensure pagination is initialized when view appears
|
||||
if viewModel.displayedAvailableGames.isEmpty && !viewModel.availableGames.isEmpty {
|
||||
viewModel.loadInitialAvailableGames()
|
||||
}
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
@@ -950,6 +959,9 @@ extension TripCreationViewModel.ViewState {
|
||||
struct GamePickerSheet: View {
|
||||
let games: [RichGame]
|
||||
@Binding var selectedIds: Set<String>
|
||||
let hasMoreGames: Bool
|
||||
let totalGamesCount: Int
|
||||
let loadMoreGames: () -> Void
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@Environment(\.colorScheme) private var colorScheme
|
||||
|
||||
@@ -1047,6 +1059,28 @@ struct GamePickerSheet: View {
|
||||
selectedCount: selectedCountForSport(sport)
|
||||
)
|
||||
}
|
||||
|
||||
// Load more indicator with infinite scroll trigger
|
||||
if hasMoreGames {
|
||||
Button {
|
||||
loadMoreGames()
|
||||
} label: {
|
||||
HStack(spacing: Theme.Spacing.sm) {
|
||||
ProgressView()
|
||||
.tint(Theme.warmOrange)
|
||||
Text("Load more games (\(games.count) of \(totalGamesCount))")
|
||||
.font(.subheadline)
|
||||
.foregroundStyle(Theme.textSecondary(colorScheme))
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(Theme.Spacing.md)
|
||||
.background(Theme.cardBackground(colorScheme))
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.onAppear {
|
||||
loadMoreGames()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.themedBackground()
|
||||
|
||||
Reference in New Issue
Block a user