/ template / player.ctml
player.ctml
  1  <!DOCTYPE html>
  2  <html lang="en">
  3  <head>
  4    <title data-text="title">Asteroid Radio - Web Player</title>
  5    <meta charset="utf-8">
  6    <meta name="viewport" content="width=device-width, initial-scale=1">
  7    <link rel="icon" type="image/x-icon" href="/asteroid/static/favicon.ico">
  8    <link rel="icon" type="image/png" sizes="32x32" href="/asteroid/static/favicon-32x32.png">
  9    <link rel="icon" type="image/png" sizes="16x16" href="/asteroid/static/favicon-16x16.png">
 10    <link rel="stylesheet" type="text/css" href="/asteroid/static/asteroid.css">
 11    <script src="/asteroid/static/js/auth-ui.js"></script>
 12    <script src="/asteroid/static/js/front-page.js"></script>
 13    <script src="/asteroid/static/js/player.js"></script>
 14  </head>
 15  <body>
 16    <div class="container">
 17      <h1 style="display: flex; align-items: center; justify-content: center; gap: 15px;">
 18        <img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 50px; width: auto;">
 19        <span>WEB PLAYER</span>
 20        <img src="/asteroid/static/asteroid.png" alt="Asteroid" style="height: 50px; width: auto;">
 21      </h1>
 22      <div class="nav">
 23        <a href="/asteroid">Home</a>
 24        <a href="/asteroid/profile">Profile</a>
 25        <a href="/asteroid/admin" data-show-if-admin>Admin</a>
 26        <a href="/asteroid/login" data-show-if-logged-out>Login</a>
 27        <a href="/asteroid/register" data-show-if-logged-out>Register</a>
 28        <a href="/asteroid/logout" data-show-if-logged-in class="btn-logout">Logout</a>
 29      </div>
 30      
 31      <!-- Live Stream Section -->
 32      <div class="player-section">
 33        <h2 style="color: #00ff00;">
 34          <span class="live-stream-indicator" style="font-size: 1rem;">๐ŸŸข </span>
 35          Live Radio Stream
 36        </h2>
 37        <div class="live-stream">
 38          <input type="hidden" id="stream-base-url" lquery="(val stream-base-url)">
 39          <!-- Stream Quality Selector -->
 40          <div class="live-stream-quality">
 41            <label for="live-stream-quality"><strong>Quality:</strong></label>
 42            <select id="live-stream-quality" onchange="changeLiveStreamQuality()">
 43              <option value="aac">AAC 96kbps (Recommended)</option>
 44              <option value="mp3">MP3 128kbps (Compatible)</option>
 45              <option value="low">MP3 64kbps (Low Bandwidth)</option>
 46            </select>
 47          </div>
 48          
 49          <audio id="live-stream-audio" controls style="width: 100%; margin-top: 20px;">
 50            <source id="live-stream-source" lquery="(attr :src default-stream-url)" type="audio/aac">
 51            Your browser does not support the audio element.
 52          </audio>
 53          <p><em>Listen to the live Asteroid Radio stream</em></p>
 54        </div>
 55      </div>
 56  
 57      <div id="now-playing" class="now-playing"></div>
 58  
 59      <!-- Track Browser -->
 60      <div class="player-section">
 61        <h2>Personal Track Library</h2>
 62        <div class="track-browser">
 63          <input type="text" id="search-tracks" placeholder="Search tracks..." class="search-input">
 64          <select id="library-tracks-per-page" class="sort-select" onchange="changeLibraryTracksPerPage()" style="margin: 10px 0px;">
 65            <option value="10">10 per page</option>
 66            <option value="20" selected>20 per page</option>
 67            <option value="50">50 per page</option>
 68          </select>
 69          <div id="track-list" class="track-list">
 70            <div class="loading">Loading tracks...</div>
 71          </div>
 72          <!-- Pagination Controls -->
 73          <div id="library-pagination-controls" style="display: none; margin-top: 20px; text-align: center;">
 74            <button onclick="libraryGoToPage(1)" class="btn btn-secondary">ยซ First</button>
 75            <button onclick="libraryPreviousPage()" class="btn btn-secondary">โ€น Prev</button>
 76            <span id="library-page-info" style="margin: 0 15px; font-weight: bold;">Page 1 of 1</span>
 77            <button onclick="libraryNextPage()" class="btn btn-secondary">Next โ€บ</button>
 78            <button onclick="libraryGoToLastPage()" class="btn btn-secondary">Last ยป</button>
 79          </div>
 80        </div>
 81      </div>
 82  
 83      <!-- Audio Player Widget -->
 84      <div class="player-section">
 85        <h2>Audio Player</h2>
 86        <div class="audio-player">
 87          <div class="now-playing">
 88            <div class="track-art">๐ŸŽต</div>
 89            <div class="track-details">
 90              <div class="track-title" id="current-title">No track selected</div>
 91              <div class="track-artist" id="current-artist">Unknown Artist</div>
 92              <div class="track-album" id="current-album">Unknown Album</div>
 93            </div>
 94          </div>
 95          
 96          <audio id="audio-player" controls preload="none" style="width: 100%; margin: 20px 0; display: none;">
 97            Your browser does not support the audio element.
 98          </audio>
 99          
100          <div class="player-controls">
101            <button id="prev-btn" class="btn btn-secondary">โฎ๏ธ Previous</button>
102            <button id="play-pause-btn" class="btn btn-primary">โ–ถ๏ธ Play</button>
103            <button id="next-btn" class="btn btn-secondary">โญ๏ธ Next</button>
104            <button id="shuffle-btn" class="btn btn-info">๐Ÿ”€ Shuffle</button>
105            <button id="repeat-btn" class="btn btn-warning">๐Ÿ” Repeat</button>
106          </div>
107          
108          <div class="player-info">
109            <div class="time-display">
110              <span id="current-time">0:00</span> / <span id="total-time">0:00</span>
111            </div>
112            <div class="volume-control">
113              <label for="volume-slider">๐Ÿ”Š</label>
114              <input type="range" id="volume-slider" min="0" max="100" value="50" class="volume-slider">
115            </div>
116          </div>
117        </div>
118      </div>
119  
120      <!-- Playlist Management -->
121      <div class="player-section">
122        <h2>Playlists</h2>
123        <div class="playlist-controls">
124          <input type="text" id="new-playlist-name" placeholder="New playlist name..." class="playlist-input">
125          <button id="create-playlist" class="btn btn-success">โž• Create Playlist</button>
126        </div>
127        
128        <div class="playlist-list">
129          <div id="playlists-container">
130            <div class="no-playlists">No playlists created yet.</div>
131          </div>
132        </div>
133      </div>
134  
135      <!-- Queue -->
136      <div class="player-section">
137        <h2>Play Queue</h2>
138        <div class="queue-controls">
139          <button id="clear-queue" class="btn btn-danger">๐Ÿ—‘๏ธ Clear Queue</button>
140          <button id="save-queue" class="btn btn-info">๐Ÿ’พ Save as Playlist</button>
141        </div>
142        <div id="play-queue" class="play-queue">
143          <div class="empty-queue">Queue is empty</div>
144        </div>
145      </div>
146    </div>
147  </body>
148  </html>