Skip to content

Phase 5: Multi-Document Workspace#42

Merged
jamesainslie merged 5 commits intomainfrom
phase-5-multi-document-workspace
Mar 20, 2026
Merged

Phase 5: Multi-Document Workspace#42
jamesainslie merged 5 commits intomainfrom
phase-5-multi-document-workspace

Conversation

@jamesainslie
Copy link
Owner

Summary

  • Transforms the Electron app from a single-file viewer into a full multi-document workspace
  • Tab Bar: Create/switch/close tabs, middle-click to close, in-process tab containers (hidden/shown, not destroyed)
  • Application Menu: File/Edit/View/Export/Help with accelerators, Open File/Folder dialogs, Recent Files submenu
  • File Tree Sidebar: Recursive directory listing filtered to markdown files, expand/collapse, chokidar file watching, Cmd+B toggle
  • Status Bar: Word count, heading/code-block/diagram counts, theme name, render state
  • Keyboard Shortcuts: Ctrl/Cmd+Tab cycle, Cmd+1-9 jump to tab, Cmd+W close tab
  • Drag and Drop: Drop .md files onto window to open as tabs
  • Session Restore: Saves open tabs on quit, restores on relaunch (filters deleted files)
  • Workspace State: StateManager tracks tabs, active tab, sidebar, folder path; persists to electron-store

Test plan

  • 1389 tests pass (107 new, 0 regressions from 1282 baseline)
  • npm -w @mdview/electron run build succeeds
  • Manual: launch app, open multiple files, verify tab switching
  • Manual: File > Open Folder populates sidebar, click opens tab
  • Manual: close and reopen app, verify session restores
  • Manual: drag .md file onto window opens new tab
  • Manual: Cmd+W closes tab, Ctrl+Tab cycles tabs

…ce state model

- buildApplicationMenu: File/Edit/View/Export/Help menus with accelerators
- RecentFilesManager: add/dedup/cap/clear/persist recent files
- StateManager workspace methods: openTab, closeTab, setActiveTab,
  updateTabMetadata, updateTabScrollPosition, setSidebarVisible, setOpenFolder
- workspace-types.ts: TabState, WorkspaceState, DirectoryEntry types
- IPC channels for dialogs, workspace state, and directory operations
- Preload API extended with workspace and directory methods
- DirectoryService stub for future implementation
…derer

- TabManager: tab bar UI with create/activate/close, click/middle-click
  handlers, and content container visibility management
- DocumentContext: extracted from viewer's initialize(), owns RenderPipeline,
  TOC, ExportUI, Comments, and auto-reload per document
- Refactored viewer.ts from single-file viewer to multi-document orchestrator
  with openFile/closeFile/switchTab, IPC event listeners, and empty state UI
- Restructured index.html: workspace > sidebar + main > tab-bar + content-area
  + status-bar
- Keyboard shortcuts: Ctrl/Cmd+Tab (next tab), Ctrl/Cmd+Shift+Tab (prev
  tab), Ctrl/Cmd+1-9 (switch to tab N), with cleanup function
- Drag and drop: dragover indicator, .md file filtering, multi-file
  support, cleanup function
- DirectoryService: recursive directory listing with .md filter, dirs-first
  sort, chokidar watch with debounce, dispose
- FileTree renderer: tree DOM with expand/collapse, file selection callback,
  visibility toggle, active file highlight, refresh/dispose
StatusBar displays file name, word count, heading count, code block count,
diagram count, theme name, and render state. Integrated into viewer: updates
on file load and tab switch, clears when last tab closes.
…ish main process

- SessionManager: save/restore/clear session with tab file paths and active
  tab index, filters nonexistent files, handles corrupt data
- Main process: wire menu bar, recent files, session manager, directory
  service. Save session on quit. macOS open-file sends IPC to renderer
  instead of reloading page. Window title updates with active file.
- Viewer: integrate keyboard shortcuts (Ctrl+Tab, Cmd+1-9), drag-drop
  (.md file opening), file tree sidebar (folder loading, visibility toggle),
  cycle/switch-to-index helpers, folder loading via IPC
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@jamesainslie jamesainslie merged commit 9983340 into main Mar 20, 2026
0 of 2 checks passed
@jamesainslie jamesainslie deleted the phase-5-multi-document-workspace branch March 20, 2026 17:51
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.

1 participant