diff --git a/CHDataManagement.xcodeproj/project.pbxproj b/CHDataManagement.xcodeproj/project.pbxproj index 639b699..16b70f6 100644 --- a/CHDataManagement.xcodeproj/project.pbxproj +++ b/CHDataManagement.xcodeproj/project.pbxproj @@ -207,6 +207,7 @@ E2F3B3982DC54F9400CFA712 /* ChangeObservingItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2F3B3972DC54F8600CFA712 /* ChangeObservingItem.swift */; }; E2F3B39C2DC5542E00CFA712 /* LabelEditingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2F3B39B2DC5542E00CFA712 /* LabelEditingView.swift */; }; E2F3B39E2DC55B1C00CFA712 /* LabelCreationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2F3B39D2DC55B1C00CFA712 /* LabelCreationView.swift */; }; + E2F3B3A22DC769C300CFA712 /* DeleteButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2F3B3A12DC769BF00CFA712 /* DeleteButton.swift */; }; E2FD1D0D2D2DBBA600B48627 /* LinkPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2FD1D0C2D2DBBA100B48627 /* LinkPreview.swift */; }; E2FD1D192D2DC4F500B48627 /* LoadingContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2FD1D182D2DC4F500B48627 /* LoadingContext.swift */; }; E2FD1D1B2D2DC63800B48627 /* LinkPreviewDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2FD1D1A2D2DC62C00B48627 /* LinkPreviewDetailView.swift */; }; @@ -490,6 +491,7 @@ E2F3B3972DC54F8600CFA712 /* ChangeObservingItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeObservingItem.swift; sourceTree = ""; }; E2F3B39B2DC5542E00CFA712 /* LabelEditingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelEditingView.swift; sourceTree = ""; }; E2F3B39D2DC55B1C00CFA712 /* LabelCreationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelCreationView.swift; sourceTree = ""; }; + E2F3B3A12DC769BF00CFA712 /* DeleteButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteButton.swift; sourceTree = ""; }; E2FD1D0C2D2DBBA100B48627 /* LinkPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkPreview.swift; sourceTree = ""; }; E2FD1D182D2DC4F500B48627 /* LoadingContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingContext.swift; sourceTree = ""; }; E2FD1D1A2D2DC62C00B48627 /* LinkPreviewDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkPreviewDetailView.swift; sourceTree = ""; }; @@ -829,6 +831,7 @@ E2A21C372CB9A4F10060935B /* Generic */ = { isa = PBXGroup; children = ( + E2F3B3A12DC769BF00CFA712 /* DeleteButton.swift */, E229902F2D0F75CF009F8D77 /* BoolPropertyView.swift */, E22990312D0F7678009F8D77 /* DatePropertyView.swift */, E29D312F2D03A2BD0051B7F4 /* DescriptionField.swift */, @@ -1449,6 +1452,7 @@ E25DA58B2D020C9500AEF16D /* PageImage.swift in Sources */, E2521DFC2D5020BE00C56662 /* PostContentGenerator.swift in Sources */, E21850232CF10C850090B18B /* TagSelectionView.swift in Sources */, + E2F3B3A22DC769C300CFA712 /* DeleteButton.swift in Sources */, E2A21C332CB5BCAC0060935B /* PageContentView.swift in Sources */, E22990402D0F95EC009F8D77 /* FolderOnDiskPropertyView.swift in Sources */, E2FE0F422D2B4821002963B7 /* OtherCodeBlock.swift in Sources */, diff --git a/CHDataManagement/Main/SelectedContent.swift b/CHDataManagement/Main/SelectedContent.swift index c5d3add..df53e63 100644 --- a/CHDataManagement/Main/SelectedContent.swift +++ b/CHDataManagement/Main/SelectedContent.swift @@ -16,4 +16,10 @@ final class SelectedContent: ObservableObject { @Published var file: FileResource? + + func remove(_ post: Post) { + if self.post == post { + self.post = nil + } + } } diff --git a/CHDataManagement/Model/Content.swift b/CHDataManagement/Model/Content.swift index 53a7a75..4ceb9f9 100644 --- a/CHDataManagement/Model/Content.swift +++ b/CHDataManagement/Model/Content.swift @@ -113,6 +113,8 @@ final class Content: ObservableObject { loadFromDisk(callback: callback) } + // MARK: Removing items + func remove(_ file: FileResource) { files.remove(file) for post in posts { @@ -129,6 +131,10 @@ final class Content: ObservableObject { settings.remove(file) } + func remove(_ post: Post) { + posts.remove(post) + } + func file(withOutputPath: String) -> FileResource? { files.first { $0.absoluteUrl == withOutputPath } } diff --git a/CHDataManagement/Storage/Storage.swift b/CHDataManagement/Storage/Storage.swift index 6bc24ca..1e4d8c0 100644 --- a/CHDataManagement/Storage/Storage.swift +++ b/CHDataManagement/Storage/Storage.swift @@ -186,6 +186,16 @@ final class Storage: ObservableObject { return contentScope.move(postFilePath(post: postId), to: postFilePath(post: newId)) } + /** + Completely delete a post file from the content folder + */ + func delete(post postId: String) -> Bool { + guard let contentScope else { + return false + } + return contentScope.deleteFile(at: postFilePath(post: postId)) + } + // MARK: Tags private func tagFileName(tagId: String) -> String { diff --git a/CHDataManagement/Views/Generic/DeleteButton.swift b/CHDataManagement/Views/Generic/DeleteButton.swift new file mode 100644 index 0000000..a29b5b6 --- /dev/null +++ b/CHDataManagement/Views/Generic/DeleteButton.swift @@ -0,0 +1,20 @@ +import SwiftUI + +struct DeleteButton: View { + + let action: () -> Void + + var body: some View { + Button(action: action) { + HStack { + Spacer() + Image(systemSymbol: .trash) + Text("Delete") + .padding(.vertical, 8) + Spacer() + } + .foregroundStyle(Color.white) + .background(RoundedRectangle(cornerRadius: 8).fill(Color.red)) + }.buttonStyle(.plain) + } +} diff --git a/CHDataManagement/Views/Posts/PostDetailView.swift b/CHDataManagement/Views/Posts/PostDetailView.swift index 0d77cd3..4158962 100644 --- a/CHDataManagement/Views/Posts/PostDetailView.swift +++ b/CHDataManagement/Views/Posts/PostDetailView.swift @@ -76,6 +76,7 @@ struct PostDetailView: View { LocalizedPostDetailView( post: post.localized(in: language), transferImage: transferImage) + DeleteButton(action: deletePost) } .padding() } @@ -90,6 +91,15 @@ struct PostDetailView: View { selection.tab = .pages } } + + private func deletePost() { + guard content.storage.delete(post: post.id) else { + print("Post '\(post.id)': Failed to delete file in content folder") + return + } + content.remove(post) + selection.remove(post) + } } extension PostDetailView: MainContentView {