From 12fd0cd942f4d34b777b6b67d926b5aa7684adfe Mon Sep 17 00:00:00 2001 From: dscyrescotti Date: Thu, 27 Jun 2024 22:47:34 +0700 Subject: [PATCH] feat: add soft delete action --- Memola/Features/Memos/MemosView.swift | 38 +++++++++++++++---- Memola/Persistence/Objects/MemoObject.swift | 1 + .../MemolaModel.xcdatamodel/contents | 1 + 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/Memola/Features/Memos/MemosView.swift b/Memola/Features/Memos/MemosView.swift index e75fbb5..bd2a982 100644 --- a/Memola/Features/Memos/MemosView.swift +++ b/Memola/Features/Memos/MemosView.swift @@ -27,13 +27,14 @@ struct MemosView: View { init() { let standard = UserDefaults.standard var descriptors: [SortDescriptor] = [] - var predicate: NSPredicate? + var predicates: [NSPredicate] = [NSPredicate(format: "isTrash = NO")] let sort = Sort(rawValue: standard.value(forKey: "memola.memo-objects.sort") as? String ?? "") ?? .recent let filter = Filter(rawValue: standard.value(forKey: "memola.memo-objects.filter") as? String ?? "") ?? .none if filter == .favorites { - predicate = NSPredicate(format: "isFavorite = YES") + predicates.append(NSPredicate(format: "isFavorite = YES")) } descriptors = sort.memoSortDescriptors + let predicate = NSCompoundPredicate(type: .and, subpredicates: predicates) _memoObjects = FetchRequest(sortDescriptors: descriptors, predicate: predicate) } @@ -156,6 +157,18 @@ struct MemosView: View { Rectangle() .frame(height: cellHeight) .clipShape(RoundedRectangle(cornerRadius: 10)) + .contextMenu { + Button { + openMemo(for: memoObject) + } label: { + Label("Open", systemImage: "doc.text") + } + Button(role: .destructive) { + markAsTrash(for: memoObject) + } label: { + Label("Delete", systemImage: "trash") + } + } .overlay(alignment: .topTrailing) { Image(systemName: memoObject.isFavorite ? "star.fill" : "star") .foregroundStyle(memoObject.isFavorite ? .yellow : .white) @@ -165,10 +178,7 @@ struct MemosView: View { .cornerRadius(5) .contentShape(Rectangle()) .onTapGesture { - memoObject.isFavorite.toggle() - withPersistence(\.viewContext) { context in - try context.saveIfNeeded() - } + toggleFavorite(for: memoObject) } .contentTransition(.symbolEffect(.replace)) .padding(5) @@ -243,7 +253,7 @@ struct MemosView: View { } func updatePredicate() { - var predicates: [NSPredicate] = [] + var predicates: [NSPredicate] = [NSPredicate(format: "isTrash = NO")] if !query.isEmpty { predicates.append(NSPredicate(format: "title contains[c] %@", query)) } @@ -252,4 +262,18 @@ struct MemosView: View { } memoObjects.nsPredicate = NSCompoundPredicate(type: .and, subpredicates: predicates) } + + func toggleFavorite(for memo: MemoObject) { + memo.isFavorite.toggle() + withPersistence(\.viewContext) { context in + try context.saveIfNeeded() + } + } + + func markAsTrash(for memo: MemoObject) { + memo.isTrash = true + withPersistence(\.viewContext) { context in + try context.saveIfNeeded() + } + } } diff --git a/Memola/Persistence/Objects/MemoObject.swift b/Memola/Persistence/Objects/MemoObject.swift index 724bc9e..87ab58d 100644 --- a/Memola/Persistence/Objects/MemoObject.swift +++ b/Memola/Persistence/Objects/MemoObject.swift @@ -15,6 +15,7 @@ final class MemoObject: NSManagedObject, Identifiable { @NSManaged var createdAt: Date @NSManaged var updatedAt: Date @NSManaged var isFavorite: Bool + @NSManaged var isTrash: Bool @NSManaged var tool: ToolObject @NSManaged var canvas: CanvasObject } diff --git a/Memola/Resources/Models/MemolaModel.xcdatamodeld/MemolaModel.xcdatamodel/contents b/Memola/Resources/Models/MemolaModel.xcdatamodeld/MemolaModel.xcdatamodel/contents index 69dfb37..bf92615 100644 --- a/Memola/Resources/Models/MemolaModel.xcdatamodeld/MemolaModel.xcdatamodel/contents +++ b/Memola/Resources/Models/MemolaModel.xcdatamodeld/MemolaModel.xcdatamodel/contents @@ -30,6 +30,7 @@ +