- Add get-geo-stats-by-city function for city-level queries
- Add /api/asteroid/stats/geo/cities endpoint
- Add expandable country rows in admin geo stats table
- Click country to expand/collapse city breakdown
- Detect when browser pauses muted stream (throttling)
- Auto-reconnect after 3 seconds when paused while muted
- Apply to all three players for consistency
- Implement isReconnecting flag to prevent duplicate reconnect attempts
- Add exponential backoff for error retries (3s, 6s, 12s, max 30s)
- Retry indefinitely until stream returns
- Handle error, stalled, and ended events consistently
- Reset state on successful playback
- Apply same logic to frame player, popout player, and front-page player
- Add Liquidsoap control panel: status display, skip track, reload playlist, restart container
- Add Icecast restart button to System Status section
- Remove redundant Web Player Control section from admin
- Fix music library scan to follow symlinks (truename resolution)
- Fix database timestamp error (let PostgreSQL default handle added-date)
- Update docker-compose mount for stream-queue.m3u
- Clean up playlist path handling
- Add geo IP lookup for listener locations (ip-api.com)
- Add geo stats table with country flags to admin dashboard
- Fix listener stats table alignment with proper centering
- Fix Now Playing display to update without requiring audio playback
- Add caching for geo lookups to reduce API calls
- Add database schema for listener snapshots, sessions, and aggregates
- Implement background polling of Icecast admin XML stats
- Add API endpoints for current, daily, and geo stats
- Add listener stats section to admin dashboard with auto-refresh
- GDPR compliant: IP hashing, data retention cleanup
- Add reconnect button (🔄) to frameset player bar
- Recreate audio element on reconnect to fix wedged MediaElementSource
- Properly close and reinitialize AudioContext for spectrum analyzer
- Preserve volume and muted state when reconnecting
- Show status messages for connection issues
- Reduce Now Playing update interval to 5 seconds
- Add front-page.js to player-content.ctml for Now Playing updates
- Create About pages (about.ctml and about-content.ctml)
- Add About link to navigation in both modes
- Add monotone theme with deep blue to cobalt gradient
- Update canvas border color dynamically to match selected theme
- Set initial border color on page load based on saved preference
Major Changes:
- Convert all JavaScript files to Parenscript for better maintainability
- Move spectrum-analyzer to parenscript/ directory structure
- Add parenscript-utils.lisp for shared utilities
- Convert admin.js, player.js, front-page.js, auth-ui.js to Parenscript
- Convert profile.js, users.js, recently-played.js to Parenscript
Stream Reconnect Fixes (from merged PR):
- Add reset-spectrum-analyzer function to properly clean up Web Audio API
- Implement reconnect logic for pauses longer than 10 seconds
- Detect stale audio in 'playing' event and force stream reconnection
- Prevent 'Now Playing' updates while stream is paused
- Reduce reconnect delay to 200ms for faster response
- Add proper spectrum analyzer reset/reinit during reconnection
UX Improvements:
- Change live indicator from blink to smooth pulse (2s ease-in-out)
- Pulse animation like old PowerBook/MacBook sleep indicator
- Add MUTED indicator to spectrum analyzer when audio is muted
- Spectrum continues to flow even when muted (data still streaming)
- Red 'MUTED' text displayed in top-right corner of canvas
Technical Details:
- Parenscript files generate JavaScript via API endpoints
- All player modes updated: main player, front page, popout, frame player
- Improved audio context handling to only create once per element
- Added comprehensive error handling and logging
- Updated asteroid.asd to include parenscript module structure
Documentation:
- Updated all documentation dates to 2025-12-06
- Added PARENSCRIPT-EXPERIMENT.org documenting the conversion
- Updated PROJECT-HISTORY.org with Phase 9 (Visual Audio Features)
- Added comprehensive project statistics (408 commits, 9,300 LOC)
This conversion improves code maintainability by using Lisp throughout
the stack and makes it easier to share code between frontend and backend.
Optimized the timeout after stream reconnection to make the pause/unpause
experience more responsive. The 200ms delay is sufficient for the browser
to clear buffers and start the fresh stream while minimizing perceived lag.
- Detect pauses longer than 10 seconds across all player modes
- Intercept 'playing' event to stop stale buffered audio
- Force stream reconnect to get live audio after long pause
- Reset and reinitialize spectrum analyzer during reconnect
- Prevent 'Now Playing' updates while stream is paused
- Move spectrum-analyzer.lisp to parenscript/ directory
- Update all documentation dates to 2025-12-06
- Add comprehensive project statistics (408 commits, 9,300 LOC)
- Add Phase 9 (Visual Audio Features) to project history
Fixes issue where resuming playback after a long pause would play
old buffered audio instead of the current live stream. The fix uses
the 'playing' event to detect when stale audio starts and immediately
stops it, then reconnects to get fresh stream data.
All player modes updated: main player, front page, popout, and frame player.
- Reduced Icecast burst-size from 64KB to 8KB to minimize buffer accumulation
- Fixed spectrum analyzer to only create MediaElementSource once
- Added resetSpectrumAnalyzer() function to allow reconnection
- Prevent now-playing info updates when stream is paused across all players:
* Player page
* Front page
* Pop-out player
* Frame player
* Admin page
- After pause >10s, reconnect stream and reinitialize spectrum analyzer
- Preserves spectrum analyzer functionality after pause/unpause
- Eliminates stuttering and buffer accumulation issues
- Implement Web Audio API-based spectrum analyzer with green gradient bars
- Add spectrum analyzer to front page and persistent player content frames
- Support cross-frame audio element access for frameset mode
- Add CORS headers to Icecast configuration for Web Audio API
- Serve Parenscript-generated JavaScript dynamically via API endpoint
- Canvas visualization appears below page title, above navigation
Changed from static file generation to Radiance API endpoint.
Parenscript now generates JavaScript in-memory at runtime when
the /api/asteroid/spectrum-analyzer.js endpoint is requested.
This is the correct approach for Parenscript integration with Radiance.
Implements real-time audio visualization for the main page:
- Added Parenscript dependency to asteroid.asd
- Created spectrum-analyzer.lisp with Parenscript code
- Added canvas element to front-page.ctml above nav buttons
- Auto-generates JavaScript at compile time
- Green gradient bars matching Asteroid aesthetic
- Uses Web Audio API for FFT analysis
This is the first Parenscript component in Asteroid Radio,
demonstrating the approach for future JavaScript conversions.
- Add favicon.ico, favicon-16x16.png, and favicon-32x32.png
- Add asteroid.png graphic to header on both front-page.ctml and front-page-content.ctml
- Update header styling to display asteroid graphics flanking the station name
- Display last 3 played tracks on front page
- Auto-updates every 30 seconds
- Shows track title, artist, and time ago
- Links to MusicBrainz search for each track
- Thread-safe in-memory storage
- Works in both normal and frameset modes
- Hacker-themed green styling
Implements feature request from fade to show recently played tracks
with linkage to track info at music database.
- Add user password change functionality in profile page
- Add admin password reset functionality in admin dashboard
- Fix listener count to show total from Icecast root tag
- Replace concatenate with format
- Add with-error-handling to API endpoints
- Make Icecast port binding configurable via ICECAST_BIND env var
- Add comprehensive docstrings to public functions
Note: Password reset has known issue with LambdaLite db:update
not updating password-hash field. Issue reported as an issue.
Removed the display of default admin username and password from the
login page template. This information should not be publicly visible
as it poses a security risk in production environments.
Administrators should use secure credential management practices
and change default passwords during initial setup.
- Changed font-family from 'Courier New' to 'VT323' in body style
- Updated quality selector dropdown font to VT323
- Updated disable button inline style to use VT323
- Ensures consistent typography across the entire site
- Popout player already inherits VT323 from main stylesheet
- Add frameset mode with persistent audio player in bottom frame
- Add localStorage preference system for user choice
- Update all page navigation to work in both regular and frameset modes
- Add enable/disable buttons for frameset mode
- Fix redirect loops and template parameter issues
- Add pop-out player window (400x300px) with auto-reconnect on stream errors
- Add queue reordering with up/down buttons in admin panel
- Add 'Load Queue from M3U' functionality
- Remove Play/Stream buttons from track management
- Fix Liquidsoap audio quality issues:
- Remove ReplayGain and compression to prevent pulsing
- Change reload_mode to 'seconds' to prevent playlist exhaustion
- Reduce crossfade to 3 seconds
- Add audio buffering settings for stability
- Add auto-reconnect logic for both front page and pop-out players
- Queue management section with add/remove/clear controls
- Add to Queue button on each track in library browser
- Search tracks and add to queue
- Add 10 random tracks button
- Live stream monitor with Now Playing display
- Toast notifications for user feedback
- Real-time queue updates
- Increased auth-form max-width from 400px to 600px to match site styling
- Reduced form-group margin-bottom from 3rem to 1.5rem for better spacing
- Added display:none to error/success message boxes by default
- Message boxes now only show when server sets display-error/display-success
- Add registration page with form validation
- Add login/register/logout navigation with conditional display
- Add auth-status API endpoint for session checking
- Add auth-ui.js for dynamic nav based on login state
- Update navigation across all pages (front, admin, profile, player)
- Style logout button with subtle red color
- Auto-login after successful registration
- Created profile.chtml template with listening statistics, recent tracks, and top artists
- Added profile.js for dynamic data loading and user interactions
- Extended LASS styles for profile-specific elements (artist stats, track items, activity charts)
- Implemented /profile route with authentication and template rendering
- Added profile API endpoints for user data, stats, recent tracks, and top artists
- Added profile link to main navigation
- Includes placeholder functionality for future listening metrics implementation