multi player / per user playing and translation

This commit is contained in:
2026-08-28 16:53:05 +02:00
parent 2743dfb4c0
commit e10f2cf7d7
17 changed files with 1432 additions and 482 deletions
+48 -41
View File
@@ -1,5 +1,5 @@
<!doctype html>
<html lang="nl">
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
@@ -16,23 +16,26 @@
</div>
<div class="output-control">
<label for="renderer">UITVOER</label>
<label for="renderer" data-i18n="output">OUTPUT</label>
<select id="renderer"></select>
<button id="discover" class="square-button" type="button" title="Netwerkspelers zoeken" aria-label="Netwerkspelers zoeken"></button>
<button id="logout" class="text-button" type="button" hidden>UITLOGGEN</button>
<button id="discover" class="square-button" type="button" data-i18n-title="searchPlayers" title="Search for network players" aria-label="Search for network players"></button>
<select id="language" class="language-select" aria-label="Language">
<option value="en">EN</option><option value="nl">NL</option><option value="de">DE</option><option value="fr">FR</option><option value="es">ES</option>
</select>
<button id="logout" class="text-button" type="button" data-i18n="logout" data-i18n-aria="logout" aria-label="Log out" hidden>LOG OUT</button>
</div>
</header>
<section class="transport-bar" aria-label="Afspeelbediening">
<section class="transport-bar" data-i18n-aria="playbackControls" aria-label="Playback controls">
<div class="transport-buttons">
<button id="previous" class="command-button" type="button" aria-label="Vorige track"></button>
<button id="play" class="command-button play-button" type="button" aria-label="Afspelen of pauzeren"></button>
<button id="stop" class="command-button" type="button" aria-label="Stoppen"></button>
<button id="next" class="command-button" type="button" aria-label="Volgende track"></button>
<button id="previous" class="command-button" type="button" data-i18n-aria="previousTrack" aria-label="Previous track"></button>
<button id="play" class="command-button play-button" type="button" data-i18n-aria="playOrPause" aria-label="Play or pause"></button>
<button id="stop" class="command-button" type="button" data-i18n-aria="stop" aria-label="Stop"></button>
<button id="next" class="command-button" type="button" data-i18n-aria="nextTrack" aria-label="Next track"></button>
</div>
<div class="seek-control">
<input id="seek" type="range" min="0" max="100" value="0" step="0.1" aria-label="Afspeelpositie">
<input id="seek" type="range" min="0" max="100" value="0" step="0.1" data-i18n-aria="playbackPosition" aria-label="Playback position">
<div class="time-display">
<span id="position">00:00:00</span>
<span class="time-divider">/</span>
@@ -40,12 +43,15 @@
</div>
</div>
<button id="repeat" class="command-button repeat-button" type="button" aria-label="Herhaalmodus"></button>
<label class="volume-control" for="volume">
<span aria-hidden="true">VOL</span>
<input id="volume" type="range" min="0" max="100" value="50">
<output id="volume-value">50%</output>
</label>
<button id="repeat" class="command-button repeat-button" type="button" data-i18n-aria="repeatMode" aria-label="Repeat mode"></button>
<div id="volume-control" class="volume-control">
<button id="volume-toggle" class="volume-toggle" type="button" data-i18n-aria="setVolume" aria-label="Set volume" aria-controls="volume-slider" aria-expanded="false">VOL</button>
<label id="volume-slider" class="volume-slider" for="volume">
<span aria-hidden="true">VOL</span>
<input id="volume" type="range" min="0" max="100" value="50" data-i18n-aria="volume" aria-label="Volume">
<output id="volume-value">50%</output>
</label>
</div>
</section>
<section class="workspace">
@@ -53,17 +59,17 @@
<section class="library-pane panel">
<div class="panel-header library-header">
<div>
<span class="panel-kicker">MUZIEKBIBLIOTHEEK</span>
<select id="library" aria-label="Muziekbibliotheek"></select>
<span class="panel-kicker" data-i18n="musicLibrary">MUSIC LIBRARY</span>
<select id="library" data-i18n-aria="musicLibrary" aria-label="Music library"></select>
</div>
<button id="library-up" class="square-button" type="button" title="Eén map omhoog" aria-label="Eén map omhoog"></button>
<button id="library-up" class="square-button" type="button" data-i18n-title="upFolder" title="Up one folder" aria-label="Up one folder"></button>
</div>
<nav id="breadcrumb" class="breadcrumb" aria-label="Huidige map"></nav>
<nav id="breadcrumb" class="breadcrumb" data-i18n-aria="currentFolder" aria-label="Current folder"></nav>
<div id="library-empty" class="empty-state" hidden>
<p>Geen bibliotheek geconfigureerd.</p>
<p data-i18n="noLibraryConfigured">No library configured.</p>
<code>[libraries] muziek=D:\Muziek</code>
</div>
<ul id="library-entries" class="library-list" aria-label="Mapinhoud"></ul>
<ul id="library-entries" class="library-list" data-i18n-aria="folderContents" aria-label="Folder contents"></ul>
</section>
<section class="now-playing-pane panel">
@@ -75,30 +81,30 @@
<img id="cover-image" alt="" hidden>
</div>
<div class="track-summary">
<span class="panel-kicker">NU AAN HET SPELEN</span>
<h1 id="now-title">Nog niets gekozen</h1>
<p id="now-meta">Voeg een track toe vanuit de bibliotheek</p>
<span class="panel-kicker" data-i18n="nowPlaying">NOW PLAYING</span>
<h1 id="now-title" data-i18n="nothingSelected">Nothing selected yet</h1>
<p id="now-meta" data-i18n="addTrackHint">Add a track from the library</p>
</div>
</section>
</aside>
<section class="playlist-pane panel">
<div class="tabs-bar">
<div id="tabs" class="tabs" role="tablist" aria-label="Afspeellijsten"></div>
<button id="tab-add" class="tab-add" type="button" title="Nieuwe afspeellijst" aria-label="Nieuwe afspeellijst"></button>
<div id="tabs" class="tabs" role="tablist" data-i18n-aria="playlists" aria-label="Playlists"></div>
<button id="tab-add" class="tab-add" type="button" data-i18n-title="newPlaylist" title="New playlist" aria-label="New playlist"></button>
</div>
<div class="playlist-toolbar">
<div>
<span class="panel-kicker">AFSPEELLIJST</span>
<span class="panel-kicker" data-i18n="playlist">PLAYLIST</span>
<strong id="track-count">0 tracks</strong>
</div>
<button id="playlist-clear" class="text-button" type="button">LIJST WISSEN</button>
<button id="playlist-clear" class="text-button" type="button" data-i18n="clearList">CLEAR LIST</button>
</div>
<div id="playlist-empty" class="empty-state playlist-empty">
<p>Deze afspeellijst is leeg.</p>
<span>Gebruik <strong></strong> bij een track of map.</span>
<p data-i18n="emptyPlaylist">This playlist is empty.</p>
<span data-i18n="emptyPlaylistHint">Use next to a track or folder.</span>
</div>
<div class="playlist-scroll">
@@ -106,10 +112,10 @@
<thead>
<tr>
<th class="number-column">#</th>
<th>TITEL</th>
<th>ALBUM</th>
<th class="duration-column">DUUR</th>
<th class="action-column"><span class="visually-hidden">Acties</span></th>
<th data-i18n="title">TITLE</th>
<th data-i18n="album">ALBUM</th>
<th class="duration-column" data-i18n="duration">DURATION</th>
<th class="action-column"><span class="visually-hidden" data-i18n="actions">Actions</span></th>
</tr>
</thead>
<tbody id="playlist"></tbody>
@@ -122,11 +128,11 @@
<div class="audio-status">
<span id="audio-bits">— bit</span>
<span id="audio-rate">— kHz</span>
<span id="audio-channels">kanalen</span>
<span id="audio-channels">channels</span>
<span id="audio-format"></span>
<span id="audio-source"></span>
</div>
<p id="status" role="status" aria-live="polite">Verbinden</p>
<p id="status" role="status" aria-live="polite" data-i18n="connecting">Connecting</p>
</footer>
</main>
@@ -134,16 +140,17 @@
<form id="login-form" class="login-panel">
<span class="brand-mark">RKT</span>
<p class="panel-kicker">WEB PLAYER</p>
<h1 id="login-title">Aanmelden</h1>
<label for="login-username">Gebruikersnaam</label>
<h1 id="login-title" data-i18n="signIn">Sign in</h1>
<label for="login-username" data-i18n="username">Username</label>
<input id="login-username" name="username" autocomplete="username" required>
<label for="login-password">Wachtwoord</label>
<label for="login-password" data-i18n="password">Password</label>
<input id="login-password" name="password" type="password" autocomplete="current-password" required>
<p id="login-error" class="login-error" role="alert"></p>
<button id="login-submit" class="text-button" type="submit">AANMELDEN</button>
<button id="login-submit" class="text-button" type="submit" data-i18n="signIn">Sign in</button>
</form>
</section>
<script src="/translate.js" defer></script>
<script src="/app.js" defer></script>
</body>
</html>