From a5acdf57d92fcd09957693a5da1a476c191dcaf0 Mon Sep 17 00:00:00 2001
From: Christian Heller <c.heller@plomlompom.de>
Date: Thu, 28 Nov 2024 17:32:13 +0100
Subject: [PATCH] Add up/down movement of playlist entries.

---
 src/templates/playlist.tmpl | 41 +++++++++++++++++++------------------
 src/ytplom/misc.py          | 21 +++++++++++++++++++
 2 files changed, 42 insertions(+), 20 deletions(-)

diff --git a/src/templates/playlist.tmpl b/src/templates/playlist.tmpl
index 977c65d..3a6e44c 100644
--- a/src/templates/playlist.tmpl
+++ b/src/templates/playlist.tmpl
@@ -34,9 +34,28 @@ table { width: 100%; }
 th { text-align: center; }
 td { vertical-align: top; }
 td.history { width: 50%; }
+td.entry_buttons { width: 5em; }
 {% endblock %}
 
 
+{% macro playlist_entries(files_w_idx, reverse) %}
+<td class="history">
+<table>
+{% for idx, file in files_w_idx %}
+<tr>
+<td class="entry_buttons">
+<input type="submit" name="jump_{{idx}}" value=">" />
+<input type="submit" name="up_{{idx}}" value="{% if reverse %}v{% else %}^{% endif %}" />
+<input type="submit" name="down_{{idx}}" value="{% if reverse %}^{% else %}v{% endif %}" />
+</td>
+<td><a href="/{{page_names.file}}/{{file.rel_path_b64}}">{{ file.basename }}</a></td>
+</tr>
+{% endfor %}
+</table>
+</td>
+{% endmacro %}
+
+
 {% block body %}
 {{ macros.nav_head(page_names, "playlist") }}
 <table>
@@ -52,26 +71,8 @@ td.history { width: 50%; }
 </td></tr>
 <tr><th>past</th><th>future</th></tr>
 <tr>
-<td class="history">
-<table>
-{% for idx, file in prev_files_w_idx %}
-<tr>
-<td><input type="submit" name="jump_{{idx}}" value=">" /></td>
-<td><a href="/{{page_names.file}}/{{file.rel_path_b64}}">{{ file.basename }}</a></td>
-</tr>
-{% endfor %}
-</table>
-</td>
-<td class="history">
-<table>
-{% for idx, file in next_files_w_idx %}
-<tr>
-<td><input type="submit" name="jump_{{idx}}" value=">" /></td>
-<td><a href="/{{page_names.file}}/{{file.rel_path_b64}}">{{ file.basename }}</a></td>
-</tr>
-{% endfor %}
-</table>
-</td>
+{{ playlist_entries(prev_files_w_idx, reverse=true) }}
+{{ playlist_entries(next_files_w_idx, reverse=false) }}
 </tr>
 </form>
 </table>
diff --git a/src/ytplom/misc.py b/src/ytplom/misc.py
index 8409aee..4d544ba 100644
--- a/src/ytplom/misc.py
+++ b/src/ytplom/misc.py
@@ -583,6 +583,23 @@ class Player:
         if self._mpv:
             self._mpv.command('playlist-play-index', self._idx)
 
+    def move_entry(self, start_idx: int, upwards=True) -> None:
+        """Move playlist entry at start_idx up or down one step."""
+        if (start_idx == self._idx
+                or (upwards and start_idx == self._idx + 1)
+                or ((not upwards) and start_idx == self._idx - 1)
+                or (upwards and start_idx < 1)
+                or ((not upwards) and start_idx > len(self._files) - 2)):
+            return
+        i0, i1 = start_idx, start_idx + (-1 if upwards else 1)
+        if self._mpv:
+            # NB: a functional playlist-move would do this in a single step,
+            # but for some reason I don't seem to get it to do anything
+            path = self._files[i1].full_path
+            self._mpv.command('playlist-remove', i1)
+            self._mpv.command('loadfile', path, 'insert-at', i0)
+        self._files[i0], self._files[i1] = self._files[i1], self._files[i0]
+
     def reload(self) -> None:
         """Close MPV, re-read (and re-shuffle) filenames, then re-start MPV."""
         self._kill_mpv()
@@ -727,6 +744,10 @@ class TaskHandler(BaseHTTPRequestHandler):
             self.server.player.reload()
         elif command.startswith('jump_'):
             self.server.player.jump_to(int(command.split('_')[1]))
+        elif command.startswith('up'):
+            self.server.player.move_entry(int(command.split('_')[1]))
+        elif command.startswith('down_'):
+            self.server.player.move_entry(int(command.split('_')[1]), False)
         sleep(0.5)  # avoid redir happening before current_file update
         self._redirect(PathStr('/'))
 
-- 
2.30.2