My personal dotfiles
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

spotify-playlist-search.el 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. ;; spotify-playlist-search.el --- Spotify.el playlist search major mode
  2. ;; Copyright (C) 2014-2016 Daniel Fernandes Martins
  3. ;; Code:
  4. (require 'spotify-api)
  5. (defvar spotify-playlist-search-mode-map
  6. (let ((map (make-sparse-keymap)))
  7. (set-keymap-parent map tabulated-list-mode-map)
  8. (define-key map (kbd "RET") 'spotify-playlist-select)
  9. (define-key map (kbd "t") 'spotify-playlist-tracks)
  10. (define-key map (kbd "l") 'spotify-playlist-load-more)
  11. (define-key map (kbd "g") 'spotify-playlist-reload)
  12. (define-key map (kbd "f") 'spotify-playlist-follow)
  13. (define-key map (kbd "u") 'spotify-playlist-unfollow)
  14. map)
  15. "Local keymap for `spotify-playlist-search-mode' buffers.")
  16. ;; Enables the `spotify-remote-mode' the track search buffer
  17. (add-hook 'spotify-playlist-search-mode-hook 'spotify-remote-mode)
  18. (define-derived-mode spotify-playlist-search-mode tabulated-list-mode "Playlist-Search"
  19. "Major mode for displaying the playlists returned by a Spotify search.")
  20. (defun spotify-playlist-select ()
  21. "Plays the playlist under the cursor."
  22. (interactive)
  23. (let ((selected-playlist (tabulated-list-get-id)))
  24. (spotify-play-track nil selected-playlist)))
  25. (defun spotify-playlist-reload ()
  26. "Reloads the first page of results for the current playlist view."
  27. (interactive)
  28. (let ((page 1))
  29. (cond ((bound-and-true-p spotify-query) (spotify-playlist-search-update page))
  30. ((bound-and-true-p spotify-browse-message) (spotify-featured-playlists-update page))
  31. (t (spotify-user-playlists-update spotify-user-id page)))))
  32. (defun spotify-playlist-load-more ()
  33. "Loads the next page of results for the current playlist view."
  34. (interactive)
  35. (let ((next-page (1+ spotify-current-page)))
  36. (cond ((bound-and-true-p spotify-query) (spotify-playlist-search-update next-page))
  37. ((bound-and-true-p spotify-browse-message) (spotify-featured-playlists-update next-page))
  38. (t (spotify-user-playlists-update spotify-user-id next-page)))))
  39. (defun spotify-playlist-follow ()
  40. "Adds the current user as the follower of the playlist under the cursor."
  41. (interactive)
  42. (let* ((selected-playlist (tabulated-list-get-id))
  43. (name (spotify-get-item-name selected-playlist)))
  44. (when (and (y-or-n-p (format "Follow playlist '%s'?" name))
  45. (spotify-api-playlist-follow selected-playlist))
  46. (message (format "Followed playlist '%s'" name)))))
  47. (defun spotify-playlist-unfollow ()
  48. "Removes the current user as the follower of the playlist under the cursor."
  49. (interactive)
  50. (let* ((selected-playlist (tabulated-list-get-id))
  51. (name (spotify-get-item-name selected-playlist)))
  52. (when (and (y-or-n-p (format "Unfollow playlist '%s'?" name))
  53. (spotify-api-playlist-unfollow selected-playlist))
  54. (message (format "Unfollow playlist '%s'" name)))))
  55. (defun spotify-playlist-search-update (current-page)
  56. "Fetches the given page of results using the search endpoint."
  57. (let* ((json (spotify-api-search 'playlist spotify-query current-page))
  58. (items (spotify-get-search-playlist-items json)))
  59. (if items
  60. (progn
  61. (spotify-playlist-search-print items current-page)
  62. (message "playlist view updated"))
  63. (message "No more playlists"))))
  64. (defun spotify-user-playlists-update (user-id current-page)
  65. "Fetches the given page of results using the user's playlist endpoint."
  66. (let* ((json (spotify-api-user-playlists user-id current-page))
  67. (items (spotify-get-items json)))
  68. (if items
  69. (progn
  70. (spotify-playlist-search-print items current-page)
  71. (message "Playlist view updated"))
  72. (message "No more playlists"))))
  73. (defun spotify-featured-playlists-update (current-page)
  74. "Fetches the given page of results of Spotify's featured playlists."
  75. (let* ((json (spotify-api-featured-playlists current-page))
  76. (msg (spotify-get-message json))
  77. (items (spotify-get-search-playlist-items json)))
  78. (if items
  79. (progn
  80. (spotify-playlist-search-print items current-page)
  81. (setq-local spotify-browse-message msg)
  82. (message msg))
  83. (message "No more playlists"))))
  84. (defun spotify-playlist-tracks ()
  85. "Displays the tracks that belongs to the playlist under the cursor."
  86. (interactive)
  87. (let* ((selected-playlist (tabulated-list-get-id))
  88. (name (spotify-get-item-name selected-playlist)))
  89. (let ((buffer (get-buffer-create (format "*Playlist Tracks: %s*" name))))
  90. (with-current-buffer buffer
  91. (spotify-track-search-mode)
  92. (spotify-track-search-set-list-format)
  93. (setq-local spotify-selected-playlist selected-playlist)
  94. (spotify-playlist-tracks-update 1)
  95. (pop-to-buffer buffer)
  96. buffer))))
  97. (defun spotify-playlist-set-list-format ()
  98. "Configures the column data for the typical playlist view."
  99. (setq tabulated-list-format
  100. (vector `("Playlist Name" ,(- (window-width) 45) t)
  101. '("Owner Id" 30 t)
  102. '("# Tracks" 8 (lambda (row-1 row-2)
  103. (< (spotify-get-playlist-track-count (first row-1))
  104. (spotify-get-playlist-track-count (first row-2)))) :right-align t))))
  105. (defun spotify-playlist-search-print (playlists current-page)
  106. "Appends the given playlists to the current playlist view."
  107. (let (entries)
  108. (dolist (playlist playlists)
  109. (let ((user-id (spotify-get-playlist-owner-id playlist))
  110. (playlist-name (spotify-get-item-name playlist)))
  111. (push (list playlist
  112. (vector playlist-name
  113. (cons user-id
  114. (list 'face 'link
  115. 'follow-link t
  116. 'action `(lambda (_) (spotify-user-playlists ,user-id))
  117. 'help-echo (format "Show %s's public playlists" user-id)))
  118. (number-to-string (spotify-get-playlist-track-count playlist))))
  119. entries)))
  120. (when (eq 1 current-page)
  121. (setq-local tabulated-list-entries nil))
  122. (setq-local tabulated-list-entries (append tabulated-list-entries (nreverse entries)))
  123. (setq-local spotify-current-page current-page)
  124. (spotify-playlist-set-list-format)
  125. (tabulated-list-init-header)
  126. (tabulated-list-print t)))
  127. (provide 'spotify-playlist-search)