128 lines
3.8 KiB
Swift
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())
|
|
}
|