From 6c6b55f3cc954cfaaea475e786d5760120890fe7 Mon Sep 17 00:00:00 2001 From: Luna Date: Mon, 25 May 2026 22:36:27 -0700 Subject: [PATCH] Shuffle button: play a random unwatched video MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🎲 button in the header picks a random video from {unwatched + downloaded + has video_url} and opens it directly in the player. Falls through to "any downloaded video" when everything is already watched, with a status message that lets the user know. Tartube has nothing like it — small bit of extra "surpass" beyond plain parity. Co-Authored-By: Claude Opus 4.7 --- src/web_ui/index.html | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/web_ui/index.html b/src/web_ui/index.html index f7ea09a..ed4a6cc 100644 --- a/src/web_ui/index.html +++ b/src/web_ui/index.html @@ -131,6 +131,7 @@ + @@ -870,6 +871,22 @@ async function rescan(){try{await api('/api/rescan',{method:'POST'});await loadL function findVideo(id){for(const ch of library)for(const v of[...ch.videos,...ch.playlists.flatMap(p=>p.videos)])if(v.id===id)return v;return null} /* ── Player ─────────────────────────────────────────────────────── */ +// Pick a random unwatched, downloaded video from the whole library and +// open it in the player. Falls back to "any unwatched" if nothing's +// downloaded yet, and finally to "any video" if everything's watched. +function shufflePlay(){ + const all=library.flatMap(ch=>[...ch.videos,...ch.playlists.flatMap(p=>p.videos)]); + const pickFrom=arr=>arr[Math.floor(Math.random()*arr.length)]; + const pool=all.filter(v=>!v.watched&&v.has_video&&v.video_url); + let pick; + if(pool.length){pick=pickFrom(pool)} + else{ + const downloaded=all.filter(v=>v.has_video&&v.video_url); + if(downloaded.length){pick=pickFrom(downloaded);setStatus('Everything is watched — playing a random one anyway')} + else{setStatus('No downloaded videos to shuffle from');return} + } + playVideo(pick.id); +} function playVideo(id){ const v=findVideo(id);if(!v||!v.video_url)return; currentPlayingId=id;