feat: focus delete in note confirmation
This commit is contained in:
@@ -141,7 +141,7 @@ Search for **Conjure Notes**, identified by its centered 📔 icon, or assign it
|
|||||||
|
|
||||||
Notes uses a standard macOS window with system-inherited appearance and only the native Close button visible; minimize and zoom are hidden. The editor uses monospaced text, including Markdown headings, bold, and italic, while retaining Conjure’s warm palette. Closing still saves first and keeps the window open if saving fails. Other launcher views remain borderless with their existing dark appearance.
|
Notes uses a standard macOS window with system-inherited appearance and only the native Close button visible; minimize and zoom are hidden. The editor uses monospaced text, including Markdown headings, bold, and italic, while retaining Conjure’s warm palette. Closing still saves first and keeps the window open if saving fails. Other launcher views remain borderless with their existing dark appearance.
|
||||||
|
|
||||||
Actions (Command-K) opens the same searchable popup style used throughout Conjure, with **Browse Notes** (Command-P), **New Note** (Command-N), and **Delete Note**. Delete Note asks for confirmation before permanently deleting the currently selected note and its embedded images. Cancel is the default; deletion cannot be undone. After deletion, Notes selects a remaining note or creates a fresh blank note if none remain. Save or deletion failures preserve the current note and editor buffer. Command-N creates a note while the editor or either popup is focused. Command-P toggles Browse Notes even while its title-bar controls are covered. Escape or clicking outside closes an open popup and returns focus to the editor without leaving Notes; another Escape dismisses the launcher. Control-J/K navigates only while a popup is open, preserving normal editor commands when it is closed.
|
Actions (Command-K) opens the same searchable popup style used throughout Conjure, with **Browse Notes** (Command-P), **New Note** (Command-N), and **Delete Note**. Delete Note asks for confirmation before permanently deleting the currently selected note and its embedded images. Delete is focused by default: Return confirms and Escape cancels; deletion cannot be undone. After deletion, Notes selects a remaining note or creates a fresh blank note if none remain. Save or deletion failures preserve the current note and editor buffer. Command-N creates a note while the editor or either popup is focused. Command-P toggles Browse Notes even while its title-bar controls are covered. Escape or clicking outside closes an open popup and returns focus to the editor without leaving Notes; another Escape dismisses the launcher. Control-J/K navigates only while a popup is open, preserving normal editor commands when it is closed.
|
||||||
|
|
||||||
The bottom strip applies Markdown headings, bold, italic, strikethrough, inline code, links, fenced code blocks, quotes, numbered lists, bullet lists, and checklists. Formatting preserves embedded images and supports Undo. List buttons convert existing list types; clicking the current type removes its marker. The strip’s × hides formatting controls; the text-format icon restores them. Successful autosaves stay unobtrusive; only save, load, or deletion errors appear below the editor.
|
The bottom strip applies Markdown headings, bold, italic, strikethrough, inline code, links, fenced code blocks, quotes, numbered lists, bullet lists, and checklists. Formatting preserves embedded images and supports Undo. List buttons convert existing list types; clicking the current type removes its marker. The strip’s × hides formatting controls; the text-format icon restores them. Successful autosaves stay unobtrusive; only save, load, or deletion errors appear below the editor.
|
||||||
|
|
||||||
|
|||||||
@@ -517,8 +517,12 @@ final class NotesController: NSViewController, NSTextViewDelegate {
|
|||||||
alert.alertStyle = .warning
|
alert.alertStyle = .warning
|
||||||
alert.messageText = "Delete “\(noteTitle.stringValue)”?"
|
alert.messageText = "Delete “\(noteTitle.stringValue)”?"
|
||||||
alert.informativeText = "This permanently deletes the note and its embedded images. This cannot be undone."
|
alert.informativeText = "This permanently deletes the note and its embedded images. This cannot be undone."
|
||||||
alert.addButton(withTitle: "Cancel")
|
alert.addButton(withTitle: "Cancel").keyEquivalent = "\u{1b}"
|
||||||
alert.addButton(withTitle: "Delete Note").hasDestructiveAction = true
|
let delete = alert.addButton(withTitle: "Delete Note")
|
||||||
|
delete.contentTintColor = .systemRed
|
||||||
|
delete.keyEquivalent = "\r"
|
||||||
|
alert.window.initialFirstResponder = delete
|
||||||
|
alert.window.defaultButtonCell = delete.cell as? NSButtonCell
|
||||||
alert.beginSheetModal(for: window) { [weak self] response in
|
alert.beginSheetModal(for: window) { [weak self] response in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
defer { self.focusEditor() }
|
defer { self.focusEditor() }
|
||||||
|
|||||||
@@ -1530,8 +1530,10 @@ func notesDeletionRequiresConfirmationPreservesFailuresAndReplacesTheLastNote()
|
|||||||
#expect(controller.handle(#selector(NSResponder.insertNewline(_:))))
|
#expect(controller.handle(#selector(NSResponder.insertNewline(_:))))
|
||||||
let sheet = try #require(window.attachedSheet)
|
let sheet = try #require(window.attachedSheet)
|
||||||
let content = try #require(sheet.contentView)
|
let content = try #require(sheet.contentView)
|
||||||
let button = try #require(descendants(content).compactMap { $0 as? NSButton }
|
let buttons = descendants(content).compactMap { $0 as? NSButton }
|
||||||
.first { $0.title == (confirm ? "Delete Note" : "Cancel") })
|
let delete = try #require(buttons.first { $0.title == "Delete Note" })
|
||||||
|
#expect(sheet.firstResponder === delete)
|
||||||
|
let button = try #require(buttons.first { $0.title == (confirm ? "Delete Note" : "Cancel") })
|
||||||
button.performClick(nil)
|
button.performClick(nil)
|
||||||
// Scheduling deadline only; deletion does not depend on wall-clock time.
|
// Scheduling deadline only; deletion does not depend on wall-clock time.
|
||||||
for _ in 0..<1_000 {
|
for _ in 0..<1_000 {
|
||||||
|
|||||||
Reference in New Issue
Block a user