112 lines
3.9 KiB
HTML
112 lines
3.9 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>NeoRose</title>
|
|
<link rel="stylesheet" href="styles.css?v=4">
|
|
</head>
|
|
<body>
|
|
<div id="app">
|
|
<h1>MusicRoom <span id="sync-indicator"></span></h1>
|
|
|
|
<div id="login-panel">
|
|
<h2>Sign in to continue</h2>
|
|
<div class="tabs">
|
|
<button id="tab-login" class="active">Login</button>
|
|
<button id="tab-signup">Sign Up</button>
|
|
</div>
|
|
<div id="login-fields" class="form-group">
|
|
<input type="text" id="login-username" placeholder="Username">
|
|
<input type="password" id="login-password" placeholder="Password">
|
|
<button class="submit-btn" id="btn-login">Login</button>
|
|
<div id="auth-error"></div>
|
|
</div>
|
|
<div id="signup-fields" class="form-group hidden">
|
|
<input type="text" id="signup-username" placeholder="Username (min 3 chars)">
|
|
<input type="password" id="signup-password" placeholder="Password (min 6 chars)">
|
|
<button class="submit-btn" id="btn-signup">Sign Up</button>
|
|
<div id="signup-error"></div>
|
|
</div>
|
|
<div id="guest-section" class="hidden">
|
|
<div class="divider"><span>or</span></div>
|
|
<button class="guest-btn" id="btn-guest">Continue as Guest</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="player-content">
|
|
<div id="header-row">
|
|
<div id="auth-section">
|
|
<div class="user-info">
|
|
<span class="username" id="current-username"></span>
|
|
<span class="admin-badge" id="admin-badge" style="display:none;">Admin</span>
|
|
<button id="btn-kick-others" title="Disconnect all other devices">kick others</button>
|
|
<button id="btn-logout">logout</button>
|
|
</div>
|
|
</div>
|
|
<div id="stream-select"></div>
|
|
</div>
|
|
|
|
<div id="main-content">
|
|
<div id="channels-panel">
|
|
<div class="panel-header">
|
|
<h3>Channels</h3>
|
|
<button id="btn-new-channel" title="New channel">+</button>
|
|
</div>
|
|
<div id="channels-list"></div>
|
|
</div>
|
|
<div id="library-panel">
|
|
<div class="panel-header">
|
|
<h3>Library</h3>
|
|
<input type="text" id="library-search" placeholder="Search..." class="search-input">
|
|
</div>
|
|
<div id="library"></div>
|
|
</div>
|
|
<div id="queue-panel">
|
|
<h3 id="queue-title">Queue</h3>
|
|
<div id="queue"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="player-bar">
|
|
<div id="now-playing">
|
|
<div id="channel-name"></div>
|
|
<div id="track-name" class="empty">
|
|
<span class="marquee-inner"><span id="track-title">Loading...</span></span>
|
|
</div>
|
|
</div>
|
|
<div id="player-controls">
|
|
<div id="progress-row">
|
|
<span id="btn-sync" title="Toggle sync">sync</span>
|
|
<span id="btn-prev" title="Previous track">⏮</span>
|
|
<span id="status-icon">▶</span>
|
|
<span id="btn-next" title="Next track">⏭</span>
|
|
<span id="btn-mode" title="Playback mode">🔁</span>
|
|
<div id="progress-container"><div id="progress-bar"></div><div id="seek-tooltip"></div></div>
|
|
<div id="time"><span id="time-current">0:00</span>/<span id="time-total">0:00</span></div>
|
|
</div>
|
|
<div id="buffer-bar"></div>
|
|
<div id="download-speed"></div>
|
|
</div>
|
|
<div id="volume-controls">
|
|
<span id="btn-mute" title="Toggle mute">🔊</span>
|
|
<input type="range" id="volume" min="0" max="1" step="0.01" value="1">
|
|
</div>
|
|
</div>
|
|
<div id="status"></div>
|
|
</div>
|
|
<div id="toast-container"></div>
|
|
</div>
|
|
<script src="trackStorage.js"></script>
|
|
<script src="core.js"></script>
|
|
<script src="utils.js"></script>
|
|
<script src="audioCache.js"></script>
|
|
<script src="channelSync.js"></script>
|
|
<script src="ui.js"></script>
|
|
<script src="queue.js"></script>
|
|
<script src="controls.js"></script>
|
|
<script src="auth.js"></script>
|
|
<script src="init.js"></script>
|
|
</body>
|
|
</html>
|