Add route files, show overview
This commit is contained in:
87
CHDataManagement/Workouts/RoutePreviewView.swift
Normal file
87
CHDataManagement/Workouts/RoutePreviewView.swift
Normal file
@@ -0,0 +1,87 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user