asteroid/issue-57-resolution.md

149 lines
5.7 KiB
Markdown

# Resolution for Issue #57: Persistent Stream Playback Halts on Login Page Navigation
## Summary
This issue has been resolved. The persistent audio stream now continues playing uninterrupted when navigating to the login page and throughout the authentication flow in frameset mode.
## Original Problem
When using the frameset mode with the persistent audio player, navigating to the login page would halt the audio stream. This occurred because:
1. The login page was not frameset-aware (no `-content` version existed)
2. Navigation to `/login` would load the full page, replacing the frameset
3. This destroyed the persistent player frame, stopping the audio
## Solution Implemented
### 1. Created Frameset-Aware Login Page
Created `template/login-content.ctml` to be loaded within the content frame while preserving the persistent player frame.
### 2. Implemented AJAX Navigation
Modified all navigation links in frameset-aware pages to use AJAX loading via the `loadInFrame()` function:
```javascript
function loadInFrame(link) {
const url = link.href;
// Clear all intervals to prevent old page scripts from running
const highestId = window.setTimeout(() => {}, 0);
for (let i = 0; i < highestId; i++) {
window.clearInterval(i);
window.clearTimeout(i);
}
fetch(url)
.then(response => response.text())
.then(html => {
document.open();
document.write(html);
document.close();
// Execute scripts in the new content
const scripts = document.querySelectorAll('script');
scripts.forEach(oldScript => {
const newScript = document.createElement('script');
if (oldScript.src) {
newScript.src = oldScript.src;
} else {
newScript.textContent = oldScript.textContent;
}
oldScript.parentNode.replaceChild(newScript, oldScript);
});
// Re-initialize spectrum analyzer after navigation
if (window.initializeSpectrumAnalyzer) {
setTimeout(() => window.initializeSpectrumAnalyzer(), 100);
}
if (window.history && window.history.pushState) {
window.history.pushState({}, '', url);
}
});
return false;
}
```
### 3. Implemented AJAX Logout
Created `handleLogout()` function to perform logout without navigation:
```javascript
function handleLogout() {
fetch('/asteroid/logout', {
method: 'GET',
redirect: 'manual'
})
.then(() => {
// Reload the current page content to show logged-out state
fetch(window.location.href)
.then(response => response.text())
.then(html => {
document.open();
document.write(html);
document.close();
});
});
}
```
### 4. Updated Server-Side Logout Handler
Modified the logout route to detect frameset mode and redirect appropriately:
```lisp
(define-page logout #@"/logout" ()
"Handle user logout"
(setf (session:field "user-id") nil)
;; Check if we're in a frameset by looking at the Referer header
(let* ((referer (radiance:header "Referer"))
(in-frameset (and referer
(or (search "/frameset" referer)
(search "/content" referer)
(search "-content" referer)))))
(radiance:redirect (if in-frameset "/content" "/"))))
```
### 5. Created Additional Frameset-Aware Pages
- `template/admin-content.ctml` - Admin page for frameset mode
- `template/profile-content.ctml` - Profile page for frameset mode
- `template/status-content.ctml` - Status page placeholder for frameset mode
### 6. Added Route Handlers
Added corresponding route handlers in `asteroid.lisp`:
```lisp
(define-page login-content #@"/login-content" ()
"Login page content (displayed in content frame)"
(clip:process-to-string
(load-template "login-content")
:title "🔐 Asteroid Radio - Login"))
(define-page status-content #@"/status-content" ()
"Status page content (displayed in content frame)"
(clip:process-to-string
(load-template "status-content")
:title "📡 Asteroid Radio - Status"))
```
## Files Modified
- `auth-routes.lisp` - Updated logout handler to detect frameset mode
- `asteroid.lisp` - Added routes for login-content and status-content
- `template/login-content.ctml` - Created frameset-aware login page
- `template/admin-content.ctml` - Added AJAX navigation and logout handlers
- `template/profile-content.ctml` - Added AJAX navigation and logout handlers
- `template/front-page-content.ctml` - Added AJAX navigation and logout handlers
- `template/player-content.ctml` - Added AJAX navigation and logout handlers
- `template/status-content.ctml` - Created placeholder status page
## Testing Results
✅ Stream continues playing when clicking Login link
✅ Stream continues playing during login form submission
✅ Stream continues playing after successful login
✅ Stream continues playing when clicking Logout
✅ Stream continues playing when navigating between all pages (Home, Player, Status, Profile, Admin)
✅ Login form works correctly with AJAX submission
✅ Logout updates UI to show logged-out state
✅ All navigation links maintain persistent audio
## Additional Improvements
While fixing this issue, we also resolved:
1. **Now Playing panel not updating** - Scripts now execute after AJAX navigation
2. **MUTED indicator not appearing** - Spectrum analyzer properly re-initializes after navigation
3. **Console errors from abandoned intervals** - All intervals/timeouts are cleared before navigation
4. **Faster Now Playing updates** - Reduced initial update delay from 1s to 200ms
## Conclusion
The persistent player with frameset mode is now fully functional. Users can navigate throughout the entire application, including login/logout flows, without any interruption to the audio stream.