import SwiftUI import HighlightedTextEditor import SFSafeSymbols struct PostContentView: View { @ObservedObject var post: Post @Environment(\.language) private var language init(post: Post) { self.post = post } var body: some View { LocalizedPostContentView( post: post.localized(in: language), other: post.localized(in: language.next), tags: $post.tags, page: $post.linkedPage) } } extension PostContentView: MainContentView { init(item: Post) { self.post = item } static let itemDescription = "a post" } private struct LinkedPageTagView: View { @ObservedObject var page: Page var body: some View { TagDisplayView(tags: $page.tags) } } struct LocalizedPostContentView: 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) { self.post = post self.other = other self._tags = tags self._page = page } var body: some View { VStack(alignment: .leading) { HStack { Text("Images/Video") .font(.headline) Button("Images") { fileTypeToSelect = .image showImagePicker = true } .disabled(post.hasVideos) Button("Videos") { fileTypeToSelect = .video showImagePicker = true } .disabled(post.hasImages) Button("Transfer from \(language.next.text)") { post.images = other.images } .disabled(other.images.isEmpty) } ScrollView(.horizontal) { HStack(alignment: .center, spacing: 8) { ForEach(post.images) { image in if image.type.isImage { image.imageToDisplay .resizable() .aspectRatio(contentMode: .fill) .frame(maxWidth: 300, maxHeight: 200) .cornerRadius(8) } else { VStack { Image(systemSymbol: .film) .resizable() .aspectRatio(contentMode: .fit) .frame(height: 100) Text(image.id) .font(.title) } //.foregroundStyle(.secondary) .frame(width: 300, height: 200) .background(Color.gray) .cornerRadius(8) } } } } 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) } 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 } } #Preview(traits: .fixedLayout(width: 450, height: 600)) { List { PostContentView(post: .fullMock) .listRowSeparator(.hidden) .environment(\.language, ContentLanguage.german) PostContentView(post: .mock) .listRowSeparator(.hidden) } .environmentObject(Content.mock) //.listStyle(.plain) }