Compare commits
No commits in common. "ff651e6a362e4f27a5056848c3bfa6450e914f12" and "151f6c5569b267b0560585e3abdb13ac0810f2c7" have entirely different histories.
ff651e6a36
...
151f6c5569
|
|
@ -853,8 +853,7 @@
|
||||||
(define-page front-page-content #@"/content" ()
|
(define-page front-page-content #@"/content" ()
|
||||||
"Front page content (displayed in content frame)"
|
"Front page content (displayed in content frame)"
|
||||||
(clip:process-to-string
|
(clip:process-to-string
|
||||||
(load-template "front-page")
|
(load-template "front-page-content")
|
||||||
:framesetp t
|
|
||||||
:title "ASTEROID RADIO"
|
:title "ASTEROID RADIO"
|
||||||
:station-name "ASTEROID RADIO"
|
:station-name "ASTEROID RADIO"
|
||||||
:status-message "🟢 LIVE - Broadcasting asteroid music for hackers"
|
:status-message "🟢 LIVE - Broadcasting asteroid music for hackers"
|
||||||
|
|
@ -1285,8 +1284,7 @@
|
||||||
(define-page-with-limit player-content #@"/player-content" (:limit-group "public")
|
(define-page-with-limit player-content #@"/player-content" (:limit-group "public")
|
||||||
"Player page content (displayed in content frame)"
|
"Player page content (displayed in content frame)"
|
||||||
(clip:process-to-string
|
(clip:process-to-string
|
||||||
(load-template "player")
|
(load-template "player-content")
|
||||||
:framesetp t
|
|
||||||
:title "Asteroid Radio - Web Player"
|
:title "Asteroid Radio - Web Player"
|
||||||
:stream-base-url *stream-base-url*
|
:stream-base-url *stream-base-url*
|
||||||
:default-stream-url (format nil "~a/asteroid.aac" *stream-base-url*)
|
:default-stream-url (format nil "~a/asteroid.aac" *stream-base-url*)
|
||||||
|
|
@ -1312,22 +1310,14 @@
|
||||||
(define-page-with-limit about-content #@"/about-content" (:limit-group "public")
|
(define-page-with-limit about-content #@"/about-content" (:limit-group "public")
|
||||||
"About page content (displayed in content frame)"
|
"About page content (displayed in content frame)"
|
||||||
(clip:process-to-string
|
(clip:process-to-string
|
||||||
(load-template "about")
|
(load-template "about-content")
|
||||||
:framesetp t
|
|
||||||
:title "About - Asteroid Radio"))
|
:title "About - Asteroid Radio"))
|
||||||
|
|
||||||
(define-page-with-limit status-page #@"/status" (:limit-group "public")
|
|
||||||
"Status page content"
|
|
||||||
(clip:process-to-string
|
|
||||||
(load-template "status")
|
|
||||||
:title "Status - Asteroid Radio"))
|
|
||||||
|
|
||||||
;; Status content (for frameset mode)
|
;; Status content (for frameset mode)
|
||||||
(define-page-with-limit status-content #@"/status-content" (:limit-group "public")
|
(define-page-with-limit status-content #@"/status-content" (:limit-group "public")
|
||||||
"Status page content (displayed in content frame)"
|
"Status page content (displayed in content frame)"
|
||||||
(clip:process-to-string
|
(clip:process-to-string
|
||||||
(load-template "status")
|
(load-template "status-content")
|
||||||
:framesetp t
|
|
||||||
:title "Status - Asteroid Radio"))
|
:title "Status - Asteroid Radio"))
|
||||||
|
|
||||||
(define-api-with-limit asteroid/status () ()
|
(define-api-with-limit asteroid/status () ()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
<!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="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" target="_self">Status</a>
|
||||||
|
<a href="/asteroid/profile" target="_self" data-show-if-logged-in>Profile</a>
|
||||||
|
<a href="/asteroid/admin" target="_self" data-show-if-admin>Admin</a>
|
||||||
|
<a href="/asteroid/login" target="_self" data-show-if-logged-out>Login</a>
|
||||||
|
<a href="/asteroid/register" target="_self" data-show-if-logged-out>Register</a>
|
||||||
|
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout">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>
|
||||||
|
|
@ -18,32 +18,16 @@
|
||||||
<span>ABOUT ASTEROID RADIO</span>
|
<span>ABOUT ASTEROID RADIO</span>
|
||||||
<img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 50px; width: auto;">
|
<img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 50px; width: auto;">
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<nav class="nav">
|
<nav class="nav">
|
||||||
<c:if test="(not framesetp)">
|
<a href="/asteroid/">Home</a>
|
||||||
<c:then>
|
<a href="/asteroid/player">Player</a>
|
||||||
<a href="/asteroid/">Home</a>
|
<a href="/asteroid/about">About</a>
|
||||||
<a href="/asteroid/player">Player</a>
|
<a href="/asteroid/status">Status</a>
|
||||||
<a href="/asteroid/about">About</a>
|
<a href="/asteroid/profile" data-show-if-logged-in>Profile</a>
|
||||||
<a href="/asteroid/status">Status</a>
|
<a href="/asteroid/admin" data-show-if-admin>Admin</a>
|
||||||
<a href="/asteroid/profile" data-show-if-logged-in>Profile</a>
|
<a href="/asteroid/login" data-show-if-logged-out>Login</a>
|
||||||
<a href="/asteroid/admin" data-show-if-admin>Admin</a>
|
<a href="/asteroid/register" data-show-if-logged-out>Register</a>
|
||||||
<a href="/asteroid/login" data-show-if-logged-out>Login</a>
|
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout">Logout</a>
|
||||||
<a href="/asteroid/register" data-show-if-logged-out>Register</a>
|
|
||||||
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout">Logout</a>
|
|
||||||
</c:then>
|
|
||||||
<c:else>
|
|
||||||
<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" target="_self" data-show-if-logged-in>Profile</a>
|
|
||||||
<a href="/asteroid/admin" target="_self" data-show-if-admin>Admin</a>
|
|
||||||
<a href="/asteroid/login" target="_self" data-show-if-logged-out>Login</a>
|
|
||||||
<a href="/asteroid/register" target="_self" data-show-if-logged-out>Register</a>
|
|
||||||
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout">Logout</a>
|
|
||||||
</c:else>
|
|
||||||
</c:if>
|
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
<main style="max-width: 800px; margin: 0 auto; padding: 20px;">
|
<main style="max-width: 800px; margin: 0 auto; padding: 20px;">
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,125 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title data-text="title">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="icon" type="image/png" sizes="32x32" href="/asteroid/static/favicon-32x32.png">
|
||||||
|
<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/recently-played.js"></script>
|
||||||
|
<script src="/api/asteroid/spectrum-analyzer.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<header>
|
||||||
|
<h1 class="page-title">
|
||||||
|
<img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 60px; width: auto;">
|
||||||
|
<span data-text="station-name">ASTEROID RADIO</span>
|
||||||
|
<img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 60px; width: auto;">
|
||||||
|
</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="_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" target="_self" data-show-if-logged-in>Profile</a>
|
||||||
|
<a href="/asteroid/admin" target="_self" data-show-if-admin>Admin</a>
|
||||||
|
<a href="/asteroid/login" target="_self" data-show-if-logged-out>Login</a>
|
||||||
|
<a href="/asteroid/register" target="_self" data-show-if-logged-out>Register</a>
|
||||||
|
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout">Logout</a>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<div class="live-stream">
|
||||||
|
<h2 style="color: #00ff00; margin: 0;"><span class="live-stream-indicator" style="font-size: 1rem;">🟢</span> LIVE STREAM</h2>
|
||||||
|
|
||||||
|
<!-- Channel Selector -->
|
||||||
|
<div class="live-stream-quality" style="margin-bottom: 15px;">
|
||||||
|
<label for="stream-channel" class="live-stream-label"><strong>Channel:</strong></label>
|
||||||
|
<select id="stream-channel" onchange="changeChannel()">
|
||||||
|
<option value="curated">🎧 <c:splice lquery="(text curated-channel-name)">Curated</c:splice></option>
|
||||||
|
<option value="shuffle">🎲 Shuffle</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="hidden" id="stream-base-url" lquery="(val stream-base-url)">
|
||||||
|
<p><strong class="live-stream-label">Stream URL:</strong> <code id="stream-url" lquery="(text default-stream-url)"></code></p>
|
||||||
|
<p><strong class="live-stream-label">Stream Quality:</strong> <span id="stream-format" lquery="(text default-stream-encoding-desc)"></span></p>
|
||||||
|
<p><strong class="live-stream-label">BROADCASTING:</strong> <span id="stream-status" style="">Asteroid music for Hackers</span></p>
|
||||||
|
<p class="frame-enable-message"><em>The live stream player is now in the persistent bar at the bottom of the page</em></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="now-playing" class="now-playing"></div>
|
||||||
|
|
||||||
|
<!-- Recently Played Tracks -->
|
||||||
|
<div id="recently-played-panel" class="recently-played-panel">
|
||||||
|
<h3>Recently Played</h3>
|
||||||
|
<div id="recently-played-list" class="recently-played-list">
|
||||||
|
<p class="loading">Loading...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Track Request Section -->
|
||||||
|
<div class="request-panel">
|
||||||
|
<h3>🎵 Request a Track</h3>
|
||||||
|
<p class="request-description">Want to hear something specific? Submit a request and an admin will review it.</p>
|
||||||
|
<div class="request-form">
|
||||||
|
<input type="text" id="request-title" class="request-input" placeholder="Suggest a track, artist, or album...">
|
||||||
|
<input type="text" id="request-message" class="request-input" placeholder="Why do you want to hear this? (optional)">
|
||||||
|
<button class="btn btn-primary" onclick="submitTrackRequest()">Submit Request</button>
|
||||||
|
</div>
|
||||||
|
<div id="request-status" class="request-status" style="display: none;"></div>
|
||||||
|
<div class="recent-requests">
|
||||||
|
<h4>Recently Played Requests</h4>
|
||||||
|
<div id="recent-requests-list">
|
||||||
|
<p class="no-requests">Loading...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="site-footer">
|
||||||
|
<span>Listed on <a href="http://www.internet-radio.com/stations/ambient/" target="_blank" rel="noopener">Internet Radio</a></span>
|
||||||
|
<span class="craftering">
|
||||||
|
<a href="https://craftering.systemcrafters.net/@asteroid/previous">←</a>
|
||||||
|
<a href="https://craftering.systemcrafters.net/">craftering</a>
|
||||||
|
<a href="https://craftering.systemcrafters.net/@asteroid/next">→</a>
|
||||||
|
</span>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -51,30 +51,15 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<nav class="nav">
|
<nav class="nav">
|
||||||
<c:if test="(not framesetp)">
|
<a href="/asteroid/">Home</a>
|
||||||
<c:then>
|
<a href="/asteroid/player">Player</a>
|
||||||
<a href="/asteroid/">Home</a>
|
<a href="/asteroid/about">About</a>
|
||||||
<a href="/asteroid/player">Player</a>
|
<a href="/asteroid/status">Status</a>
|
||||||
<a href="/asteroid/about">About</a>
|
<a href="/asteroid/profile" data-show-if-logged-in>Profile</a>
|
||||||
<a href="/asteroid/status">Status</a>
|
<a href="/asteroid/admin" data-show-if-admin>Admin</a>
|
||||||
<a href="/asteroid/profile" data-show-if-logged-in>Profile</a>
|
<a href="/asteroid/login" data-show-if-logged-out>Login</a>
|
||||||
<a href="/asteroid/admin" data-show-if-admin>Admin</a>
|
<a href="/asteroid/register" data-show-if-logged-out>Register</a>
|
||||||
<a href="/asteroid/login" data-show-if-logged-out>Login</a>
|
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout">Logout</a>
|
||||||
<a href="/asteroid/register" data-show-if-logged-out>Register</a>
|
|
||||||
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout">Logout</a>
|
|
||||||
</c:then>
|
|
||||||
<c:else>
|
|
||||||
<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" target="_self" data-show-if-logged-in>Profile</a>
|
|
||||||
<a href="/asteroid/admin" target="_self" data-show-if-admin>Admin</a>
|
|
||||||
<a href="/asteroid/login" target="_self" data-show-if-logged-out>Login</a>
|
|
||||||
<a href="/asteroid/register" target="_self" data-show-if-logged-out>Register</a>
|
|
||||||
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout">Logout</a>
|
|
||||||
</c:else>
|
|
||||||
</c:if>
|
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
@ -93,53 +78,42 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<c:if test="(not framesetp)">
|
<!-- Stream Quality Selector -->
|
||||||
<c:then>
|
<div class="live-stream-quality" style="margin-bottom: 15px;">
|
||||||
<!-- Stream Quality Selector -->
|
<label for="stream-quality" class="live-stream-label" ><strong>Quality:</strong></label>
|
||||||
<div class="live-stream-quality" style="margin-bottom: 15px;">
|
<select id="stream-quality" onchange="changeStreamQuality()">
|
||||||
<label for="stream-quality" class="live-stream-label" ><strong>Quality:</strong></label>
|
<option value="aac">AAC 96kbps (Recommended)</option>
|
||||||
<select id="stream-quality" onchange="changeStreamQuality()">
|
<option value="mp3">MP3 128kbps (Compatible)</option>
|
||||||
<option value="aac">AAC 96kbps (Recommended)</option>
|
<option value="low">MP3 64kbps (Low Bandwidth)</option>
|
||||||
<option value="mp3">MP3 128kbps (Compatible)</option>
|
</select>
|
||||||
<option value="low">MP3 64kbps (Low Bandwidth)</option>
|
</div>
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</c:then>
|
|
||||||
</c:if>
|
|
||||||
|
|
||||||
<input type="hidden" id="stream-base-url" lquery="(val stream-base-url)">
|
<input type="hidden" id="stream-base-url" lquery="(val stream-base-url)">
|
||||||
<p><strong class="live-stream-label">Stream URL:</strong> <code id="stream-url" lquery="(text default-stream-url)"></code></p>
|
<p><strong class="live-stream-label">Stream URL:</strong> <code id="stream-url" lquery="(text default-stream-url)"></code></p>
|
||||||
<p><strong class="live-stream-label">Stream Quality:</strong> <span id="stream-format" lquery="(text default-stream-encoding-desc)"></span></p>
|
<p><strong class="live-stream-label">Stream Quality:</strong> <span id="stream-format" lquery="(text default-stream-encoding-desc)"></span></p>
|
||||||
<p><strong class="live-stream-label" class="live-stream-label">BROADCASTING:</strong> <span id="stream-status" style="">Asteroid music for Hackers</span></p>
|
<p><strong class="live-stream-label" class="live-stream-label">BROADCASTING:</strong> <span id="stream-status" style="">Asteroid music for Hackers</span></p>
|
||||||
|
|
||||||
<c:if test="(not framesetp)">
|
<div style="display: flex; gap: 10px; justify-content: end; margin-bottom: 20px;">
|
||||||
<c:then>
|
<button id="reconnect-btn" class="btn btn-warning" onclick="reconnectStream()" style="font-size: 0.9em; display: none;">
|
||||||
<div style="display: flex; gap: 10px; justify-content: end; margin-bottom: 20px;">
|
|
||||||
<button id="reconnect-btn" class="btn btn-warning" onclick="reconnectStream()" style="font-size: 0.9em; display: none;">
|
|
||||||
🔄 Reconnect Stream
|
🔄 Reconnect Stream
|
||||||
</button>
|
</button>
|
||||||
<button id="popout-btn" class="btn btn-info" onclick="openPopoutPlayer()" style="font-size: 0.9em;">
|
<button id="popout-btn" class="btn btn-info" onclick="openPopoutPlayer()" style="font-size: 0.9em;">
|
||||||
🗗 Pop Out Player
|
🗗 Pop Out Player
|
||||||
</button>
|
</button>
|
||||||
<button id="frameset-btn" class="btn btn-secondary" onclick="enableFramesetMode()" style="font-size: 0.9em;">
|
<button id="frameset-btn" class="btn btn-secondary" onclick="enableFramesetMode()" style="font-size: 0.9em;">
|
||||||
🖼️ Enable Persistent Player
|
🖼️ Enable Persistent Player
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Stream connection status -->
|
<!-- Stream connection status -->
|
||||||
<div id="stream-status-indicator" style="display: none; padding: 8px; margin-bottom: 10px; border-radius: 4px; text-align: center;"></div>
|
<div id="stream-status-indicator" style="display: none; padding: 8px; margin-bottom: 10px; border-radius: 4px; text-align: center;"></div>
|
||||||
|
|
||||||
<div id="audio-container">
|
<div id="audio-container">
|
||||||
<audio id="live-audio" controls crossorigin="anonymous" style="width: 100%; margin: 10px 0;">
|
<audio id="live-audio" controls crossorigin="anonymous" style="width: 100%; margin: 10px 0;">
|
||||||
<source id="audio-source" lquery="(attr :src default-stream-url :type default-stream-encoding)">
|
<source id="audio-source" lquery="(attr :src default-stream-url :type default-stream-encoding)">
|
||||||
Your browser does not support the audio element.
|
Your browser does not support the audio element.
|
||||||
</audio>
|
</audio>
|
||||||
</div>
|
</div>
|
||||||
</c:then>
|
|
||||||
<c:else>
|
|
||||||
<p class="frame-enable-message"><em>The live stream player is now in the persistent bar at the bottom of the page</em></p>
|
|
||||||
</c:else>
|
|
||||||
</c:if>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="now-playing" class="now-playing"></div>
|
<div id="now-playing" class="now-playing"></div>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,157 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title data-text="title">Asteroid Radio - Web Player</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>
|
||||||
|
<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">
|
||||||
|
<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>WEB PLAYER</span>
|
||||||
|
<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">
|
||||||
|
<a href="/asteroid/content" target="content-frame">Home</a>
|
||||||
|
<a href="/asteroid/profile" target="content-frame" data-show-if-logged-in>Profile</a>
|
||||||
|
<a href="/asteroid/admin" target="content-frame" data-show-if-admin>Admin</a>
|
||||||
|
<a href="/asteroid/login" target="content-frame" data-show-if-logged-out>Login</a>
|
||||||
|
<a href="/asteroid/register" target="content-frame" data-show-if-logged-out>Register</a>
|
||||||
|
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout">Logout</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Live Stream Section - Note about persistent player -->
|
||||||
|
<div class="player-section">
|
||||||
|
<h2 style="color: #00ff00;">
|
||||||
|
<span class="live-stream-indicator" style="font-size: 1rem;">🟢 </span>
|
||||||
|
Live Radio Stream
|
||||||
|
</h2>
|
||||||
|
<p><em>The live stream player is now in the persistent bar at the bottom of the page. It will continue playing as you navigate between pages!</em></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="now-playing" class="now-playing"></div>
|
||||||
|
|
||||||
|
<!-- Track Browser -->
|
||||||
|
<div class="player-section">
|
||||||
|
<h2>Personal Track Library</h2>
|
||||||
|
<div class="track-browser">
|
||||||
|
<input type="text" id="search-tracks" placeholder="Search tracks..." class="search-input">
|
||||||
|
<select id="library-tracks-per-page" class="sort-select" onchange="changeLibraryTracksPerPage()" style="margin: 10px 0px;">
|
||||||
|
<option value="10">10 per page</option>
|
||||||
|
<option value="20" selected>20 per page</option>
|
||||||
|
<option value="50">50 per page</option>
|
||||||
|
</select>
|
||||||
|
<div id="track-list" class="track-list">
|
||||||
|
<div class="loading">Loading tracks...</div>
|
||||||
|
</div>
|
||||||
|
<!-- Pagination Controls -->
|
||||||
|
<div id="library-pagination-controls" style="display: none; margin-top: 20px; text-align: center;">
|
||||||
|
<button onclick="libraryGoToPage(1)" class="btn btn-secondary">« First</button>
|
||||||
|
<button onclick="libraryPreviousPage()" class="btn btn-secondary">‹ Prev</button>
|
||||||
|
<span id="library-page-info" style="margin: 0 15px; font-weight: bold;">Page 1 of 1</span>
|
||||||
|
<button onclick="libraryNextPage()" class="btn btn-secondary">Next ›</button>
|
||||||
|
<button onclick="libraryGoToLastPage()" class="btn btn-secondary">Last »</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Audio Player Widget -->
|
||||||
|
<div class="player-section">
|
||||||
|
<h2>Audio Player</h2>
|
||||||
|
<div class="audio-player">
|
||||||
|
<div class="now-playing">
|
||||||
|
<div class="track-art">🎵</div>
|
||||||
|
<div class="track-details">
|
||||||
|
<div class="track-title" id="current-title">No track selected</div>
|
||||||
|
<div class="track-artist" id="current-artist">Unknown Artist</div>
|
||||||
|
<div class="track-album" id="current-album">Unknown Album</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<audio id="audio-player" controls preload="none" style="width: 100%; margin: 20px 0; display: none;">
|
||||||
|
Your browser does not support the audio element.
|
||||||
|
</audio>
|
||||||
|
|
||||||
|
<div class="player-controls">
|
||||||
|
<button id="prev-btn" class="btn btn-secondary">⏮️ Previous</button>
|
||||||
|
<button id="play-pause-btn" class="btn btn-primary">▶️ Play</button>
|
||||||
|
<button id="next-btn" class="btn btn-secondary">⏭️ Next</button>
|
||||||
|
<button id="shuffle-btn" class="btn btn-info">🔀 Shuffle</button>
|
||||||
|
<button id="repeat-btn" class="btn btn-warning">🔁 Repeat</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="player-info">
|
||||||
|
<div class="time-display">
|
||||||
|
<span id="current-time">0:00</span> / <span id="total-time">0:00</span>
|
||||||
|
</div>
|
||||||
|
<div class="volume-control">
|
||||||
|
<label for="volume-slider">🔊</label>
|
||||||
|
<input type="range" id="volume-slider" min="0" max="100" value="50" class="volume-slider">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Playlist Management -->
|
||||||
|
<div class="player-section">
|
||||||
|
<h2>Playlists</h2>
|
||||||
|
<div class="playlist-controls">
|
||||||
|
<input type="text" id="new-playlist-name" placeholder="New playlist name..." class="playlist-input">
|
||||||
|
<button id="create-playlist" class="btn btn-success">➕ Create Playlist</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="playlist-list">
|
||||||
|
<div id="playlists-container">
|
||||||
|
<div class="no-playlists">No playlists created yet.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Queue -->
|
||||||
|
<div class="player-section">
|
||||||
|
<h2>Play Queue</h2>
|
||||||
|
<div class="queue-controls">
|
||||||
|
<button id="clear-queue" class="btn btn-danger">🗑️ Clear Queue</button>
|
||||||
|
<button id="save-queue" class="btn btn-info">💾 Save as Playlist</button>
|
||||||
|
</div>
|
||||||
|
<div id="play-queue" class="play-queue">
|
||||||
|
<div class="empty-queue">Queue is empty</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -11,11 +11,6 @@
|
||||||
<script src="/asteroid/static/js/auth-ui.js"></script>
|
<script src="/asteroid/static/js/auth-ui.js"></script>
|
||||||
<script src="/asteroid/static/js/front-page.js"></script>
|
<script src="/asteroid/static/js/front-page.js"></script>
|
||||||
<script src="/asteroid/static/js/player.js"></script>
|
<script src="/asteroid/static/js/player.js"></script>
|
||||||
<c:if test="framesetp">
|
|
||||||
<c:then>
|
|
||||||
<script src="/api/asteroid/spectrum-analyzer.js"></script>
|
|
||||||
</c:then>
|
|
||||||
</c:if>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
@ -24,57 +19,13 @@
|
||||||
<span>WEB PLAYER</span>
|
<span>WEB PLAYER</span>
|
||||||
<img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 50px; width: auto;">
|
<img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 50px; width: auto;">
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<!-- Spectrum Analyzer Canvas -->
|
|
||||||
<c:if test="framesetp">
|
|
||||||
<c:then>
|
|
||||||
<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>
|
|
||||||
</c:then>
|
|
||||||
</c:if>
|
|
||||||
|
|
||||||
<div class="nav">
|
<div class="nav">
|
||||||
<c:if test="(not framesetp)">
|
<a href="/asteroid">Home</a>
|
||||||
<c:then>
|
<a href="/asteroid/profile">Profile</a>
|
||||||
<a href="/asteroid">Home</a>
|
<a href="/asteroid/admin" data-show-if-admin>Admin</a>
|
||||||
<a href="/asteroid/profile">Profile</a>
|
<a href="/asteroid/login" data-show-if-logged-out>Login</a>
|
||||||
<a href="/asteroid/admin" data-show-if-admin>Admin</a>
|
<a href="/asteroid/register" data-show-if-logged-out>Register</a>
|
||||||
<a href="/asteroid/login" data-show-if-logged-out>Login</a>
|
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout">Logout</a>
|
||||||
<a href="/asteroid/register" data-show-if-logged-out>Register</a>
|
|
||||||
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout">Logout</a>
|
|
||||||
</c:then>
|
|
||||||
<c:else>
|
|
||||||
<a href="/asteroid/content" target="content-frame">Home</a>
|
|
||||||
<a href="/asteroid/profile" target="content-frame" data-show-if-logged-in>Profile</a>
|
|
||||||
<a href="/asteroid/admin" target="content-frame" data-show-if-admin>Admin</a>
|
|
||||||
<a href="/asteroid/login" target="content-frame" data-show-if-logged-out>Login</a>
|
|
||||||
<a href="/asteroid/register" target="content-frame" data-show-if-logged-out>Register</a>
|
|
||||||
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout">Logout</a>
|
|
||||||
</c:else>
|
|
||||||
</c:if>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Live Stream Section -->
|
<!-- Live Stream Section -->
|
||||||
|
|
@ -83,31 +34,24 @@
|
||||||
<span class="live-stream-indicator" style="font-size: 1rem;">🟢 </span>
|
<span class="live-stream-indicator" style="font-size: 1rem;">🟢 </span>
|
||||||
Live Radio Stream
|
Live Radio Stream
|
||||||
</h2>
|
</h2>
|
||||||
<c:if test="(not framesetp)">
|
<div class="live-stream">
|
||||||
<c:then>
|
<input type="hidden" id="stream-base-url" lquery="(val stream-base-url)">
|
||||||
<div class="live-stream">
|
<!-- Stream Quality Selector -->
|
||||||
<input type="hidden" id="stream-base-url" lquery="(val stream-base-url)">
|
<div class="live-stream-quality">
|
||||||
<!-- Stream Quality Selector -->
|
<label for="live-stream-quality"><strong>Quality:</strong></label>
|
||||||
<div class="live-stream-quality">
|
<select id="live-stream-quality" onchange="changeLiveStreamQuality()">
|
||||||
<label for="live-stream-quality"><strong>Quality:</strong></label>
|
<option value="aac">AAC 96kbps (Recommended)</option>
|
||||||
<select id="live-stream-quality" onchange="changeLiveStreamQuality()">
|
<option value="mp3">MP3 128kbps (Compatible)</option>
|
||||||
<option value="aac">AAC 96kbps (Recommended)</option>
|
<option value="low">MP3 64kbps (Low Bandwidth)</option>
|
||||||
<option value="mp3">MP3 128kbps (Compatible)</option>
|
</select>
|
||||||
<option value="low">MP3 64kbps (Low Bandwidth)</option>
|
</div>
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<audio id="live-stream-audio" controls style="width: 100%; margin-top: 20px;">
|
<audio id="live-stream-audio" controls style="width: 100%; margin-top: 20px;">
|
||||||
<source id="live-stream-source" lquery="(attr :src default-stream-url)" type="audio/aac">
|
<source id="live-stream-source" lquery="(attr :src default-stream-url)" type="audio/aac">
|
||||||
Your browser does not support the audio element.
|
Your browser does not support the audio element.
|
||||||
</audio>
|
</audio>
|
||||||
<p><em>Listen to the live Asteroid Radio stream</em></p>
|
<p><em>Listen to the live Asteroid Radio stream</em></p>
|
||||||
</div>
|
</div>
|
||||||
</c:then>
|
|
||||||
<c:else>
|
|
||||||
<p><em>The live stream player is now in the persistent bar at the bottom of the page. It will continue playing as you navigate between pages!</em></p>
|
|
||||||
</c:else>
|
|
||||||
</c:if>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="now-playing" class="now-playing"></div>
|
<div id="now-playing" class="now-playing"></div>
|
||||||
|
|
|
||||||
|
|
@ -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/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" target="_self" data-show-if-logged-in>Profile</a>
|
||||||
|
<a href="/asteroid/admin" target="_self" data-show-if-admin>Admin</a>
|
||||||
|
<a href="/asteroid/login" target="_self" data-show-if-logged-out>Login</a>
|
||||||
|
<a href="/asteroid/register" target="_self" data-show-if-logged-out>Register</a>
|
||||||
|
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout">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>
|
||||||
|
|
@ -15,32 +15,16 @@
|
||||||
<span>📡 SYSTEM STATUS</span>
|
<span>📡 SYSTEM STATUS</span>
|
||||||
<img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 50px; width: auto;">
|
<img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 50px; width: auto;">
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<nav class="nav">
|
<nav class="nav">
|
||||||
<c:if test="(not framesetp)">
|
<a href="/asteroid/frameset">Home</a>
|
||||||
<c:then>
|
<a href="/asteroid/player">Player</a>
|
||||||
<a href="/asteroid">Home</a>
|
<a href="/asteroid/about">About</a>
|
||||||
<a href="/asteroid/player">Player</a>
|
<a href="/asteroid/status">Status</a>
|
||||||
<a href="/asteroid/about">About</a>
|
<a href="/asteroid/profile" data-show-if-logged-in>Profile</a>
|
||||||
<a href="/asteroid/status">Status</a>
|
<a href="/asteroid/admin" data-show-if-admin>Admin</a>
|
||||||
<a href="/asteroid/profile" data-show-if-logged-in>Profile</a>
|
<a href="/asteroid/login" data-show-if-logged-out>Login</a>
|
||||||
<a href="/asteroid/admin" data-show-if-admin>Admin</a>
|
<a href="/asteroid/register" data-show-if-logged-out>Register</a>
|
||||||
<a href="/asteroid/login" data-show-if-logged-out>Login</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>
|
||||||
<a href="/asteroid/register" data-show-if-logged-out>Register</a>
|
|
||||||
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout">Logout</a>
|
|
||||||
</c:then>
|
|
||||||
<c:else>
|
|
||||||
<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" target="_self" data-show-if-logged-in>Profile</a>
|
|
||||||
<a href="/asteroid/admin" target="_self" data-show-if-admin>Admin</a>
|
|
||||||
<a href="/asteroid/login" target="_self" data-show-if-logged-out>Login</a>
|
|
||||||
<a href="/asteroid/register" target="_self" data-show-if-logged-out>Register</a>
|
|
||||||
<a href="/asteroid/logout" data-show-if-logged-in class="btn-logout">Logout</a>
|
|
||||||
</c:else>
|
|
||||||
</c:if>
|
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue