Commit graph

12 commits

Author SHA1 Message Date
Jan-Henrik Bruhn
efc712995b Move error display to header with clickable popover
- Replace content-pushing error banners with header status indicator
- Add categorized error labels (Python Error, Connection Error, etc.)
- Show detailed error info with solutions in 600px popover on click
- Fix layout shift by always rendering error button (invisible when no error)
- Clear machineError state on disconnect
- Fix TypeScript error in WorkflowStepper ref callback

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-11 12:31:57 +01:00
f80cabc5f2 Add Electron desktop application support with Electron Forge
Major changes:
- Add Electron main process and preload scripts with Web Bluetooth support
- Implement platform abstraction layer for storage and file services
- Create BluetoothDevicePicker component for device selection UI
- Migrate from electron-builder to Electron Forge for packaging
- Configure Vite for dual browser/Electron builds
- Add native file dialogs and persistent storage via electron-store
- Hide menu bar for cleaner desktop app appearance

The app now works in both browser (npm run dev) and Electron (npm run start).
Package with 'npm run package' or create installers with 'npm run make'.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-07 22:39:38 +01:00
8ee7d0ce7b Add Bluetooth pairing error detection and automatic disconnect handling
Detect when device is not paired at OS level and handle automatic disconnections. The app now properly updates UI state when the device is disconnected by the OS.

Changes:
- Add BluetoothPairingError custom error class in BrotherPP1Service
- Track isInitialConnection state to differentiate pairing issues from disconnects
- Detect pairing issues in sendCommand() only during initial connection
- Add onDisconnect() subscription method to BrotherPP1Service
- Listen for 'gattserverdisconnected' events and update state automatically
- Add isPairingError state to useBrotherMachine hook
- Display pairing errors with blue info styling instead of red error styling
- Include step-by-step pairing instructions: long-press Bluetooth button on machine, then pair in OS settings
- Automatically reset connection state when device disconnects

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-07 13:49:34 +01:00
b7ea024df3 Improve polling indicator with service-level communication state
Previously, isPolling was manually set in individual refresh functions,
which didn't cover all BLE communication and could have race conditions.

Now the communication indicator is driven by the service layer:
- Added isCommunicating state to BrotherPP1Service
- setCommunicating() called at queue processing boundaries
- onCommunicationChange() callback subscription pattern
- Hook subscribes to service communication state automatically

Benefits:
- Indicator shows for ALL BLE commands (status, progress, service count, etc)
- Prevents race conditions from overlapping command queue processing
- More accurate representation of actual BLE communication
- Cleaner code - no manual setIsPolling in each function

The indicator now properly shows whenever the command queue is being
processed, regardless of which specific command triggered it.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-07 00:02:22 +01:00
085ac1a5f7 Fix pattern re-upload after deletion by preserving filename
Fix bug where deleting a cached pattern prevented re-uploading because
the filename was lost. After deletion, the pattern remains visible in
the UI for re-editing and re-uploading, but the upload would silently
fail because displayFileName was empty.

The issue occurred because:
1. Pattern loaded from cache uses resumeFileName (from hook)
2. Local fileName state in FileUpload was never set (empty string)
3. After deletion, resumeFileName is cleared to null
4. displayFileName becomes empty, preventing upload

Solution:
- Add fallback to 'pattern.pes' when pesDataProp exists but no filename
- This ensures re-upload works after deletion while keeping pattern visible
- Pattern data (pesData) persists in App.tsx state for re-editing

Now users can delete a cached pattern and immediately re-upload it
with position adjustments or other modifications.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-06 23:39:31 +01:00
711f291eff Add immediate loading states for Upload and Delete operations
Fix UI delay issue where buttons remained clickable during BLE communication
setup. Now provides instant visual feedback when operations begin.

Changes:
- Add isUploading and isDeleting state tracking in useBrotherMachine hook
- Set loading states immediately on button click, before BLE communication
- Update FileUpload component to disable upload button and show spinner
- Update ProgressMonitor to disable delete button with loading indicator
- Add PatternCacheService.deletePattern() method for proper cache cleanup
- Pass loading state props through App.tsx to child components

The UI now responds immediately with disabled buttons and loading spinners,
preventing double-clicks and providing clear feedback during the initial
BLE setup period before progress reporting begins.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-06 23:20:01 +01:00
c5ec118b95 Enhance UI/UX with loading states, animations, and pattern lock functionality
Loading State Improvements:
- Add SkeletonLoader component with pattern info, canvas, and connection skeletons
- Show loading spinner on file selection and during pattern upload
- Display upload progress with enhanced progress bar and percentage
- Add success confirmation message when upload completes
- Show thread color preview dots inline with pattern info (up to 5 colors)

Visual Polish & Animations:
- Add custom animations: fadeIn, slideInRight, pulseGlow, skeleton-loading
- Enhance all cards with subtle hover shadow effects
- Improve header with richer gradient (blue-600 → blue-700 → blue-800)
- Polish error messages with icons and improved layouts
- Enhance empty state with decorative patterns and feature highlights
- Add smooth transitions to all NextStepGuide states
- Current color block pulses with blue glow animation
- Color blocks have hover states for better interactivity

Pattern Upload & Lock Functionality:
- Hide upload button after pattern is uploaded (patternUploaded && uploadProgress === 100)
- Disable pattern dragging when uploaded with visual lock indicator
- Pattern position overlay shows amber background with lock icon when locked
- Pattern remains in canvas after deletion for re-editing and re-upload
- Delete pattern from cache when deleting from machine to prevent auto-resume
- Add LockClosedIcon to indicate locked pattern state

Pattern Management:
- Keep pattern data in UI after deletion for repositioning and re-uploading
- Clear machine-related state but preserve pattern visualization
- Reset upload progress and pattern uploaded state on deletion

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-06 19:28:24 +01:00
d0a8273fee Fix PEN encoding and improve UI layout
Major fixes:
- Fix PEN data encoding to properly mark color changes and end markers
  - COLOR_END (0x03) for intermediate color blocks
  - DATA_END (0x05) for the final stitch only
  - Machine now correctly reads total stitch count across all color blocks
- Reset uploadProgress when pattern is deleted to re-enable upload button
- Allow pattern deletion during WAITING states
- Allow pattern upload in COMPLETE states
- Fix pattern state tracking to reset when patternInfo is null

UI improvements:
- Integrate workflow stepper into compact header
- Change app title to "SKiTCH Controller"
- Reduce header size from ~200px to ~70px
- Make Sewing Progress section more compact with two-column layout
- Replace emojis with Heroicons throughout
- Reorganize action buttons with better visual hierarchy
- Add cursor-pointer to all buttons for better UX
- Fix cached pattern not showing info in Pattern File box
- Remove duplicate status messages (keep only state visual indicator)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 12:56:27 +01:00
cd43a64bc4 Migrate to declarative react-konva and add pattern offset caching
React-Konva Migration:
- Create KonvaComponents.tsx with declarative components
- Convert Grid, Origin, Hoop, Stitches, PatternBounds, and CurrentPosition to React components
- Add React.memo and useMemo for performance optimization
- Remove imperative layer manipulation (destroyChildren, add, batchDraw)
- Remove backgroundLayerRef and patternLayerRef
- Let React handle component lifecycle and updates
- Improve performance through React's diffing algorithm

Pattern Offset Persistence:
- Add patternOffset field to CachedPattern interface
- Update PatternCacheService.savePattern to accept and store offset
- Modify useBrotherMachine to save offset when uploading pattern
- Update resumedPattern state to include offset information
- Restore cached pattern offset in App.tsx on resume
- Add initialPatternOffset prop to PatternCanvas component
- Pattern position now persists across page reloads and reconnections

Benefits:
- More maintainable and React-idiomatic code
- Better performance with large patterns
- Automatic cleanup and no memory leaks
- Pattern positioning workflow preserved across sessions
- Improved developer experience

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 23:38:23 +01:00
0f40cec8ec Implement interactive pattern canvas with Konva.js
- Replace vanilla canvas with Konva.js for better interactivity
- Add pan and zoom functionality (mouse wheel zoom, drag to pan)
- Make pattern draggable within hoop coordinate system
- Center canvas on embroidery origin (0,0)
- Default zoom shows entire 100x100mm hoop
- Pass user-defined pattern offset to LAYOUT command
- Replace auto-centering with manual pattern positioning
- Add visual overlays for thread legend, dimensions, pattern position, and zoom controls
- Fix effect dependencies to prevent drag interruption on machine status updates
- Memoize callbacks to prevent unnecessary re-renders
- Create konvaRenderers.ts utility for rendering grid, hoop, stitches, etc.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:27:22 +01:00
e0fadf69da Fix PES to PEN conversion and protocol implementation
- Use PyStitch raw stitches with proper command flag handling
- Import constants from pystitch.EmbConstant (STITCH, JUMP, TRIM, etc.)
- Filter COLOR_CHANGE, STOP, and END command-only stitches
- Properly encode jump/trim stitches with PEN_FEED_DATA flag
- Add pattern centering with moveX/moveY in layout
- Fix color change detection and PEN_COLOR_END marking
- Add comprehensive debug logging for pattern analysis
- Fix machine state helpers for IDLE and MASK_TRACE_COMPLETE states
- Update ProgressMonitor UI for proper button visibility
- Add error handling for undefined error codes

Machine now successfully uploads patterns, completes mask trace,
and transitions to sewing mode.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 21:08:52 +01:00
Jan-Henrik Bruhn
acdf87b237 initial 2025-11-30 22:18:14 +01:00