Skip to content

feat: use a commands for a user interactions - #195

Merged
vitonsky merged 85 commits into
DeepinkApp:masterfrom
katsyuta:116-use-commands-for-user-interactions
Mar 8, 2026
Merged

feat: use a commands for a user interactions#195
vitonsky merged 85 commits into
DeepinkApp:masterfrom
katsyuta:116-use-commands-for-user-interactions

Conversation

@katsyuta

@katsyuta katsyuta commented Jan 4, 2026

Copy link
Copy Markdown
Collaborator

Closes #116

Changes:

  • Use command in note menu
  • Use command in note context menu
  • Added shortcuts:
    • CmdOrCtrl+Shift+A: toggle current note archive
    • CmdOrCtrl+Shift+B: toggle current note bookmark
    • CmdOrCtrl+Delete: delete current note to bin
    • CmdOrCtrl+Shift+R: restore current note from bin
    • CmdOrCtrl+S: save changes to db
    • CmdOrCtrl+H: open note history
    • CmdOrCtrl+F: focus to search input
    • CmdOrCtrl+.: open setting

Summary by CodeRabbit

  • New Features

    • Added keyboard shortcuts for note operations: archive, bookmark, delete, export, duplicate, and restore.
    • Added database synchronization keyboard shortcut.
    • Added note history panel toggle keyboard shortcut.
    • Added search input focus keyboard shortcut.
  • Tests

    • Added unit tests for note file naming and markdown link utilities.

@katsyuta
katsyuta force-pushed the 116-use-commands-for-user-interactions branch from ad27f4a to e071a03 Compare January 4, 2026 20:52
@katsyuta katsyuta changed the title feat: add command for history feat: use commands for user interactions Jan 5, 2026
@katsyuta
katsyuta marked this pull request as ready for review January 6, 2026 21:47
@katsyuta
katsyuta force-pushed the 116-use-commands-for-user-interactions branch 2 times, most recently from ed2b7f8 to ea535f1 Compare January 12, 2026 23:24
@vitonsky
vitonsky marked this pull request as draft January 13, 2026 16:46
@katsyuta
katsyuta force-pushed the 116-use-commands-for-user-interactions branch from f3fc234 to ff01ae2 Compare January 13, 2026 22:56
@katsyuta
katsyuta marked this pull request as ready for review January 13, 2026 23:05
@katsyuta
katsyuta force-pushed the 116-use-commands-for-user-interactions branch from 7669598 to e35ce32 Compare January 23, 2026 21:06
Comment thread src/features/accentColorsMap.tsx
Comment thread src/hooks/commands/index.ts Outdated
Comment thread src/features/App/Profile/ProfileStatusBar/useProfileSyncButton.tsx Outdated
@katsyuta
katsyuta force-pushed the 116-use-commands-for-user-interactions branch 3 times, most recently from e312f8d to f485353 Compare February 2, 2026 13:25
@katsyuta
katsyuta force-pushed the 116-use-commands-for-user-interactions branch from 49eaebf to 0d6ca6b Compare February 14, 2026 12:16
@katsyuta
katsyuta requested a review from vitonsky February 14, 2026 12:41
Comment thread src/hooks/commands/index.ts Outdated
Comment thread src/hooks/shortcuts/useWorkspaceShortcutsHandlers.ts Outdated
Comment thread src/hooks/shortcuts/useWorkspaceShortcutsHandlers.ts
Comment thread src/hooks/useGlobalShortcutHandlers.ts Outdated
Comment thread src/hooks/commands/shortcuts/index.ts Outdated
Comment thread src/hooks/shortcuts/useShortcutCallback.ts
Comment thread src/hooks/notes/useNoteCommandHandlers.ts Outdated
@katsyuta katsyuta closed this Feb 19, 2026
@katsyuta
katsyuta force-pushed the 116-use-commands-for-user-interactions branch from 2715bfe to c7f0d07 Compare February 19, 2026 17:53
@katsyuta katsyuta reopened this Feb 19, 2026
@katsyuta
katsyuta requested a review from vitonsky February 20, 2026 11:26
@katsyuta

katsyuta commented Mar 4, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Mar 4, 2026

Copy link
Copy Markdown
✅ Actions performed

Full review triggered.

@coderabbitai

coderabbitai Bot commented Mar 4, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This pull request refactors the application to use a command-dispatch architecture for user interactions. It replaces direct callbacks and state updates with centralized command handlers, introduces a dedicated shortcuts management system, and migrates note-related operations (archiving, bookmarking, deleting, exporting, copying links, duplicating) to command-based flows across the editor, menus, and context menus.

Changes

Cohort / File(s) Summary
Command Infrastructure
src/hooks/commands/index.ts, src/hooks/commands/useCommandCallback.ts
Expanded GLOBAL_COMMANDS enum with 10+ new commands for note operations (DELETE_NOTE_PERMANENTLY, MOVE_NOTE_TO_BIN, TOGGLE_NOTE_ARCHIVE, TOGGLE_NOTE_BOOKMARK, etc.), added CommandsWithPayload type mapping commands to their payload structures, and added type-safe payload casting in command callback invocation.
Shortcuts Module
src/hooks/shortcuts/index.ts, src/hooks/shortcuts/useShortcutCallback.ts, src/hooks/shortcuts/useShortcutsBinding.ts, src/hooks/shortcuts/useWorkspaceShortcutsCallback.ts
Created centralized shortcuts system with Shortcuts enum, SHORTCUTS_MAP, and SHORTCUT_NAMES; added useShortcutCallback hook for shortcut handling; updated useShortcutsBinding to dispatch SHORTCUT_PRESSED commands; created useWorkspaceShortcutsCallback to gate shortcuts by workspace active state. Removed old shortcuts from commands module.
Workspace Shortcut Handlers
src/features/App/Profile/useVaultShortcutsHandlers.ts, src/features/App/Workspace/useWorkspaceShortcutsHandlers.ts
Added useVaultShortcutsHandlers hook binding three profile shortcuts (LOCK_CURRENT_PROFILE, SYNC_DATABASE, OPEN_GLOBAL_SETTINGS) to commands; added comprehensive useWorkspaceShortcutsHandlers hook with 11 shortcut bindings for note operations, including conditional logic for delete (permanent vs. bin) and archive/bookmark/history panel toggles guarded by activeNoteId.
Note Command Handlers
src/hooks/notes/useNoteCommandHandlers.ts
New centralized handler hook registering 8 global commands for note mutations (MOVE_NOTE_TO_BIN, DELETE_NOTE_PERMANENTLY, RESTORE_NOTE_FROM_BIN, EXPORT_NOTE, COPY_NOTE_MARKDOWN_LINK, DUPLICATE_NOTE, TOGGLE_NOTE_ARCHIVE, TOGGLE_NOTE_BOOKMARK), replacing direct registry updates with command dispatch, including telemetry integration.
Note Utilities
src/hooks/notes/convertNoteToFileName.ts, src/hooks/notes/getNoteMarkdownLinkTitle.ts, src/hooks/notes/convertNoteToFileName.test.ts, src/hooks/notes/getNoteMarkdownLinkTitle.test.ts
Added convertNoteToFileName utility to sanitize note titles into filenames with truncation and fallback; added getNoteMarkdownLinkTitle utility to format note content for Markdown links with escaping; included comprehensive unit tests for both utilities.
Editor UI Refactoring
src/features/NoteEditor/NoteMenu.tsx, src/features/NoteEditor/index.tsx, src/features/App/Workspace/useActiveNoteHistoryButton.tsx
Converted NoteMenu from callback-driven to command-driven, removed onClick prop, added command dispatch for copy link, export, archive, delete, and restore operations; updated NoteEditor to dispatch commands for bookmark/archive/history panel toggles via useWorkspaceCommandCallback; wired history button to dispatch TOGGLE_NOTE_HISTORY_PANEL command.
Context Menu Refactoring
src/features/NotesContainer/NoteContextMenu/useNoteContextMenu.ts
Removed ContextMenuOptions parameter and external callbacks (closeNote, updateNotes), replaced direct registry operations and side effects with GLOBAL_COMMANDS dispatch for all note mutations, simplified hook dependencies to only telemetry and command runner.
Container Components
src/features/NotesContainer/OpenedNotesPanel.tsx, src/features/NotesContainer/index.tsx, src/features/MainScreen/NotesListPanel/NotesList.tsx, src/features/MainScreen/NotesListPanel/index.tsx
Removed updateNotes prop propagation through TopBarProps and component tree; updated useNoteContextMenu calls to be parameterless; renamed useNoteShortcutActions to useNotesShortcutActions; added searchInputRef and FOCUS_SEARCH command handler for programmatic search focus.
Command Registry & Initialization
src/features/MainScreen/WorkspaceCommandRegistry.tsx, src/features/MainScreen/index.tsx
Added WorkspaceCommandRegistry component that mounts useWorkspaceShortcutsHandlers and useNoteCommandHandlers hooks to register all command handlers; rendered in MainScreen layout to centralize command/handler initialization.
Settings & Migrations
src/features/App/Profile/index.tsx, src/features/App/Settings/sections/HotKeysSettings.tsx, src/hooks/commands/shortcuts/index.ts, src/hooks/notes/useNotesShortcutActions.ts
Updated Profile component to invoke useVaultShortcutsHandlers; updated HotKeysSettings to import from centralized shortcuts module (SHORTCUTS_MAP instead of shortcuts); removed old shortcuts export from commands module; renamed hook useNoteShortcutActions → useNotesShortcutActions.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI as NoteEditor/Menu
    participant Command as Command System
    participant Handler as Note Handlers
    participant Registry as Notes Registry
    
    User->>UI: Click archive/bookmark/delete button
    UI->>Command: dispatch GLOBAL_COMMAND with noteId
    Command->>Handler: execute registered handler
    Handler->>Registry: fetch note, update state
    Handler->>Handler: emit NOTE_UPDATED/NOTES_UPDATED
    Handler->>Handler: log telemetry
    Handler-->>UI: (async, state update via event)
    UI-->>User: UI reflects updated note state
Loading
sequenceDiagram
    participant User
    participant Keyboard as Keyboard Input
    participant Shortcuts as Shortcuts System
    participant Command as Command System
    participant Handlers as Workspace Handlers
    
    User->>Keyboard: Press shortcut key (e.g., Cmd+D)
    Keyboard->>Shortcuts: useShortcutsBinding detects keystroke
    Shortcuts->>Command: dispatch SHORTCUT_PRESSED with shortcut enum
    Command->>Handlers: useShortcutCallback matches & calls handler
    Handlers->>Handlers: execute associated GLOBAL_COMMAND
    Handlers-->>User: action completed (delete, archive, etc.)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 Hops through code with glee,
Commands now flow endlessly,
Shortcuts dance, handlers sing,
Notes find wings—what joy they bring!
From callbacks old to dispatch new,
The refactor hops straight through!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title mentions 'use a commands' (grammatically awkward) and refers to a valid core aspect of the changeset—adopting commands for user interactions—but is vague about scope and contains grammatical error. Correct grammar to 'feat: use commands for user interactions' to improve clarity and grammatical accuracy.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The PR fully implements all coding requirements from issue #116: replaces direct UI handlers with commands in note menu and context menu, wires keyboard shortcuts for note actions and app-wide operations, applies commands to features from PR #115, and integrates the app-wide commands system throughout.
Out of Scope Changes check ✅ Passed All changes align with the issue #116 objectives. The PR includes utility functions for note file naming and markdown links, new hooks for command handling and shortcuts binding, and command registry infrastructure—all directly supporting the implementation of command-driven user interactions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/features/App/Profile/index.tsx`:
- Line 162: The current useCommandCallback handler calls db.sync() without
awaiting or handling rejections, causing potential unhandled promise rejections;
update the callback registered with
useCommandCallback(GLOBAL_COMMANDS.SYNC_DATABASE, ...) to call db.sync() and
attach explicit error handling (e.g., .catch or async/try-catch) that logs the
error and handles failure appropriately instead of leaving the Promise
unhandled—ensure you reference the useCommandCallback registration and the
db.sync() call so the fix is applied to the exact listener.

In `@src/features/App/Workspace/useWorkspaceShortcutsHandlers.ts`:
- Around line 76-87: The current shortcut handler for
Shortcuts.DELETE_CURRENT_NOTE uses deletionConfig.permanentDeletion to decide
deletion mode, so it doesn't support a distinct "permanently delete" shortcut;
update this by adding a new shortcut handler (e.g.,
Shortcuts.DELETE_CURRENT_NOTE_PERMANENT) alongside the existing
useShortcutCallback for Shortcuts.DELETE_CURRENT_NOTE and call
command(GLOBAL_COMMANDS.DELETE_NOTE, { noteId: activeNoteId, permanently: true
}) in that new handler, while leaving the existing handler to use
deletionConfig.permanentDeletion; reference deletionConfig, useShortcutCallback,
Shortcuts.DELETE_CURRENT_NOTE, the new Shortcuts constant name you choose,
GLOBAL_COMMANDS.DELETE_NOTE, and activeNoteId when making the changes.

In `@src/features/NoteEditor/index.tsx`:
- Around line 213-221: The TOGGLE_NOTE_HISTORY_PANEL handler registered with
useWorkspaceCommandCallback (GLOBAL_COMMANDS.TOGGLE_NOTE_HISTORY_PANEL)
currently ignores the command payload and toggles the panel for every editor;
update the callback to inspect the incoming payload (e.g., payload.noteId) and
only call setSidePanel to toggle NoteSidebarTabs.HISTORY when payload.noteId
matches this editor's noteId (or when payload is undefined for broadcast
behavior), leaving other editors untouched; ensure the check uses the same
noteId identifier available in this component and preserve the existing isActive
gating.

In `@src/features/NoteEditor/NoteMenu.tsx`:
- Around line 51-56: Several menu entries in NoteMenu.tsx (the MenuItem elements
around the shown FaBell/HStack block and the groups at ranges 72-95 and 107-118)
are placeholders that look actionable but do nothing; mark those MenuItem
instances as disabled (e.g., add the isDisabled prop and appropriate
aria-disabled/title text) or replace them with non-interactive elements so they
cannot be clicked until their handlers are implemented, and ensure any visual
affordance (opacity/tooltip) communicates they are disabled.
- Around line 35-37: The icon-only menu trigger (MenuButton in NoteMenu.tsx)
lacks an accessible name; add an aria-label (or aria-labelledby to a visually
hidden label) to the MenuButton used as the Button (the MenuButton as={Button}
variant="ghost" size="sm") so assistive tech gets a clear name (e.g., "More
options" or similar); update the MenuButton props to include aria-label="More
options" or hook it up to a hidden span and ensure the label text is localized
if applicable.

In `@src/hooks/notes/useNoteCommandHandlers.ts`:
- Around line 128-130: The warning message in useNoteCommandHandlers (inside the
handler where it checks if (!sourceNote)) logs the wrong variable; change the
console.warn call to interpolate the requested note id (noteId) instead of
sourceNote so the message shows the actual missing note id; locate the check
using sourceNote and update the log string to reference noteId and include clear
context (e.g., "Not found note with id ${noteId}") to avoid misleading output.
- Line 119: Remove the plaintext markdown-link logging in
useNoteCommandHandlers: locate the console.log(`Copy markdown link
${markdownLink}`) call inside the handler in useNoteCommandHandlers and delete
it (or replace with a non-sensitive diagnostic such as a static debug flag or
count). Ensure no note-derived title or id is emitted to runtime logs; if you
need telemetry, send an anonymized event (e.g., success boolean) instead of the
markdownLink string.
- Around line 93-102: The handler registered with useWorkspaceCommandCallback
for GLOBAL_COMMANDS.EXPORT_NOTE calls notesExport.exportNote even when
notes.getById([noteId]) returns undefined; update the callback to check the
retrieved note (from notes.getById) before calling notesExport.exportNote: if
note is missing, bail out early (return or log/report an error) and avoid
calling buildFileName with note?.content; otherwise proceed to call
notesExport.exportNote with the safe filename built from workspaceData?.name and
note.content.title (trimmed and truncated) so you never dereference a missing
note.

In `@src/hooks/shortcuts/index.ts`:
- Around line 33-35: The shortcuts map is missing a binding for the
permanent-delete action; add a key 'CmdOrCtrl+Shift+Delete' mapped to the
appropriate enum value (e.g., Shortcuts.PERMANENT_DELETE) alongside the existing
'CmdOrCtrl+Delete' and 'CmdOrCtrl+Shift+R' entries in
src/hooks/shortcuts/index.ts, and if the Shortcuts enum/type lacks a
PERMANENT_DELETE member add it to the Shortcuts declaration so the action can be
uniquely triggered.

In `@src/hooks/shortcuts/useShortcutsBinding.ts`:
- Around line 35-45: The hotkeys handler created in the loop over
normalizedShortcuts (where hotkeys(...) calls runCommand with
GLOBAL_COMMANDS.SHORTCUT_PRESSED) must suppress native browser actions; update
the handler to accept the event parameter and call event.preventDefault() (or
return false) before invoking runCommand so shortcuts like Cmd/Ctrl+F and
Cmd/Ctrl+S don't trigger default browser behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9fd5224f-5c23-4a29-a9bb-904dec8dca04

📥 Commits

Reviewing files that changed from the base of the PR and between 3039225 and 4bcf4ba.

📒 Files selected for processing (21)
  • src/features/App/Profile/index.tsx
  • src/features/App/Profile/useVaultShortcutsHandlers.ts
  • src/features/App/Settings/sections/HotKeysSettings.tsx
  • src/features/App/Workspace/useActiveNoteHistoryButton.tsx
  • src/features/App/Workspace/useWorkspaceShortcutsHandlers.ts
  • src/features/MainScreen/NotesListPanel/NotesList.tsx
  • src/features/MainScreen/NotesListPanel/index.tsx
  • src/features/MainScreen/index.tsx
  • src/features/NoteEditor/NoteMenu.tsx
  • src/features/NoteEditor/index.tsx
  • src/features/NotesContainer/NoteContextMenu/useNoteContextMenu.ts
  • src/features/NotesContainer/OpenedNotesPanel.tsx
  • src/features/NotesContainer/index.tsx
  • src/hooks/commands/index.ts
  • src/hooks/commands/shortcuts/index.ts
  • src/hooks/commands/useCommandCallback.ts
  • src/hooks/notes/useNoteCommandHandlers.ts
  • src/hooks/notes/useNotesShortcutActions.ts
  • src/hooks/shortcuts/index.ts
  • src/hooks/shortcuts/useShortcutCallback.ts
  • src/hooks/shortcuts/useShortcutsBinding.ts
💤 Files with no reviewable changes (1)
  • src/hooks/commands/shortcuts/index.ts

Comment thread src/features/App/Profile/index.tsx
Comment thread src/features/App/Workspace/useWorkspaceShortcutsHandlers.ts Outdated
Comment thread src/features/NoteEditor/index.tsx
Comment thread src/features/NoteEditor/NoteMenu.tsx Outdated
Comment thread src/features/NoteEditor/NoteMenu.tsx
Comment thread src/hooks/notes/useNoteCommandHandlers.ts
Comment thread src/hooks/notes/useNoteCommandHandlers.ts Outdated
Comment thread src/hooks/notes/useNoteCommandHandlers.ts
Comment thread src/hooks/shortcuts/index.ts
Comment thread src/hooks/shortcuts/useShortcutsBinding.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
src/hooks/notes/useNoteCommandHandlers.ts (2)

32-36: Consolidate duplicate useNotesRegistry() calls.

Both notes (line 32) and notesRegistry (line 36) call the same hook, creating redundant references. Consider using a single variable throughout the hook for consistency.

♻️ Suggested consolidation
 	const telemetry = useTelemetryTracker();
 	const notes = useNotesRegistry();
 	const tagsRegistry = useTagsRegistry();

 	const noteActions = useNoteActions();
-	const notesRegistry = useNotesRegistry();

Then update the usages in TOGGLE_NOTE_ARCHIVE and TOGGLE_NOTE_BOOKMARK handlers to use notes instead of notesRegistry.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/hooks/notes/useNoteCommandHandlers.ts` around lines 32 - 36, There are
duplicate calls to useNotesRegistry(): the variables notes and notesRegistry
both reference the same hook; remove the redundant call by keeping a single
variable (e.g., notes) returned from useNotesRegistry() and delete the other
declaration, then update all usages within this file—specifically inside the
TOGGLE_NOTE_ARCHIVE and TOGGLE_NOTE_BOOKMARK handlers—to reference notes instead
of notesRegistry (ensure any other references in useNoteCommandHandlers,
noteActions or related handlers now use the consolidated variable).

93-104: Minor: Unnecessary optional chaining after null guard.

At line 101, note?.content.title uses optional chaining even though note is confirmed to exist at line 95. This is not a bug but a minor inconsistency.

♻️ Suggested fix
 		await notesExport.exportNote(
 			noteId,
 			buildFileName(
 				workspaceData?.name,
-				note?.content.title.trim().slice(0, 50).trim() || `note_${noteId}`,
+				note.content.title.trim().slice(0, 50).trim() || `note_${noteId}`,
 			),
 		);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/hooks/notes/useNoteCommandHandlers.ts` around lines 93 - 104, The
optional chaining on note (note?.content.title) is redundant because note is
already null-guarded earlier; update the EXPORT_NOTE handler
(useWorkspaceCommandCallback for GLOBAL_COMMANDS.EXPORT_NOTE) to use
note.content.title instead of note?.content.title when building the filename
(references: notes.getById, notesExport.exportNote, buildFileName,
workspaceData, note.content.title) to remove the unnecessary optional chaining.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/hooks/notes/useNoteCommandHandlers.ts`:
- Around line 32-36: There are duplicate calls to useNotesRegistry(): the
variables notes and notesRegistry both reference the same hook; remove the
redundant call by keeping a single variable (e.g., notes) returned from
useNotesRegistry() and delete the other declaration, then update all usages
within this file—specifically inside the TOGGLE_NOTE_ARCHIVE and
TOGGLE_NOTE_BOOKMARK handlers—to reference notes instead of notesRegistry
(ensure any other references in useNoteCommandHandlers, noteActions or related
handlers now use the consolidated variable).
- Around line 93-104: The optional chaining on note (note?.content.title) is
redundant because note is already null-guarded earlier; update the EXPORT_NOTE
handler (useWorkspaceCommandCallback for GLOBAL_COMMANDS.EXPORT_NOTE) to use
note.content.title instead of note?.content.title when building the filename
(references: notes.getById, notesExport.exportNote, buildFileName,
workspaceData, note.content.title) to remove the unnecessary optional chaining.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: aa08c910-547e-48dc-b347-e0e55b7d5ae9

📥 Commits

Reviewing files that changed from the base of the PR and between 4bcf4ba and 0aafb9e.

📒 Files selected for processing (1)
  • src/hooks/notes/useNoteCommandHandlers.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
src/features/NoteEditor/NoteMenu.tsx (1)

35-37: ⚠️ Potential issue | 🟡 Minor

The title attribute does not provide an accessible name for screen readers.

While title="Note options" was added, the title attribute is not reliably announced by screen readers and doesn't serve as an accessible name. The previous review suggested adding aria-label, which is the correct approach for icon-only buttons.

♿ Suggested fix
-			<MenuButton as={Button} variant="ghost" size="sm" title="Note options">
+			<MenuButton
+				as={Button}
+				variant="ghost"
+				size="sm"
+				title="Note options"
+				aria-label="Note options"
+			>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/features/NoteEditor/NoteMenu.tsx` around lines 35 - 37, The MenuButton
icon-only control in NoteMenu.tsx (the MenuButton as={Button} rendering
FaEllipsis) lacks a proper accessible name; add an aria-label (e.g.,
aria-label="Note options") to the MenuButton component so screen readers get a
reliable name (you can keep or remove the title attribute but ensure aria-label
is present on the MenuButton/Button element that renders the FaEllipsis icon).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/features/NoteEditor/NoteMenu.tsx`:
- Around line 35-37: The MenuButton icon-only control in NoteMenu.tsx (the
MenuButton as={Button} rendering FaEllipsis) lacks a proper accessible name; add
an aria-label (e.g., aria-label="Note options") to the MenuButton component so
screen readers get a reliable name (you can keep or remove the title attribute
but ensure aria-label is present on the MenuButton/Button element that renders
the FaEllipsis icon).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a7ab6815-1186-4e10-89e6-46f81a876fb4

📥 Commits

Reviewing files that changed from the base of the PR and between 0aafb9e and 3d5489c.

📒 Files selected for processing (1)
  • src/features/NoteEditor/NoteMenu.tsx

@katsyuta

katsyuta commented Mar 4, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Mar 4, 2026

Copy link
Copy Markdown
✅ Actions performed

Full review triggered.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/hooks/notes/useNoteCommandHandlers.ts (1)

92-186: Consider extracting a shared note-fetch guard helper.

Several handlers repeat getById + missing-note logging/return logic. A small helper would reduce duplication and keep guard behavior uniform.

♻️ Refactor sketch
+const getNoteOrWarn = async (noteId: string) => {
+	const [note] = await notes.getById([noteId]);
+	if (!note) {
+		console.warn(`Not found note with id ${noteId}`);
+		return null;
+	}
+	return note;
+};
+
 useWorkspaceCommandCallback(GLOBAL_COMMANDS.EXPORT_NOTE, async ({ noteId }) => {
-	const [note] = await notes.getById([noteId]);
-	if (!note) return;
+	const note = await getNoteOrWarn(noteId);
+	if (!note) return;
 	// ...
 });

 useWorkspaceCommandCallback(
 	GLOBAL_COMMANDS.TOGGLE_NOTE_ARCHIVE,
 	async ({ noteId }) => {
-		const [note] = await notes.getById([noteId]);
-		if (!note) {
-			console.warn(`Not found note with id ${noteId}`);
-			return;
-		}
+		const note = await getNoteOrWarn(noteId);
+		if (!note) return;
 		// ...
 	},
 );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/hooks/notes/useNoteCommandHandlers.ts` around lines 92 - 186, Extract a
small helper (e.g., fetchNoteOrWarn or getNoteOrLog) that wraps
notes.getById(noteId) and centralizes the missing-note behavior (log a
consistent warning/error and return null/undefined), then replace the repeated
patterns inside the useWorkspaceCommandCallback handlers for
GLOBAL_COMMANDS.EXPORT_NOTE, COPY_NOTE_MARKDOWN_LINK, DUPLICATE_NOTE,
TOGGLE_NOTE_ARCHIVE and TOGGLE_NOTE_BOOKMARK to call this helper and
early-return when it yields no note; ensure the helper preserves the original
logging levels/messages used in the current handlers
(console.error/console.warn) and update consumers to use the returned note
object for their subsequent logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/hooks/notes/useNoteCommandHandlers.ts`:
- Around line 92-186: Extract a small helper (e.g., fetchNoteOrWarn or
getNoteOrLog) that wraps notes.getById(noteId) and centralizes the missing-note
behavior (log a consistent warning/error and return null/undefined), then
replace the repeated patterns inside the useWorkspaceCommandCallback handlers
for GLOBAL_COMMANDS.EXPORT_NOTE, COPY_NOTE_MARKDOWN_LINK, DUPLICATE_NOTE,
TOGGLE_NOTE_ARCHIVE and TOGGLE_NOTE_BOOKMARK to call this helper and
early-return when it yields no note; ensure the helper preserves the original
logging levels/messages used in the current handlers
(console.error/console.warn) and update consumers to use the returned note
object for their subsequent logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 24e365f5-9227-4241-b0a5-136bdf43237f

📥 Commits

Reviewing files that changed from the base of the PR and between 3d5489c and cb5325d.

📒 Files selected for processing (1)
  • src/hooks/notes/useNoteCommandHandlers.ts

@katsyuta
katsyuta force-pushed the 116-use-commands-for-user-interactions branch from 5244e23 to 097dd85 Compare March 7, 2026 23:32
@katsyuta
katsyuta requested a review from vitonsky March 8, 2026 01:03
Comment thread src/hooks/notes/getNoteMarkdownLinkTitle.test.ts Outdated
Comment thread src/hooks/notes/getNoteMarkdownLinkTitle.ts Outdated
Comment thread src/hooks/notes/getNoteMarkdownLinkTitle.ts Outdated
@katsyuta
katsyuta requested a review from vitonsky March 8, 2026 10:51
@vitonsky vitonsky changed the title feat: use commands for user interactions feat: use a commands for a user interactions Mar 8, 2026
@vitonsky
vitonsky merged commit 5f7374a into DeepinkApp:master Mar 8, 2026
9 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request May 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use commands for user interactions

2 participants