First button with command shortcut

This commit is contained in:
Christoph Hagen
2025-01-24 22:47:54 +01:00
parent 51eff690d2
commit 200fdc813d
5 changed files with 164 additions and 0 deletions

View File

@ -0,0 +1,55 @@
import SwiftUI
import SFSafeSymbols
struct InsertableImage: View, InsertableCommand {
static let title = "Image"
static let sheetTitle = "Insert image"
static let icon: SFSymbol = .photo
@State
private var selectedImage: FileResource?
@State
private var caption: String? = ""
@Binding
private var command: String?
init(command: Binding<String?>) {
self._command = command
}
var body: some View {
VStack {
FilePropertyView(
title: "Image",
footer: "Select the image to insert",
selectedFile: $selectedImage,
allowedType: .image)
OptionalStringPropertyView(
title: "Caption",
text: $caption,
prompt: "Image Caption",
footer: "The caption to show on the fullscreen image")
}
.onChange(of: caption) { updateCommand() }
.onChange(of: selectedImage) { updateCommand() }
}
func updateCommand() {
command = currentCommand
}
private var currentCommand: String? {
guard let selectedImage else {
return nil
}
guard let caption else {
return "![image](\(selectedImage.id))"
}
return "![image](\(selectedImage.id);\(caption))"
}
}

View File

@ -0,0 +1,59 @@
import SwiftUI
import SFSafeSymbols
protocol InsertableCommand: View {
static var title: String { get }
static var sheetTitle: String { get }
static var icon: SFSymbol { get }
init(command: Binding<String?>)
}
struct InsertableCommandSheet<Presented>: View where Presented: InsertableCommand {
@Environment(\.dismiss)
var dismiss
@State
private var error: String? = nil
@State
private var command: String?
init() { }
var body: some View {
VStack {
Text(Presented.sheetTitle)
.font(.title)
Presented(command: $command)
if let error {
Text(error)
.foregroundStyle(.red)
}
HStack {
Button("Copy to clipboard", action: copyToClipboard)
.padding()
Button("Cancel") {
dismiss()
}.padding()
}
}
.padding()
}
func copyToClipboard() {
guard let command else {
error = "Not all fields set"
return
}
defer { dismiss() }
let pasteboard = NSPasteboard.general
pasteboard.clearContents()
pasteboard.setString(command, forType: .string)
}
}

View File

@ -0,0 +1,29 @@
import SwiftUI
import SFSafeSymbols
private struct InsertableView<Command>: View where Command: InsertableCommand {
@State
private var showSheet: Bool = false
var body: some View {
Button(action: { showSheet = true }) {
Label(Command.title, systemSymbol: Command.icon)
}
.sheet(isPresented: $showSheet) {
InsertableCommandSheet<Command>()
}
}
}
struct InsertableItemsView: View {
var body: some View {
HStack {
Text("Commands")
.font(.headline)
InsertableView<InsertableImage>()
}
}
}

View File

@ -53,6 +53,7 @@ struct LocalizedPageContentView: View {
text: "\(linkingPosts.count) linking posts",
items: linkingPosts.map { $0.title(in: language) })
}.foregroundStyle(.secondary)
InsertableItemsView()
HighlightedTextEditor(
text: $pageContent,
highlightRules: .markdown)