;;; livie-playlist.el --- Auxiliary mode to display playlist results ;; Copyright (C) 2018 - 2021 ;;; Authors: ;; Charlie Ritter ;; Jesus E. ;; Gabriele Rastello ;; Pablo BC ;;; Commentary: ;; livie grabs a list of youtube videos based on a search. ;; the user can then select a video to watch through `livie-player' ;;; Code: (defvar livie-playlist-mode-map (let ((map (make-sparse-keymap))) (set-keymap-parent map text-mode-map) (define-key map "h" #'describe-mode) (define-key map "q" #'livie--quit-playlist-buffer) (define-key map ">" #'livie-playlist-next-page) (define-key map "<" #'livie-playlist-previous-page) (define-key map (kbd "") #'next-line) (define-key map (kbd "") #'previous-line) (define-key map "A" #'livie--open-channel) (define-key map (kbd "RET") #'livie-open-entry) (define-key map "y" #'livie-watch-this-video) map) "Keymap for `livie-playlist-mode'.") (define-derived-mode livie-playlist-mode livie-mode "livie-playlist-mode" "Mode for displaying livie-playlists. \\{livie-playlist-mode-map}" (buffer-disable-undo) (make-local-variable 'livie-videos) (make-local-variable 'livie-playlist-title) (make-local-variable 'livie-playlistId) (setq-local livie-type-of-results "video") (setf buffer-read-only t)) (defun livie--process-playlist-videos (videos) "Process VIDEOS fetched from a playlist." (dotimes (i (length videos)) (let* ((v (aref videos i))) (aset videos i (livie-video--create :title (assoc-default 'title v) :author (assoc-default 'author v) :authorId (assoc-default 'authorId v) :length (assoc-default 'lengthSeconds v) :id (assoc-default 'videoId v))))) videos) (defun livie-playlist--insert-entry (video) "Insert VIDEO into the playlist buffer." (insert (livie--format-author (livie-video-author video)) " " (livie--format-video-length (livie-video-length video)) " " (livie--format-title (livie-video-title video)))) (defun livie--get-playlist-videos () "Fetch the videos of the current playlist." (let* ((entry (livie-get-current-video))) (if (livie-playlist-p entry) (progn (switch-to-buffer (livie-playlist-title entry)) (unless (eq major-mode 'livie-playlist-mode) (livie-playlist-mode)) (setf livie-playlistId (livie-playlist-playlistId entry)) (setf livie-playlist-title (livie-playlist-title entry)) (livie-playlist--query livie-playlistId livie-current-page) (livie-playlist--draw-buffer))))) (defun livie-playlist-previous-page () "Go to the previous page of playlist." (interactive) (setf livie-current-page (1- livie-current-page)) (livie-playlist--query livie-playlistId livie-current-page) (livie-playlist--draw-buffer)) (defun livie-playlist-next-page () "Go to the next page of playlist." (interactive) (setf livie-current-page (1+ livie-current-page)) (livie-playlist--query livie-playlistId livie-current-page) (livie-playlist--draw-buffer)) (defun livie-playlist--draw-buffer () "Draw buffer for the current playlist." (let ((inhibit-read-only t)) (erase-buffer) (setq header-line-format (concat "Displaying videos from " (propertize livie-playlist-title 'face 'livie-parameter-face) ", page " (propertize (number-to-string livie-current-page) 'face 'livie-parameter-face))) (seq-do (lambda (v) (livie-playlist--insert-entry v) (insert "\n")) livie-videos) (goto-char (point-min)))) (defun livie-playlist--query (playlistID page) "Query Invidious for videos from PLAYLISTID on PAGE." (let* ((results (livie--API-call (concat "playlists/" livie-playlistId) '(("fields" "videos") ("page" ,livie-current-page))))) (setf livie-videos (livie--process-playlist-videos (assoc-default 'videos results))))) (defun livie--quit-playlist-buffer () "Deletes the current buffer." (interactive) (kill-buffer (current-buffer))) (provide 'livie-playlist) ;;; livie-playlist.el ends here