Skip to content

Conversation

@dannysmith
Copy link
Owner

@dannysmith dannysmith commented Jan 10, 2026

Summary by CodeRabbit

  • New Features

    • Vault integration: browse, read, create, update, delete tasks/projects/areas; deep linking (taskdn://)
    • Month & Week calendar views with drag‑and‑drop; Area Kanban with per‑project swimlanes
  • UI

    • New Task/Project/Area cards, Markdown editor & rich preview, date picker button, collapsible notes, view header, progress circle, updated titlebar
  • Preferences

    • Ignore patterns, Obsidian features toggle, permanent‑delete option
  • Chores

    • Expanded localization keys and window/quick‑pane sizing adjustments

✏️ Tip: You can customize this high-level summary in your review settings.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@tdn-desktop/src/App.css`:
- Around line 275-283: The checkmark SVG in .milkdown-editor
.milkdown-list-item-block .label.checked::after hardcodes stroke='white', which
can be invisible on light primary colors; update the rule to make the checkmark
color theme-aware by either using currentColor in the embedded SVG (e.g.,
stroke='currentColor') and setting color on .label.checked to a suitable theme
variable (like --primary-foreground) or by switching to an inline SVG mask/PNG
with background-color driven by a CSS variable or applying a CSS filter that
maps white to a theme variable; change the SVG stroke and ensure the element
sets the corresponding CSS variable (e.g., color or --checkmark-color) so
contrast follows the active theme.

In `@tdn-desktop/src/components/cards/TaskCard.tsx`:
- Around line 287-289: The placeholder string in the TaskCard component is
hardcoded and must be internationalized: import useTranslation from
'react-i18next', call const { t } = useTranslation() inside the TaskCard
component, then replace the literal placeholder on the textarea/input (the
element with className "... placeholder=\"Task title...\"") with a t(...) call
using a new translation key (e.g. 'task.titlePlaceholder' or similar) so the
user-facing string comes from i18n.
- Around line 314-333: Replace the hardcoded "Scheduled" and "Due" label props
on the DatePickerButton components with translated strings: import and use the
useTranslation hook (e.g., const { t } = useTranslation()) and pass
t('task.scheduled') and t('task.due') (or similar keys) to the label prop for
the DatePickerButton instances (references: DatePickerButton,
handleScheduledSelect, handleDueSelect, onScheduledChange, onDueChange). Add the
corresponding keys to the locales JSON files under /locales/*.json (e.g.,
"task": { "scheduled": "...", "due": "..." }) and ensure tests/type checks pick
up the new keys.
♻️ Duplicate comments (2)
tdn-desktop/src/components/cards/TaskCard.tsx (1)

198-200: Date parsing timezone issue previously flagged.

The timezone concern with new Date(task.scheduled) parsing YYYY-MM-DD as UTC has already been raised in a prior review. Please address that feedback.

tdn-desktop/locales/en.json (1)

208-209: Missing .label key for revealInFinder command.

Other commands include .label, .description, and .success/.error keys. The revealInFinder command is missing its .label key for consistency.

Suggested fix
+  "commands.revealInFinder.label": "Reveal in File Manager",
   "commands.revealInFinder.description": "Show the file in the system file manager",
   "commands.revealInFinder.error": "Failed to reveal file",
🧹 Nitpick comments (3)
tdn-desktop/src/components/cards/TaskCard.tsx (1)

211-246: Compact variant lacks keyboard accessibility.

The compact card has cursor-pointer but no tabIndex or onKeyDown handler, making it inaccessible via keyboard navigation unlike the default variant.

♻️ Suggested fix
       <div
         onClick={onEditClick}
         onContextMenu={handleContextMenu}
+        onKeyDown={(e) => e.key === 'Enter' && onEditClick?.()}
+        tabIndex={0}
+        role="button"
         className={cn(
           'group flex items-center gap-2 rounded-lg border px-2 py-1.5 transition-all cursor-pointer',
           'hover:shadow-sm hover:shadow-black/5',
+          'focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
tdn-desktop/src-tauri/tauri.conf.json (1)

16-19: Default window size may exceed some displays.

The new default size of 1800×1200 is larger than many laptop screens (e.g., 1366×768 or 1440×900). While the minimum size (1000×700) is reasonable and window-state plugin will restore user preferences, the initial experience on smaller displays may have the window extending off-screen.

Consider reducing the default to something more universally compatible (e.g., 1280×800) or relying on maximized: true for larger initial coverage.

tdn-desktop/locales/en.json (1)

49-87: Consider consolidating duplicate preference keys.

Several keys are duplicated between preferences.general.* and preferences.vault.* namespaces (e.g., tasksDir, tasksDirDescription, choose, notConfigured). If these render identical text, consider using a shared namespace (e.g., preferences.shared.*) to reduce maintenance burden and ensure consistency.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5d10e54 and 3bc360c.

⛔ Files ignored due to path filters (13)
  • tdn-desktop/bun.lock is excluded by !**/*.lock
  • tdn-desktop/docs/developer/deep-linking.md is excluded by !**/*.md
  • tdn-desktop/docs/tasks-done/task-2026-01-13-2-url-scheme.md is excluded by !**/*.md
  • tdn-desktop/docs/tasks-done/task-2026-01-14-4-phase1-findings.md is excluded by !**/*.md
  • tdn-desktop/docs/tasks-done/task-2026-01-14-4-ui-component-review.md is excluded by !**/*.md
  • tdn-desktop/docs/tasks-done/task-2026-01-14-5-datepicker.md is excluded by !**/*.md
  • tdn-desktop/docs/tasks-done/task-2026-01-14-6-quick-search.md is excluded by !**/*.md
  • tdn-desktop/docs/tasks-done/task-2026-01-14-7-navigation-history.md is excluded by !**/*.md
  • tdn-desktop/docs/tasks-todo/task-10-publishing.md is excluded by !**/*.md
  • tdn-desktop/docs/tasks-todo/task-8-quick-capture-pane.md is excluded by !**/*.md
  • tdn-desktop/docs/tasks-todo/task-9-reviews.md is excluded by !**/*.md
  • tdn-desktop/docs/tasks-todo/task-x-undo.md is excluded by !**/*.md
  • tdn-desktop/src/components/ui/README.md is excluded by !**/*.md
📒 Files selected for processing (44)
  • tdn-desktop/knip.json
  • tdn-desktop/locales/en.json
  • tdn-desktop/package.json
  • tdn-desktop/src-tauri/capabilities/desktop.json
  • tdn-desktop/src-tauri/src/lib.rs
  • tdn-desktop/src-tauri/tauri.conf.json
  • tdn-desktop/src/App.css
  • tdn-desktop/src/components/cards/TaskCard.tsx
  • tdn-desktop/src/components/layout/LeftSideBar.tsx
  • tdn-desktop/src/components/layout/MainWindow.tsx
  • tdn-desktop/src/components/preferences/PreferencesDialog.tsx
  • tdn-desktop/src/components/preferences/panes/AdvancedPane.tsx
  • tdn-desktop/src/components/preferences/panes/AppearancePane.tsx
  • tdn-desktop/src/components/preferences/panes/GeneralPane.tsx
  • tdn-desktop/src/components/preferences/panes/QuickEntryPane.tsx
  • tdn-desktop/src/components/preferences/panes/VaultPane.tsx
  • tdn-desktop/src/components/preferences/shared/SettingsComponents.tsx
  • tdn-desktop/src/components/quick-search/QuickSearch.tsx
  • tdn-desktop/src/components/quick-search/QuickSearchResult.tsx
  • tdn-desktop/src/components/quick-search/utils.ts
  • tdn-desktop/src/components/sidebar/AppSidebar.tsx
  • tdn-desktop/src/components/ui/calendar.tsx
  • tdn-desktop/src/components/ui/date-button.tsx
  • tdn-desktop/src/components/ui/date-picker.tsx
  • tdn-desktop/src/components/ui/popover-date-picker.tsx
  • tdn-desktop/src/components/views/AreaView.tsx
  • tdn-desktop/src/components/views/ComponentReference.tsx
  • tdn-desktop/src/components/views/NoAreaView.tsx
  • tdn-desktop/src/components/views/WeekView.tsx
  • tdn-desktop/src/hooks/use-command-context.ts
  • tdn-desktop/src/hooks/use-deep-link.ts
  • tdn-desktop/src/lib/commands/app-commands.ts
  • tdn-desktop/src/lib/commands/commands.test.ts
  • tdn-desktop/src/lib/commands/navigation-commands.ts
  • tdn-desktop/src/lib/commands/types.ts
  • tdn-desktop/src/lib/deep-link.test.ts
  • tdn-desktop/src/lib/deep-link.ts
  • tdn-desktop/src/lib/task-navigation.test.ts
  • tdn-desktop/src/lib/task-navigation.ts
  • tdn-desktop/src/main.tsx
  • tdn-desktop/src/store/navigation-store.test.ts
  • tdn-desktop/src/store/navigation-store.ts
  • tdn-desktop/src/store/task-detail-store.ts
  • tdn-desktop/src/store/ui-store.ts
💤 Files with no reviewable changes (1)
  • tdn-desktop/knip.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • tdn-desktop/package.json
  • tdn-desktop/src-tauri/capabilities/desktop.json
🧰 Additional context used
📓 Path-based instructions (5)
tdn-desktop/**/*.{tsx,css,scss}

📄 CodeRabbit inference engine (tdn-desktop/AGENTS.md)

Use CSS logical properties (e.g., text-start instead of text-left) for RTL support

Files:

  • tdn-desktop/src/App.css
  • tdn-desktop/src/components/cards/TaskCard.tsx
tdn-desktop/**/*.{tsx,ts}

📄 CodeRabbit inference engine (tdn-desktop/AGENTS.md)

tdn-desktop/**/*.{tsx,ts}: Use selector syntax in Zustand hooks to access state (e.g., useUIStore(state => state.leftSidebarVisible)), never destructure from Zustand hooks
Use getState() in callbacks to access Zustand state instead of destructuring
Use type-safe Tauri commands from @/lib/tauri-bindings (tauri-specta) with Result handling, never use string-based invoke()

Files:

  • tdn-desktop/src/components/cards/TaskCard.tsx
tdn-desktop/**/*.tsx

📄 CodeRabbit inference engine (tdn-desktop/AGENTS.md)

tdn-desktop/**/*.tsx: Use useTranslation hook from react-i18next in React components for internationalization
Place all user-facing strings in /locales/*.json translation files
Use React Compiler for automatic memoization handling (no manual useMemo/useCallback needed)

Files:

  • tdn-desktop/src/components/cards/TaskCard.tsx
tdn-desktop/**/*.{rs,tsx,ts}

📄 CodeRabbit inference engine (tdn-desktop/AGENTS.md)

Emit events from Rust to React using app.emit("event-name", data) and listen with listen("event-name", handler) in React

Files:

  • tdn-desktop/src/components/cards/TaskCard.tsx
  • tdn-desktop/src-tauri/src/lib.rs
tdn-desktop/**/*.rs

📄 CodeRabbit inference engine (tdn-desktop/AGENTS.md)

Use modern Rust formatting with format!() macro (e.g., format!("{variable}"))

Files:

  • tdn-desktop/src-tauri/src/lib.rs
🧠 Learnings (7)
📚 Learning: 2025-12-28T17:09:11.509Z
Learnt from: CR
Repo: dannysmith/taskdn PR: 0
File: tdn-desktop/AGENTS.md:0-0
Timestamp: 2025-12-28T17:09:11.509Z
Learning: Applies to tdn-desktop/**/*.{tsx,css,scss} : Use CSS logical properties (e.g., text-start instead of text-left) for RTL support

Applied to files:

  • tdn-desktop/src/App.css
📚 Learning: 2026-01-08T18:21:32.095Z
Learnt from: CR
Repo: dannysmith/taskdn PR: 0
File: website/AGENTS.md:0-0
Timestamp: 2026-01-08T18:21:32.095Z
Learning: Applies to website/src/content/docs/**/*.mdx : Use H2 for main sections, H3 for subsections or individual items, and H4 rarely for deeply nested content

Applied to files:

  • tdn-desktop/src/App.css
📚 Learning: 2026-01-08T18:21:32.095Z
Learnt from: CR
Repo: dannysmith/taskdn PR: 0
File: website/AGENTS.md:0-0
Timestamp: 2026-01-08T18:21:32.095Z
Learning: Applies to website/src/content/docs/**/*.mdx : Use <Card> and <CardGrid> components sparingly to add visual interest, with cards almost always including a title, icon, and content

Applied to files:

  • tdn-desktop/src/components/cards/TaskCard.tsx
📚 Learning: 2025-12-28T12:22:45.546Z
Learnt from: CR
Repo: dannysmith/taskdn PR: 0
File: tdn-cli/CLAUDE.md:0-0
Timestamp: 2025-12-28T12:22:45.546Z
Learning: Applies to tdn-cli/crates/**/*.rs : Rust code must use the `#[napi]` macro to expose functions that will be auto-generated as TypeScript bindings

Applied to files:

  • tdn-desktop/src-tauri/src/lib.rs
📚 Learning: 2025-12-28T12:22:45.546Z
Learnt from: CR
Repo: dannysmith/taskdn PR: 0
File: tdn-cli/CLAUDE.md:0-0
Timestamp: 2025-12-28T12:22:45.546Z
Learning: Regenerate TypeScript bindings by running `bun run build` after modifying any `#[napi]` function signatures, structs, or enums in Rust code

Applied to files:

  • tdn-desktop/src-tauri/src/lib.rs
📚 Learning: 2025-12-28T17:09:11.509Z
Learnt from: CR
Repo: dannysmith/taskdn PR: 0
File: tdn-desktop/AGENTS.md:0-0
Timestamp: 2025-12-28T17:09:11.509Z
Learning: Applies to tdn-desktop/**/*.{tsx,ts} : Use type-safe Tauri commands from `@/lib/tauri-bindings` (tauri-specta) with Result handling, never use string-based invoke()

Applied to files:

  • tdn-desktop/src-tauri/src/lib.rs
📚 Learning: 2025-12-28T17:09:11.509Z
Learnt from: CR
Repo: dannysmith/taskdn PR: 0
File: tdn-desktop/AGENTS.md:0-0
Timestamp: 2025-12-28T17:09:11.509Z
Learning: Applies to tdn-desktop/**/*.tsx : Place all user-facing strings in /locales/*.json translation files

Applied to files:

  • tdn-desktop/locales/en.json
🔇 Additional comments (20)
tdn-desktop/src/App.css (6)

5-10: LGTM!

The datepicker import and field-sizing-content utility are cleanly defined.


66-106: LGTM!

Good handling of Milkdown's nested DOM structure with proper height inheritance. The :focus-visible affordance (lines 96-100) correctly addresses keyboard accessibility, and the word-break handling prevents layout overflow from long URLs.


108-179: LGTM!

Clean reset for block elements and well-structured heading hierarchy. The border-bottom and padding-bottom properties are appropriate here since they're block-direction (vertical) properties unaffected by RTL text direction.


180-239: LGTM!

Correct use of padding-inline-start for RTL support. The list item block component structure properly handles Milkdown's custom list rendering with flex layout. Based on coding guidelines, logical properties are correctly applied.


285-339: LGTM!

Correct use of padding-inline-start and border-inline-start for blockquotes ensuring RTL support. Code styling and horizontal rules are well-structured. Based on coding guidelines, logical properties are correctly applied.


340-443: LGTM!

The Markdown preview styles mirror the editor styles appropriately with consistent use of logical properties (padding-inline-start, border-inline-start) for RTL support. Good separation between editable and read-only rendering contexts. Based on coding guidelines, logical properties are correctly applied.

tdn-desktop/src/components/cards/TaskCard.tsx (4)

16-73: Well-documented component with clear API.

The JSDoc comment provides excellent context about usage scenarios, variants, and behavior. Props interface is comprehensive with proper TypeScript typing.


104-120: LGTM!

Effects are correctly implemented with proper dependencies. The sync effect guards against overwriting during edit, and the focus effect handles auto-sizing appropriately.


248-273: LGTM!

Default variant properly implements keyboard accessibility with tabIndex={0}, onKeyDown handler, and focus-visible ring styles. Container query responsive design is well-applied.


371-448: LGTM!

DatePickerButton subcomponent is well-structured with proper conditional rendering, popover state management, and clear separation between "add date" and "edit date" modes.

tdn-desktop/src-tauri/src/lib.rs (7)

11-14: LGTM!

The vault module is correctly declared as public and the VaultManager import is properly structured for state management later in the file.


24-37: LGTM!

The bindings export logic is well-guarded for different build scenarios. The dual path check handles both development working directories gracefully.


60-71: LGTM!

Good workaround with clear documentation. The issue reference helps future maintainers understand why quick-pane is denylisted.


90-92: LGTM!

Reasonable log rotation configuration. 5MB limit with KeepOne strategy prevents unbounded disk usage while retaining recent logs for debugging.


157-180: LGTM!

Good initialization pattern with non-fatal error handling. The logging provides clear feedback about vault state, and users can configure paths in preferences if initialization fails.


54-58: Deep link event handling is properly implemented.

The useDeepLink hook in tdn-desktop/src/hooks/use-deep-link.ts listens for deep link events using onOpenUrl from the Tauri deep-link plugin, parses the taskdn:// URLs, and routes them appropriately to navigate to the correct views.


188-235: Vault cleanup is already handled automatically.

The VaultManager holds the file watcher in a struct field, which will be automatically cleaned up via Rust's Drop trait when the VaultManager is dropped. Since VaultManager is managed by Tauri (registered with .manage()), it will be properly dropped when the application exits, ensuring file watchers are gracefully stopped. No explicit cleanup is needed on window close.

tdn-desktop/src-tauri/tauri.conf.json (1)

64-68: LGTM!

Deep link configuration is correctly set up for the taskdn:// URL scheme, consistent with the plugin registration in lib.rs.

tdn-desktop/locales/en.json (2)

14-33: LGTM!

Comprehensive menu localization with consistent naming conventions. As per coding guidelines, user-facing strings are properly placed in the locale file.


238-269: LGTM!

Good additions for quick search, section UI, and collapsible notes. The titlebar.default change to "Tasks" provides appropriate app branding. Based on learnings, all user-facing strings are correctly placed in the locale file.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Repository owner deleted a comment from coderabbitai bot Jan 15, 2026
@dannysmith
Copy link
Owner Author

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Jan 15, 2026

✅ Actions performed

Full review triggered.

@dannysmith dannysmith merged commit 7c3f4c9 into main Jan 16, 2026
4 checks passed
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.

2 participants