Commit Graph

48 Commits

Author SHA1 Message Date
lucaronin
8141644729 fix: revert note width modes 2026-04-27 10:13:55 +02:00
lucaronin
f8721f2a1b feat: add note width modes 2026-04-27 05:34:11 +02:00
lucaronin
a2f8ba72a2 fix: complete app localization pass 2026-04-26 19:37:21 +02:00
lucaronin
c7edc71a97 feat: add note layout preference 2026-04-26 04:41:18 +02:00
lucaronin
54c0efa3e4 feat: add dark mode foundation 2026-04-24 22:28:07 +02:00
lucaronin
2ca8f1b2a6 fix: remove legacy title section fallback 2026-04-11 23:51:58 +02:00
lucaronin
c24f60c594 fix: restore breadcrumb action icon sizing 2026-04-10 21:22:27 +02:00
lucaronin
71a3be577d fix: always show breadcrumb filename 2026-04-10 21:08:45 +02:00
lucaronin
f37d11101e fix: replace breadcrumb shadow with border 2026-04-10 13:14:10 +02:00
lucaronin
459145ba0d fix: improve note icon property editing 2026-04-08 20:40:14 +02:00
lucaronin
5c5d40ff24 fix: require cmd-click for editor links 2026-04-08 19:06:21 +02:00
lucaronin
a12b3503e4 fix: hide title section for untitled drafts 2026-04-07 17:47:15 +02:00
lucaronin
d50f3479dc feat: H1-as-title — title resolution, TitleField hiding, breadcrumb filename
- Rust: extract_title now prioritizes H1 > frontmatter > filename
- Rust: add has_h1 field to VaultEntry for frontend TitleField control
- Frontend: hide TitleField + icon picker when note has H1 in body
- Frontend: breadcrumb shows filename stem instead of display title
- Frontend: new notes use untitled-{type}-{timestamp}.md, no title in frontmatter
- CSS: only hide first H1 in BlockNote when TitleField is visible
- Updated all tests for new title resolution and note creation behavior

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 13:08:17 +02:00
lucaronin
fea8038263 feat: disable BlockNote/Mantine editor animations and transitions
Adds a scoped wildcard CSS override on .editor__blocknote-container
that sets transition: none and animation: none on all child elements.
Only affects the editor internals — app-wide UI (dialogs, sidebar,
breadcrumb, icon buttons) retains its animations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 02:17:17 +02:00
lucaronin
8cbbe1e7a0 fix: editor title textarea clips wrapped lines — add field-sizing + robust auto-resize
The textarea auto-resize was not reliably expanding for wrapped titles because
scrollHeight could be stale on the first read (e.g. during tab switches).
Added CSS field-sizing: content as the primary solution, plus requestAnimationFrame
and ResizeObserver fallbacks for older WebKit versions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 23:24:03 +02:00
lucaronin
fc1d74b84c fix: editor title wraps to multiple lines instead of overflow hidden
Converted the title field from <input> to <textarea> with auto-resize
so long titles wrap naturally onto multiple lines. The textarea grows
to fit content (via scrollHeight) and shrinks back when text is
removed. Added resize:none and overflow:hidden in CSS to suppress
the drag handle and scrollbar.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 19:59:09 +02:00
lucaronin
a353509038 fix: reduce editor minimum width and padding at narrow sizes
Halve the editor min-width from 800px to 400px so the window can be
resized narrower. Add a container query that reduces horizontal padding
from 40px to 16px when the editor panel is under 600px wide, keeping
content readable without wasting space on padding.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 02:29:05 +02:00
lucaronin
06485d517c fix: eliminate scroll stutter and fix breadcrumb shadow consistency
Replace React state (useState + re-render) with direct DOM manipulation
for the breadcrumb title visibility. IntersectionObserver now toggles a
data-title-hidden attribute on the bar element, and CSS handles shadow
+ title visibility. This avoids re-rendering the heavy BlockNote editor
on every scroll intersection change.

Fixes: shadow always appears when title is hidden (CSS-driven, no race),
scroll is smooth (zero React re-renders during scroll).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:48:52 +02:00
lucaronin
99d1987203 fix: remove left indent from title when no emoji icon present 2026-03-30 15:35:43 +02:00
lucaronin
18fd740988 fix: move 'Add icon' button above title when no emoji (Notion-style)
When a note has no emoji icon, the NoteIcon area was occupying horizontal
space in the title row, pushing the title text to the right. Fix: render
NoteIcon in a separate div above the title row when no emoji is set, so
the title starts flush with the left margin. When an emoji is present,
the original inline-left layout is preserved.
2026-03-30 15:16:55 +02:00
lucaronin
196ed61e9c fix: align title section with editor body text and stabilize top margin
Apply theme CSS variables to the editor scroll area so the title section
uses the same max-width as the BlockNote editor. Add matching margin-left
to the title row/separator for body text alignment. Move NoteIcon inside
the title row unconditionally so top margin is constant regardless of
emoji presence.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 13:04:04 +02:00
lucaronin
b1d2c7168f fix: title H1 layout — no emoji gap, add-icon above title, larger font
- Remove reserved left space when note has no emoji icon (conditional render)
- Move "Add icon" button above the title row (Notion-style hover reveal)
- Increase title font size to 32px and top padding to 32px for proper H1 weight
- Update smoke test to validate no-emoji layout and new hover target

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 19:28:58 +02:00
lucaronin
fc4427750d fix: title H1 style with inline emoji layout
Wrap NoteIcon + TitleField in a flex row container so the emoji
renders inline-left of the title instead of stacked vertically.
Add fallback values for H1 CSS variables (28px, 700 weight).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 14:31:35 +02:00
lucaronin
85efe31296 fix: match TitleField font-size/weight to BlockNote H1 and fix left alignment
TitleField now uses var(--headings-h1-font-size/weight/line-height/letter-spacing)
instead of hardcoded 28px, matching the editor H1 exactly. Added margin-left: 8px
to align with BlockNote's bn-block-content offset. Fixed bn-editor max-width to
use the same CSS var as the title-section for consistent horizontal alignment.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 20:03:26 +01:00
lucaronin
2214a5c45c fix: align TitleField with editor by sharing scroll container
Move title-section inside a shared .editor-scroll-area wrapper so both
title and editor content center within the same scrollable context,
fixing alignment drift at wide widths caused by scrollbar offset.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 21:32:03 +01:00
lucaronin
ddbbebbb67 feat: add emoji icon picker for notes stored in frontmatter
Every note can now have an optional emoji icon (frontmatter `icon` field).
The icon is displayed in the editor header, note list, search results,
and Quick Open. Includes command palette commands "Set Note Icon" and
"Remove Note Icon", plus full test coverage (Vitest + Playwright).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 22:42:55 +01:00
lucaronin
db94b8b3a0 feat: add dedicated TitleField above editor
Adds a TitleField component between the breadcrumb bar and BlockNote
editor that serves as the primary title editing surface. The H1 block
inside BlockNote is hidden via CSS. The title field:
- Shows the note title in a prominent input field
- Displays the expected filename when it differs from the current one
- Triggers onTitleSync on blur/Enter to rename the file
- Responds to laputa:focus-editor selectTitle events for new notes
- Reverts on Escape or empty input

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 05:06:24 +01:00
lucaronin
19830c1734 fix: disable Tauri native drag-drop to unblock HTML5 DnD (tabs, blocks)
Root cause: Tauri's dragDropEnabled (default: true) intercepts drag events
at the webview level, preventing HTML5 DnD from working for tab reorder
and BlockNote block handle drag. Setting dragDropEnabled: false lets all
drag events flow through the standard DOM API.

Image drops now use the HTML5 drop handler + uploadImageFile (same as
paste-upload) instead of Tauri's onDragDropEvent + copyImageToVault.
Removed the useInternalDragFlag workaround and padding hack.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 22:37:12 +01:00
lucaronin
b916204a9a fix: prevent image drop overlay from breaking internal DnD and block handle
Three fixes for the image drop overlay interference:

1. Block handle clipping: Add padding (0 4px) to editor container so
   BlockNote's side menu (42px) fits within the overflow clip edge.
   overflow-y:auto forces overflow-x:auto (CSS spec), which was clipping
   the menu 2px past the container's left boundary.

2. Block handle click interference: Extract isInteractiveTarget() to
   exclude .bn-side-menu from handleContainerClick — prevents the
   container from stealing focus when clicking drag handle or add button.

3. Internal drag isolation: Track document-level dragstart/dragend to
   flag internal HTML5 drags (tabs, blocks). Tauri onDragDropEvent
   handler skips entirely during internal drags to prevent interference.
   Extract useInternalDragFlag() and handleTauriDrop() to keep
   useImageDrop under CodeScene complexity threshold.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:38:37 +01:00
lucaronin
7a919ffd78 fix: make empty space below editor content clickable to focus editor
Clicking anywhere in the editor container (including empty space below the
last block) now focuses the editor and places the cursor at the end of the
last block. This matches the behavior of Notion, Bear, and Obsidian.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 00:18:58 +01:00
lucaronin
c78d4b3c43 fix: editor background matches vault theme in dark mode
BlockNote's internal CSS sets `.bn-editor { background-color: var(--bn-colors-editor-background); }`
using its own hardcoded variables (#ffffff light, #1f1f1f dark). Our `.bn-container` rule set
`background: var(--bg-primary)` but this didn't cascade to `.bn-editor` which has its own rule.

Override the BlockNote internal CSS variables (`--bn-colors-editor-background` etc.) on
`.bn-container` so BlockNote's own rules pick up our vault theme colors. CSS custom properties
cascade normally, and our selector specificity (2 classes) matches BlockNote's dark theme rule
(1 class + 1 attribute) — source order wins since our CSS loads after BlockNote's.

Fixes: editor content area now seamlessly blends with sidebar and container in any vault theme.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 19:33:57 +01:00
lucaronin
8a5df707f5 feat: add drag & drop image support in editor
Extract uploadImageFile to shared hook, add useImageDrop hook that
handles dragover/dragleave/drop events on the editor container.
Drops image files (jpg, png, gif, webp), uploads them via the existing
save_image flow, and inserts BlockNote image blocks at the drop position.
Visual feedback via drop overlay and dashed border.

Refactored Editor.tsx uploadFile to use the shared function.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 23:15:32 +01:00
lucaronin
3d35eaff20 feat: color wikilinks by destination note type
Wikilinks in the editor now show the accent color of the target note's
type (Project=red, Person=yellow, Topic=green, etc.) instead of always
being blue. Broken links (target not found) show muted text with a
dashed underline.

- Extract wikilink color resolution to src/utils/wikilinkColors.ts
- Use getTypeColor from typeColors.ts (single source of truth)
- Support alias and pipe-syntax matching in findEntryByTarget
- Add wikilink--broken CSS class for non-existent targets
- Add 17 unit tests covering all color resolution cases
- Update mock data with wikilinks to various note types + broken link

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 20:44:30 +01:00
lucaronin
4e4cffe6a3 fix: ensure editor has full width regardless of title/content length
The BlockNote editor container (.bn-container) had no explicit width,
so it sized based on content. With short or empty document titles,
the editor collapsed to a very small width.

Fix: set width: 100% on .bn-container and .bn-editor so the editor
always fills available space. Added margin: 0 auto on .bn-editor to
keep the 760px text column centered.

Also adds an E2E test verifying editor width stays above 300px.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 09:39:37 +01:00
lucaronin
fe997b8d4d feat: redesign v2 — inspector layout fix, editor scroll, diff moved to breadcrumb bar
- Fix editor scroll (min-height: 0 + overflow)
- Properties panel extends full height
- Moved Diff button to git-branch icon in breadcrumb bar
- Minor CSS fixes for app layout
2026-02-17 11:31:23 +01:00
lucaronin
6989f44031 feat: migrate to shadcn/ui
Install Tailwind CSS v4 + shadcn/ui with Radix UI primitives. Migrate all
UI components (Sidebar, NoteList, Editor tabs, Inspector, dialogs, palette)
from BEM CSS to Tailwind utility classes and shadcn components (Button,
Input, Dialog, Badge, etc.). Map theme system to shadcn CSS variables while
preserving BlockNote editor styles untouched. Remove 8 old CSS files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:56:44 +01:00
lucaronin
94cd8bdcc1 feat: title separator, centered editor, handle spacing, list line alignment 2026-02-16 13:50:21 +01:00
lucaronin
9afc13811e merge: blocknote-poc into main 2026-02-16 07:55:46 +01:00
lucaronin
9a9769334e feat: proper wiki-links as custom BlockNote inline content with suggestion menu
- Custom 'wikilink' inline content type via createReactInlineContentSpec
- Extended BlockNote schema with wikilink spec
- Suggestion menu triggered by [[ showing all vault entries
- Markdown round-trip: [[target]] → placeholder tokens → wikilink inline content
- Click handler on .wikilink elements for navigation
- Removed old hack (regex preprocessing to wikilink.internal URLs + DOM click interception on <a> tags)
- Added .wikilink CSS styles
- Passed entries prop from App.tsx to Editor for suggestion menu
2026-02-15 19:50:23 +01:00
lucaronin
fdd7a248b2 Editor UX: zero horizontal shift for headings and bullets (Bear-style)
Three CSS fixes for the codemirror-live-markdown live preview:

1. Remove header underlines (border-bottom: none on .cm-heading-line)
2. Heading markers (## etc) positioned absolutely in left gutter area
   so they never push heading text horizontally when revealed
3. List bullets always occupy fixed width (font-size: 1em, not collapsed),
   showing • when inactive and source char (-) when active

Verified via Playwright: 0px horizontal shift on both headings and bullets.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 19:18:08 +01:00
lucaronin
1e95174197 feat: replace CodeMirror 6 with BlockNote editor (PoC)
- Swap CM6 editor with BlockNote block-based editor
- Strip YAML frontmatter before passing to BlockNote, keep separate
- Intercept link clicks for wikilink navigation
- Remove all @codemirror/*, @lezer/*, codemirror-live-markdown deps
- Remove frontmatterHide.ts (no longer needed)
- Update Editor.css: remove .cm-* styles, add BlockNote container styles
- Tab bar, diff toggle, inspector panel unchanged
2026-02-15 19:14:55 +01:00
lucaronin
1eccaf7f76 Add diff view toggle for modified files in editor
Editor tab bar shows Edit/Diff toggle button when viewing a modified file.
Diff view renders git diff output with green (added), red (removed), and
gray (context) line coloring. Uses `get_file_diff` Tauri command.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 12:58:00 +01:00
lucaronin
b5971c9618 Add light/dark mode toggle with CSS variables
Replace all hardcoded colors across 10 CSS files with CSS variables defined
in index.css. Dark mode (default) uses the existing navy/purple palette,
light mode uses Notion-inspired warm neutrals from the design tokens
(--bg-primary: #FFFFFF, --bg-sidebar: #F7F6F3, --text-primary: #37352F).

Toggle button (sun/moon) in the sidebar header persists preference to
localStorage. An inline script in index.html applies the saved theme
before React mounts to prevent flash.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 10:34:59 +01:00
lucaronin
9d29959fba Add frameless window with custom drag regions (Obsidian-style)
Remove native macOS titlebar via decorations:false + titleBarStyle:overlay.
Add -webkit-app-region:drag to panel headers (Sidebar, NoteList, Editor tab
bar, Inspector) with no-drag on interactive elements. Sidebar header gets
78px left padding for macOS traffic light buttons.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 10:00:29 +01:00
lucaronin
6d07b7afe3 Refine visual polish: blue accent states, tab hover, editor hints (M5 Task 4)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 21:26:58 +01:00
lucaronin
eb87c0d223 Add tab bar with open/close/switch for multi-note editing
- Replace single selectedNote with tabs state in App (open/close/switch)
- Tab bar above editor: title + x close button, active tab highlighted
- Clicking note opens new tab or switches to existing
- Closing active tab switches to adjacent tab
- Fix race condition: editor re-creates when tab content loads async
- Add Playwright test verifying multi-tab behavior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 20:15:44 +01:00
lucaronin
bc2dd10f9e Add CodeMirror 6 editor with dark theme and note selection
- Install CM6 packages (state, view, lang-markdown, theme-one-dark, commands, language)
- Replace Editor placeholder with real CodeMirror 6 instance
- Add realistic markdown content to all mock entries in mock-tauri.ts
- Wire up note selection: clicking a note in NoteList loads its content in the editor
- Dark theme matching app colors, line numbers, active line highlighting, line wrapping
- Update NoteList with selected state styling
- Update Playwright screenshot test to capture editor with note selected

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 20:07:23 +01:00
lucaronin
57083ad12c Add four-panel layout shell with vault scanning on load
- Sidebar (250px, resizable): navigation placeholder
- Note list (300px, resizable): displays vault entries from scan
- Editor (flex grow): placeholder for CodeMirror 6
- Inspector (280px, collapsible): properties/relationships placeholder
- Resizable panels with drag handles
- Calls list_vault on app load and displays results in note list

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 18:22:42 +01:00