Add insert button for links
This commit is contained in:
60
CHDataManagement/Views/Generic/TagPickerView.swift
Normal file
60
CHDataManagement/Views/Generic/TagPickerView.swift
Normal 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)
|
||||
}
|
30
CHDataManagement/Views/Generic/TagPropertyView.swift
Normal file
30
CHDataManagement/Views/Generic/TagPropertyView.swift
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
118
CHDataManagement/Views/Pages/Commands/Insert+Link.swift
Normal file
118
CHDataManagement/Views/Pages/Commands/Insert+Link.swift
Normal 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 ")"
|
||||
}
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ struct InsertableItemsView: View {
|
||||
InsertableView<InsertableImage>()
|
||||
InsertableView<InsertableLabels>()
|
||||
InsertableView<InsertableButtons>()
|
||||
InsertableView<InsertableLink>()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user