mirror of
https://github.com/dscyrescotti/Memola.git
synced 2026-04-25 01:58:52 +02:00
feat: add soft delete action
This commit is contained in:
@@ -27,13 +27,14 @@ struct MemosView: View {
|
|||||||
init() {
|
init() {
|
||||||
let standard = UserDefaults.standard
|
let standard = UserDefaults.standard
|
||||||
var descriptors: [SortDescriptor<MemoObject>] = []
|
var descriptors: [SortDescriptor<MemoObject>] = []
|
||||||
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 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
|
let filter = Filter(rawValue: standard.value(forKey: "memola.memo-objects.filter") as? String ?? "") ?? .none
|
||||||
if filter == .favorites {
|
if filter == .favorites {
|
||||||
predicate = NSPredicate(format: "isFavorite = YES")
|
predicates.append(NSPredicate(format: "isFavorite = YES"))
|
||||||
}
|
}
|
||||||
descriptors = sort.memoSortDescriptors
|
descriptors = sort.memoSortDescriptors
|
||||||
|
let predicate = NSCompoundPredicate(type: .and, subpredicates: predicates)
|
||||||
_memoObjects = FetchRequest(sortDescriptors: descriptors, predicate: predicate)
|
_memoObjects = FetchRequest(sortDescriptors: descriptors, predicate: predicate)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,6 +157,18 @@ struct MemosView: View {
|
|||||||
Rectangle()
|
Rectangle()
|
||||||
.frame(height: cellHeight)
|
.frame(height: cellHeight)
|
||||||
.clipShape(RoundedRectangle(cornerRadius: 10))
|
.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) {
|
.overlay(alignment: .topTrailing) {
|
||||||
Image(systemName: memoObject.isFavorite ? "star.fill" : "star")
|
Image(systemName: memoObject.isFavorite ? "star.fill" : "star")
|
||||||
.foregroundStyle(memoObject.isFavorite ? .yellow : .white)
|
.foregroundStyle(memoObject.isFavorite ? .yellow : .white)
|
||||||
@@ -165,10 +178,7 @@ struct MemosView: View {
|
|||||||
.cornerRadius(5)
|
.cornerRadius(5)
|
||||||
.contentShape(Rectangle())
|
.contentShape(Rectangle())
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
memoObject.isFavorite.toggle()
|
toggleFavorite(for: memoObject)
|
||||||
withPersistence(\.viewContext) { context in
|
|
||||||
try context.saveIfNeeded()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.contentTransition(.symbolEffect(.replace))
|
.contentTransition(.symbolEffect(.replace))
|
||||||
.padding(5)
|
.padding(5)
|
||||||
@@ -243,7 +253,7 @@ struct MemosView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func updatePredicate() {
|
func updatePredicate() {
|
||||||
var predicates: [NSPredicate] = []
|
var predicates: [NSPredicate] = [NSPredicate(format: "isTrash = NO")]
|
||||||
if !query.isEmpty {
|
if !query.isEmpty {
|
||||||
predicates.append(NSPredicate(format: "title contains[c] %@", query))
|
predicates.append(NSPredicate(format: "title contains[c] %@", query))
|
||||||
}
|
}
|
||||||
@@ -252,4 +262,18 @@ struct MemosView: View {
|
|||||||
}
|
}
|
||||||
memoObjects.nsPredicate = NSCompoundPredicate(type: .and, subpredicates: predicates)
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ final class MemoObject: NSManagedObject, Identifiable {
|
|||||||
@NSManaged var createdAt: Date
|
@NSManaged var createdAt: Date
|
||||||
@NSManaged var updatedAt: Date
|
@NSManaged var updatedAt: Date
|
||||||
@NSManaged var isFavorite: Bool
|
@NSManaged var isFavorite: Bool
|
||||||
|
@NSManaged var isTrash: Bool
|
||||||
@NSManaged var tool: ToolObject
|
@NSManaged var tool: ToolObject
|
||||||
@NSManaged var canvas: CanvasObject
|
@NSManaged var canvas: CanvasObject
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
<entity name="MemoObject" representedClassName="MemoObject" syncable="YES">
|
<entity name="MemoObject" representedClassName="MemoObject" syncable="YES">
|
||||||
<attribute name="createdAt" attributeType="Date" usesScalarValueType="NO"/>
|
<attribute name="createdAt" attributeType="Date" usesScalarValueType="NO"/>
|
||||||
<attribute name="isFavorite" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
<attribute name="isFavorite" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="isTrash" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
<attribute name="title" attributeType="String"/>
|
<attribute name="title" attributeType="String"/>
|
||||||
<attribute name="updatedAt" attributeType="Date" usesScalarValueType="NO"/>
|
<attribute name="updatedAt" attributeType="Date" usesScalarValueType="NO"/>
|
||||||
<relationship name="canvas" maxCount="1" deletionRule="Cascade" destinationEntity="CanvasObject" inverseName="memo" inverseEntity="CanvasObject"/>
|
<relationship name="canvas" maxCount="1" deletionRule="Cascade" destinationEntity="CanvasObject" inverseName="memo" inverseEntity="CanvasObject"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user