feat: delete the selected note
This commit is contained in:
@@ -36,6 +36,7 @@ final class ApplicationActionsController: NSViewController, NSSearchFieldDelegat
|
||||
var selectNote: ((UUID) -> Void)?
|
||||
var browseNotes: (() -> Void)?
|
||||
var newNote: (() -> Void)?
|
||||
var deleteNote: (() -> Void)?
|
||||
private enum ChoiceID: Equatable {
|
||||
case language(String)
|
||||
case note(UUID)
|
||||
@@ -84,7 +85,8 @@ final class ApplicationActionsController: NSViewController, NSSearchFieldDelegat
|
||||
ActionEntry(title: "MyMemory (no key)", symbol: "checkmark", color: SunsetPalette.text),
|
||||
ActionEntry(title: "OpenAI · gpt-6-luna", symbol: "checkmark", color: SunsetPalette.text),
|
||||
ActionEntry(title: "Browse Notes", symbol: "list.bullet", color: SunsetPalette.text, commandKey: "P"),
|
||||
ActionEntry(title: "New Note", symbol: "square.and.pencil", color: SunsetPalette.text, commandKey: "N")
|
||||
ActionEntry(title: "New Note", symbol: "square.and.pencil", color: SunsetPalette.text, commandKey: "N"),
|
||||
ActionEntry(title: "Delete Note", symbol: "trash", color: .systemRed)
|
||||
]
|
||||
view = ActionsPanelView()
|
||||
view.wantsLayer = true
|
||||
@@ -257,7 +259,7 @@ final class ApplicationActionsController: NSViewController, NSSearchFieldDelegat
|
||||
}
|
||||
|
||||
func showNotesActions(relativeTo anchor: NSView) {
|
||||
show(title: "Notes", relativeTo: anchor, available: [12, 13],
|
||||
show(title: "Notes", relativeTo: anchor, available: [12, 13, 14],
|
||||
searchAccessibilityLabel: "Search notes actions", belowAnchor: true)
|
||||
}
|
||||
|
||||
@@ -464,7 +466,7 @@ final class ApplicationActionsController: NSViewController, NSSearchFieldDelegat
|
||||
}
|
||||
|
||||
private func handleCommandKey(_ key: String) -> Bool {
|
||||
guard isShown, availableEntries == [12, 13] else { return false }
|
||||
guard isShown, availableEntries == [12, 13, 14] else { return false }
|
||||
switch key {
|
||||
case "p": close(); browseNotes?()
|
||||
case "n": close(); newNote?()
|
||||
@@ -537,6 +539,7 @@ final class ApplicationActionsController: NSViewController, NSSearchFieldDelegat
|
||||
case 11: selectProvider?(true)
|
||||
case 12: browseNotes?()
|
||||
case 13: newNote?()
|
||||
case 14: deleteNote?()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ final class NotesController: NSViewController, NSTextViewDelegate {
|
||||
actions.selectNote = { [weak self] in self?.switchNote($0) }
|
||||
actions.newNote = { [weak self] in self?.newNote() }
|
||||
actions.browseNotes = { [weak self] in self?.browseNotes() }
|
||||
actions.deleteNote = { [weak self] in self?.deleteNote() }
|
||||
let tools = [
|
||||
("textformat.size", "Heading"), ("bold", "Bold"), ("italic", "Italic"),
|
||||
("strikethrough", "Strikethrough"), ("chevron.left.forwardslash.chevron.right", "Inline code"),
|
||||
@@ -509,6 +510,33 @@ final class NotesController: NSViewController, NSTextViewDelegate {
|
||||
catch { showError(error) }
|
||||
}
|
||||
|
||||
private func deleteNote() {
|
||||
guard let window = view.window, window.attachedSheet == nil, let id = selectedID else { return }
|
||||
actions.close(animated: false)
|
||||
let alert = NSAlert()
|
||||
alert.alertStyle = .warning
|
||||
alert.messageText = "Delete “\(noteTitle.stringValue)”?"
|
||||
alert.informativeText = "This permanently deletes the note and its embedded images. This cannot be undone."
|
||||
alert.addButton(withTitle: "Cancel")
|
||||
alert.addButton(withTitle: "Delete Note").hasDestructiveAction = true
|
||||
alert.beginSheetModal(for: window) { [weak self] response in
|
||||
guard let self else { return }
|
||||
defer { self.focusEditor() }
|
||||
guard response == .alertSecondButtonReturn, self.selectedID == id,
|
||||
self.save(), let store = self.store else { return }
|
||||
do {
|
||||
try store.delete(id: id)
|
||||
self.selectedID = nil
|
||||
self.defaults.removeObject(forKey: "selectedNote")
|
||||
self.editor.setMarkdownContents(NSAttributedString(string: ""))
|
||||
self.editor.undoManager?.removeAllActions()
|
||||
self.editor.isEditable = false
|
||||
self.noteTitle.stringValue = "Untitled Note"
|
||||
self.select(try store.notes.first?.id ?? store.create())
|
||||
} catch { self.showError(error) }
|
||||
}
|
||||
}
|
||||
|
||||
private func switchNote(_ id: UUID) {
|
||||
guard save() else { return }
|
||||
select(id)
|
||||
@@ -532,7 +560,7 @@ final class NotesController: NSViewController, NSTextViewDelegate {
|
||||
|
||||
private func showError(_ error: Error) {
|
||||
status.isHidden = false
|
||||
status.stringValue = "Couldn’t save or load notes: \(error.localizedDescription)"
|
||||
status.stringValue = "Couldn’t save, load, or delete notes: \(error.localizedDescription)"
|
||||
status.toolTip = status.stringValue
|
||||
status.textColor = .systemRed
|
||||
}
|
||||
|
||||
@@ -63,6 +63,14 @@ public final class NotesStore {
|
||||
notes[index] = note
|
||||
}
|
||||
|
||||
public func delete(id: UUID) throws {
|
||||
guard let index = notes.firstIndex(where: { $0.id == id }) else {
|
||||
throw CocoaError(.fileNoSuchFile)
|
||||
}
|
||||
try FileManager.default.removeItem(at: directory.appendingPathComponent(id.uuidString + ".rtfd"))
|
||||
notes.remove(at: index)
|
||||
}
|
||||
|
||||
private func save(_ note: Note) throws {
|
||||
let wrapper = try note.contents.fileWrapper(
|
||||
from: NSRange(location: 0, length: note.contents.length),
|
||||
|
||||
Reference in New Issue
Block a user