Add insert button for links

This commit is contained in:
Christoph Hagen
2025-02-27 22:51:49 +01:00
parent cdc84cdf4c
commit b08303cd12
5 changed files with 226 additions and 5 deletions

View File

@ -0,0 +1,60 @@
import SwiftUI
struct TagPickerView: View {
@EnvironmentObject
private var content: Content
@Environment(\.language)
private var language
@Environment(\.dismiss)
var dismiss
@Binding var selectedTag: Tag?
@State
private var newSelection: Tag?
init(selectedTag: Binding<Tag?>) {
self._selectedTag = selectedTag
self.newSelection = selectedTag.wrappedValue
// TODO: Fix assignment not working
}
var body: some View {
VStack {
Text("Select a tag to link to")
List(content.tags, selection: $newSelection) { tag in
let loc = tag.localized(in: language)
Text("\(loc.title) (\(tag.id))")
.tag(tag)
}
.frame(minHeight: 300)
HStack {
Button("Use selection") {
DispatchQueue.main.async {
self.selectedTag = self.newSelection
dismiss()
}
}
Button("Remove tag", role: .destructive) {
DispatchQueue.main.async {
self.selectedTag = nil
dismiss()
}
}
Button("Cancel", role: .cancel) {
dismiss()
}
}
}
.navigationTitle("Pick a tag")
.padding()
}
}
#Preview {
TagPickerView(selectedTag: .constant(nil))
.environmentObject(Content.mock)
}

View File

@ -0,0 +1,30 @@
import SwiftUI
struct TagPropertyView: View {
let title: LocalizedStringKey
@Binding
var selectedTag: Tag?
let footer: LocalizedStringKey
@State
private var showTagSelectionSheet = false
var body: some View {
GenericPropertyView(title: title, footer: footer) {
HStack {
Text(selectedTag?.id ?? "No tag selected")
Spacer()
Button("Select") {
showTagSelectionSheet = true
}
}
}
.sheet(isPresented: $showTagSelectionSheet) {
TagPickerView(selectedTag: $selectedTag)
}
}
}

View File

@ -0,0 +1,118 @@
import SwiftUI
import SFSafeSymbols
struct InsertableLink: View, InsertableCommandView {
final class Model: ObservableObject, InsertableCommandModel {
@Published
var selectedType: ItemType = .page
@Published
var selectedFile: FileResource?
@Published
var selectedPage: Page?
@Published
var selectedTag: Tag?
@Published
var isInlineLink = false
@Published
var inlineText = ""
var isReady: Bool {
switch selectedType {
case .post, .tagOverview:
return false
case .page:
return selectedPage != nil
case .tag:
return selectedTag != nil
case .file:
return selectedFile != nil
}
}
init() {
}
private var linkContent: String? {
switch selectedType {
case .post, .tagOverview:
return nil
case .page:
return selectedPage?.id
case .tag:
return selectedTag?.id
case .file:
return selectedFile?.id
}
}
var command: String? {
guard let linkContent else {
return nil
}
guard isInlineLink else {
return "![\(selectedType.rawValue)](\(linkContent))"
}
return "[\(inlineText)](\(selectedType.rawValue):\(linkContent))"
}
}
static let title = "Link"
static let sheetTitle = "Insert a link to a tag, page or file"
static let icon: SFSymbol = .photo
@ObservedObject
private var model: Model
init(model: Model) {
self.model = model
}
var body: some View {
VStack {
Picker("", selection: $model.selectedType) {
Text("Page").tag(ItemType.page)
Text("Tag").tag(ItemType.tag)
Text("File").tag(ItemType.file)
}
.pickerStyle(.segmented)
Toggle("Inline Link", isOn: $model.isInlineLink)
if model.isInlineLink {
StringPropertyView(
title: "Link text",
text: $model.inlineText,
footer: "The text to show")
}
switch model.selectedType {
case .post:
Text("Linking posts is not supported")
case .page:
PagePropertyView(
title: "Linked page",
selectedPage: $model.selectedPage,
footer: "Select the page to link to")
case .tag:
TagPropertyView(
title: "Linked tag",
selectedTag: $model.selectedTag,
footer: "Select the tag to link to")
case .file:
FilePropertyView(
title: "File",
footer: "Select the image to insert",
selectedFile: $model.selectedFile)
case .tagOverview:
Text("Linking tag overview is not supported")
}
}
}
}

View File

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