- Root folder cards with hero-style layout and SVG icons
- Full-width thumbnails with aspect-ratio grid items
- List view column headers (Name, Bitrate, Duration, Size)
- Modernized breadcrumb with pill segments and overflow handling
- Proper skeleton shimmer replacing emoji hourglass on thumbnails
- Pagination shows "Showing X-Y of Z" item count
- Refined hover effects, animations, and visual hierarchy
- Download button revealed on row hover in list view
- Type badges hidden by default, shown on hover
- Localized new keys in en.json and ru.json
workflow_dispatch-triggered build.yml that produces Windows
installer/portable and Linux tarball as CI artifacts without
creating a release. Trigger from Gitea UI → Actions → Run.
- Rename GITEA_TOKEN to DEPLOY_TOKEN in release workflow
- Extract shared version detection into build-common.sh
- Use importlib.metadata for runtime version instead of hardcoded string
- Use PEP 440 parsing (packaging lib) for update version comparison
- Add packaging>=23.0 to dependencies
- Fix update banner close button alignment (CSS)
- Update CLAUDE.md with versioning docs and frontend rebuild notes
- Abstract ReleaseProvider protocol for platform-agnostic version checking
- GiteaReleaseProvider implementation using stdlib urllib
- UpdateChecker service with periodic background checks and WS broadcast
- Persistent dismissible banner in Web UI when a new version is detected
- Health endpoint now returns cached update info
- Configurable via update_check_enabled and update_check_interval settings
- i18n support (EN/RU)
The previous os.execv approach and console_script detection both
failed on Windows. Now restart always spawns `python -m media_server.main`
via subprocess.Popen with start_new_session, which works regardless
of how the server was originally started.
- Rewrite tray to run on main thread (pystray owns message loop, uvicorn
in background thread) — fixes unresponsive confirmation dialogs
- Use native Windows MessageBoxW instead of tkinter (embedded Python
has no tkinter)
- Pin numpy <2.0 to fix soundcard's numpy.fromstring (removed in 2.0)
- Strip transitive numpy 2.x wheels in build script
- Installer copies config.example.yaml as config.yaml on fresh install
- Suppress noisy screen_brightness_control warnings
- Use custom icon.ico for installer/uninstaller UI
- LaunchApp opens server then browser after install
- .onInit detects running instance and offers to stop it
- Use WMIC-based process kill targeting embedded Python path
- start-hidden.vbs prefers embedded Python over system Python
- Add pystray dependency to build script
- CLAUDE.md: note to consult CI/CD guide for build changes
Adds pystray-based tray icon (green play button) that runs alongside
uvicorn. Double-click opens the web UI in the browser, Exit triggers
graceful shutdown. Disabled with --no-tray flag for headless/service mode.
When no api_tokens are configured (the new default), all endpoints
are accessible without authentication. The frontend detects this
via /api/health's auth_required field and skips the login form.
- Backend: auth.py skips verification when api_tokens is empty
- Frontend: shared getAuthHeaders()/hasCredentials() helpers replace
scattered token logic across all JS modules
- Health endpoint exposes auth_required for frontend discovery
- config.example.yaml ships with tokens commented out
- CLI --show-token and startup log reflect disabled state
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
If the Gitea release already exists for a tag (e.g. from a retried
workflow), fall back to fetching the existing release ID instead of
failing with KeyError.
- Add build-dist-linux.sh: venv-based tarball with systemd installer
- Add build-linux job to release.yml (parallel with build-windows)
- Include Linux download in release body
- Allow pytest to pass when no tests are collected (exit code 5)
- WebGL shader background with flowing waves, radial pulse, and frequency ring arcs
- Reacts to captured audio data (frequency bands + bass) when visualizer is active
- Uses page accent color; adapts to dark/light theme via bg-primary blending
- Toggle button in header toolbar, state persisted in localStorage
- Cached uniform locations and color values to avoid per-frame getComputedStyle calls
- i18n support for EN/RU locales
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The POST /visualizer/device response has 'success' but no 'available'
field, causing updateAudioDeviceStatus to always fall to 'Unavailable'.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Service worker, manifest, and SVG icon for PWA installability
- Root /sw.js route for full-scope service worker registration
- Meta tags: theme-color, apple-mobile-web-app, viewport-fit=cover
- Safe area insets for notched phones (container, mini-player, footer, banner)
- Dynamic theme-color sync on light/dark toggle
- Overscroll prevention and touch-action optimization
- Hide mini-player prev/next buttons on small screens
- Updated README with PWA and new feature documentation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Visualizer: FPS 25→30, chunk_size 2048→1024, smoothing 0.65→0.15
- Beat effect: scale 0.03→0.04, glow range 0.5-0.8→0.4-0.8
- UI: reduce container/section paddings from 2rem to 1rem
- Source name: add ellipsis overflow for long names
- Mobile browser toolbar: use flex-wrap instead of column stack,
hide "Items per page" label text on small screens
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Audio capture starts only when first client subscribes,
stops when last client unsubscribes (saves CPU/battery)
- Add lifecycle lock to AudioAnalyzer for thread-safe start/stop
- Status badge uses local visualizer state instead of server flag
- Fix script name vertical text break on narrow screens
- Fix script grid minimum column width on small viewports
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix CORS: set allow_credentials=False (token auth, not cookies)
- Add threading.Lock for position cache thread safety
- Add shutdown_executor() for clean ThreadPoolExecutor cleanup
- Dedicated ThreadPoolExecutors for script/callback execution
- Fix Mutagen file handle leaks with try/finally close
- Reduce idle WebSocket polling (0.5s → 2.0s when no clients)
- Add :focus-visible styles for playback control buttons
- Add aria-label to icon-only header buttons
- Dynamic album art alt text for screen readers
- Persist MDI icon cache to localStorage
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Registry of 17 popular media apps (browsers, players, streaming)
- Substring matching resolves raw process names to friendly names
- Brand-colored SVG icons displayed inline next to source name
- Russian locale support for Yandex Music (Яндекс Музыка)
- Unknown sources fall back to .exe-stripped name
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Unified header-toolbar container with border and rounded corners
- Consistent header-btn styling for all action buttons
- Compact locale select, separator before logout icon
- Header links integrate as part of the toolbar with divider
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Native select with explicit font stack and focus glow
- Hide mini player volume section below 900px
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Subtle oscillating Y/X rotation with perspective for depth
- Enhanced vinyl mode filter: more desaturation + sepia warmth
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Save vinyl rotation angle before flipping vinylMode flag off
- Wrap vinyl + visualizer buttons in .player-toggles container
- Move margin-left:auto from individual buttons to group
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New audio_analyzer service: loopback capture via soundcard + numpy FFT
- Real-time spectrogram bars below album art with accent color gradient
- Album art and vinyl pulse to bass energy beats
- WebSocket subscriber pattern for opt-in audio data streaming
- Audio device selection in Settings tab with auto-detect fallback
- Optimized FFT pipeline: vectorized cumsum bin grouping, pre-serialized JSON broadcast
- Visualizer config: enabled/fps/bins/device in config.yaml
- Optional deps: soundcard + numpy (graceful degradation if missing)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Save current rotation angle to localStorage every 2s and on page unload
- Restore angle on page load via CSS custom property --vinyl-offset
- Extract angle from computed transform matrix
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Detect primary monitor via Windows EnumDisplayMonitors API and show badge
- Expand accent color picker with 9 presets and custom color input
- Auto-generate hover color for custom accent colors
- Re-render accent swatches on locale change for proper i18n
- Replace restart-server.bat with PowerShell restart-server.ps1
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>