mirror of
https://github.com/tonytins/amtkstat.git
synced 2026-10-24 13:42:51 -04:00
Compare commits
No commits in common. "bf420b748073176f06024b629561ba4925028b0d" and "0543d43ba593ca36b4334842859453a489a3cc25" have entirely different histories.
bf420b7480
...
0543d43ba5
5 changed files with 34 additions and 87 deletions
|
|
@ -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"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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``.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue