Improve content saving, label editing
This commit is contained in:
@ -160,7 +160,7 @@ private struct FileButtonView: View {
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
LabelEditingView(label: content.label)
|
||||
LabelEditingView(label: $content.label)
|
||||
Button("\(content.file?.id ?? "Select file")", action: { showFileSelectionSheet = true })
|
||||
OptionalTextField("", text: $content.downloadedFileName, prompt: "Downloaded file name")
|
||||
.textFieldStyle(.roundedBorder)
|
||||
@ -178,7 +178,7 @@ private struct UrlButtonView: View {
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
LabelEditingView(label: content.label)
|
||||
LabelEditingView(label: $content.label)
|
||||
TextField("", text: $content.url, prompt: Text("URL"))
|
||||
.textFieldStyle(.roundedBorder)
|
||||
}
|
||||
@ -192,7 +192,7 @@ private struct EventButtonView: View {
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
LabelEditingView(label: content.label)
|
||||
LabelEditingView(label: $content.label)
|
||||
TextField("", text: $content.event, prompt: Text("Javascript"))
|
||||
.textFieldStyle(.roundedBorder)
|
||||
}
|
||||
|
@ -35,47 +35,15 @@ struct InsertableLabels: View, InsertableCommandView {
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(\.colorScheme)
|
||||
private var colorScheme
|
||||
|
||||
@ObservedObject
|
||||
private var model: Model
|
||||
|
||||
|
||||
|
||||
init(model: Model) {
|
||||
self.model = model
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 2) {
|
||||
ForEach(model.labels, id: \.icon) { label in
|
||||
HStack {
|
||||
Button(action: { remove(label) }) {
|
||||
Image(systemSymbol: .minusCircleFill)
|
||||
.foregroundStyle(.red)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
LabelEditingView(label: label)
|
||||
}
|
||||
.padding(.vertical, 2)
|
||||
.padding(.horizontal, 8)
|
||||
.background(colorScheme == .light ? Color.white : Color.black)
|
||||
.cornerRadius(8)
|
||||
}
|
||||
Button("Add", action: addLabel)
|
||||
.padding(.vertical, 2)
|
||||
}
|
||||
LabelCreationView(labels: $model.labels)
|
||||
}
|
||||
|
||||
private func addLabel() {
|
||||
model.labels.append(.init(icon: .clockFill, value: "Value"))
|
||||
}
|
||||
|
||||
private func remove(_ label: ContentLabel) {
|
||||
guard let index = model.labels.firstIndex(of: label) else {
|
||||
return
|
||||
}
|
||||
model.labels.remove(at: index)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,54 @@
|
||||
import SwiftUI
|
||||
|
||||
struct LabelCreationView: View {
|
||||
|
||||
@Environment(\.colorScheme)
|
||||
private var colorScheme
|
||||
|
||||
@Binding
|
||||
var labels: [ContentLabel]
|
||||
|
||||
var body: some View {
|
||||
List {
|
||||
ForEach($labels) { label in
|
||||
HStack {
|
||||
Button(action: { remove(label.wrappedValue) }) {
|
||||
Image(systemSymbol: .minusCircleFill)
|
||||
.foregroundStyle(.red)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
LabelEditingView(label: label)
|
||||
}
|
||||
.padding(.vertical, 2)
|
||||
.padding(.horizontal, 8)
|
||||
.background(colorScheme == .light ? Color.white : Color.black)
|
||||
.cornerRadius(8)
|
||||
}
|
||||
.onMove(perform: moveLabel)
|
||||
Button("Add new label", action: addLabel)
|
||||
.padding(.vertical, 2)
|
||||
}
|
||||
.frame(minHeight: 250)
|
||||
}
|
||||
|
||||
private func addLabel() {
|
||||
var label = ContentLabel(icon: .statisticsTime, value: "Value")
|
||||
var number = 0
|
||||
while labels.contains(label) {
|
||||
number += 1
|
||||
label.value = "Value \(number)"
|
||||
}
|
||||
labels.append(label)
|
||||
}
|
||||
|
||||
private func remove(_ label: ContentLabel) {
|
||||
guard let index = labels.firstIndex(of: label) else {
|
||||
return
|
||||
}
|
||||
labels.remove(at: index)
|
||||
}
|
||||
|
||||
private func moveLabel(from source: IndexSet, to destination: Int) {
|
||||
labels.move(fromOffsets: source, toOffset: destination)
|
||||
}
|
||||
}
|
65
CHDataManagement/Views/Posts/LabelEditingView.swift
Normal file
65
CHDataManagement/Views/Posts/LabelEditingView.swift
Normal file
@ -0,0 +1,65 @@
|
||||
import SwiftUI
|
||||
|
||||
struct LabelEditingView: View {
|
||||
|
||||
@Binding
|
||||
var label: ContentLabel
|
||||
|
||||
@State
|
||||
private var showIconPicker: Bool = false
|
||||
|
||||
let scale: CGFloat
|
||||
|
||||
init(label: Binding<ContentLabel>, scale: CGFloat = 1.0) {
|
||||
self._label = label
|
||||
self.scale = scale
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
Button(action: { showIconPicker = true }) {
|
||||
PageIconView(icon: label.icon)
|
||||
.frame(maxWidth: 16, maxHeight: 16)
|
||||
.scaleEffect(scale)
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
TextField("", text: $label.value)
|
||||
.textFieldStyle(.plain)
|
||||
}
|
||||
.sheet(isPresented: $showIconPicker) {
|
||||
LabelIconSelectionView(selected: $label.icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct LabelIconSelectionView: View {
|
||||
|
||||
@Environment(\.dismiss)
|
||||
var dismiss
|
||||
|
||||
@Binding
|
||||
var selected: PageIcon
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
List(PageIcon.allCases, id: \.rawValue) { icon in
|
||||
HStack {
|
||||
Image(systemSymbol: selected == icon ? .checkmarkCircleFill : .circle)
|
||||
PageIconView(icon: icon)
|
||||
.frame(maxWidth: 20, maxHeight: 20)
|
||||
Text(icon.name)
|
||||
Spacer()
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture {
|
||||
selected = icon
|
||||
dismiss()
|
||||
}
|
||||
}.frame(minHeight: 300)
|
||||
Button("Done") {
|
||||
dismiss()
|
||||
}
|
||||
}.padding()
|
||||
}
|
||||
}
|
@ -1,61 +1,5 @@
|
||||
import SwiftUI
|
||||
|
||||
struct LabelEditingView: View {
|
||||
|
||||
@ObservedObject
|
||||
var label: ContentLabel
|
||||
|
||||
@State
|
||||
private var showIconPicker: Bool = false
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
Button(action: { showIconPicker = true }) {
|
||||
PageIconView(icon: label.icon)
|
||||
.frame(maxWidth: 20, maxHeight: 20)
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
TextField("", text: $label.value)
|
||||
.textFieldStyle(.plain)
|
||||
}
|
||||
.sheet(isPresented: $showIconPicker) {
|
||||
LabelIconSelectionView(selected: $label.icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct LabelIconSelectionView: View {
|
||||
|
||||
@Environment(\.dismiss)
|
||||
var dismiss
|
||||
|
||||
@Binding
|
||||
var selected: PageIcon
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
List(PageIcon.allCases, id: \.rawValue) { icon in
|
||||
HStack {
|
||||
Image(systemSymbol: selected == icon ? .checkmarkCircleFill : .circle)
|
||||
PageIconView(icon: icon)
|
||||
.frame(maxWidth: 20, maxHeight: 20)
|
||||
Text(icon.name)
|
||||
Spacer()
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture {
|
||||
selected = icon
|
||||
dismiss()
|
||||
}
|
||||
}.frame(minHeight: 300)
|
||||
Button("Done") {
|
||||
dismiss()
|
||||
}
|
||||
}.padding()
|
||||
}
|
||||
}
|
||||
|
||||
struct PostLabelsView: View {
|
||||
|
||||
@ObservedObject
|
||||
@ -67,26 +11,38 @@ struct PostLabelsView: View {
|
||||
@Environment(\.colorScheme)
|
||||
var colorScheme
|
||||
|
||||
@State
|
||||
private var showLabelEditor: Bool = false
|
||||
|
||||
var body: some View {
|
||||
ScrollView(.horizontal) {
|
||||
HStack(spacing: 5) {
|
||||
Text("Labels")
|
||||
.font(.headline)
|
||||
ForEach(post.labels, id: \.icon) { label in
|
||||
if post.labels.isEmpty {
|
||||
Text("Labels")
|
||||
.font(.headline)
|
||||
}
|
||||
ForEach(post.labels) { label in
|
||||
HStack {
|
||||
Button(action: { remove(label) }) {
|
||||
Image(systemSymbol: .minusCircleFill)
|
||||
.foregroundStyle(.red)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
LabelEditingView(label: label)
|
||||
PageIconView(icon: label.icon)
|
||||
.frame(maxWidth: 16, maxHeight: 16)
|
||||
.scaleEffect(25/16)
|
||||
Text(label.value)
|
||||
}
|
||||
.padding(.vertical, 2)
|
||||
.padding(.horizontal, 8)
|
||||
.background(colorScheme == .light ? Color.white : Color.black)
|
||||
.cornerRadius(8)
|
||||
}
|
||||
Button("Add", action: addLabel)
|
||||
Button(action: { showLabelEditor = true }) {
|
||||
Image(systemSymbol: .squareAndPencilCircleFill)
|
||||
.resizable()
|
||||
.aspectRatio(1, contentMode: .fit)
|
||||
.frame(height: 22)
|
||||
.foregroundColor(Color.gray)
|
||||
.background(Circle()
|
||||
.fill(Color.white)
|
||||
.padding(1))
|
||||
}.buttonStyle(.plain)
|
||||
if !other.labels.isEmpty {
|
||||
Button("Transfer") {
|
||||
post.labels = other.labels.map {
|
||||
@ -95,9 +51,24 @@ struct PostLabelsView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
if !post.labels.isEmpty {
|
||||
Button("Copy") {
|
||||
var command = "```labels"
|
||||
for label in post.labels {
|
||||
command += "\n\(label.icon.rawValue): \(label.value)"
|
||||
}
|
||||
command += "\n```"
|
||||
let pasteboard = NSPasteboard.general
|
||||
pasteboard.clearContents()
|
||||
pasteboard.setString(command, forType: .string)
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.vertical, 2)
|
||||
}
|
||||
.sheet(isPresented: $showLabelEditor) {
|
||||
LabelModificationView(labels: $post.labels)
|
||||
}
|
||||
}
|
||||
|
||||
func addLabel() {
|
||||
@ -111,3 +82,23 @@ struct PostLabelsView: View {
|
||||
post.labels.remove(at: index)
|
||||
}
|
||||
}
|
||||
|
||||
private struct LabelModificationView: View {
|
||||
|
||||
@Environment(\.dismiss)
|
||||
private var dismiss
|
||||
|
||||
@Binding
|
||||
var labels: [ContentLabel]
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
Text("Labels")
|
||||
.font(.title)
|
||||
LabelCreationView(labels: $labels)
|
||||
Button("Save") {
|
||||
dismiss()
|
||||
}
|
||||
}.padding()
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user