2025-05-02 14:54:41 +02:00

128 lines
3.8 KiB
Swift

import SwiftUI
import SFSafeSymbols
struct InsertableRoute: View, InsertableCommandView {
@Environment(\.language)
var language
final class Model: ObservableObject, InsertableCommandModel {
@Published
var caption: String?
@Published
var chartTitle: String?
@Published
var components: Set<RouteStatisticType> = Set(RouteStatisticType.allCases)
@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)")
if components != Set(RouteStatisticType.allCases) {
let list = components
.map { $0.rawValue }
.joined(separator: ", ")
result.append("\(RouteBlock.Key.components.rawValue): \(list)")
}
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")
ForEach(RouteStatisticType.allCases.sorted(), id: \.rawValue) { type in
Toggle(isOn: Binding(
get: {
model.components.contains(type)
},
set: { isSelected in
if isSelected {
model.components.insert(type)
} else {
model.components.remove(type)
}
}
)) {
Text(type.displayText(in: language))
}.toggleStyle(.checkbox)
}
}
}
}
#Preview {
InsertableRoute(model: .init())
}