Commit Graph

908 Commits

Author SHA1 Message Date
spencrmartin 6950fd4aa2 Fix height calculation for triple-backtick code blocks
- Detect presence of code blocks using regex
- Trigger display-based height measurement for both live IDE and permanent code blocks
- Measure display layer scrollHeight when code blocks are present
- Prevents code blocks from being cut off or drifting
- Ensures proper container height even after exiting code mode
- Fixes height sync for backtick code blocks
2025-10-31 10:49:16 -04:00
spencrmartin cfbb558018 Convert live IDE code to permanent code block on double-Enter exit
- When exiting code mode with double-Enter, convert to triple-backtick format
- Format: ```language\ncode\n```
- Code block remains visible and styled after exit
- User can continue typing in normal mode below the code block
- Preserves syntax highlighting in the final message
- Fixes issue where code block disappeared after exiting
2025-10-31 10:44:15 -04:00
spencrmartin 054fe3fad1 Add double-Enter to exit code mode and return to normal text
- Detect when code content ends with double newline (\n\n)
- Exit code mode automatically when double newline detected
- Remove the #language trigger from the value
- Keep the code content as normal text
- Move cursor to end of text after exiting
- Allows user to continue typing in normal mode after code
- Press Enter twice in code mode to exit
2025-10-31 10:41:24 -04:00
spencrmartin 730bb34165 Fix cursor tracking in code mode to follow actual typing position
- Calculate cursor position within code content
- Split code at cursor position for rendering
- Render code before cursor, cursor, then code after cursor
- Use inline span elements for proper cursor placement
- Cursor now appears at current typing position, not at end
- Fixes confusing cursor placement issue in code mode
2025-10-31 10:40:32 -04:00
spencrmartin eba14946d8 Fix regex to trigger code mode immediately after language name
- Changed regex from (\s|$) to (?![a-z]) negative lookahead
- Now matches #python immediately without requiring space
- Prevents #pythonprint from breaking the trigger
- Auto-inserts newline as soon as full language name is typed
- Updated both detection and rendering regex to match
- Fixes issue where typing continued on trigger line
2025-10-31 10:39:38 -04:00
spencrmartin fb635770ff Auto-insert newline after #language trigger to move cursor into code block
- When #language is typed, automatically insert a newline after it
- Move cursor to the new line (inside the code block)
- Prevents typing from continuing on the trigger line
- Only inserts newline if one doesn't already exist
- Updates codeMode.startPos to account for the inserted newline
- Fixes issue where typing after #python would break the code box
2025-10-31 10:37:57 -04:00
spencrmartin 90b384c1c9 Fix code mode height calculation to use display layer scrollHeight
- Add useEffect that triggers when codeMode changes
- Measure display layer's actual scrollHeight instead of textarea's
- Textarea doesn't know about styled code block height
- Use 50ms delay to ensure SyntaxHighlighter has rendered
- This fixes initial load where code block was below the fold
- Ensures containerHeight is properly set for code mode
2025-10-31 10:35:10 -04:00
spencrmartin 83eba3f3a7 Fix code block width constraints and ensure proper height calculation
- Add width constraints to code mode rendering to prevent overflow
- Change code container from inline to block display
- Add overflow-x-auto for horizontal scrolling when needed
- Ensure code blocks respect container boundaries
- Add maxWidth: 100% and boxSizing: border-box for proper sizing
- This ensures the code block properly influences chat input height
2025-10-31 10:31:05 -04:00
spencrmartin 33608e961d Enable inline code mode - #language can now appear anywhere in text
- Changed regex from ^# to # (removed start-of-line anchor)
- Code mode now activates when #language appears anywhere
- Text before the trigger is preserved and displayed
- Example: 'Here is some code #python print(hello)' works!
- Maintains all existing functionality
2025-10-31 10:20:41 -04:00
spencrmartin 78d38bed7e Implement live IDE input with #language trigger
- Type #python, #javascript, #typescript, etc. to activate code mode
- Live syntax highlighting as you type
- Enter key inserts newlines (doesn't send message)
- Cmd/Ctrl+Enter to send message
- Language badge displayed
- IDE-style visual appearance
- Supports 30+ programming languages
2025-10-31 10:18:08 -04:00
spencrmartin 02b38f3ac8 Add IDE-style syntax highlighting for code blocks in chat input
- Detect code blocks with triple backtick syntax ()
- Render using react-syntax-highlighter with VS Code dark theme
- Display language badge in top-right corner
- Support all common programming languages
- Maintain cursor positioning and height synchronization
- Code blocks excluded from spell checking
2025-10-31 10:10:18 -04:00
spencrmartin 44d2e0b774 Fix resetHeight to not call syncDisplayHeight
- Remove syncDisplayHeight and ensureStyleConsistency calls from resetHeight
- These were recalculating height based on scrollHeight, preventing shrinking
- Now resetHeight just sets to minHeight directly
- Add console logs for debugging
2025-10-31 09:35:34 -04:00
spencrmartin 221647007d Add rows dependency to ensureStyleConsistency callback
- Ensures callback has access to latest rows value
- Prevents stale closure issues
2025-10-31 09:25:44 -04:00
spencrmartin 222211b7b1 Fix resetHeight to properly update containerHeight and include dependencies
- Added setContainerHeight call in resetHeight method
- Added proper dependencies to useImperativeHandle
- Ensures resetHeight method has access to latest callbacks
2025-10-31 09:24:35 -04:00
spencrmartin fd830cdfec Add explicit useEffect to sync height on value changes
- Ensures syncDisplayHeight runs whenever value prop changes
- Fixes issue where height wasn't recalculating on text deletion
- Complements existing ResizeObserver with direct value monitoring
2025-10-31 09:22:26 -04:00
spencrmartin 9a31c2eda9 Fix text input to shrink back to base size when text is deleted
- Added value dependency to syncDisplayHeight callback
- Ensures height recalculation triggers when content changes
- Fixes issue where input stayed large after deleting text
2025-10-31 09:21:42 -04:00
spencrmartin 14ead0a4af Fix container height to prevent layout pushing by tracking and applying computed height 2025-10-31 09:16:47 -04:00
spencrmartin 54da15bc3b Fix input container overflow by adding maxHeight constraint to wrapper div 2025-10-31 09:15:34 -04:00
spencrmartin 0bd3c4edce Fix toolbar overlap by respecting parent maxHeight constraint 2025-10-31 09:14:40 -04:00
spencrmartin 422f3c0531 Fix line spacing discrepancy causing highlight drift
Fixed the rendering layer having slightly larger line spacing than the input
layer by eliminating CSS class interference and enforcing exact line height:

1. Removed conflicting CSS classes:
   - Removed 'leading-relaxed' class from content divs
   - This class was applying Tailwind's line height that conflicted with computed values
   - Removed 'min-h-[1.5em]' that could interfere with line height calculations

2. Enforced exact line height matching:
   - Use setProperty() with '!important' to override any CSS inheritance
   - Calculate minHeight using the same computed line height values
   - Ensure display layer uses identical line height as textarea

3. Child element line height inheritance:
   - Force all child elements to inherit the parent's exact line height
   - Prevents individual spans/divs from having different line spacing
   - Uses '!important' to override any Tailwind or other CSS classes

This should eliminate the line spacing discrepancy that was causing
highlights to gradually drift away from the text alignment.
2025-10-31 09:12:36 -04:00
spencrmartin 2235b93020 Fix cumulative highlight drift with comprehensive style sync
Fixed the gradual highlight misalignment that gets worse with each line
by ensuring perfect style synchronization between layers:

1. Comprehensive style synchronization:
   - Replaced simple line height sync with full style consistency
   - Copies all computed styles that affect text layout from textarea
   - Includes fontSize, fontFamily, letterSpacing, wordSpacing
   - Ensures identical padding values to prevent cumulative drift

2. Box model consistency:
   - Added explicit boxSizing: 'border-box' to display layer
   - Matches textarea box model to prevent layout differences
   - Eliminates padding/border calculation discrepancies

3. Rounded line height calculations:
   - Uses Math.round() to prevent fractional pixel accumulation
   - Eliminates subpixel differences that compound over multiple lines
   - Ensures consistent line spacing throughout the text

4. Text rendering consistency:
   - Copies textRendering, webkitFontSmoothing, mozOsxFontSmoothing
   - Prevents browser-specific text rendering differences
   - Eliminates subpixel positioning variations

This should eliminate the gradual 'walking away' of highlights and
fix the bottom text cutoff issue by ensuring perfect layer alignment.
2025-10-31 09:12:27 -04:00
spencrmartin 08fb455eac Fix highlight offset by ensuring line height consistency
Fixed the issue where highlights (spell check, selection) were offset from
text due to inconsistent line height calculations between layers:

1. Dynamic line height calculation:
   - Replaced hardcoded 21px with computed line height from actual textarea
   - Uses window.getComputedStyle() to get real rendered line height
   - Handles both 'normal' and explicit line height values properly

2. Explicit line height synchronization:
   - Sets both textarea and display layers to use identical pixel line heights
   - Added ensureLineHeightConsistency() function for ongoing sync
   - Called after every height sync to maintain consistency

3. Consistent cursor positioning:
   - Updated resetHeight method to use calculated line height
   - All line-based calculations now use the same computed value
   - Eliminates discrepancies between layers

This ensures that spell check highlights, selection highlights, and cursor
positioning are perfectly aligned with the actual rendered text, regardless
of font size, browser differences, or CSS inheritance.
2025-10-31 09:12:20 -04:00
spencrmartin f49769d39b Fix layer synchronization issues between input and display 2025-10-31 09:12:10 -04:00
Spence b3b4e4a7eb Spence/sizingpolish (#5485) 2025-10-30 18:04:05 -04:00
Spence 0e30709c9a feat: Update pill colors - light blue for actions, light orange for f… (#5483) 2025-10-30 16:16:57 -04:00
spencrmartin 07391f6127 feat: improve built-in command styling with consistent disabled state and overlay pill
- Update built-in command badges to use grey styling matching ActionPopover
- Add blur effect to disabled edit/copy/delete buttons for built-in commands
- Position built-in pill as overlay on top of disabled action buttons
- Center align action buttons within their container space
- Add 8px left spacing to built-in pill overlay for better visual balance
2025-10-23 09:52:52 -04:00
spencrmartin 0313c7e938 fix: use consistent hover styling for both mouse and keyboard selection
Changed keyboard selection to use the same subtle gray background as mouse hover
instead of the bright blue. This creates a unified visual experience where:

- Mouse hover: Light gray background
- Keyboard selection: Same light gray background
- Both states look identical and use the system's natural hover styling

Removed the complex text color overrides since we're now using the same
background for both hover and selection states. This creates a more
subtle and consistent user experience.
2025-10-23 09:52:51 -04:00
spencrmartin 50f44f4d9e fix: make hover styling more visible in popovers
Changed hover background from subtle 'hover:bg-background-muted' to more
visible 'hover:bg-gray-100 dark:hover:bg-gray-700' so users can clearly
see which item they're hovering over with their mouse.

Now both mouse and keyboard interactions have clear visual feedback:
- Mouse hover: Light gray background (gray-100/gray-700)
- Keyboard selection: Bright blue background (blue-500)
- Both provide clear indication of what will be selected
2025-10-23 09:52:51 -04:00
spencrmartin d653154858 fix: make keyboard selection visually distinct in popovers
Updated both ActionPopover and MentionPopover to use more visible selection styling:

- Changed selected background from bgProminent to bright blue-500
- Added proper text color overrides for selected state
- Icon colors change to white when selected
- Description text uses blue-100 for better contrast on blue background
- Custom badge gets blue-400 background when parent is selected

This makes it crystal clear which item is selected when navigating with arrow keys.
Users can now easily see what they're about to select with both mouse hover
and keyboard navigation.
2025-10-23 09:52:51 -04:00
spencrmartin e0e5d227e5 fix: keyboard navigation in RichChatInput for popover controls
Fixed the issue where arrow up/down keys weren't working when the ActionPopover
was open after typing '/'. The problem was in the synthetic event creation in
RichChatInput's handleTextareaKeyDown function.

Changes:
- Properly preserve all keyboard event properties (key, code, keyCode, etc.)
- Bind event methods correctly to maintain proper context
- Ensure target/currentTarget reference the display div for positioning
- Maintain all event properties needed by ChatInput's handleKeyDown

This fixes the keyboard navigation for both ActionPopover (/) and MentionPopover (@)
when using the new RichChatInput component with pills and spell checking.
2025-10-23 09:52:51 -04:00
spencrmartin 566c3ee49d feat: improve hover styles for ActionPopover and MentionPopover
- Apply consistent hover styling from settings to both popovers
- Use hover:bg-background-muted for better visual feedback
- Change border-radius from rounded-md to rounded-lg for consistency
- Update transition from transition-colors to transition-all for smoother animations
- Maintain selected state styling with bg-bgProminent

This creates a consistent hover experience across the application where users
can clearly see what they're about to select in both @ and / popovers.
2025-10-23 09:52:51 -04:00
spencrmartin 09798a86da feat: enhance custom slash commands with search, pills, and dynamic loading
- Add search functionality to ActionPopover when typing / + text
- Show starred commands first, then all commands during search
- Add 'Create Command' button in empty states with modal integration
- Implement visual action pills in both input and user messages
- Hide expanded 'what AI sees' text from UI while sending full prompts to AI
- Add dynamic action mapping from localStorage for custom commands
- Implement action pill expansion in useMessageStream before API calls
- Add proper keyboard navigation and modal state management
- Include usage tracking for custom commands

Files modified:
- ChatInput.tsx: Query passing, modal integration, keyboard navigation
- ActionPopover.tsx: Search functionality and empty state enhancements
- RichChatInput.tsx: Dynamic action mapping from localStorage
- MessageContent.tsx: Dynamic action mapping from localStorage
- useMessageStream.ts: Action pill expansion before API calls
2025-10-23 09:52:51 -04:00
spencrmartin 7736442aa8 feat: implement custom slash commands with modal-based creation
- Add CustomCommandsSettings component with row-based design matching Mode section
- Integrate AddCustomCommandModal using proper Dialog components for consistent styling
- Remove category filtering and inline editing for cleaner UX
- Update modal to use proper Dialog background instead of dark overlay
- Remove category field from modal form for simplified command creation
- Apply subtle text colors to form helper text for better visual hierarchy
- Remove preview section from modal to reduce height and improve usability
- Add proper header styling with CardTitle and CardDescription
- Update command icons to display without background circles
- Implement proper padding and spacing throughout the interface
- Connect modal functionality to Plus button and edit actions
- Preserve existing command categories while preventing new category assignment
2025-10-23 09:52:51 -04:00
spencrmartin 35491ae349 Fine-tune custom commands settings styling
- Remove header and description from Custom Commands card
- Convert card-style layout to row-based design matching mode section
- Update styling to use proper text-* and background-* classes
- Remove unused onClose parameter
- Make commands display as compact rows with inline actions
- Improve empty state styling and sizing
2025-10-23 09:52:51 -04:00
spencrmartin 6fcd074ece chore: remove test file for custom commands 2025-10-23 09:52:51 -04:00
spencrmartin f79c0868fa feat: implement custom slash commands with pill expansion
- Add comprehensive custom slash commands system
- Users can create /command shortcuts that expand to full prompts
- ActionPopover now only shows user-created custom commands
- Add custom commands management in Settings → Chat
- Implement pill rendering: users see [Command Label], AI gets full prompt
- Add localStorage-based storage with upgrade path to API
- Include example commands: document, review, explain, optimize, test
- Add complete type system with validation and categories
- Support usage tracking, favorites, and command management
- Fix pill expansion to use proper labels instead of IDs

Components added:
- CustomCommandsSettings: Full CRUD interface for command management
- AddCustomCommandModal: Modal for creating/editing commands
- useCustomCommands: Hook for command state management
- customCommands types: Complete type system with validation

Components modified:
- ActionPopover: Filtered to show only custom commands
- ChatInput: Fixed handleActionSelect for proper pill rendering
- ChatSettingsSection: Added custom commands card
- Added UI components: label, textarea for form inputs
2025-10-23 09:52:49 -04:00
spencrmartin f9176dc89d Fix chat input height synchronization with complete reset
- Force complete height reset to 0px before measuring scrollHeight
- Add reflow trigger to ensure accurate measurements
- Prevents input from staying large when content is removed
2025-10-23 09:51:49 -04:00
spencrmartin 485a6836e3 Fix spell check tooltip positioning to appear right above misspelled words
- Update SpellCheckTooltip styling to match commit 663c921 design
- Add numbered suggestions with hover highlighting and blue selection states
- Include keyboard hints and improved action buttons with icons
- Fix tooltip positioning to appear directly above words with minimal gap
- Remove translateY(-100%) transform that was pushing tooltip too far away
- Position tooltip 5px above word with only horizontal centering
- Maintain viewport boundary detection to prevent cutoff on edges
- Improve overall tooltip UX with professional styling and close proximity
2025-10-23 09:51:49 -04:00
spencrmartin 1c5b585e6c Restore custom spell checking implementation with hover tooltips and highlighting
- Add back SpellCheckTooltip component with custom styling and suggestions
- Restore custom spell checking logic in RichChatInput component
- Add back IPC spell-check and spell-suggestions handlers in main process
- Re-enable custom misspelled word highlighting with red background
- Restore hover/click popover tooltips with spell suggestions
- Disable native browser spell checking (spellCheck={false}) to use custom implementation
- Add back all spell checking state management and event handlers

This provides the custom spell checking UI with highlighting and popovers as requested.
2025-10-23 09:51:49 -04:00
spencrmartin de52931e17 Remove custom spell checking implementation in favor of native OS spell checking
- Remove custom spell checking logic from RichChatInput component
- Remove SpellCheckTooltip and SpellCheckContextMenu components
- Remove IPC spell-check and spell-suggestions handlers from main process
- Enable native browser spell checking with spellCheck={true} on textarea
- Simplify component by removing misspelled word highlighting and tooltip state
- Users now get familiar OS-native spell check with right-click context menus

This provides better UX with system dictionary integration and familiar behavior.
2025-10-23 09:51:49 -04:00
spencrmartin f809bb689c Fix cursor positioning to center with text baseline
- Changed cursor transform from translateY(-0.1em) to translateY(0.1em)
- Cursor now appears properly centered with text instead of floating above
- Applied fix to all cursor instances throughout RichChatInput component
2025-10-23 09:51:49 -04:00
spencrmartin 4d6cc4cd9c Fix cursor vertical alignment to better match text baseline 2025-10-23 09:51:48 -04:00
spencrmartin 240a1627de Adjust cursor vertical alignment in empty state
- Changed cursor top position from 0px to 0.125em
- Aligns cursor with text baseline instead of sitting below it
- Improves visual consistency with placeholder text
2025-10-23 09:51:48 -04:00
spencrmartin eef8690452 Fix placeholder text movement on empty state click
- Position placeholder text absolutely to prevent displacement
- Position cursor absolutely at start of empty input
- Maintains visual stability when focusing empty input
2025-10-23 09:51:48 -04:00
spencrmartin 833347daa2 Fix cursor width and positioning to prevent text displacement
- Set cursor width to 1px for minimal visual footprint
- Removed left margin to prevent text from being pushed left/right
- Applied consistent styling across all cursor instances
- Cursor now appears as thin line without displacing text
2025-10-23 09:51:48 -04:00
spencrmartin 5dde45bebf Update text selection to custom light blue color #BBD6FB
- Changed selection background to #BBD6FB for softer, more pleasant highlighting
- Provides excellent visibility while being gentle on the eyes
- Custom blue tone as requested by user
2025-10-23 09:51:48 -04:00
spencrmartin 64f102126c Lighten text selection blue color for better visibility
- Changed selection background from #3b82f6 (blue-500) to #60a5fa (blue-400)
- Provides lighter, more subtle selection highlighting
- Maintains clear selection feedback while being easier on the eyes
2025-10-23 09:51:48 -04:00
spencrmartin 95ee57809b Fix white text duplication in selection by keeping text transparent
- Changed selection text color from white to transparent
- Maintains blue selection background while eliminating white text artifacts
- Fixes holographic effect caused by visible selected text
2025-10-23 09:51:48 -04:00
spencrmartin 044f5fd030 Fix holographic text effect by using WebkitTextFillColor
- Changed from rgba(0,0,0,0) back to transparent for cleaner text hiding
- Added WebkitTextFillColor: transparent to eliminate text visibility artifacts
- Should maintain blue selection highlighting while removing ghost text effect
2025-10-23 09:51:48 -04:00
spencrmartin e2323c3f0a Fix text selection visibility by making textarea fully visible
- Changed opacity from 0.01 to 1 to allow selection highlighting
- Used rgba(0,0,0,0) for transparent text while keeping element visible
- Added explicit user-select CSS properties
- Made selection text fully opaque white for better visibility
2025-10-23 09:51:48 -04:00