From 9c5be2ea4fc2c3951d6ea60108907d7b588782ba Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Thu, 28 Nov 2024 15:52:54 +0100 Subject: [PATCH] Add playlist jumping. --- src/templates/playlist.tmpl | 26 ++++++++++++++++++-------- src/ytplom/misc.py | 33 +++++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/templates/playlist.tmpl b/src/templates/playlist.tmpl index b25d131..977c65d 100644 --- a/src/templates/playlist.tmpl +++ b/src/templates/playlist.tmpl @@ -29,8 +29,8 @@ window.onload = keep_updated; {% block css %} -#status { text-align: center; font-weight: bold; } table { width: 100%; } +#status { text-align: center; font-weight: bold; } th { text-align: center; } td { vertical-align: top; } td.history { width: 50%; } @@ -49,21 +49,31 @@ td.history { width: 50%; } - pastfuture - + +{% for idx, file in prev_files_w_idx %} + + + + +{% endfor %} +
{{ file.basename }}
- + +{% for idx, file in next_files_w_idx %} + + + + +{% endfor %} +
{{ file.basename }}
+ {% endblock %} diff --git a/src/ytplom/misc.py b/src/ytplom/misc.py index e5f3c6f..339c97c 100644 --- a/src/ytplom/misc.py +++ b/src/ytplom/misc.py @@ -47,11 +47,12 @@ PlayerUpdateId = NewType('PlayerUpdateId', str) B64Str = NewType('B64Str', str) PageNames: TypeAlias = dict[str, PathStr] DownloadsIndex: TypeAlias = dict[YoutubeId, PathStr] +FilesWithIndex: TypeAlias = list[tuple[int, 'VideoFile']] TemplateContext: TypeAlias = dict[ str, None | bool - | PageNames | PathStr | PlayerUpdateId | QueryText | QuotaCost - | 'VideoFile' | YoutubeId | 'YoutubeVideo' + | FilesWithIndex | PageNames | PathStr | PlayerUpdateId | QueryText + | QuotaCost | 'VideoFile' | YoutubeId | 'YoutubeVideo' | list[FlagName] | list['VideoFile'] | list['YoutubeVideo'] | list['YoutubeQuery'] ] @@ -491,8 +492,8 @@ class Player: @staticmethod def _if_mpv_available(f) -> Callable: - def wrapper(self): - return f(self) if self._mpv else None + def wrapper(self, *args, **kwargs): + return f(self, *args, **kwargs) if self._mpv else None return wrapper def _signal_update(self) -> None: @@ -534,14 +535,18 @@ class Player: return self._files[self._idx] @property - def prev_files(self) -> list[VideoFile]: + def _files_w_idx(self) -> FilesWithIndex: + return list(enumerate(self._files)) + + @property + def prev_files_w_idx(self) -> FilesWithIndex: """List 'past' files of playlist.""" - return list(reversed(self._files[:self._idx])) + return list(reversed(self._files_w_idx[:self._idx])) @property - def next_files(self) -> list[VideoFile]: + def next_files_w_idx(self) -> FilesWithIndex: """List 'coming' files of playlist.""" - return self._files[self._idx + 1:] + return self._files_w_idx[self._idx + 1:] @property def is_running(self) -> bool: @@ -590,6 +595,12 @@ class Player: else: self._mpv.command('playlist-play-index', max_idx) + @_if_mpv_available + def jump_to(self, target_idx: int) -> None: + """Move player to target_idx position in playlist.""" + assert self._mpv is not None + self._mpv.command('playlist-play_index', target_idx) + def reload(self) -> None: """Close MPV, re-read (and re-shuffle) filenames, then re-start MPV.""" self._kill_mpv() @@ -732,6 +743,8 @@ class TaskHandler(BaseHTTPRequestHandler): self.server.player.toggle_run() elif 'reload' == command: self.server.player.reload() + elif command.startswith('jump_'): + self.server.player.jump_to(int(command.split('_')[1])) sleep(0.5) # avoid redir happening before current_file update self._redirect(PathStr('/')) @@ -944,5 +957,5 @@ class TaskHandler(BaseHTTPRequestHandler): 'running': self.server.player.is_running, 'paused': self.server.player.is_paused, 'current_video': self.server.player.current_file, - 'prev_files': self.server.player.prev_files, - 'next_files': self.server.player.next_files}) + 'prev_files_w_idx': self.server.player.prev_files_w_idx, + 'next_files_w_idx': self.server.player.next_files_w_idx}) -- 2.30.2