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 } } } }