Commit Graph
23 Commits
Author SHA1 Message Date
amitwh f1f8a16a79 fix: list-directory returns flat array, drop defensive fallback
The list-directory handler returned { path, entries } while the
renderer typed result.data as FileEntry[]; the file-store had to fall
back to raw.entries via Array.isArray. Extract the entries builder into
src/main/files/list-directory.js so it can be unit-tested, return a
plain array, and skip entries that can't be stat'd (broken symlinks,
permission errors) instead of throwing.

Also tighten jest config so dist/*.snap electron-builder artifacts are
not matched as test suites.
2026-07-23 09:34:57 +05:30
amitwh 36422a9ab3 feat: complete master feature parity with interactive PDF editing, Reveal.js export dialog, Large File Mode, and scoped CSS 2026-06-15 01:22:17 +05:30
amitwh f2398e6e1a feat: enhance WelcomeDialog, export dialogs, GitStatusPanel, add CommandPalette, FindReplaceBar, and new converter dialogs
- WelcomeDialog: add quick start, feature showcase, keyboard shortcuts, recent files, version display
- ExportDocxDialog/ExportHtmlDialog/ExportPdfDialog: add header/footer, paper size, margin controls
- GitStatusPanel: full staging/unstaging, discard, commit workflow
- CommandPalette: fuzzy command search with keyboard navigation
- FindReplaceBar: find/replace with regex, case, whole-word options
- New dialogs: BatchMediaConverterDialog, HeaderFooterDialog, PdfEditorDialog, UniversalConverterDialog
- Tests: comprehensive coverage for all new/updated components
2026-06-13 19:34:42 +05:30
amitwh 6b564a4569 style: run prettier formatter over src and tests 2026-06-11 20:46:00 +05:30
amitwh 2389d4f297 feat: add writing analytics dashboard and daily word goal tracking 2026-06-11 20:44:16 +05:30
amitwh 50f4f62575 fix: handle list-directory return shape {entries} in openFolder/loadChildren
The main process list-directory handler returns {path, entries} but
the file store was calling .map() directly on result.data. Since
arrays have a .entries iterator method, the nullish coalescing
fallback didn't work. Now properly extracts the entries array with
Array.isArray check.
2026-06-11 07:49:42 +05:30
amitwh e25a5e1d75 fix(migration): normalize legacy theme values under v5 marker
Two related bugs surfaced during end-to-end verification:

1. The 'isAlreadyV5' short-circuit in both the main-side and renderer-side
   v4-to-v5 transforms returned the persisted object as-is when a
   migration.version=5 marker was present. A previously-shipped v4 build
   had written theme: 'ayu-light' (and similar) under the v5 marker;
   the transform trusted the marker and passed the invalid theme through,
   which then failed the renderer's zod schema on every launch and
   reset user settings to defaults.

   Fix: in both transforms, when isAlreadyV5 matches, normalize theme
   against the v5 enum (light/dark/system) and validate the full result
   with the v5 schema before returning. Out-of-range values are replaced
   with the v5 default ('system').

2. The renderer's settings-store onRehydrateStorage callback called
   useSettingsStore.setState() to reset the store on validation failure.
   At that moment the store is still being constructed, and setState
   could hit a TDZ ReferenceError (the one we already wrapped in a
   try/catch in v5.0.0, which only hid the symptom).

   Fix: return the normalized state object from onRehydrateStorage
   instead. Zustand's persist middleware applies the returned value
   *after* construction completes, so there is no TDZ.

Tests: 334 vitest + 208 jest = 542 passing.
E2E: 12/12 verify-features.mjs steps green; no console errors.

Amit Haridas
2026-06-08 07:45:06 +05:30
amitwh 6df1389cc8 fix(updater): dispatch setFeedURL by provider instead of raw url 2026-06-08 07:11:28 +05:30
amitwh 9b899b5205 feat(renderer): mount UpdateBanner, FirstRunWizard, and CrashReportModal 2026-06-08 06:43:40 +05:30
amitwh 5ef1610873 fix(ipc): wire preload bridge so menu Open file actually loads in editor + preview
Two related defects were breaking the 'open file' flow:

1. The BrowserWindow webPreferences had no preload path AND
   contextIsolation: false, so contextBridge.exposeInMainWorld
   threw on load and window.electronAPI was never set. Result:
   every renderer-side ipc.* call returned CHANNEL_MISSING and
   silently no-op'd. Toolbar Open/Save, the file menu, every
   dialog — all broken.

2. The 'file.opened' IPC bridge in register-menu-commands.ts
   dispatched to a 'file.opened' command that was never registered
   as a handler. Even if the preload had worked, the main menu's
   File -> Open would have been a no-op once it reached the
   command store.

Fixes:
- window/index.js: add preload path; set contextIsolation: true
  (required for contextBridge) and nodeIntegration: false
  (renderer no longer needs direct Node access; everything goes
  through the whitelisted preload bridge).
- file-store.ts: add openFileFromMain(path, content) that opens
  a tab + editor buffer from content the main process already read
  (skips the renderer's ipc.file.read since main has the bytes).
  Preserves existing buffer content if the file is already open.
- register-menu-commands.ts: register 'file.opened' to call
  openFileFromMain. Drop the dead 'command.palette' bridge
  (no consumer, no UI, no handler).
- tests: two new cases for openFileFromMain — verifies it does
  not call ipc.file.read and does not clobber user edits on
  re-open.

Verified end-to-end via the run-desktop driver: triggering
file-opened from the main process with a test .md now shows the
content in BOTH the CodeMirror editor and the rendered preview
pane (plus the Outline panel picks up the H1). 497 tests pass.
2026-06-07 22:35:30 +05:30
amitwh a8f7547c7e feat(renderer): Phase 9 foundation — settings, modal union, ipc, commands, docx-export 2026-06-06 07:33:00 +05:30
amitwh 338669f2db feat(renderer): file-store toasts on save/open/folder 2026-06-05 22:59:54 +05:30
amitwh 41942a1316 feat(renderer): useSettingsStore (persisted, validated, reset-able) 2026-06-05 18:31:27 +05:30
amitwh 9ad484744a feat(renderer): useAppStore extended with modal discriminated union 2026-06-05 18:28:02 +05:30
Amit Haridas 813582aa8d feat(renderer): command store persists userBindings (Phase 6)
- add userBindings map (commandId -> combo string)
- setUserBinding / clearUserBinding / getUserBinding actions
- persist middleware with partialize: handlers are runtime-only,
  userBindings are serialized
- TDD: 7 persistence tests + existing 10 command-store tests still pass
- 162/162 total tests pass
2026-06-05 16:02:26 +05:30
Amit Haridas c93747c476 feat(renderer): command store (action registry for menu/shortcut/toolbar)
- useCommandStore: register/unregister/registerMany/dispatch/get
- keyed by id (e.g. 'file.open', 'view.toggleSidebar')
- TDD: 10 unit tests covering register, dispatch, unregister, batch
- foundation for Phase 6 native menu + toolbar wiring
2026-06-05 15:49:45 +05:30
amitwh 5e5bab3da9 feat(renderer): persist last-opened folder (mc-file-store) + restore on mount 2026-06-05 15:36:59 +05:30
amitwh 3598d06240 feat(preload): add file.list, file.pickFolder, file.pickFile convenience methods 2026-06-05 15:13:16 +05:30
amitwh 17f318dd75 fix(renderer): drop redundant ternary, add loadChildren idempotence test 2026-06-05 14:50:56 +05:30
amitwh fa5a46d5ac feat(renderer): file store with FileNode tree, openTabs, lazy loadChildren 2026-06-05 14:42:08 +05:30
amitwh 559d09cad9 feat(renderer): preview store with 300ms debounced source 2026-06-05 13:04:39 +05:30
amitwh 4c0b7d6e84 feat(renderer): editor store with buffers, dirty state, cursor (immer) 2026-06-05 12:21:48 +05:30
amitwh 6525de7667 feat(renderer): add useAppStore with sidebar/preview/zen/pane-sizes 2026-06-05 11:30:25 +05:30