Implements WebSocket-based TUIO protocol support to connect physical tangibles
to presentation mode. When tangibles are placed on/removed from a touch screen,
they trigger configured actions (label filtering or state switching).
Features:
- TUIO 1.1 and 2.0 protocol support with version selection
- WebSocket connection management with real-time status
- Test connection feature in configuration dialog
- Persistent settings (WebSocket URL and protocol version)
- Multi-tangible handling: union for filters, last-wins for states
- Automatic connection in presentation mode
Implementation:
- TuioClientManager: Wrapper for tuio-client library with dual protocol support
- WebsocketTuioReceiver: Custom OSC/WebSocket transport layer
- useTuioIntegration: React hook bridging TUIO events to app stores
- TuioConnectionConfig: Settings UI with real-time tangible detection
- tuioStore: Zustand store with localStorage persistence
Technical details:
- TUIO 1.1 uses symbolId for hardware identification
- TUIO 2.0 uses token.cId for hardware identification
- Filter mode: Activates labels, union of all active tangibles
- State mode: Switches timeline state, last tangible wins
- Cleanup: Removes only labels no longer in use by any tangible
- Unknown hardware IDs are silently ignored
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add comprehensive presentation/viewer mode optimized for touch table
interactions with clean UI and touch-friendly timeline navigation.
State Management:
- Add presentationMode toggle to settingsStore with localStorage persistence
- Add preferPresentationMode to DocumentMetadata for per-document preferences
- Auto-enter presentation mode when opening documents that prefer it
- Add setDocumentPresentationPreference() helper to workspaceStore
UI Components:
- Create PresentationTimelineOverlay component with floating timeline control
- Previous/Next navigation buttons with chevron icons
- Horizontal scrollable state list
- Only shows when document has 2+ states
- Proper vertical alignment using flex items-stretch and centered content
- Scales to ~10 states with max-w-screen-md (768px) container
- Create presentation.css for touch optimizations (60px+ touch targets)
UI Modifications:
- App.tsx: Conditional rendering hides editing chrome in presentation mode
- GraphEditor: Disable editing interactions, keep pan/zoom enabled
- MenuBar: Add "Presentation Mode" menu item
- Global shortcuts: F11 to toggle, Escape to exit presentation mode
Tests:
- Add presentation mode tests to settingsStore.test.ts
- Add document preference tests to workspaceStore.test.ts
- All 376 tests passing
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements complete bibliography management with citation assignment to
nodes and edges, following CSL-JSON standard.
Features:
- Bibliography store with Zustand and citation.js integration
- Smart import supporting DOI, BibTeX, PubMed ID, and URLs
- Manual entry and editing forms for references
- Citation selector with autocomplete text field interface
- History tracking for undo/redo support
- Workspace integration for import/export
- Support for multiple reference types including interview and other
- Description/notes field for additional reference information
Components:
- CitationSelector: autocomplete UI for selecting citations
- BibliographyConfigModal: main bibliography management interface
- QuickAddReferenceForm: smart import and manual entry
- EditReferenceInline: full reference editing form
- ReferenceManagementList: list view with citation counts
Integration:
- NodeEditorPanel: citation assignment to actors
- EdgeEditorPanel: citation assignment to relations
- MenuBar: bibliography menu item
- WorkspaceStore: bibliography persistence in workspace files
Technical details:
- CSL-JSON format for bibliographic data
- citation.js for parsing and formatting
- TypeScript with proper type definitions
- Debounced updates for performance
- Citation count tracking across graph elements
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements a comprehensive label system and completely redesigns all
filtering (labels, actor types, relation types) to use intuitive positive
filtering where empty selection shows all items.
Label System Features:
- Create, edit, delete labels with names, colors, and scope (actors/relations/both)
- Inline editing with click-to-edit UI for quick modifications
- Quick-add label forms in config modals
- Autocomplete label selector with inline label creation
- Label badges rendered on nodes and edges (no overflow limits)
- Full undo/redo support for label operations
- Label validation and cleanup when labels are deleted
- Labels stored per-document in workspace system
Filter System Redesign:
- Changed from negative to positive filtering for all filter types
- Empty selection = show all items (intuitive default)
- Selected items = show only those items (positive filter)
- Consistent behavior across actor types, relation types, and labels
- Clear visual feedback with selection counts and helper text
- Auto-zoom viewport adjustment works for all filter types including labels
Label Cleanup & Validation:
- When label deleted, automatically removed from all nodes/edges across all timeline states
- Label references validated during node/edge updates
- Unknown label IDs filtered out to maintain data integrity
UI Improvements:
- All labels rendered without overflow limits (removed +N more indicators)
- Filter checkboxes start unchecked (select to filter, not hide)
- Helper text explains current filter state
- Selection counts displayed in filter section headers
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removes the Ctrl+A keyboard shortcut and associated select-all functionality
that was not working properly.
Changes:
- Remove select-all shortcut definition from useGlobalShortcuts
- Remove "Select All" menu item from View menu
- Remove handleSelectAll stub function from App.tsx
- Clean up onSelectAll prop from MenuBar component
The select-all feature was dysfunctional (only logging to console) and
not properly implemented, so it has been removed entirely.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removes the upper toolbar and consolidates undo/redo controls into the
Edit menu for a cleaner interface with more screen space.
Changes:
- Move undo/redo buttons from Toolbar to Edit menu with descriptions
- Remove Toolbar component from App layout
- Implement closeAllMenus event system for coordinated menu management
- Add event listeners to close menus when clicking on graph/timeline canvas
- Add cross-menu closing: context menus close menu bar and vice versa
- Fix React warning by deferring event dispatch with setTimeout
Benefits:
- Cleaner UI with more vertical space for graph editor
- Unified menu system prevents multiple menus open simultaneously
- Context menus and menu bar dropdowns coordinate properly
- Consistent UX: clicking anywhere closes open menus
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements a user-friendly dialog that prompts for document names before
creating new documents, replacing the default "Untitled Analysis" behavior.
Features:
- InputDialog component for text input with validation
- useCreateDocument hook to centralize naming logic
- Pre-filled default value "Untitled Analysis"
- Validation to prevent empty document names
- Helpful placeholder text with examples
- Keyboard shortcuts (Enter/Escape)
- Auto-focus and select input field
Updated all document creation entry points:
- Menu Bar: "New Document" and "New from Template"
- Document Tabs: "+" button
- Document Manager: "New Document" button
- Empty State: "New Document" button
- Keyboard shortcut: Ctrl+N
This provides a consistent UX across the application and reduces code
duplication by using a single reusable hook.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implemented image export functionality using html-to-image that actually
slaps. No more bloated screenshots with miles of blank space - this baby
wraps your graph tighter than shrink wrap on a fresh deck.
Features:
- PNG export with proper 300 DPI quality (4x pixelRatio)
- SVG vector export for infinite scaling
- Smart bounds calculation that hugs your nodes
- Configurable padding (default: 10px of breathing room)
- Accessible via File menu
Technical highlights:
- Direct transform calculation instead of getViewportForBounds bloat
- Proper pixelRatio handling (not that 16x scaling nonsense)
- Based on React Flow's official pattern but actually optimized
- Uses html-to-image@1.11.11 (newer versions are broken)
Export quality goes hard. Print-ready PNGs. Crisp. Clean. Chef's kiss.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
All keyboard shortcut labels in the MenuBar now come from the
centralized keyboard shortcut manager via the new useShortcutLabels
hook, eliminating hardcoded duplicates.
Changes:
- Add useShortcutLabels hook for retrieving formatted shortcut labels
- Update MenuBar to use dynamic shortcut labels from manager
- Platform-aware display (Cmd on Mac, Ctrl elsewhere)
- Shortcuts automatically update if changed in manager
- Fix MUI icon fontSize prop issue in LeftPanel
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>