133 lines
3.8 KiB
Swift
133 lines
3.8 KiB
Swift
import Foundation
|
|
import Observation
|
|
|
|
@Observable
|
|
@MainActor
|
|
final class LeagueCenterViewModel {
|
|
var scheduleGames: [StatsGame] = []
|
|
var standings: [StandingsDivisionRecord] = []
|
|
var teams: [LeagueTeamSummary] = []
|
|
|
|
var selectedTeam: TeamProfile?
|
|
var roster: [RosterPlayerSummary] = []
|
|
var selectedPlayer: PlayerProfile?
|
|
|
|
var isLoadingOverview = false
|
|
var isLoadingTeam = false
|
|
var isLoadingPlayer = false
|
|
|
|
var overviewErrorMessage: String?
|
|
var teamErrorMessage: String?
|
|
var playerErrorMessage: String?
|
|
|
|
private let statsAPI = MLBStatsAPI()
|
|
private(set) var scheduleDate = Date()
|
|
|
|
private var seasonString: String {
|
|
String(Calendar.current.component(.year, from: scheduleDate))
|
|
}
|
|
|
|
private var scheduleDateString: String {
|
|
Self.scheduleFormatter.string(from: scheduleDate)
|
|
}
|
|
|
|
var displayDateString: String {
|
|
Self.displayFormatter.string(from: scheduleDate)
|
|
}
|
|
|
|
func loadInitial() async {
|
|
isLoadingOverview = true
|
|
overviewErrorMessage = nil
|
|
|
|
async let scheduleTask = statsAPI.fetchSchedule(date: scheduleDateString)
|
|
async let standingsTask = statsAPI.fetchStandingsRecords(season: seasonString)
|
|
async let teamsTask = statsAPI.fetchLeagueTeams(season: seasonString)
|
|
|
|
do {
|
|
scheduleGames = try await scheduleTask
|
|
standings = try await standingsTask
|
|
teams = try await teamsTask
|
|
|
|
if selectedTeam == nil, let firstTeam = teams.first {
|
|
await selectTeam(firstTeam.id)
|
|
}
|
|
} catch {
|
|
overviewErrorMessage = "Failed to load league information."
|
|
}
|
|
|
|
isLoadingOverview = false
|
|
}
|
|
|
|
func goToPreviousDay() async {
|
|
scheduleDate = Calendar.current.date(byAdding: .day, value: -1, to: scheduleDate) ?? scheduleDate
|
|
await loadSchedule()
|
|
}
|
|
|
|
func goToNextDay() async {
|
|
scheduleDate = Calendar.current.date(byAdding: .day, value: 1, to: scheduleDate) ?? scheduleDate
|
|
await loadSchedule()
|
|
}
|
|
|
|
func goToToday() async {
|
|
scheduleDate = Date()
|
|
await loadSchedule()
|
|
}
|
|
|
|
func loadSchedule() async {
|
|
do {
|
|
scheduleGames = try await statsAPI.fetchSchedule(date: scheduleDateString)
|
|
} catch {
|
|
overviewErrorMessage = "Failed to load schedule."
|
|
}
|
|
}
|
|
|
|
func selectTeam(_ teamID: Int) async {
|
|
isLoadingTeam = true
|
|
teamErrorMessage = nil
|
|
selectedPlayer = nil
|
|
playerErrorMessage = nil
|
|
|
|
do {
|
|
async let profileTask = statsAPI.fetchTeamProfile(teamID: teamID, season: seasonString)
|
|
async let rosterTask = statsAPI.fetchTeamRoster(teamID: teamID, season: seasonString)
|
|
|
|
selectedTeam = try await profileTask
|
|
roster = try await rosterTask
|
|
|
|
if let firstPlayer = roster.first {
|
|
await selectPlayer(firstPlayer.id)
|
|
}
|
|
} catch {
|
|
teamErrorMessage = "Failed to load team details."
|
|
roster = []
|
|
}
|
|
|
|
isLoadingTeam = false
|
|
}
|
|
|
|
func selectPlayer(_ playerID: Int) async {
|
|
isLoadingPlayer = true
|
|
playerErrorMessage = nil
|
|
|
|
do {
|
|
selectedPlayer = try await statsAPI.fetchPlayerProfile(personID: playerID, season: seasonString)
|
|
} catch {
|
|
playerErrorMessage = "Failed to load player details."
|
|
}
|
|
|
|
isLoadingPlayer = false
|
|
}
|
|
|
|
private static let scheduleFormatter: DateFormatter = {
|
|
let formatter = DateFormatter()
|
|
formatter.dateFormat = "yyyy-MM-dd"
|
|
return formatter
|
|
}()
|
|
|
|
private static let displayFormatter: DateFormatter = {
|
|
let formatter = DateFormatter()
|
|
formatter.dateFormat = "EEEE, MMM d"
|
|
return formatter
|
|
}()
|
|
}
|