Added runes-based autosave functionality to PhotoPostForm following the same pattern as EssayForm:
- Added autosave store with updatedAt conflict detection
- Smart navigation guards and beforeunload warnings
- Draft recovery banner instead of inline prompt
- Only saves to localStorage on autosave failure
- Added AutoSaveStatus component
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add createAutoSaveStore for edit mode
- Add updatedAt tracking for conflict detection
- Add hasLoaded flag to prevent autosave on initial load
- Prime autosave after initial data loads
- Add AutoSaveStatus indicator in header
- Move draft recovery from inline to prominent banner
- Only save draft on autosave failure (not every change)
- Smart navigation guard (only blocks if unsaved)
- Add beforeunload warning (only if unsaved changes)
- Add keyboard shortcut (Cmd/Ctrl+S)
- Add proper cleanup on unmount
- Update clearDraft calls in restore/dismiss functions
- Fix $derived syntax (use $derived.by for draftTimeText)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update beforeNavigate guard to check autosave status before blocking
- Allow instant navigation when status is 'saved' (no interruption)
- Add beforeunload warning for browser close/reload
- Only show warnings when status is NOT 'saved' (saving/error/idle)
- Improves UX by not interrupting users when everything is already saved
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove redundant localStorage saves on every form change
- Only save draft when autosave status is 'error' or 'offline'
- Reduces draft recovery banner noise for successful autosaves
- Navigation guard still prevents data loss when navigating away
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update ProjectForm to use new createAutoSaveStore with Svelte 5 runes
- Fix $derived syntax in AutoSaveStatus (use $derived.by for multi-statement)
- Add hasLoaded flag to prevent infinite loop on autosave completion
- Move draft recovery from inline header to prominent banner below header
- Style draft banner with blue info colors and slide-down animation
- Fix draft persistence by clearing localStorage on restore/dismiss
- Call beforeNavigate at top level for proper Svelte 5 lifecycle
- Add keyboard shortcut (Cmd/Ctrl+S) and navigation guard effects
- Update AutoSaveStatus to support both old stores and new reactive props
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Introduces createAutoSaveStore() using $state() for automatic reactivity.
New store provides cleaner API while maintaining backward compatibility.
Changes:
- New: src/lib/admin/autoSave.svelte.ts with createAutoSaveStore()
- Uses $state() for status and lastError (reactive getters)
- Export AutoSaveStore and AutoSaveStoreOptions types
- Add JSDoc with usage examples
- Update autoSaveLifecycle.ts to accept both old and new types
- Export AutoSaveController type from old file for compatibility
Old createAutoSaveController() remains unchanged for gradual migration.
Type checking passes with no new errors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Enhances autosave controller with missing features:
- prime(payload): Sets initial hash baseline to prevent autosaves on page load
- idleResetMs option: Auto-transitions from 'saved' → 'idle' status (default 2s)
- onSaved callback: Now receives { prime } helper for re-priming after server response
- Cleanup: destroy() now properly clears idle reset timer
All existing tests pass. Backward compatible - forms not using new features yet.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Introduces createListFilters() with type-safe, reactive filtering and sorting
for admin list pages. Eliminates ~120 lines of duplicate code across projects
and posts pages.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add video player with controls in MediaDetailsModal
- Display video metadata (duration, codecs, bitrate) in metadata panel
- Show video thumbnails with play icon overlay in MediaGrid
- Support video preview in upload components
- Replace emoji icons with SVG play icon
- Maintain natural video aspect ratio in all views
- Add proper styling for video thumbnails and placeholders
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add video MIME types support (WebM, MP4, OGG, MOV, AVI)
- Increase upload size limit to 100MB for videos
- Add ffmpeg integration for local video processing
- Generate video thumbnails at 50% duration
- Extract video metadata (duration, codecs, bitrate)
- Add database fields for video metadata
- Support video uploads in both local and Cloudinary storage
- Maintain aspect ratio for video thumbnails (1920px max width)
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix renderEdraContent to accept albumSlug option parameter
- Fix album listing links from /photos/{slug} to /albums/{slug}
- Remove album header section for cleaner photo story presentation
- Remove broken photo page conditional that was preventing render
- Pass album slug to content renderer for proper photo linking
Creates more immersive experience where content speaks for itself.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add URL field to Apple Music data type
- Include Apple Music URL in album transformation
- Prioritize Apple Music links over Last.fm in Album component
- Falls back to Last.fm URL when Apple Music data unavailable
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Create CacheManager class to unify all Redis cache operations
- Define cache types with prefixes and default TTLs
- Provide type-safe cache operations
- Add bulk clear operations for related caches
- Include cache statistics and monitoring capabilities
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Create DebugPanel component with Now Playing, Albums, and Cache tabs
- Show real-time connection status and update intervals
- Display detailed Apple Music data for each album
- Add inline cache clearing for individual albums
- Implement Apple Music search modal for testing queries
- Add admin endpoints for cache management and API testing
- Only visible in development mode
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add fallback to search for songs when album search fails
- Handle artist name variations (with/without spaces in Japanese names)
- Create synthetic album entries for singles not found as albums
- Add search metadata to track failed searches and debug info
- Fix Hachikō preview detection by normalizing artist names
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Adjust update frequency based on remaining track time
- Poll every 5s when <20s remaining, 10s for 20-60s, 15s for >60s
- Add heartbeat timestamps to track update timing
- Implement time-based fallback for tracks without Apple Music data
- Assume tracks scrobbled within 5 minutes are still playing
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Merge albumStream and nowPlayingStream into unified musicStream store
- Simplify confidence scoring to binary detection (playing/not playing)
- Create single source of truth for music state across components
- Fix synchronization issues between header and album indicators
- Make Album spring animation more subtle (stiffness: 150, damping: 25)
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Always fetch fresh data from Last.fm for now playing detection
- Add confidence-based detection with progress tracking
- Implement dynamic polling intervals (10s when playing, 30s idle)
- Add marquee animation for now playing text in header
- Fix release date formatting to show only year
- Add gradient fade effects to marquee edges
- Enhanced logging for debugging detection issues
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Show currently playing track info when hovering over avatar
- Display album artwork, artist name, and track/album name
- Add music note icons with pulse animation
- Maintain exact same container size as navigation
- Only shows when music is actively playing (avatar has headphones)
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add Japanese character detection to prioritize JP storefront
- Improve album/artist matching logic with helper functions
- Support flexible matching for albums with extra text (e.g., "- Single")
- Handle comma-separated artists by matching primary artist
- Clean up code by removing duplicate logic and verbose logging
- Fix issue where Japanese albums weren't found due to strict matching
This ensures albums like "ランデヴー" properly fetch artwork from Apple Music
even when Last.fm has no images available.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Enhance albumEnricher with better error handling and type safety
- Refactor lastfmStreamManager for cleaner event management
- Update lastfmTransformers with improved data validation
- Add better type guards in mediaHelpers
- Improve nowPlayingDetector logic and state management
- Enhance SSE error handling in Last.fm stream endpoint
Key improvements:
- Better error boundaries and fallback values
- More robust type checking and validation
- Cleaner async/await patterns
- Improved logging for debugging
- Consistent error response formats
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Migrate all Edra components to Svelte 5 with runes syntax
- Implement unified ContentInsertionPane for consistent content insertion
- Standardize placeholder components with improved layouts
- Enhance bubble menu with better color picker and text styling
- Improve drag handle interactions and visual feedback
- Update slash command system for better extensibility
Key improvements:
- ContentInsertionPane: New unified interface for all content types
- Placeholder components: Consistent sizing and spacing
- GeolocationPlaceholder: Simplified map integration
- UrlEmbedPlaceholder: Better preview handling
- ComposerMediaHandler: Converted to Svelte 5 class syntax
- BubbleMenu components: Enhanced UI/UX with modern patterns
All components now use:
- Interface Props pattern for better type safety
- $state and $derived for reactive state
- Modern event handling syntax
- Consistent styling with CSS variables
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add BasePane and Pane components for consistent panel UI
- Create pane-manager store for centralized pane state management
- Support for different pane positions and animations
- Establish foundation for unified pane behavior across the app
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Create ContentInsertionPane component with segmented controls
- Update image placeholder to single-line format with icon + text
- Update gallery placeholder to use unified pane
- Support upload, embed link, and gallery selection for each type
- Add location search placeholder for future geocoding integration
- Add placeholder node styles to editor.css matching other media nodes
- Remove incorrect margins from individual placeholder components
- Placeholders now properly aligned with 2.25rem horizontal spacing
- Consistent with h1, h2, p text elements and YouTube embeds
- Fix slash command keyboard navigation by uncommenting handler
- Update all media placeholders to respect content block margins (2.25rem)
- Refactor placeholder styles to use SCSS variables consistently
- Fix Audio, Gallery, IFrame, Video, Location, and URL embed placeholders
- Fix Image placeholder width to match other placeholders
- Ensure responsive margins on mobile (2rem)
- Replace old slash command list styles with new design
- Use consistent SCSS variables from design system
- Match dropdown styling patterns used elsewhere
- Improve visual hierarchy with better typography
- Add smooth transitions and hover states
- Clean up old CSS styles