summaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-06 07:59:29 +0300
committerPaul Buetow <paul@buetow.org>2026-05-06 07:59:29 +0300
commit532747899cb6db7e5208a454779c37092c8c6451 (patch)
tree878316162207ed91d4cf115a20a9ef7dd255ef78 /web
parent5e1d54ecc9182abf3fd77ffa0e28f5f51b43f372 (diff)
Add 'R' hotkey to play a random track from the current media list
Diffstat (limited to 'web')
-rw-r--r--web/index.html1
-rw-r--r--web/js/app.js15
-rw-r--r--web/js/keyboard.js4
3 files changed, 20 insertions, 0 deletions
diff --git a/web/index.html b/web/index.html
index 4b90f92..b2c3ca6 100644
--- a/web/index.html
+++ b/web/index.html
@@ -121,6 +121,7 @@
<div class="help-row"><span><kbd>Enter</kbd></span><span>Open selected item</span></div>
<div class="help-row"><span><kbd>Space</kbd> <kbd>p</kbd></span><span>Play / pause</span></div>
<div class="help-row"><span><kbd>N</kbd> <kbd>P</kbd></span><span>Next / previous track</span></div>
+ <div class="help-row"><span><kbd>R</kbd></span><span>Play random track</span></div>
<div class="help-row"><span><kbd>i</kbd></span><span>Show / hide media info</span></div>
<div class="help-row"><span><kbd>n</kbd></span><span>Open notes</span></div>
<div class="help-row"><span><kbd>f</kbd></span><span>Toggle fullscreen</span></div>
diff --git a/web/js/app.js b/web/js/app.js
index 13cc824..7c824e5 100644
--- a/web/js/app.js
+++ b/web/js/app.js
@@ -131,6 +131,7 @@ async function initApp() {
playPause: () => togglePlay(),
nextTrack: () => navigatePlayable(1),
prevTrack: () => navigatePlayable(-1),
+ playRandom: () => playRandom(),
mediaInfo: () => toggleMediaInfo(),
fullscreen: () => toggleFullscreen(),
toggleMinimize: () => toggleMinimize(),
@@ -621,6 +622,20 @@ async function playSelected() {
}
}
+async function playRandom() {
+ if (!state.media.length) return;
+ const idx = Math.floor(Math.random() * state.media.length);
+ const media = state.media[idx];
+ if (!media) return;
+ try {
+ const detail = await API.mediaDetail(media.id);
+ const resumeFrom = detail?.progress?.position_seconds ?? 0;
+ selectAndPlay(media, idx, resumeFrom);
+ } catch {
+ selectAndPlay(media, idx, 0);
+ }
+}
+
function visiblePlayableCards() {
return Array.from(document.querySelectorAll('#media-grid .media-card[data-id], #media-grid .media-row[data-id]'));
}
diff --git a/web/js/keyboard.js b/web/js/keyboard.js
index dc3eb4e..d1f9ee7 100644
--- a/web/js/keyboard.js
+++ b/web/js/keyboard.js
@@ -218,6 +218,10 @@ export function initKeyboard(handlers) {
case 'Escape': handlers.escape?.(e); break;
case 'Backspace': handlers.backspace?.(e); break;
case 'r': handlers.shuffle?.(e); break;
+ case 'R':
+ e.preventDefault();
+ handlers.playRandom?.(e);
+ break;
// Note: 's' / 'S' are handled above by the e.code === 'KeyS' block
case '/':
e.preventDefault();