perf: add pagination to schedule list

Loads 50 games at a time to fix lag with large datasets.

- Add pagination state (displayedGames, currentPage, allFilteredGames)
- Add loadInitialGames() and loadMoreGames() methods
- Update gamesBySport to use displayedGames
- Add infinite scroll trigger via onAppear on last game
- Add ProgressView indicator when more games available
- Reset pagination when search text changes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-01-12 19:07:54 -06:00
parent 3530b31cca
commit 746b56bc77
2 changed files with 66 additions and 3 deletions

View File

@@ -12,11 +12,11 @@ struct ScheduleListView: View {
var body: some View {
Group {
if viewModel.isLoading && viewModel.games.isEmpty {
if viewModel.isLoading && viewModel.displayedGames.isEmpty {
loadingView
} else if let errorMessage = viewModel.errorMessage {
errorView(message: errorMessage)
} else if viewModel.games.isEmpty {
} else if viewModel.displayedGames.isEmpty {
emptyView
} else {
gamesList
@@ -58,6 +58,9 @@ struct ScheduleListView: View {
.task {
await viewModel.loadGames()
}
.onChange(of: viewModel.searchText) {
viewModel.updateFilteredGames()
}
}
// MARK: - Sport Filter
@@ -93,6 +96,12 @@ struct ScheduleListView: View {
Section {
ForEach(sportGroup.games) { richGame in
GameRowView(game: richGame, showDate: true, showLocation: true)
.onAppear {
// Trigger load more when the last game appears
if richGame.id == viewModel.lastDisplayedGame?.id {
viewModel.loadMoreGames()
}
}
}
} header: {
HStack(spacing: 8) {
@@ -103,6 +112,18 @@ struct ScheduleListView: View {
}
.listRowBackground(Theme.cardBackground(colorScheme))
}
// Show loading indicator when more games are available
if viewModel.hasMoreGames {
Section {
HStack {
Spacer()
ProgressView()
Spacer()
}
.listRowBackground(Color.clear)
}
}
}
.listStyle(.plain)
.scrollContentBackground(.hidden)