home · contact · privacy
In /playlist add buttons to control playing entry too. master
authorPlom Heller <plom@plomlompom.com>
Thu, 12 Mar 2026 02:19:53 +0000 (03:19 +0100)
committerPlom Heller <plom@plomlompom.com>
Thu, 12 Mar 2026 02:19:53 +0000 (03:19 +0100)
src/templates/_base.js
src/templates/playlist.html
src/templates/playlist.js
src/ytplom/http.py
src/ytplom/misc.py

index 0aa2c25439d9ec4b1585783670bd31f659d6e8ee..d83b0da72485265f714bbc945942fa4bde1927e5 100644 (file)
@@ -89,6 +89,10 @@ export const
     ],
     CMD_ADD_NEXT = "inject",
     CMD_ADD_PLAY = "injectplay",
+    CMD_PAUSE = "pause",
+    CMD_PLAY = "play",
+    CMD_PREV = "prev",
+    CMD_NEXT = "next",
     CMD_RM = "rm",
     IDX_PATH_ID = 2,
     IDX_START = 0,
@@ -359,16 +363,16 @@ eventHandlers.player = (
         );
     playerDiv.innerHTML = "";
     addPlayerBtnToDiv(
-        "prev",
-        "prev"
+        CMD_PREV,
+        CMD_PREV,
     );
     addPlayerBtnToDiv(
-        "next",
-        "next"
+        CMD_NEXT,
+        CMD_NEXT,
     );
     addPlayerBtnToDiv(
-        data.is_playing ? "pause" : "play",
-        "play"
+        data.is_playing ? CMD_PAUSE : CMD_PLAY,
+        CMD_PLAY
     );
     addSeparator();
     addTextToDiv(
index 3f553311c5223af8820e64f0c75437ef9e19511a..c032ae0ae64f5078db412a4c90404ee419e82e45 100644 (file)
@@ -8,6 +8,10 @@ html {
 td.entry_control {
     width: 6em;
 }
+tr.playing td, tr.playing a {
+    background-color: black;
+    color: white;
+}
 {% endblock %}
 
 
index 890e0d449ffb6bcd0f37f49aef6f05374f0cdd41..dbb65d7476b8714bf54e1e19f4f88619c83bd0ff 100644 (file)
@@ -14,18 +14,24 @@ eslint
 ],
 "max-lines-per-function": [
     "error",
-    51
+    53
 ],
 "max-statements": [
     "error",
-    12
+    13
+],
+"multiline-ternary": [
+    "error",
+    "always-multiline"
 ],
 "newline-after-var": "off",
 "no-inline-comments": "off",
+"no-nested-ternary": "off",
 "no-multi-spaces": [
     "error",
     { "ignoreEOLComments": true }
 ],
+"no-ternary": "off",
 "padded-blocks": [
     "error",
     "never"
@@ -33,6 +39,7 @@ eslint
  */
 import {
     BUTTONS_UP_DOWN,
+    CMD_PLAY,
     CMD_RM,
     PATH_PREFIX_FILE,
     SYMBOL_RM,
@@ -48,9 +55,11 @@ import {
 } from "./_base.js";
 
 const
+    BTN_PAUSE = "||",
+    BTN_PLAY = ">",
     BUTTONS_ENTRY = [
         [
-            ">",
+            BTN_PLAY,
             "jump"
         ]
     ].concat(BUTTONS_UP_DOWN).concat([
@@ -64,6 +73,7 @@ const
         "rebuild"
     ],
     CLS_ENTRY_CTL = "entry_control",
+    CLS_PLAYING_ROW = "playing",
     CLS_PLAYLIST_ROW = "playlist_row",
     ID_TABLE = `${CLS_PLAYLIST_ROW}s`,
     PARAM_PLAYLIST = "playlist",
@@ -95,31 +105,33 @@ eventHandlers.playlist = (
             );
             const tdEntryControl = addTdTo(tr);
             tdEntryControl.classList.add(CLS_ENTRY_CTL);
+            for (
+                const [
+                    symbol,
+                    prefix
+                ] of BUTTONS_ENTRY
+            ) {
+                const isBtnPlaying = symbol === BTN_PLAY && idx === update.idx;
+                addPlayerBtnTo(
+                    tdEntryControl,
+                    isBtnPlaying
+                        ? update.is_playing ? BTN_PAUSE : BTN_PLAY
+                        : symbol,
+                    isBtnPlaying ? CMD_PLAY : `${prefix}_${idx}`
+                );
+            }
             addATdTo(
                 tr,
                 file.rel_path,
                 `${PATH_PREFIX_FILE}${file.digest}`
             );
             if (idx === update.idx) { // currently playing
-                tdEntryControl.textContent = TOK_PLAYING;
+                tr.classList.add(CLS_PLAYING_ROW);
                 tdEntryControl.id = TOK_PLAYING;
                 if (firstLoad) {        // replace anchor jump to #playing
                     firstLoad = false;  // (initially un-built, won"t work)
                     tdEntryControl.scrollIntoView({"block": "center"});
                 }
-            } else { // only non-playing items get playlist manip. buttons
-                for (
-                    const [
-                        symbol,
-                        prefix
-                    ] of BUTTONS_ENTRY
-                ) {
-                    addPlayerBtnTo(
-                        tdEntryControl,
-                        symbol,
-                        `${prefix}_${idx}`
-                    );
-                }
             }
         }
     );
index f4c3ad95dfb6608dd72e039d2d1ef4d3b93b0615..28041766d623ce4174d8cc9bab36047b8c732293 100644 (file)
@@ -292,7 +292,8 @@ class _TaskHandler(PlomHttpHandler):
                         'playlist_files': [
                             {'rel_path': str(f.rel_path),
                              'digest': f.digest.b64}
-                            for f in self.server.player.playlist]
+                            for f in self.server.player.playlist],
+                        'is_playing': self.server.player.is_playing,
                     }
             if 'download' in subscriptions:
                 yt_id = YoutubeId(download_id)
index bdd79a93bcecbf529b78bf9fb64f4773be8b7d86..efd389a9dfb7a1e0e400f1153918e74225fdacb8 100644 (file)
@@ -798,6 +798,9 @@ class Player:
 
     def move_entry(self, start_idx: int, upwards: bool = True) -> None:
         """Move playlist entry at start_idx up or down one step."""
+        if start_idx == self._idx:
+            start_idx += -1 if upwards else 1
+            upwards = not upwards
         i0, i1 = start_idx, start_idx + (-1 if upwards else 1)
         if i1 < 0 or i1 >= len(self.playlist):
             return