Add route block

This commit is contained in:
Christoph Hagen
2025-04-29 16:56:46 +02:00
parent bbb1143600
commit 3c7681b769
13 changed files with 446 additions and 9 deletions

View File

@ -42,6 +42,10 @@ struct GenerationContentView: View {
}
Text(content.generationStatus)
.padding(.vertical, 5)
GenerationStringIssuesView(
text: "output files",
statusWhenNonEmpty: .nominal,
items: $content.results.outputFiles)
GenerationResultsIssueView(
text: "\(content.results.imagesToGenerate.count) images",
status: .nominal,
@ -66,6 +70,10 @@ struct GenerationContentView: View {
text: "empty pages",
statusWhenNonEmpty: .warning,
items: $content.results.emptyPages) { "\($0.pageId) (\($0.language))" }
GenerationStringIssuesView(
text: "additional output files",
statusWhenNonEmpty: .warning,
items: $content.results.unusedFilesInOutput)
GenerationStringIssuesView(
text: "inaccessible files",
items: $content.results.inaccessibleFiles) { $0.id }
@ -93,14 +101,6 @@ struct GenerationContentView: View {
GenerationStringIssuesView(
text: "invalid blocks",
items: $content.results.invalidBlocks)
GenerationStringIssuesView(
text: "output files",
statusWhenNonEmpty: .nominal,
items: $content.results.outputFiles)
GenerationStringIssuesView(
text: "additional output files",
statusWhenNonEmpty: .warning,
items: $content.results.unusedFilesInOutput)
GenerationStringIssuesView(
text: "warnings",
statusWhenNonEmpty: .warning,

View File

@ -0,0 +1,111 @@
import SwiftUI
import SFSafeSymbols
struct InsertableRoute: View, InsertableCommandView {
final class Model: ObservableObject, InsertableCommandModel {
@Published
var caption: String?
@Published
var chartTitle: String?
@Published
var components: RouteViewComponents = .all
@Published
var mapTitle: String?
@Published
var selectedImage: FileResource?
@Published
var dataFile: FileResource?
var isReady: Bool {
selectedImage != nil && dataFile != nil
}
init() {
}
var command: String? {
guard let selectedImage,
let dataFile else {
return nil
}
var result = ["```route"]
result.append("\(RouteBlock.Key.image.rawValue): \(selectedImage.id)")
result.append("\(RouteBlock.Key.file.rawValue): \(dataFile.id)")
result.append("\(RouteBlock.Key.components.rawValue): \(components.rawValue)")
if let caption {
result.append("\(RouteBlock.Key.caption.rawValue): \(caption)")
}
if let chartTitle {
result.append("\(RouteBlock.Key.chartTitle.rawValue): \(chartTitle)")
}
if let mapTitle {
result.append("\(RouteBlock.Key.mapTitle.rawValue): \(mapTitle)")
}
result.append("\n```")
return result.joined(separator: "\n")
}
}
static let title = "Route"
static let sheetTitle = "Insert route map and statistics"
static let icon: SFSymbol = .map
@ObservedObject
private var model: Model
init(model: Model) {
self.model = model
}
var body: some View {
VStack {
FilePropertyView(
title: "Map Image",
footer: "Select the image to insert as the map",
selectedFile: $model.selectedImage,
allowedType: .image)
FilePropertyView(
title: "Data File",
footer: "Select the file containing the statistics",
selectedFile: $model.dataFile,
allowedType: .text)
OptionalStringPropertyView(
title: "Map Title",
text: $model.mapTitle,
prompt: "Map title",
footer: "The title to show above the map image")
OptionalStringPropertyView(
title: "Map Image Caption",
text: $model.caption,
prompt: "Image Caption",
footer: "The caption to show below the fullscreen map")
OptionalStringPropertyView(
title: "Chart Title",
text: $model.chartTitle,
prompt: "Title",
footer: "The title to show above the statistics")
Picker(selection: $model.components) {
Text("All").tag(RouteViewComponents.all)
Text("Only elevation").tag(RouteViewComponents.withoutHeartRate)
Text("No heart rate").tag(RouteViewComponents.withoutHeartRate)
} label: {
Text("")
}
.pickerStyle(.segmented)
}
}
}
#Preview {
InsertableRoute(model: .init())
}

View File

@ -10,6 +10,7 @@ struct InsertableItemsView: View {
InsertableView<InsertableLabels>()
InsertableView<InsertableButtons>()
InsertableView<InsertableLink>()
InsertableView<InsertableRoute>()
}
}
}

View File

@ -62,6 +62,11 @@ struct PageSettingsDetailView: View {
footer: "The manifest file with the properties of the website when used as a progressive web app",
selectedFile: $pageSettings.manifestFile)
FilePropertyView(
title: "Route Statistics Javascript File",
footer: "The JavaScript file containing the logic to compute and animate statistics about workout routes",
selectedFile: $pageSettings.routeJsFile)
LocalizedPageSettingsView(settings: pageSettings.localized(in: language))
.id(language)
}