201 lines
5.1 KiB
Swift
201 lines
5.1 KiB
Swift
import SwiftUI
|
|
import SFSafeSymbols
|
|
|
|
final class InsertableFileButton: ObservableObject {
|
|
|
|
@Published
|
|
var label: ContentLabel = .init(icon: .buttonDownload, value: "Text")
|
|
|
|
@Published
|
|
var file: FileResource?
|
|
|
|
@Published
|
|
var downloadedFileName: String? = nil
|
|
|
|
var command: String? {
|
|
guard let file else {
|
|
return nil
|
|
}
|
|
let result =
|
|
"""
|
|
icon: \(label.icon.rawValue)
|
|
text: \(label.value)
|
|
file: \(file.id)
|
|
"""
|
|
guard let downloadedFileName else {
|
|
return result
|
|
}
|
|
return result + "\n" + "name: \(downloadedFileName)"
|
|
}
|
|
}
|
|
|
|
final class InsertableUrlButton: ObservableObject {
|
|
|
|
@Published
|
|
var label: ContentLabel = .init(icon: .buttonDownload, value: "Text")
|
|
|
|
@Published
|
|
var url: String = "Url"
|
|
|
|
var command: String? {
|
|
"""
|
|
icon: \(label.icon.rawValue)
|
|
text: \(label.value)
|
|
url: \(url)
|
|
"""
|
|
}
|
|
}
|
|
|
|
final class InsertableEventButton: ObservableObject {
|
|
|
|
@Published
|
|
var label: ContentLabel = .init(icon: .buttonDownload, value: "Text")
|
|
|
|
@Published
|
|
var event: String = "Javascript"
|
|
|
|
var command: String? {
|
|
"""
|
|
icon: \(label.icon.rawValue)
|
|
text: \(label.value)
|
|
event: \(event)
|
|
"""
|
|
}
|
|
}
|
|
|
|
struct InsertableButtons: View, InsertableCommandView {
|
|
|
|
final class Model: ObservableObject, InsertableCommandModel {
|
|
|
|
enum AnyButton: Identifiable {
|
|
case file(InsertableFileButton)
|
|
case url(InsertableUrlButton)
|
|
case event(InsertableEventButton)
|
|
|
|
var command: String? {
|
|
switch self {
|
|
case .file(let file):
|
|
return file.command
|
|
case .url(let url):
|
|
return url.command
|
|
case .event(let event):
|
|
return event.command
|
|
}
|
|
}
|
|
|
|
var id: String {
|
|
switch self {
|
|
case .file(let file):
|
|
return "file-\(file.file?.id ?? "none")"
|
|
case .url(let url):
|
|
return "url-\(url.url)"
|
|
case .event(let event):
|
|
return "event-\(event.event)"
|
|
}
|
|
}
|
|
}
|
|
|
|
@Published
|
|
var buttons: [AnyButton] = []
|
|
|
|
var isReady: Bool {
|
|
!buttons.isEmpty
|
|
}
|
|
|
|
var command: String? {
|
|
let result = buttons.compactMap { $0.command }
|
|
guard result.count == buttons.count else {
|
|
return nil
|
|
}
|
|
return result.map {
|
|
"```buttons\n\($0)\n```"
|
|
}.joined(separator: "\n\n")
|
|
}
|
|
}
|
|
|
|
static let title = "Buttons"
|
|
|
|
static let sheetTitle = "Insert buttons"
|
|
|
|
static let icon: SFSymbol = .rectangleAndHandPointUpLeft
|
|
|
|
@ObservedObject
|
|
private var model: Model
|
|
|
|
init(model: Model) {
|
|
self.model = model
|
|
}
|
|
|
|
var body: some View {
|
|
VStack(alignment: .leading) {
|
|
List(model.buttons) { button in
|
|
switch button {
|
|
case .file(let file):
|
|
FileButtonView(content: file)
|
|
case .url(let url):
|
|
UrlButtonView(content: url)
|
|
case .event(let event):
|
|
EventButtonView(content: event)
|
|
}
|
|
}
|
|
.frame(minHeight: 300)
|
|
HStack {
|
|
Spacer()
|
|
Button("File", action: { model.buttons.append(.file(.init())) })
|
|
Button("Url", action: { model.buttons.append(.url(.init())) })
|
|
Button("Event", action: { model.buttons.append(.event(.init())) })
|
|
Spacer()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private struct FileButtonView: View {
|
|
|
|
@ObservedObject
|
|
var content: InsertableFileButton
|
|
|
|
@State
|
|
private var showFileSelectionSheet = false
|
|
|
|
var body: some View {
|
|
HStack {
|
|
LabelEditingView(label: content.label)
|
|
Button("\(content.file?.id ?? "Select file")", action: { showFileSelectionSheet = true })
|
|
OptionalTextField("", text: $content.downloadedFileName, prompt: "Downloaded file name")
|
|
.textFieldStyle(.roundedBorder)
|
|
}
|
|
.sheet(isPresented: $showFileSelectionSheet) {
|
|
FileSelectionView(selectedFile: $content.file)
|
|
}
|
|
}
|
|
}
|
|
|
|
private struct UrlButtonView: View {
|
|
|
|
@ObservedObject
|
|
var content: InsertableUrlButton
|
|
|
|
var body: some View {
|
|
HStack {
|
|
LabelEditingView(label: content.label)
|
|
TextField("", text: $content.url, prompt: Text("URL"))
|
|
.textFieldStyle(.roundedBorder)
|
|
}
|
|
}
|
|
}
|
|
|
|
private struct EventButtonView: View {
|
|
|
|
@ObservedObject
|
|
var content: InsertableEventButton
|
|
|
|
var body: some View {
|
|
HStack {
|
|
LabelEditingView(label: content.label)
|
|
TextField("", text: $content.event, prompt: Text("Javascript"))
|
|
.textFieldStyle(.roundedBorder)
|
|
}
|
|
}
|
|
}
|