Compare commits

..

No commits in common. "bf420b748073176f06024b629561ba4925028b0d" and "0543d43ba593ca36b4334842859453a489a3cc25" have entirely different histories.

5 changed files with 34 additions and 87 deletions

View file

@ -3,7 +3,7 @@ format_version = 2
[apps.AmtrakStatus] [apps.AmtrakStatus]
identifier = 'com.tonybark.AmtrakStatus' identifier = 'com.tonybark.AmtrakStatus'
product = 'AmtrakStatus' product = 'AmtrakStatus'
version = '0.2.103' version = '0.2.102'
icon = "./assets/icon.png" icon = "./assets/icon.png"

View file

@ -26,26 +26,13 @@ struct AmtrakDateFormatting {
return isoFormatter.date(from: isoString) return isoFormatter.date(from: isoString)
} }
func time(from isoString: String?, timeZone: TimeZone?, relativeTo otherZone: TimeZone? = nil) -> String? { func time(from isoString: String?, timeZone: TimeZone? = nil) -> String? {
guard let isoString, !isoString.isEmpty, let date = isoFormatter.date( guard let isoString, !isoString.isEmpty, let date = isoFormatter.date(
from: isoString) else { from: isoString) else {
return nil return nil
} }
timeFormatter.timeZone = timeZone timeFormatter.timeZone = timeZone
return timeFormatter.string(from: date)
let formatted = timeFormatter.string(from: date)
guard
let timeZone,
let otherZone,
timeZone.identifier != otherZone.identifier,
let abbreviation = timeZone.abbreviation(for: date)
else {
return formatted
}
return "\(formatted) \(abbreviation)"
} }
func localTime(timeZone: TimeZone?) -> String { func localTime(timeZone: TimeZone?) -> String {

View file

@ -51,12 +51,11 @@ struct ContentView: View {
} }
Table(rows) { Table(rows) {
TableColumn("Time", value: \TrainStatusRow.time) TableColumn("Time", value: \TrainStatusRow.arrival)
TableColumn("Number", value: \TrainStatusRow.trainNum) TableColumn("Number", value: \TrainStatusRow.trainNum)
TableColumn("", value: \TrainStatusRow.presence.rawValue) TableColumn("Train", value: \TrainStatusRow.routeName)
TableColumn("Train", value: \TrainStatusRow.train) TableColumn("To", value: \TrainStatusRow.destination)
TableColumn("To", value: \TrainStatusRow.to) TableColumn("From", value: \TrainStatusRow.origin)
TableColumn("From", value: \TrainStatusRow.from)
TableColumn("Status") { TableColumn("Status") {
(row: TrainStatusRow) in (row: TrainStatusRow) in
ZStack { ZStack {
@ -68,7 +67,7 @@ struct ContentView: View {
) )
} }
} }
TableColumn("Track", value: \TrainStatusRow.track) TableColumn("Track", value: \TrainStatusRow.platform)
}.frame(minWidth: 600) }.frame(minWidth: 600)
.overlay(alignment: .bottomTrailing) { .overlay(alignment: .bottomTrailing) {
if isLoading { if isLoading {
@ -136,8 +135,6 @@ struct ContentView: View {
return return
} }
var zoneCache: [String: TimeZone?] = [code: lookup.timeZone]
var newRows: [TrainStatusRow] = [] var newRows: [TrainStatusRow] = []
for number in lookup.trainNumbers { for number in lookup.trainNumbers {
let trains = try await client.fetchAllTrainStatus(num: number) let trains = try await client.fetchAllTrainStatus(num: number)
@ -146,13 +143,12 @@ struct ContentView: View {
where: { $0.code == code where: { $0.code == code
}, },
)?.platform )?.platform
await newRows newRows
.append( .append(
trainStatus( trainStatus(
for: train, for: train,
atStationCode: code, atStationCode: code,
timeZone: lookup.timeZone, timeZone: lookup.timeZone
zoneCache: &zoneCache
) )
) )
} }
@ -190,65 +186,30 @@ struct ContentView: View {
} }
} }
func trainStatus( func trainStatus(for train: Train, atStationCode code: String, timeZone: TimeZone?) -> TrainStatusRow {
for train: Train,
atStationCode code: String,
timeZone: TimeZone?,
zoneCache: inout [String: TimeZone?]
) async -> TrainStatusRow {
let leg = train.stations?.first { $0.code == code } let leg = train.stations?.first { $0.code == code }
let stationName = leg?.name ?? unknown let stationName = leg?.name ?? unknown
let track = leg?.platform ?? "" let arrival = amtrakDate.time(from: leg?.arr, timeZone: timeZone) ?? amtrakDate.time(
var originZone: TimeZone?
if let orgCode = train.origCode {
originZone = await fetchTimeZone(
forStationCode: orgCode,
cache: &zoneCache
)
}
let time = amtrakDate.time(
from: leg?.arr,
timeZone: timeZone,
relativeTo: originZone
) ?? amtrakDate.time(
from: leg?.schArr, from: leg?.schArr,
timeZone: timeZone, timeZone: timeZone)
relativeTo: originZone let depature = amtrakDate.time(from: leg?.dep, timeZone: timeZone) ?? amtrakDate.time(
) from: leg?.schDep,
timeZone: timeZone)
currentStation = stationName currentStation = stationName
localTimeZone = timeZone localTimeZone = timeZone
return TrainStatusRow( return TrainStatusRow(
trainID: train.trainID, trainID: train.trainID,
time: time ?? "",
trainNum: train.trainNum, trainNum: train.trainNum,
presence: leg?.status ?? .unknown, // Yeah... It's a little confusing routeName: train.routeName,
train: train.routeName, status: isOnTime(arr: leg?.arr, schArr: leg?.schArr),
to: train.destName, platform: leg?.platform ?? "",
from: train.origName, arrival: arrival ?? "",
status: isOnTime( departure: depature ?? "",
arr: leg?.arr, origin: train.origName,
schArr: leg?.schArr destination: train.destName,
), // serviceDate: train.serviceDate
track: track.isEmpty ? "" : track
) )
} }
func fetchTimeZone(forStationCode code: String, cache: inout [String: TimeZone?]) async -> TimeZone? {
if let cached = cache[code] {
return cached
}
let zone: TimeZone?
do {
let response = try await client.fetchStation(code: code)
zone = response[code]?.tz.flatMap(TimeZone.init(identifier:))
} catch {
zone = nil
}
return zone
}
} }

View file

@ -90,15 +90,18 @@ typealias TrainResponse = [String: [Train]]
typealias StationResponse = [String: StationMeta] typealias StationResponse = [String: StationMeta]
struct TrainStatusRow: Identifiable { struct TrainStatusRow: Identifiable {
var id: String { trainID } var id: String {
trainID
}
var trainID: String var trainID: String
var time: String
var trainNum: String var trainNum: String
var presence: StationStatus var routeName: String
var train: String
var to: String
var from: String
var status: TrainLateness var status: TrainLateness
var track: String var platform: String
var arrival: String
var departure: String
var origin: String
var destination: String
// var serviceDate: String
} }

View file

@ -1,9 +1,5 @@
# Change Log # Change Log
## 0.2.103
- A new column after number has "Enroute," "Station," and "Departed" status. It's left blank since status is already taken.
## 0.2.102 ## 0.2.102
- The status bar at the bottom now shows ``It is <time> at <station> station``. - The status bar at the bottom now shows ``It is <time> at <station> station``.