mirror of
https://github.com/tonytins/amtkstat.git
synced 2026-10-24 05:32:54 -04:00
Compare commits
No commits in common. "bf67475107934e743cdafc54bb46966b2ce35adc" and "6f8cca9dc9374ed870ee86bb24bb1bcfd65414e2" have entirely different histories.
bf67475107
...
6f8cca9dc9
3 changed files with 27 additions and 123 deletions
|
|
@ -1,37 +0,0 @@
|
||||||
import Foundation
|
|
||||||
|
|
||||||
struct AmtrakDateFormatting {
|
|
||||||
static let isoFormatter = ISO8601DateFormatter()
|
|
||||||
|
|
||||||
static let timeFormatter: DateFormatter = {
|
|
||||||
let formatter = DateFormatter()
|
|
||||||
formatter.dateStyle = .none
|
|
||||||
formatter.timeStyle = .short
|
|
||||||
return formatter
|
|
||||||
}()
|
|
||||||
|
|
||||||
static let dateFormatter: DateFormatter = {
|
|
||||||
let formatter = DateFormatter()
|
|
||||||
formatter.dateStyle = .medium
|
|
||||||
formatter.timeStyle = .none
|
|
||||||
return formatter
|
|
||||||
}()
|
|
||||||
|
|
||||||
static func time(from isoString: String?) -> String? {
|
|
||||||
guard let isoString, !isoString.isEmpty, let date = isoFormatter.date(
|
|
||||||
from: isoString) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return timeFormatter.string(from: date)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func date(from isoString: String?) -> String? {
|
|
||||||
guard let isoString, !isoString.isEmpty, let date = isoFormatter.date(
|
|
||||||
from: isoString) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return dateFormatter.string(from: date)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +1,14 @@
|
||||||
import SwiftCrossUI
|
import SwiftCrossUI
|
||||||
import Foundation
|
|
||||||
|
|
||||||
extension Train {
|
extension Train {
|
||||||
var serviceDate: String {
|
var displayNumber: String {
|
||||||
AmtrakDateFormatting.date(from: createdAt) ?? "-"
|
let parts = trainID.split(separator: "-", maxSplits: 1)
|
||||||
|
|
||||||
|
guard parts.count <= 2 else {
|
||||||
|
return trainNum
|
||||||
|
}
|
||||||
|
|
||||||
|
return "\(trainNum) (\(parts[1]))"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -14,9 +19,6 @@ struct ContentView: View {
|
||||||
@State var rows: [TrainStatusRow] = []
|
@State var rows: [TrainStatusRow] = []
|
||||||
@State var isLoading = false
|
@State var isLoading = false
|
||||||
@State var errorMessage: String?
|
@State var errorMessage: String?
|
||||||
@State var currentStation: String = ""
|
|
||||||
|
|
||||||
let unknown = "Unknown"
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
|
|
@ -54,13 +56,11 @@ struct ContentView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
Table(rows) {
|
Table(rows) {
|
||||||
TableColumn("Time", value: \TrainStatusRow.arrival)
|
|
||||||
TableColumn("Number", value: \TrainStatusRow.trainNum)
|
TableColumn("Number", value: \TrainStatusRow.trainNum)
|
||||||
TableColumn("Train", value: \TrainStatusRow.routeName)
|
TableColumn("Route", value: \TrainStatusRow.routeName)
|
||||||
TableColumn("To", value: \TrainStatusRow.origin)
|
TableColumn("Platform", value: \TrainStatusRow.platform)
|
||||||
TableColumn("From", value: \TrainStatusRow.destination)
|
TableColumn("Origin", value: \TrainStatusRow.origin)
|
||||||
TableColumn("Status", value: \TrainStatusRow.status)
|
TableColumn("Destination", value: \TrainStatusRow.destination)
|
||||||
TableColumn("Track", value: \TrainStatusRow.platform)
|
|
||||||
|
|
||||||
}.overlay(alignment: .bottomTrailing) {
|
}.overlay(alignment: .bottomTrailing) {
|
||||||
if isLoading {
|
if isLoading {
|
||||||
|
|
@ -73,8 +73,6 @@ struct ContentView: View {
|
||||||
HStack {
|
HStack {
|
||||||
if let errorMessage {
|
if let errorMessage {
|
||||||
Text(errorMessage)
|
Text(errorMessage)
|
||||||
} else if !currentStation.isEmpty {
|
|
||||||
Text(currentStation)
|
|
||||||
}
|
}
|
||||||
}.padding(10)
|
}.padding(10)
|
||||||
}
|
}
|
||||||
|
|
@ -119,7 +117,17 @@ struct ContentView: View {
|
||||||
where: { $0.code == code
|
where: { $0.code == code
|
||||||
},
|
},
|
||||||
)?.platform
|
)?.platform
|
||||||
newRows.append(trainStatus(for: train, atStationCode: code))
|
|
||||||
|
newRows.append(TrainStatusRow(
|
||||||
|
trainID: train.trainID,
|
||||||
|
trainNum: train.displayNumber,
|
||||||
|
routeName: train.routeName,
|
||||||
|
origin: train.origName,
|
||||||
|
destination: train.destName,
|
||||||
|
platform: (
|
||||||
|
platform?.isEmpty == false,
|
||||||
|
) ? platform! : "",
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -133,43 +141,4 @@ struct ContentView: View {
|
||||||
rows = []
|
rows = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isOnTime(arr: String?, schArr: String?) -> String {
|
|
||||||
let amtrakDate = AmtrakDateFormatting()
|
|
||||||
|
|
||||||
if AmtrakDateFormatting
|
|
||||||
.time(from: arr) != AmtrakDateFormatting
|
|
||||||
.time(from: schArr) {
|
|
||||||
return "Late"
|
|
||||||
}
|
|
||||||
|
|
||||||
return "On Time"
|
|
||||||
}
|
|
||||||
|
|
||||||
func trainStatus(for train: Train, atStationCode code: String) -> TrainStatusRow {
|
|
||||||
let leg = train.stations?.first { $0.code == code }
|
|
||||||
let platform = leg?.platform ?? "-"
|
|
||||||
let stationName = leg?.name ?? unknown
|
|
||||||
let arrival = AmtrakDateFormatting.time(from: leg?.arr) ?? AmtrakDateFormatting.time(
|
|
||||||
from: leg?.schArr
|
|
||||||
)
|
|
||||||
let depature = AmtrakDateFormatting.time(from: leg?.dep) ?? AmtrakDateFormatting.time(
|
|
||||||
from: leg?.schDep
|
|
||||||
)
|
|
||||||
|
|
||||||
currentStation = "\(stationName) station"
|
|
||||||
|
|
||||||
return TrainStatusRow(
|
|
||||||
trainID: train.trainID,
|
|
||||||
trainNum: train.trainNum,
|
|
||||||
routeName: train.routeName,
|
|
||||||
status: isOnTime(arr: leg?.arr, schArr: leg?.schArr),
|
|
||||||
platform: leg?.platform ?? "",
|
|
||||||
arrival: arrival ?? "",
|
|
||||||
departure: depature ?? "",
|
|
||||||
origin: train.origName,
|
|
||||||
destination: train.destName,
|
|
||||||
// serviceDate: train.serviceDate
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,33 +4,9 @@ struct TrainAlert: Codable {
|
||||||
var message: String
|
var message: String
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Station: Codable, Sendable {
|
struct Station: Codable {
|
||||||
var name: String
|
|
||||||
var code: String
|
var code: String
|
||||||
var tz: String
|
var platform: String?
|
||||||
var bus: Bool
|
|
||||||
var schArr: String
|
|
||||||
var schDep: String
|
|
||||||
var arr: String
|
|
||||||
var dep: String
|
|
||||||
var arrCmnt: String
|
|
||||||
var depCmnt: String
|
|
||||||
var status: StationStatus
|
|
||||||
var stopIconColor: String
|
|
||||||
var platform: String
|
|
||||||
}
|
|
||||||
|
|
||||||
enum StationStatus: String, Codable, Sendable {
|
|
||||||
case enroute = "Enroute"
|
|
||||||
case station = "Station"
|
|
||||||
case departed = "Departed"
|
|
||||||
case unknown = "Unknown"
|
|
||||||
|
|
||||||
init(from decoder: any Decoder) throws {
|
|
||||||
let container = try decoder.singleValueContainer()
|
|
||||||
let rawValue = try container.decode(String.self)
|
|
||||||
self = StationStatus(rawValue: rawValue) ?? .unknown
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Train: Codable {
|
struct Train: Codable {
|
||||||
|
|
@ -93,15 +69,11 @@ struct TrainStatusRow: Identifiable {
|
||||||
var id: String {
|
var id: String {
|
||||||
trainID
|
trainID
|
||||||
}
|
}
|
||||||
|
|
||||||
var trainID: String
|
var trainID: String
|
||||||
var trainNum: String
|
var trainNum: String
|
||||||
var routeName: String
|
var routeName: String
|
||||||
var status: String
|
|
||||||
var platform: String
|
|
||||||
var arrival: String
|
|
||||||
var departure: String
|
|
||||||
var origin: String
|
var origin: String
|
||||||
var destination: String
|
var destination: String
|
||||||
// var serviceDate: String
|
var platform: String
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue