88 lines
2.5 KiB
Swift
88 lines
2.5 KiB
Swift
import SwiftUI
|
|
import CoreLocation
|
|
|
|
|
|
struct RoutePreviewView: View {
|
|
|
|
private let iconSize: CGFloat = 150
|
|
|
|
@ObservedObject
|
|
var file: FileResource
|
|
|
|
@State
|
|
var overview: RouteOverview?
|
|
|
|
@State
|
|
var message: String?
|
|
|
|
@State
|
|
var elevation: [ElevationSample] = []
|
|
|
|
var body: some View {
|
|
VStack {
|
|
Image(systemSymbol: .map)
|
|
.resizable()
|
|
.aspectRatio(contentMode:.fit)
|
|
.frame(width: iconSize)
|
|
if let message {
|
|
Text(message)
|
|
.font(.title)
|
|
} else if let overview {
|
|
if let start = overview.start {
|
|
if let end = overview.end {
|
|
Text("\(start.formatted()) - \(end.formatted()) (\(overview.duration.timeString))")
|
|
} else {
|
|
Text(start.formatted())
|
|
}
|
|
}
|
|
Text(String(format: "%.2f km (%.0f m ascended)", overview.distance / 1000, overview.ascendedElevation))
|
|
Text("\(Int(overview.energy)) kcal")
|
|
if !elevation.isEmpty {
|
|
ElevationGraph(samples: elevation)
|
|
.frame(width: 500, height: 200)
|
|
.padding()
|
|
}
|
|
} else {
|
|
Text("Loading route overview...")
|
|
.font(.title)
|
|
ProgressView()
|
|
.progressViewStyle(.circular)
|
|
}
|
|
}
|
|
.foregroundStyle(.secondary)
|
|
.onAppear { loadOverview() }
|
|
}
|
|
|
|
private func loadOverview() {
|
|
guard overview == nil && message == nil else {
|
|
return
|
|
}
|
|
Task {
|
|
guard let data = file.dataContent() else {
|
|
DispatchQueue.main.async {
|
|
self.message = "Failed to get file data"
|
|
}
|
|
return
|
|
}
|
|
let route: WorkoutData
|
|
do {
|
|
route = try WorkoutData(data: data)
|
|
} catch {
|
|
DispatchQueue.main.async {
|
|
self.message = "Failed to decode route: \(error)"
|
|
}
|
|
return
|
|
}
|
|
|
|
let overview = route.overview
|
|
|
|
let elevations = route.locations.map { ElevationSample(timestamp: $0.timestamp, altitude: $0.altitude) }
|
|
|
|
DispatchQueue.main.async {
|
|
self.overview = overview
|
|
self.elevation = elevations
|
|
}
|
|
}
|
|
}
|
|
}
|