Stabilize beta release with warning cleanup and edge-case fixes
This commit is contained in:
@@ -58,7 +58,8 @@ enum RouteFilters {
|
||||
var cityDays: [String: Set<Date>] = [:]
|
||||
|
||||
for stop in option.stops {
|
||||
let city = stop.city
|
||||
let city = normalizedCityKey(stop.city)
|
||||
guard !city.isEmpty else { continue }
|
||||
let day = calendar.startOfDay(for: stop.arrivalDate)
|
||||
cityDays[city, default: []].insert(day)
|
||||
}
|
||||
@@ -83,18 +84,34 @@ enum RouteFilters {
|
||||
|
||||
for option in options {
|
||||
var cityDays: [String: Set<Date>] = [:]
|
||||
var displayNames: [String: String] = [:]
|
||||
for stop in option.stops {
|
||||
let normalized = normalizedCityKey(stop.city)
|
||||
guard !normalized.isEmpty else { continue }
|
||||
|
||||
if displayNames[normalized] == nil {
|
||||
displayNames[normalized] = stop.city
|
||||
}
|
||||
let day = calendar.startOfDay(for: stop.arrivalDate)
|
||||
cityDays[stop.city, default: []].insert(day)
|
||||
cityDays[normalized, default: []].insert(day)
|
||||
}
|
||||
for (city, days) in cityDays where days.count > 1 {
|
||||
violatingCities.insert(city)
|
||||
for (normalized, days) in cityDays where days.count > 1 {
|
||||
violatingCities.insert(displayNames[normalized] ?? normalized)
|
||||
}
|
||||
}
|
||||
|
||||
return Array(violatingCities).sorted()
|
||||
}
|
||||
|
||||
private static func normalizedCityKey(_ city: String) -> String {
|
||||
let cityPart = city.split(separator: ",", maxSplits: 1).first.map(String.init) ?? city
|
||||
return cityPart
|
||||
.lowercased()
|
||||
.replacingOccurrences(of: ".", with: "")
|
||||
.split(whereSeparator: \.isWhitespace)
|
||||
.joined(separator: " ")
|
||||
}
|
||||
|
||||
// MARK: - Trip List Filters
|
||||
|
||||
/// Filters trips by sport.
|
||||
@@ -133,8 +150,11 @@ enum RouteFilters {
|
||||
/// - Uses calendar start-of-day for comparison
|
||||
static func filterByDateRange(_ trips: [Trip], start: Date, end: Date) -> [Trip] {
|
||||
let calendar = Calendar.current
|
||||
let rangeStart = calendar.startOfDay(for: start)
|
||||
let rangeEnd = calendar.startOfDay(for: end)
|
||||
// Be tolerant of inverted inputs from UI/state restores by normalizing bounds.
|
||||
let normalizedStart = min(start, end)
|
||||
let normalizedEnd = max(start, end)
|
||||
let rangeStart = calendar.startOfDay(for: normalizedStart)
|
||||
let rangeEnd = calendar.startOfDay(for: normalizedEnd)
|
||||
|
||||
return trips.filter { trip in
|
||||
let tripStart = calendar.startOfDay(for: trip.startDate)
|
||||
|
||||
@@ -270,7 +270,7 @@ final class ScenarioAPlanner: ScenarioPlanner {
|
||||
travelSegments: itinerary.travelSegments,
|
||||
totalDrivingHours: itinerary.totalDrivingHours,
|
||||
totalDistanceMiles: itinerary.totalDistanceMiles,
|
||||
geographicRationale: "\(stops.count) games: \(cities)"
|
||||
geographicRationale: "\(routeGames.count) games: \(cities)"
|
||||
)
|
||||
itineraryOptions.append(option)
|
||||
}
|
||||
|
||||
@@ -298,16 +298,9 @@ final class ScenarioBPlanner: ScenarioPlanner {
|
||||
to: lastGameDate
|
||||
).day ?? 0
|
||||
|
||||
// If selected games span more days than trip duration, can't fit
|
||||
// If selected games span more days than trip duration, no valid window exists.
|
||||
if gameSpanDays >= duration {
|
||||
// Just return one window that exactly covers the games
|
||||
let start = firstGameDate
|
||||
let end = Calendar.current.date(
|
||||
byAdding: .day,
|
||||
value: gameSpanDays + 1,
|
||||
to: start
|
||||
) ?? lastGameDate
|
||||
return [DateInterval(start: start, end: end)]
|
||||
return []
|
||||
}
|
||||
|
||||
// Generate sliding windows
|
||||
|
||||
Reference in New Issue
Block a user