Add About and Status pages with improved navigation
- Added About page with detailed technical stack, AGPL license info, and community links - Added Status page for both frameset and non-frameset modes - Fixed all navigation links to use /asteroid/frameset as home (workaround for Radiance routing) - Removed broken AJAX loadInFrame() navigation in frameset content pages - Fixed logout buttons to redirect properly after logout - Added spectrum analyzer support for live-stream-audio element ID - Updated all Home links across the site to avoid Radiance welcome page - Made About and Status pages consistent between frameset and non-frameset modes - Added proper navigation to all pages with About, Status, and other links
This commit is contained in:
parent
d39b155df3
commit
3aa21c8278
|
|
@ -625,12 +625,33 @@
|
|||
(format t "ERROR in profile-content: ~a~%" e)
|
||||
(format nil "<html><body><h1>Error loading profile</h1><pre>~a</pre></body></html>" e))))
|
||||
|
||||
;; Status page (non-frameset mode)
|
||||
(define-page status-page #@"/status" ()
|
||||
"Status page"
|
||||
(clip:process-to-string
|
||||
(load-template "status")
|
||||
:title " Asteroid Radio - Status"))
|
||||
|
||||
;; Status content frame (for frameset mode)
|
||||
(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"))
|
||||
:title " Asteroid Radio - Status"))
|
||||
|
||||
;; About page
|
||||
(define-page about-page #@"/about" ()
|
||||
"About Asteroid Radio"
|
||||
(clip:process-to-string
|
||||
(load-template "about")
|
||||
:title "About - Asteroid Radio"))
|
||||
|
||||
;; About content (for frameset mode)
|
||||
(define-page about-content #@"/about-content" ()
|
||||
"About content (displayed in content frame)"
|
||||
(clip:process-to-string
|
||||
(load-template "about-content")
|
||||
:title "About - Asteroid Radio"))
|
||||
|
||||
;; Configure static file serving for other files
|
||||
;; BUT exclude ParenScript-compiled JS files
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@
|
|||
|
||||
;; Try current document first
|
||||
(setf audio-element (or (ps:chain document (get-element-by-id "live-audio"))
|
||||
(ps:chain document (get-element-by-id "persistent-audio"))))
|
||||
(ps:chain document (get-element-by-id "persistent-audio"))
|
||||
(ps:chain document (get-element-by-id "live-stream-audio"))))
|
||||
|
||||
;; If not found and we're in a frame, try parent frame (frameset mode)
|
||||
(when (and (not audio-element)
|
||||
|
|
@ -253,7 +254,8 @@
|
|||
|
||||
;; Try current document first
|
||||
(setf audio-element (or (ps:chain document (get-element-by-id "live-audio"))
|
||||
(ps:chain document (get-element-by-id "persistent-audio"))))
|
||||
(ps:chain document (get-element-by-id "persistent-audio"))
|
||||
(ps:chain document (get-element-by-id "live-stream-audio"))))
|
||||
|
||||
;; If not found and we're in a frame, try parent frame (frameset mode)
|
||||
(when (and (not audio-element)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,107 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>About - Asteroid Radio</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="/asteroid/static/favicon.ico">
|
||||
<link rel="stylesheet" type="text/css" href="/asteroid/static/asteroid.css">
|
||||
<script src="/asteroid/static/js/auth-ui.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1 style="display: flex; align-items: center; justify-content: center; gap: 15px;">
|
||||
<img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 50px; width: auto;">
|
||||
<span>ABOUT ASTEROID RADIO</span>
|
||||
<img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 50px; width: auto;">
|
||||
</h1>
|
||||
<nav class="nav">
|
||||
<a href="/asteroid/content" target="_self">Home</a>
|
||||
<a href="/asteroid/player-content" target="_self">Player</a>
|
||||
<a href="/asteroid/about-content" target="_self">About</a>
|
||||
<a href="/asteroid/status-content" target="_self">Status</a>
|
||||
<a href="/asteroid/profile-content" target="_self" data-show-if-logged-in>Profile</a>
|
||||
<a href="/asteroid/admin-content" target="_self" data-show-if-admin>Admin</a>
|
||||
<a href="/asteroid/login-content" target="_self" data-show-if-logged-out>Login</a>
|
||||
<a href="/asteroid/register-content" target="_self" data-show-if-logged-out>Register</a>
|
||||
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout" onclick="event.preventDefault(); fetch('/asteroid/logout').then(() => window.location.reload());">Logout</a>
|
||||
</nav>
|
||||
</header>
|
||||
<main style="max-width: 800px; margin: 0 auto; padding: 20px;">
|
||||
<section style="margin-bottom: 30px;">
|
||||
<h2 style="color: #00ff00; border-bottom: 2px solid #00ff00; padding-bottom: 10px;">🎵 Asteroid Music for Hackers</h2>
|
||||
<p style="line-height: 1.6;">
|
||||
Asteroid Radio is a community-driven internet radio station born from the SystemCrafters community.
|
||||
We celebrate the intersection of music, technology, and hacker culture—broadcasting for those who
|
||||
appreciate both great code and great music.
|
||||
</p>
|
||||
<p style="line-height: 1.6;">
|
||||
We met through a shared set of technical biases and a love for building systems from first principles.
|
||||
Asteroid Radio embodies that ethos: <strong>music for hackers, built by hackers</strong>.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section style="margin-bottom: 30px;">
|
||||
<h2 style="color: #00ff00; border-bottom: 2px solid #00ff00; padding-bottom: 10px;">🛠️ Built with Common Lisp</h2>
|
||||
<p style="line-height: 1.6;">
|
||||
This entire platform is built using <strong>Common Lisp</strong>, demonstrating the power and elegance
|
||||
of Lisp for modern web applications. We use:
|
||||
</p>
|
||||
<ul style="line-height: 1.8; margin-left: 20px;">
|
||||
<li><strong><a href="https://codeberg.org/shirakumo/radiance" style="color: #00ff00;">Radiance</a></strong> - Web application framework</li>
|
||||
<li><strong><a href="https://codeberg.org/shinmera/clip" style="color: #00ff00;">Clip</a></strong> - HTML5-compliant template engine</li>
|
||||
<li><strong><a href="https://codeberg.org/shinmera/LASS" style="color: #00ff00;">LASS</a></strong> - Lisp Augmented Style Sheets</li>
|
||||
<li><strong><a href="https://gitlab.common-lisp.net/parenscript/parenscript" style="color: #00ff00;">ParenScript</a></strong> - Lisp-to-JavaScript compiler</li>
|
||||
<li><strong><a href="https://icecast.org/" style="color: #00ff00;">Icecast</a></strong> - Streaming media server</li>
|
||||
<li><strong><a href="https://www.liquidsoap.info/" style="color: #00ff00;">Liquidsoap</a></strong> - Audio stream generation</li>
|
||||
</ul>
|
||||
<p style="line-height: 1.6;">
|
||||
By building in Common Lisp, we're doubling down on our technical values and creating features
|
||||
for "our people"—those who appreciate the elegance of Lisp and the power of understanding your tools deeply.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section style="margin-bottom: 30px;">
|
||||
<h2 style="color: #00ff00; border-bottom: 2px solid #00ff00; padding-bottom: 10px;">📖 Open Source & AGPL Licensed</h2>
|
||||
<p style="line-height: 1.6;">
|
||||
Asteroid Radio is <strong>free and open source software</strong>, licensed under the
|
||||
<strong><a href="https://www.gnu.org/licenses/agpl-3.0.en.html" style="color: #00ff00;">GNU Affero General Public License v3.0 (AGPL)</a></strong>.
|
||||
</p>
|
||||
<p style="line-height: 1.6;">
|
||||
The source code is available at:
|
||||
<a href="https://github.com/Fade/asteroid" style="color: #00ff00; font-weight: bold;">https://github.com/Fade/asteroid</a>
|
||||
</p>
|
||||
<p style="line-height: 1.6;">
|
||||
We believe in transparency, collaboration, and the freedom to study, modify, and share the software we use.
|
||||
The AGPL ensures that improvements to Asteroid Radio remain free and available to everyone.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section style="margin-bottom: 30px;">
|
||||
<h2 style="color: #00ff00; border-bottom: 2px solid #00ff00; padding-bottom: 10px;">🎧 Features</h2>
|
||||
<ul style="line-height: 1.8; margin-left: 20px;">
|
||||
<li><strong>Live Streaming</strong> - Multiple quality options (AAC, MP3)</li>
|
||||
<li><strong>Persistent Player</strong> - Frameset mode for uninterrupted playback while browsing</li>
|
||||
<li><strong>Spectrum Analyzer</strong> - Real-time audio visualization with customizable themes</li>
|
||||
<li><strong>Track Library</strong> - Browse and search the music collection</li>
|
||||
<li><strong>User Profiles</strong> - Track your listening history</li>
|
||||
<li><strong>Admin Tools</strong> - Manage tracks, users, and playlists</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section style="margin-bottom: 30px;">
|
||||
<h2 style="color: #00ff00; border-bottom: 2px solid #00ff00; padding-bottom: 10px;">🤝 Community</h2>
|
||||
<p style="line-height: 1.6;">
|
||||
We're part of the <strong><a href="https://systemcrafters.net/" style="color: #00ff00;">SystemCrafters</a></strong>
|
||||
community—a group of developers, hackers, and enthusiasts who believe in building systems from first principles,
|
||||
understanding our tools deeply, and sharing knowledge freely.
|
||||
</p>
|
||||
<p style="line-height: 1.6;">
|
||||
Join us in celebrating the intersection of great music and great code!
|
||||
</p>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>About - Asteroid Radio</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="/asteroid/static/favicon.ico">
|
||||
<link rel="stylesheet" type="text/css" href="/asteroid/static/asteroid.css">
|
||||
<script src="/asteroid/static/js/auth-ui.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1 style="display: flex; align-items: center; justify-content: center; gap: 15px;">
|
||||
<img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 50px; width: auto;">
|
||||
<span>ABOUT ASTEROID RADIO</span>
|
||||
<img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 50px; width: auto;">
|
||||
</h1>
|
||||
<nav class="nav">
|
||||
<a href="/asteroid/frameset">Home</a>
|
||||
<a href="/asteroid/player">Player</a>
|
||||
<a href="/asteroid/about">About</a>
|
||||
<a href="/asteroid/status">Status</a>
|
||||
</nav>
|
||||
</header>
|
||||
<main style="max-width: 800px; margin: 0 auto; padding: 20px;">
|
||||
<section style="margin-bottom: 30px;">
|
||||
<h2 style="color: #00ff00; border-bottom: 2px solid #00ff00; padding-bottom: 10px;">🎵 Asteroid Music for Hackers</h2>
|
||||
<p style="line-height: 1.6;">
|
||||
Asteroid Radio is a community-driven internet radio station born from the SystemCrafters community.
|
||||
We celebrate the intersection of music, technology, and hacker culture—broadcasting for those who
|
||||
appreciate both great code and great music.
|
||||
</p>
|
||||
<p style="line-height: 1.6;">
|
||||
We met through a shared set of technical biases and a love for building systems from first principles.
|
||||
Asteroid Radio embodies that ethos: <strong>music for hackers, built by hackers</strong>.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section style="margin-bottom: 30px;">
|
||||
<h2 style="color: #00ff00; border-bottom: 2px solid #00ff00; padding-bottom: 10px;">🛠️ Built with Common Lisp</h2>
|
||||
<p style="line-height: 1.6;">
|
||||
This entire platform is built using <strong>Common Lisp</strong>, demonstrating the power and elegance
|
||||
of Lisp for modern web applications. We use:
|
||||
</p>
|
||||
<ul style="line-height: 1.8; margin-left: 20px;">
|
||||
<li><strong><a href="https://codeberg.org/shirakumo/radiance" style="color: #00ff00;">Radiance</a></strong> - Web application framework</li>
|
||||
<li><strong><a href="https://codeberg.org/shinmera/clip" style="color: #00ff00;">Clip</a></strong> - HTML5-compliant template engine</li>
|
||||
<li><strong><a href="https://codeberg.org/shinmera/LASS" style="color: #00ff00;">LASS</a></strong> - Lisp Augmented Style Sheets</li>
|
||||
<li><strong><a href="https://gitlab.common-lisp.net/parenscript/parenscript" style="color: #00ff00;">ParenScript</a></strong> - Lisp-to-JavaScript compiler</li>
|
||||
<li><strong><a href="https://icecast.org/" style="color: #00ff00;">Icecast</a></strong> - Streaming media server</li>
|
||||
<li><strong><a href="https://www.liquidsoap.info/" style="color: #00ff00;">Liquidsoap</a></strong> - Audio stream generation</li>
|
||||
</ul>
|
||||
<p style="line-height: 1.6;">
|
||||
By building in Common Lisp, we're doubling down on our technical values and creating features
|
||||
for "our people"—those who appreciate the elegance of Lisp and the power of understanding your tools deeply.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section style="margin-bottom: 30px;">
|
||||
<h2 style="color: #00ff00; border-bottom: 2px solid #00ff00; padding-bottom: 10px;">📖 Open Source & AGPL Licensed</h2>
|
||||
<p style="line-height: 1.6;">
|
||||
Asteroid Radio is <strong>free and open source software</strong>, licensed under the
|
||||
<strong><a href="https://www.gnu.org/licenses/agpl-3.0.en.html" style="color: #00ff00;">GNU Affero General Public License v3.0 (AGPL)</a></strong>.
|
||||
</p>
|
||||
<p style="line-height: 1.6;">
|
||||
The source code is available at:
|
||||
<a href="https://github.com/Fade/asteroid" style="color: #00ff00; font-weight: bold;">https://github.com/Fade/asteroid</a>
|
||||
</p>
|
||||
<p style="line-height: 1.6;">
|
||||
We believe in transparency, collaboration, and the freedom to study, modify, and share the software we use.
|
||||
The AGPL ensures that improvements to Asteroid Radio remain free and available to everyone.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section style="margin-bottom: 30px;">
|
||||
<h2 style="color: #00ff00; border-bottom: 2px solid #00ff00; padding-bottom: 10px;">🎧 Features</h2>
|
||||
<ul style="line-height: 1.8; margin-left: 20px;">
|
||||
<li><strong>Live Streaming</strong> - Multiple quality options (AAC, MP3)</li>
|
||||
<li><strong>Persistent Player</strong> - Frameset mode for uninterrupted playback while browsing</li>
|
||||
<li><strong>Spectrum Analyzer</strong> - Real-time audio visualization with customizable themes</li>
|
||||
<li><strong>Track Library</strong> - Browse and search the music collection</li>
|
||||
<li><strong>User Profiles</strong> - Track your listening history</li>
|
||||
<li><strong>Admin Tools</strong> - Manage tracks, users, and playlists</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section style="margin-bottom: 30px;">
|
||||
<h2 style="color: #00ff00; border-bottom: 2px solid #00ff00; padding-bottom: 10px;">🤝 Community</h2>
|
||||
<p style="line-height: 1.6;">
|
||||
We're part of the <strong><a href="https://systemcrafters.net/" style="color: #00ff00;">SystemCrafters</a></strong>
|
||||
community—a group of developers, hackers, and enthusiasts who believe in building systems from first principles,
|
||||
understanding our tools deeply, and sharing knowledge freely.
|
||||
</p>
|
||||
<p style="line-height: 1.6;">
|
||||
Join us in celebrating the intersection of great music and great code!
|
||||
</p>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -12,11 +12,12 @@
|
|||
<div class="container">
|
||||
<h1>🎛️ ADMIN DASHBOARD</h1>
|
||||
<div class="nav">
|
||||
<a href="/asteroid">Home</a>
|
||||
<a href="/asteroid/frameset">Home</a>
|
||||
<a href="/asteroid/player">Player</a>
|
||||
<a href="/asteroid/about">About</a>
|
||||
<a href="/asteroid/profile">Profile</a>
|
||||
<a href="/asteroid/admin/users">👥 Users</a>
|
||||
<a href="/asteroid/logout" class="btn-logout">Logout</a>
|
||||
<a href="/asteroid/logout" class="btn-logout" onclick="event.preventDefault(); fetch('/asteroid/logout').then(() => window.location.href='/asteroid/frameset');">Logout</a>
|
||||
</div>
|
||||
|
||||
<!-- System Status -->
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" type="text/css" href="/asteroid/static/asteroid.css">
|
||||
<script src="/api/asteroid/spectrum-analyzer.js"></script>
|
||||
</head>
|
||||
<body class="persistent-player-container">
|
||||
<div class="persistent-player">
|
||||
|
|
@ -31,6 +32,25 @@
|
|||
<button onclick="disableFramesetMode()" class="persistent-disable-btn">
|
||||
✕ Disable
|
||||
</button>
|
||||
|
||||
<!-- Compact Spectrum Analyzer -->
|
||||
<div style="display: inline-block; margin-left: 15px;">
|
||||
<canvas id="spectrum-canvas" width="400" height="40" style="border: 1px solid #00ff00; background: #000; border-radius: 3px; vertical-align: middle;"></canvas>
|
||||
<select id="spectrum-style-selector" onchange="setSpectrumStyle(this.value)" style="margin-left: 5px; padding: 2px; background: #000; color: #00ff00; border: 1px solid #00ff00; font-size: 0.8em; vertical-align: middle;">
|
||||
<option value="bars">Bars</option>
|
||||
<option value="wave">Wave</option>
|
||||
<option value="dots">Dots</option>
|
||||
</select>
|
||||
<select id="spectrum-theme-selector" onchange="setSpectrumTheme(this.value)" style="margin-left: 3px; padding: 2px; background: #000; color: #00ff00; border: 1px solid #00ff00; font-size: 0.8em; vertical-align: middle;">
|
||||
<option value="monotone">Monotone</option>
|
||||
<option value="green">Green</option>
|
||||
<option value="blue">Blue</option>
|
||||
<option value="purple">Purple</option>
|
||||
<option value="red">Red</option>
|
||||
<option value="amber">Amber</option>
|
||||
<option value="rainbow">Rainbow</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
|
@ -186,8 +206,8 @@
|
|||
function disableFramesetMode() {
|
||||
// Clear preference
|
||||
localStorage.removeItem('useFrameset');
|
||||
// Redirect parent window to regular view
|
||||
window.parent.location.href = '/asteroid/';
|
||||
// Redirect parent window to player page (non-frameset)
|
||||
window.parent.location.href = '/asteroid/player';
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
<script src="/asteroid/static/js/auth-ui.js"></script>
|
||||
<script src="/asteroid/static/js/front-page.js"></script>
|
||||
<script src="/asteroid/static/js/recently-played.js"></script>
|
||||
<script src="/api/asteroid/spectrum-analyzer.js"></script>
|
||||
<script>
|
||||
// Handle logout without navigation
|
||||
function handleLogout() {
|
||||
|
|
@ -20,71 +19,15 @@
|
|||
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();
|
||||
});
|
||||
// Just reload the current page
|
||||
window.location.reload();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Logout failed:', error);
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
|
||||
// Load content via AJAX to prevent audio interruption
|
||||
function loadInFrame(link) {
|
||||
const url = link.href;
|
||||
console.log('Loading via AJAX:', url);
|
||||
|
||||
// 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 => {
|
||||
// Replace entire document content
|
||||
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);
|
||||
}
|
||||
|
||||
// Update browser history
|
||||
if (window.history && window.history.pushState) {
|
||||
window.history.pushState({}, '', url);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Failed to load content:', error);
|
||||
// Fallback to normal navigation
|
||||
return true;
|
||||
});
|
||||
|
||||
// Prevent default navigation
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -97,41 +40,15 @@
|
|||
</h1>
|
||||
<h3 class="page-subtitle">The Station at the End of Time</h3>
|
||||
|
||||
<!-- Spectrum Analyzer Canvas -->
|
||||
<div style="text-align: center; margin: 15px 0;">
|
||||
<canvas id="spectrum-canvas" width="800" height="100" style="max-width: 100%; border: 1px solid #00ff00; background: #000; border-radius: 4px;"></canvas>
|
||||
<div style="margin-top: 8px; font-size: 0.9em;">
|
||||
<label style="margin-right: 10px;">
|
||||
Style:
|
||||
<select id="spectrum-style-selector" onchange="setSpectrumStyle(this.value)" style="padding: 3px; background: #000; color: #00ff00; border: 1px solid #00ff00;">
|
||||
<option value="bars">Bars</option>
|
||||
<option value="wave">Wave</option>
|
||||
<option value="dots">Dots</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Theme:
|
||||
<select id="spectrum-theme-selector" onchange="setSpectrumTheme(this.value)" style="padding: 3px; background: #000; color: #00ff00; border: 1px solid #00ff00;">
|
||||
<option value="monotone">Monotone</option>
|
||||
<option value="green">Green</option>
|
||||
<option value="blue">Blue</option>
|
||||
<option value="purple">Purple</option>
|
||||
<option value="red">Red</option>
|
||||
<option value="amber">Amber</option>
|
||||
<option value="rainbow">Rainbow</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav">
|
||||
<a href="/asteroid/content" target="content-frame" onclick="return loadInFrame(this)">Home</a>
|
||||
<a href="/asteroid/player-content" target="content-frame" onclick="return loadInFrame(this)">Player</a>
|
||||
<a href="/asteroid/status-content" target="content-frame" onclick="return loadInFrame(this)">Status</a>
|
||||
<a href="/asteroid/profile-content" target="content-frame" data-show-if-logged-in onclick="return loadInFrame(this)">Profile</a>
|
||||
<a href="/asteroid/admin-content" target="content-frame" data-show-if-admin onclick="return loadInFrame(this)">Admin</a>
|
||||
<a href="/asteroid/login-content" target="content-frame" data-show-if-logged-out onclick="return loadInFrame(this)">Login</a>
|
||||
<a href="/asteroid/register-content" target="content-frame" data-show-if-logged-out onclick="return loadInFrame(this)">Register</a>
|
||||
<a href="/asteroid/content" target="_self">Home</a>
|
||||
<a href="/asteroid/player-content" target="_self">Player</a>
|
||||
<a href="/asteroid/about-content" target="_self">About</a>
|
||||
<a href="/asteroid/status-content" target="_self">Status</a>
|
||||
<a href="/asteroid/profile-content" target="_self" data-show-if-logged-in>Profile</a>
|
||||
<a href="/asteroid/admin-content" target="_self" data-show-if-admin>Admin</a>
|
||||
<a href="/asteroid/login-content" target="_self" data-show-if-logged-out>Login</a>
|
||||
<a href="/asteroid/register-content" target="_self" data-show-if-logged-out>Register</a>
|
||||
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout" onclick="handleLogout(); return false;">Logout</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
|
|
|||
|
|
@ -51,8 +51,9 @@
|
|||
</div>
|
||||
|
||||
<nav class="nav">
|
||||
<a href="/asteroid/">Home</a>
|
||||
<a href="/asteroid/frameset">Home</a>
|
||||
<a href="/asteroid/player">Player</a>
|
||||
<a href="/asteroid/about">About</a>
|
||||
<a href="/asteroid/status">Status</a>
|
||||
<a href="/asteroid/profile" data-show-if-logged-in>Profile</a>
|
||||
<a href="/asteroid/admin" data-show-if-admin>Admin</a>
|
||||
|
|
|
|||
|
|
@ -17,8 +17,9 @@
|
|||
<span>ASTEROID RADIO - LOGIN</span>
|
||||
</h1>
|
||||
<nav class="nav">
|
||||
<a href="/asteroid">Home</a>
|
||||
<a href="/asteroid/frameset">Home</a>
|
||||
<a href="/asteroid/player">Player</a>
|
||||
<a href="/asteroid/about">About</a>
|
||||
<a href="/asteroid/status">Status</a>
|
||||
<a href="/asteroid/register">Register</a>
|
||||
</nav>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" type="text/css" href="/asteroid/static/asteroid.css">
|
||||
<script src="/asteroid/static/js/auth-ui.js"></script>
|
||||
<script src="/api/asteroid/spectrum-analyzer.js"></script>
|
||||
<script>
|
||||
// Simple Now Playing updater
|
||||
function updateNowPlaying() {
|
||||
|
|
@ -116,40 +115,14 @@
|
|||
<img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 50px; width: auto;">
|
||||
</h1>
|
||||
|
||||
<!-- Spectrum Analyzer Canvas -->
|
||||
<div style="text-align: center; margin: 15px 0;">
|
||||
<canvas id="spectrum-canvas" width="800" height="100" style="max-width: 100%; border: 1px solid #00ff00; background: #000; border-radius: 4px;"></canvas>
|
||||
<div style="margin-top: 8px; font-size: 0.9em;">
|
||||
<label style="margin-right: 10px;">
|
||||
Style:
|
||||
<select id="spectrum-style-selector" onchange="setSpectrumStyle(this.value)" style="padding: 3px; background: #000; color: #00ff00; border: 1px solid #00ff00;">
|
||||
<option value="bars">Bars</option>
|
||||
<option value="wave">Wave</option>
|
||||
<option value="dots">Dots</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Theme:
|
||||
<select id="spectrum-theme-selector" onchange="setSpectrumTheme(this.value)" style="padding: 3px; background: #000; color: #00ff00; border: 1px solid #00ff00;">
|
||||
<option value="monotone">Monotone</option>
|
||||
<option value="green">Green</option>
|
||||
<option value="blue">Blue</option>
|
||||
<option value="purple">Purple</option>
|
||||
<option value="red">Red</option>
|
||||
<option value="amber">Amber</option>
|
||||
<option value="rainbow">Rainbow</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="nav">
|
||||
<nav class="nav">
|
||||
<a href="/asteroid/content" target="content-frame" onclick="return loadInFrame(this)">Home</a>
|
||||
<a href="/asteroid/profile-content" target="content-frame" data-show-if-logged-in onclick="return loadInFrame(this)">Profile</a>
|
||||
<a href="/asteroid/admin-content" target="content-frame" data-show-if-admin onclick="return loadInFrame(this)">Admin</a>
|
||||
<a href="/asteroid/login-content" target="content-frame" data-show-if-logged-out onclick="return loadInFrame(this)">Login</a>
|
||||
<a href="/asteroid/register-content" target="content-frame" data-show-if-logged-out onclick="return loadInFrame(this)">Register</a>
|
||||
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout" onclick="handleLogout(); return false;">Logout</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Live Stream Section - Note about persistent player -->
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@
|
|||
<link rel="icon" type="image/png" sizes="16x16" href="/asteroid/static/favicon-16x16.png">
|
||||
<link rel="stylesheet" type="text/css" href="/asteroid/static/asteroid.css">
|
||||
<script src="/asteroid/static/js/auth-ui.js"></script>
|
||||
<script src="/asteroid/static/js/front-page.js"></script>
|
||||
<script src="/asteroid/static/js/player.js"></script>
|
||||
<script src="/api/asteroid/spectrum-analyzer.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
|
@ -19,8 +21,11 @@
|
|||
<img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 50px; width: auto;">
|
||||
</h1>
|
||||
<div class="nav">
|
||||
<a href="/asteroid">Home</a>
|
||||
<a href="/asteroid/profile">Profile</a>
|
||||
<a href="/asteroid/frameset">Home</a>
|
||||
<a href="/asteroid/player">Player</a>
|
||||
<a href="/asteroid/about">About</a>
|
||||
<a href="/asteroid/status">Status</a>
|
||||
<a href="/asteroid/profile" data-show-if-logged-in>Profile</a>
|
||||
<a href="/asteroid/admin" data-show-if-admin>Admin</a>
|
||||
<a href="/asteroid/login" data-show-if-logged-out>Login</a>
|
||||
<a href="/asteroid/register" data-show-if-logged-out>Register</a>
|
||||
|
|
@ -45,10 +50,38 @@
|
|||
</select>
|
||||
</div>
|
||||
|
||||
<audio id="live-stream-audio" controls style="width: 100%; margin-top: 20px;">
|
||||
<audio id="live-stream-audio" controls crossorigin="anonymous" style="width: 100%; margin-top: 20px;">
|
||||
<source id="live-stream-source" lquery="(attr :src default-stream-url)" type="audio/aac">
|
||||
Your browser does not support the audio element.
|
||||
</audio>
|
||||
|
||||
<!-- Spectrum Analyzer -->
|
||||
<div style="text-align: center; margin: 20px 0;">
|
||||
<canvas id="spectrum-canvas" width="800" height="100" style="max-width: 100%; border: 1px solid #00ff00; background: #000; border-radius: 4px;"></canvas>
|
||||
<div style="margin-top: 8px; font-size: 0.9em;">
|
||||
<label style="margin-right: 10px;">
|
||||
Style:
|
||||
<select id="spectrum-style-selector" onchange="setSpectrumStyle(this.value)" style="padding: 3px; background: #000; color: #00ff00; border: 1px solid #00ff00;">
|
||||
<option value="bars">Bars</option>
|
||||
<option value="wave">Wave</option>
|
||||
<option value="dots">Dots</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Theme:
|
||||
<select id="spectrum-theme-selector" onchange="setSpectrumTheme(this.value)" style="padding: 3px; background: #000; color: #00ff00; border: 1px solid #00ff00;">
|
||||
<option value="monotone">Monotone</option>
|
||||
<option value="green">Green</option>
|
||||
<option value="blue">Blue</option>
|
||||
<option value="purple">Purple</option>
|
||||
<option value="red">Red</option>
|
||||
<option value="amber">Amber</option>
|
||||
<option value="rainbow">Rainbow</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p><em>Listen to the live Asteroid Radio stream</em></p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -12,10 +12,11 @@
|
|||
<div class="container">
|
||||
<h1>👤 USER PROFILE</h1>
|
||||
<div class="nav">
|
||||
<a href="/asteroid">Home</a>
|
||||
<a href="/asteroid/frameset">Home</a>
|
||||
<a href="/asteroid/player">Player</a>
|
||||
<a href="/asteroid/about">About</a>
|
||||
<a href="/asteroid/admin" data-show-if-admin>Admin</a>
|
||||
<a href="/asteroid/logout" class="btn-logout">Logout</a>
|
||||
<a href="/asteroid/logout" class="btn-logout" onclick="event.preventDefault(); fetch('/asteroid/logout').then(() => window.location.href='/asteroid/frameset');">Logout</a>
|
||||
</div>
|
||||
|
||||
<!-- User Profile Header -->
|
||||
|
|
|
|||
|
|
@ -17,8 +17,9 @@
|
|||
<span>ASTEROID RADIO - REGISTER</span>
|
||||
</h1>
|
||||
<nav class="nav">
|
||||
<a href="/asteroid">Home</a>
|
||||
<a href="/asteroid/frameset">Home</a>
|
||||
<a href="/asteroid/player">Player</a>
|
||||
<a href="/asteroid/about">About</a>
|
||||
<a href="/asteroid/status">Status</a>
|
||||
<a href="/asteroid/login">Login</a>
|
||||
</nav>
|
||||
|
|
|
|||
|
|
@ -6,94 +6,52 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" type="text/css" href="/asteroid/static/asteroid.css">
|
||||
<script src="/asteroid/static/js/auth-ui.js"></script>
|
||||
<script>
|
||||
// Handle logout without navigation
|
||||
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();
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Logout failed:', error);
|
||||
});
|
||||
}
|
||||
|
||||
// Load content via AJAX to prevent audio interruption
|
||||
function loadInFrame(link) {
|
||||
const url = link.href;
|
||||
console.log('Loading via AJAX:', url);
|
||||
|
||||
// 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);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Failed to load content:', error);
|
||||
return true;
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>📡 SYSTEM STATUS</h1>
|
||||
<div class="nav">
|
||||
<a href="/asteroid/content" target="content-frame" onclick="return loadInFrame(this)">Home</a>
|
||||
<a href="/asteroid/player-content" target="content-frame" onclick="return loadInFrame(this)">Player</a>
|
||||
<a href="/asteroid/profile-content" target="content-frame" data-show-if-logged-in onclick="return loadInFrame(this)">Profile</a>
|
||||
<a href="/asteroid/admin-content" target="content-frame" data-show-if-admin onclick="return loadInFrame(this)">Admin</a>
|
||||
<a href="/asteroid/login-content" target="content-frame" data-show-if-logged-out onclick="return loadInFrame(this)">Login</a>
|
||||
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout" onclick="handleLogout(); return false;">Logout</a>
|
||||
</div>
|
||||
<header>
|
||||
<h1 style="display: flex; align-items: center; justify-content: center; gap: 15px;">
|
||||
<img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 50px; width: auto;">
|
||||
<span>📡 SYSTEM STATUS</span>
|
||||
<img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 50px; width: auto;">
|
||||
</h1>
|
||||
<nav class="nav">
|
||||
<a href="/asteroid/content" target="_self">Home</a>
|
||||
<a href="/asteroid/player-content" target="_self">Player</a>
|
||||
<a href="/asteroid/about-content" target="_self">About</a>
|
||||
<a href="/asteroid/status-content" target="_self">Status</a>
|
||||
<a href="/asteroid/profile-content" target="_self" data-show-if-logged-in>Profile</a>
|
||||
<a href="/asteroid/admin-content" target="_self" data-show-if-admin>Admin</a>
|
||||
<a href="/asteroid/login-content" target="_self" data-show-if-logged-out>Login</a>
|
||||
<a href="/asteroid/register-content" target="_self" data-show-if-logged-out>Register</a>
|
||||
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout" onclick="event.preventDefault(); fetch('/asteroid/logout').then(() => window.location.reload());">Logout</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<div class="admin-section">
|
||||
<h2>Server Status</h2>
|
||||
<p>Status page coming soon...</p>
|
||||
<p>For now, administrators can view detailed status information in the <a href="/asteroid/admin-content" target="content-frame" onclick="return loadInFrame(this)">Admin Dashboard</a>.</p>
|
||||
</div>
|
||||
<main style="max-width: 800px; margin: 0 auto; padding: 20px;">
|
||||
<section style="margin-bottom: 30px;">
|
||||
<h2 style="color: #00ff00; border-bottom: 2px solid #00ff00; padding-bottom: 10px;">🟢 Server Status</h2>
|
||||
<p style="line-height: 1.6;">
|
||||
Asteroid Radio is currently online and broadcasting.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section style="margin-bottom: 30px;">
|
||||
<h2 style="color: #00ff00; border-bottom: 2px solid #00ff00; padding-bottom: 10px;">📊 Stream Information</h2>
|
||||
<ul style="line-height: 1.8;">
|
||||
<li><strong>Status:</strong> 🟢 Live</li>
|
||||
<li><strong>Formats:</strong> AAC 96kbps, MP3 128kbps, MP3 64kbps</li>
|
||||
<li><strong>Server:</strong> Icecast</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section style="margin-bottom: 30px;">
|
||||
<h2 style="color: #00ff00; border-bottom: 2px solid #00ff00; padding-bottom: 10px;">ℹ️ Additional Information</h2>
|
||||
<p style="line-height: 1.6;">
|
||||
For detailed system status and administration, please visit the <a href="/asteroid/admin" style="color: #00ff00;" data-show-if-admin>Admin Dashboard</a>.
|
||||
</p>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Asteroid Radio - Status</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" type="text/css" href="/asteroid/static/asteroid.css">
|
||||
<script src="/asteroid/static/js/auth-ui.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1 style="display: flex; align-items: center; justify-content: center; gap: 15px;">
|
||||
<img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 50px; width: auto;">
|
||||
<span>📡 SYSTEM STATUS</span>
|
||||
<img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 50px; width: auto;">
|
||||
</h1>
|
||||
<nav class="nav">
|
||||
<a href="/asteroid/frameset">Home</a>
|
||||
<a href="/asteroid/player">Player</a>
|
||||
<a href="/asteroid/about">About</a>
|
||||
<a href="/asteroid/status">Status</a>
|
||||
<a href="/asteroid/profile" data-show-if-logged-in>Profile</a>
|
||||
<a href="/asteroid/admin" data-show-if-admin>Admin</a>
|
||||
<a href="/asteroid/login" data-show-if-logged-out>Login</a>
|
||||
<a href="/asteroid/register" data-show-if-logged-out>Register</a>
|
||||
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout" onclick="event.preventDefault(); fetch('/asteroid/logout').then(() => window.location.href='/asteroid/frameset');">Logout</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main style="max-width: 800px; margin: 0 auto; padding: 20px;">
|
||||
<section style="margin-bottom: 30px;">
|
||||
<h2 style="color: #00ff00; border-bottom: 2px solid #00ff00; padding-bottom: 10px;">🟢 Server Status</h2>
|
||||
<p style="line-height: 1.6;">
|
||||
Asteroid Radio is currently online and broadcasting.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section style="margin-bottom: 30px;">
|
||||
<h2 style="color: #00ff00; border-bottom: 2px solid #00ff00; padding-bottom: 10px;">📊 Stream Information</h2>
|
||||
<ul style="line-height: 1.8;">
|
||||
<li><strong>Status:</strong> 🟢 Live</li>
|
||||
<li><strong>Formats:</strong> AAC 96kbps, MP3 128kbps, MP3 64kbps</li>
|
||||
<li><strong>Server:</strong> Icecast</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section style="margin-bottom: 30px;">
|
||||
<h2 style="color: #00ff00; border-bottom: 2px solid #00ff00; padding-bottom: 10px;">ℹ️ Additional Information</h2>
|
||||
<p style="line-height: 1.6;">
|
||||
For detailed system status and administration, please visit the <a href="/asteroid/admin" style="color: #00ff00;" data-show-if-admin>Admin Dashboard</a>.
|
||||
</p>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -11,9 +11,11 @@
|
|||
<div class="container">
|
||||
<h1>👥 USER MANAGEMENT</h1>
|
||||
<div class="nav">
|
||||
<a href="/asteroid">Home</a>
|
||||
<a href="/asteroid/frameset">Home</a>
|
||||
<a href="/asteroid/player">Player</a>
|
||||
<a href="/asteroid/about">About</a>
|
||||
<a href="/asteroid/admin">Admin</a>
|
||||
<a href="/asteroid/logout" class="btn-logout">Logout</a>
|
||||
<a href="/asteroid/logout" class="btn-logout" onclick="event.preventDefault(); fetch('/asteroid/logout').then(() => window.location.href='/asteroid/frameset');">Logout</a>
|
||||
</div>
|
||||
|
||||
<!-- User Statistics -->
|
||||
|
|
|
|||
Loading…
Reference in New Issue