diff --git a/SportsTime/Features/Trip/ViewModels/TripCreationViewModel.swift b/SportsTime/Features/Trip/ViewModels/TripCreationViewModel.swift index 25b440d..28a15b2 100644 --- a/SportsTime/Features/Trip/ViewModels/TripCreationViewModel.swift +++ b/SportsTime/Features/Trip/ViewModels/TripCreationViewModel.swift @@ -112,6 +112,28 @@ final class TripCreationViewModel { var availableGames: [RichGame] = [] var isLoadingGames: Bool = false + // MARK: - Game Pagination + private let gamePageSize = 50 + var displayedAvailableGames: [RichGame] = [] + private var currentGamePage = 0 + + var hasMoreAvailableGames: Bool { + displayedAvailableGames.count < availableGames.count + } + + func loadInitialAvailableGames() { + currentGamePage = 0 + displayedAvailableGames = Array(availableGames.prefix(gamePageSize)) + } + + func loadMoreAvailableGames() { + guard hasMoreAvailableGames else { return } + currentGamePage += 1 + let start = currentGamePage * gamePageSize + let end = min(start + gamePageSize, availableGames.count) + displayedAvailableGames.append(contentsOf: availableGames[start.. + 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()