Fix tag assignment in post UI

This commit is contained in:
Christoph Hagen
2025-06-16 10:09:38 +02:00
parent 1d0eba9d78
commit 8508719dbe
13 changed files with 74 additions and 54 deletions

View File

@ -7,6 +7,9 @@
objects = {
/* Begin PBXBuildFile section */
E2039A152E0001B700305538 /* PostImagesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2039A142E0001B200305538 /* PostImagesView.swift */; };
E2039A172E00027600305538 /* PostTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2039A162E00027300305538 /* PostTitleView.swift */; };
E2039A192E0002C500305538 /* PostTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2039A182E0002C100305538 /* PostTextView.swift */; };
E20BCC972D53454C00B8DBEB /* StorageItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20BCC962D53454500B8DBEB /* StorageItem.swift */; };
E20BCC992D53597D00B8DBEB /* SaveState.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20BCC982D53597D00B8DBEB /* SaveState.swift */; };
E20BCC9B2D535C3500B8DBEB /* ChangeObservableItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20BCC9A2D535C3100B8DBEB /* ChangeObservableItem.swift */; };
@ -238,7 +241,6 @@
E2FD1D5A2D477AB200B48627 /* InsertableItemsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2FD1D592D477AB200B48627 /* InsertableItemsView.swift */; };
E2FD1D5C2D47EEB800B48627 /* LinkedPageTagView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2FD1D5B2D47EEB800B48627 /* LinkedPageTagView.swift */; };
E2FD1D5E2D47EED200B48627 /* PostImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2FD1D5D2D47EED200B48627 /* PostImageView.swift */; };
E2FD1D602D47EEEF00B48627 /* LocalizedPostContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2FD1D5F2D47EEEF00B48627 /* LocalizedPostContentView.swift */; };
E2FD1D642D47EF4200B48627 /* DetailListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2FD1D632D47EF4200B48627 /* DetailListItem.swift */; };
E2FD1D682D483CCF00B48627 /* Insert+Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2FD1D672D483CCA00B48627 /* Insert+Buttons.swift */; };
E2FE0EE62D15A0B5002963B7 /* GenerationResults.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2FE0EE52D15A0B1002963B7 /* GenerationResults.swift */; };
@ -299,6 +301,9 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
E2039A142E0001B200305538 /* PostImagesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostImagesView.swift; sourceTree = "<group>"; };
E2039A162E00027300305538 /* PostTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostTitleView.swift; sourceTree = "<group>"; };
E2039A182E0002C100305538 /* PostTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostTextView.swift; sourceTree = "<group>"; };
E20BCC962D53454500B8DBEB /* StorageItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorageItem.swift; sourceTree = "<group>"; };
E20BCC982D53597D00B8DBEB /* SaveState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SaveState.swift; sourceTree = "<group>"; };
E20BCC9A2D535C3100B8DBEB /* ChangeObservableItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeObservableItem.swift; sourceTree = "<group>"; };
@ -524,7 +529,6 @@
E2FD1D592D477AB200B48627 /* InsertableItemsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InsertableItemsView.swift; sourceTree = "<group>"; };
E2FD1D5B2D47EEB800B48627 /* LinkedPageTagView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkedPageTagView.swift; sourceTree = "<group>"; };
E2FD1D5D2D47EED200B48627 /* PostImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostImageView.swift; sourceTree = "<group>"; };
E2FD1D5F2D47EEEF00B48627 /* LocalizedPostContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizedPostContentView.swift; sourceTree = "<group>"; };
E2FD1D632D47EF4200B48627 /* DetailListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailListItem.swift; sourceTree = "<group>"; };
E2FD1D672D483CCA00B48627 /* Insert+Buttons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Insert+Buttons.swift"; sourceTree = "<group>"; };
E2FE0EE52D15A0B1002963B7 /* GenerationResults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenerationResults.swift; sourceTree = "<group>"; };
@ -1019,6 +1023,9 @@
E2FD1D3E2D46404900B48627 /* PostLabelsView.swift */,
E29D31502D0616890051B7F4 /* PostListView.swift */,
E218502A2CF790AC0090B18B /* PostContentView.swift */,
E2039A182E0002C100305538 /* PostTextView.swift */,
E2039A162E00027300305538 /* PostTitleView.swift */,
E2039A142E0001B200305538 /* PostImagesView.swift */,
E21850262CF3B42D0090B18B /* PostDetailView.swift */,
E29D313E2D04822C0051B7F4 /* AddPostView.swift */,
E21850222CF10C840090B18B /* TagSelectionView.swift */,
@ -1026,7 +1033,6 @@
E2A21C072CB17B810060935B /* TagView.swift */,
E29D31312D03B5610051B7F4 /* LocalizedPostDetailView.swift */,
E2FD1D5D2D47EED200B48627 /* PostImageView.swift */,
E2FD1D5F2D47EEEF00B48627 /* LocalizedPostContentView.swift */,
E2FD1D5B2D47EEB800B48627 /* LinkedPageTagView.swift */,
);
path = Posts;
@ -1352,6 +1358,7 @@
E29D317D2D086AB00051B7F4 /* Int+Random.swift in Sources */,
E2BF1BC62D6B16FF003089F1 /* HeadlineLink.swift in Sources */,
E25DA56F2D00F9A100AEF16D /* PostFeedSettingsView.swift in Sources */,
E2039A192E0002C500305538 /* PostTextView.swift in Sources */,
E2521E042D51796000C56662 /* StorageStatusView.swift in Sources */,
E29D313B2D04464A0051B7F4 /* LocalizedTagDetailView.swift in Sources */,
E2FE0F552D2BCFC4002963B7 /* ContentBlock.swift in Sources */,
@ -1381,6 +1388,7 @@
E242520A2C52C9260029FF16 /* ContentLanguage.swift in Sources */,
E2B85F452C429ED60047CD0C /* ImageGallery.swift in Sources */,
E2B85F3B2C428F0E0047CD0C /* Post.swift in Sources */,
E2039A152E0001B700305538 /* PostImagesView.swift in Sources */,
E29D31852D0AE8EE0051B7F4 /* KnownHeaderElement.swift in Sources */,
E25DA51B2CFF08BB00AEF16D /* PostFeedPageNavigation.swift in Sources */,
E22990422D107A95009F8D77 /* ImageVersion.swift in Sources */,
@ -1433,6 +1441,7 @@
E229901E2D0E4364009F8D77 /* LocalizedItem.swift in Sources */,
E29D31262D0370A80051B7F4 /* VideoCommand+Option.swift in Sources */,
E2FE0EF82D1D8110002963B7 /* IconCommand.swift in Sources */,
E2039A172E00027600305538 /* PostTitleView.swift in Sources */,
E2F3B39E2DC55B1C00CFA712 /* LabelCreationView.swift in Sources */,
E21850272CF3B42D0090B18B /* PostDetailView.swift in Sources */,
E22990242D0EDBD0009F8D77 /* HeaderElement.swift in Sources */,
@ -1592,7 +1601,6 @@
E2FD1D0D2D2DBBA600B48627 /* LinkPreview.swift in Sources */,
E20BCC972D53454C00B8DBEB /* StorageItem.swift in Sources */,
E22990362D0F79D2009F8D77 /* OptionalStringPropertyView.swift in Sources */,
E2FD1D602D47EEEF00B48627 /* LocalizedPostContentView.swift in Sources */,
E229903C2D0F8A7B009F8D77 /* OptionalTextFieldPropertyView.swift in Sources */,
E2FD1D582D477A9400B48627 /* InsertableCommand.swift in Sources */,
E2EC1FB42DC0FA8700C41784 /* Insert+Route.swift in Sources */,

View File

@ -2,7 +2,7 @@ import SwiftUI
protocol MainContentView: View {
associatedtype Item
associatedtype Item: Identifiable
init(item: Item)

View File

@ -12,6 +12,7 @@ struct SelectedContentView<Contained>: View where Contained: MainContentView {
var body: some View {
if let item = selected {
Contained(item: item)
.id(item.id)
} else {
HStack {
Spacer()

View File

@ -12,7 +12,7 @@ struct SelectedDetailView<Contained>: View where Contained: MainContentView {
var body: some View {
if let item = selected {
Contained(item: item)
//.id(item.id)
.id(item.id)
} else {
EmptyView()
}

View File

@ -18,7 +18,7 @@ struct TagDisplayView: View {
FlowHStack {
ForEach(tags, id: \.identifier) { tag in
TagView(text: tag.localized(in: language).name)
.foregroundStyle(.white)
.foregroundStyle(.white)
}
Button(action: { showTagPicker = true }) {
Image(systemSymbol: .squareAndPencilCircleFill)

View File

@ -34,6 +34,7 @@ struct PageDetailView: View {
footer: "The page id is used to link to it internally.",
validation: page.isValid,
update: { page.update(id: $0) })
.id(page.id)
OptionalStringPropertyView(
title: "External url",

View File

@ -7,5 +7,6 @@ struct LinkedPageTagView: View {
var body: some View {
TagDisplayView(tags: $page.tags)
.id(page.id)
}
}

View File

@ -15,11 +15,24 @@ struct PostContentView: View {
}
var body: some View {
LocalizedPostContentView(
post: post.localized(in: language),
other: post.localized(in: language.next),
tags: $post.tags,
page: $post.linkedPage)
let localized = post.localized(in: language)
let other = post.localized(in: language.next)
VStack(alignment: .leading) {
PostImagesView(
post: localized,
other: other)
PostTitleView(post: localized)
if let page = post.linkedPage {
LinkedPageTagView(page: page)
} else {
TagDisplayView(tags: $post.tags)
}
PostLabelsView(
post: localized,
other: other)
PostTextView(post: localized)
}
.padding()
}
}

View File

@ -47,6 +47,7 @@ struct PostDetailView: View {
footer: "The id is used to link to post and store them",
validation: post.isValid,
update: { post.update(id: $0) })
.id(post.id)
BoolPropertyView(
title: "Draft",
@ -69,6 +70,7 @@ struct PostDetailView: View {
selectedPage: $post.linkedPage,
footer: "The page to open when clicking on the post")
.onChange(of: post.linkedPage) { oldValue, newValue in
if newValue != nil {
post.tags = []
} else {

View File

@ -1,38 +1,22 @@
import SwiftUI
struct LocalizedPostContentView: View {
struct PostImagesView: View {
@Environment(\.language)
private var language
@EnvironmentObject
private var content: Content
@ObservedObject
var post: LocalizedPost
@ObservedObject
var other: LocalizedPost
@Binding
var tags: [Tag]
@Binding
var page: Page?
@State
private var fileTypeToSelect: FileTypeCategory = .image
@State
private var showImagePicker = false
init(post: LocalizedPost, other: LocalizedPost, tags: Binding<[Tag]>, page: Binding<Page?>) {
self.post = post
self.other = other
self._tags = tags
self._page = page
}
var body: some View {
VStack(alignment: .leading) {
HStack {
@ -60,36 +44,11 @@ struct LocalizedPostContentView: View {
}
}
}
OptionalTextField("", text: $post.title)
.font(.system(size: 24, weight: .bold))
.foregroundStyle(Color.primary)
.textFieldStyle(.plain)
.lineLimit(2)
.frame(minHeight: 30)
if let page = page {
LinkedPageTagView(page: page)
} else {
TagDisplayView(tags: $tags)
}
PostLabelsView(post: post, other: other)
TextEditor(text: $post.text)
.font(.body)
.frame(minHeight: 150)
.textEditorStyle(.plain)
.padding(.vertical, 8)
.padding(.leading, 3)
.background(Color.gray.opacity(0.1))
.cornerRadius(8)
}
.padding()
.sheet(isPresented: $showImagePicker) {
MultiFileSelectionView(
selectedFiles: $post.images,
allowedType: fileTypeToSelect)
}
}
private func copyImagesFromOtherLanguage() {
post.images = other.images
}
}

View File

@ -0,0 +1,18 @@
import SwiftUI
struct PostTextView: View {
@ObservedObject
var post: LocalizedPost
var body: some View {
TextEditor(text: $post.text)
.font(.body)
.frame(minHeight: 150)
.textEditorStyle(.plain)
.padding(.vertical, 8)
.padding(.leading, 3)
.background(Color.gray.opacity(0.1))
.cornerRadius(8)
}
}

View File

@ -0,0 +1,16 @@
import SwiftUI
struct PostTitleView: View {
@ObservedObject
var post: LocalizedPost
var body: some View {
OptionalTextField("", text: $post.title)
.font(.system(size: 24, weight: .bold))
.foregroundStyle(Color.primary)
.textFieldStyle(.plain)
.lineLimit(2)
.frame(minHeight: 30)
}
}

View File

@ -38,6 +38,7 @@ struct TagDetailView: View {
validation: tag.isValid) {
tag.update(id: $0)
}
.id(tag.id)
LocalizedTagDetailView(
tag: tag.localized(in: language),