feat: rewrite bootstrap, fix CloudKit sync, update canonical data, and UI fixes
- Rewrite BootstrapService: remove all legacy code paths (JSONStadium, JSONGame, bootstrapStadiumsLegacy, bootstrapGamesLegacy, venue aliases, createDefaultLeagueStructure), require canonical JSON files only - Add clearCanonicalData() to handle partial bootstrap recovery (prevents duplicate key crashes from interrupted first-launch) - Fix nullable stadium_canonical_id in games (4 MLS games have null) - Fix CKModels: logoUrl case, conference/division field keys - Fix CanonicalSyncService: sync conferenceCanonicalId/divisionCanonicalId - Add sports_canonical.json and DemoMode.swift - Delete legacy stadiums.json and games.json - Update all canonical resource JSON files with latest data - Fix TripWizardView horizontal scrolling with GeometryReader constraint - Update RegionMapSelector, TripDetailView, TripOptionsView UI improvements - Add DateRangePicker, PlanningModeStep, SportsStep enhancements - Update UI tests and marketing-videos config Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
71
SportsTime/Core/Theme/DemoMode.swift
Normal file
71
SportsTime/Core/Theme/DemoMode.swift
Normal file
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// DemoMode.swift
|
||||
// SportsTime
|
||||
//
|
||||
// Environment key and configuration for automated demo mode.
|
||||
// When enabled, UI elements auto-select as they scroll into view.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
// MARK: - Demo Mode Environment Key
|
||||
|
||||
private struct DemoModeKey: EnvironmentKey {
|
||||
static let defaultValue = false
|
||||
}
|
||||
|
||||
extension EnvironmentValues {
|
||||
var isDemoMode: Bool {
|
||||
get { self[DemoModeKey.self] }
|
||||
set { self[DemoModeKey.self] = newValue }
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Demo Mode Configuration
|
||||
|
||||
/// Configuration for the demo flow
|
||||
enum DemoConfig {
|
||||
/// Delay before auto-selecting an item (seconds)
|
||||
static let selectionDelay: Double = 0.5
|
||||
|
||||
/// Demo mode date selections
|
||||
static let demoStartDate: Date = {
|
||||
var components = DateComponents()
|
||||
components.year = 2026
|
||||
components.month = 6
|
||||
components.day = 11
|
||||
return Calendar.current.date(from: components) ?? Date()
|
||||
}()
|
||||
|
||||
static let demoEndDate: Date = {
|
||||
var components = DateComponents()
|
||||
components.year = 2026
|
||||
components.month = 6
|
||||
components.day = 16
|
||||
return Calendar.current.date(from: components) ?? Date()
|
||||
}()
|
||||
|
||||
/// Demo mode planning mode selection
|
||||
static let demoPlanningMode: PlanningMode = .dateRange
|
||||
|
||||
/// Demo mode sport selection
|
||||
static let demoSport: Sport = .mlb
|
||||
|
||||
/// Demo mode region selection
|
||||
static let demoRegion: Region = .central
|
||||
|
||||
/// Demo mode sort option
|
||||
static let demoSortOption: TripSortOption = .mostGames
|
||||
|
||||
/// Demo mode trip index to select (0-indexed)
|
||||
static let demoTripIndex: Int = 3
|
||||
}
|
||||
|
||||
// MARK: - Demo Mode Launch Argument
|
||||
|
||||
extension ProcessInfo {
|
||||
/// Check if app was launched in demo mode
|
||||
static var isDemoMode: Bool {
|
||||
ProcessInfo.processInfo.arguments.contains("-DemoMode")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user