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-track-search.el 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. ;; spotify-track-search.el --- Spotify.el track search major mode
  2. ;; Copyright (C) 2014-2016 Daniel Fernandes Martins
  3. ;; Code:
  4. (require 'spotify-api)
  5. (defvar spotify-track-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-track-select)
  9. (define-key map (kbd "M-RET") 'spotify-track-select-album)
  10. (define-key map (kbd "l") 'spotify-track-load-more)
  11. (define-key map (kbd "g") 'spotify-track-reload)
  12. (define-key map (kbd "f") 'spotify-track-playlist-follow)
  13. (define-key map (kbd "u") 'spotify-track-playlist-unfollow)
  14. map)
  15. "Local keymap for `spotify-track-search-mode' buffers.")
  16. ;; Enables the `spotify-remote-mode' the track search buffer
  17. (add-hook 'spotify-track-search-mode-hook 'spotify-remote-mode)
  18. (define-derived-mode spotify-track-search-mode tabulated-list-mode "Track-Search"
  19. "Major mode for displaying the track listing returned by a Spotify search.")
  20. (defun spotify-track-select ()
  21. "Plays the track under the cursor. If the track list represents a playlist,
  22. the given track is played in the context of that playlist; otherwise, it will
  23. be played in the context of its album."
  24. (interactive)
  25. (let ((selected-track (tabulated-list-get-id)))
  26. (if (bound-and-true-p spotify-selected-playlist)
  27. (spotify-play-track selected-track spotify-selected-playlist)
  28. (spotify-play-track selected-track (spotify-get-track-album selected-track)))))
  29. (defun spotify-track-playlist-follow ()
  30. "Adds the current user as the follower of the track's playlist under the cursor."
  31. (interactive)
  32. (if (bound-and-true-p spotify-selected-playlist)
  33. (when (and (y-or-n-p (format "Follow playlist '%s'?" (spotify-get-item-name spotify-selected-playlist)))
  34. (spotify-api-playlist-follow spotify-selected-playlist))
  35. (message (format "Followed playlist '%s'" (spotify-get-item-name spotify-selected-playlist))))
  36. (message "Cannot follow a playlist from here")))
  37. (defun spotify-track-playlist-unfollow ()
  38. "Removes the current user as the follower of the track's playlist under the cursor."
  39. (interactive)
  40. (if (bound-and-true-p spotify-selected-playlist)
  41. (when (and (y-or-n-p (format "Unfollow playlist '%s'?" (spotify-get-item-name spotify-selected-playlist)))
  42. (spotify-api-playlist-unfollow spotify-selected-playlist))
  43. (message (format "Unfollowed playlist '%s'" (spotify-get-item-name spotify-selected-playlist))))
  44. (message "Cannot unfollow a playlist from here")))
  45. (defun spotify-track-select-album ()
  46. "Plays the album of the track under the cursor in the context of its album."
  47. (interactive)
  48. (let ((selected-track (tabulated-list-get-id)))
  49. (spotify-play-track selected-track
  50. (spotify-get-track-album selected-track))))
  51. (defun spotify-track-reload ()
  52. "Reloads the first page of results for the current track view."
  53. (interactive)
  54. (if (bound-and-true-p spotify-query)
  55. (spotify-track-search-update 1)
  56. (spotify-playlist-tracks-update 1)))
  57. (defun spotify-track-load-more ()
  58. "Loads the next page of results for the current track view."
  59. (interactive)
  60. (if (bound-and-true-p spotify-query)
  61. (spotify-track-search-update (1+ spotify-current-page))
  62. (spotify-playlist-tracks-update (1+ spotify-current-page))))
  63. (defun spotify-track-search-update (current-page)
  64. "Fetches the given page of results using the search endpoint."
  65. (let* ((json (spotify-api-search 'track spotify-query current-page))
  66. (items (spotify-get-search-track-items json)))
  67. (if items
  68. (progn
  69. (spotify-track-search-print items current-page)
  70. (message "Track view updated"))
  71. (message "No more tracks"))))
  72. (defun spotify-playlist-tracks-update (current-page)
  73. "Fetches the given page of results for the current playlist."
  74. (when (bound-and-true-p spotify-selected-playlist)
  75. (let* ((json (spotify-api-playlist-tracks spotify-selected-playlist current-page))
  76. (items (spotify-get-playlist-tracks json)))
  77. (if items
  78. (progn
  79. (spotify-track-search-print items current-page)
  80. (message "Track view updated"))
  81. (message "No more tracks")))))
  82. (defun spotify-track-search-set-list-format ()
  83. "Configures the column data for the typical track view."
  84. (let ((default-width (truncate (/ (- (window-width) 30) 3))))
  85. (setq tabulated-list-format
  86. (vector '("#" 3 nil :right-align t)
  87. `("Track Name" ,default-width t)
  88. `("Artist" ,default-width t)
  89. `("Album" ,default-width t)
  90. `("Time" 8 (lambda (row-1 row-2)
  91. (< (spotify-get-track-duration (first row-1))
  92. (spotify-get-track-duration (first row-2)))))
  93. '("Popularity" 14 t)))))
  94. (defun spotify-track-search-print (songs current-page)
  95. "Appends the given songs to the current track view."
  96. (let (entries)
  97. (dolist (song songs)
  98. (when (spotify-is-track-playable song)
  99. (push (list song
  100. (vector (number-to-string (spotify-get-track-number song))
  101. (spotify-get-item-name song)
  102. (spotify-get-track-artist song)
  103. (spotify-get-track-album-name song)
  104. (spotify-get-track-duration-formatted song)
  105. (spotify-popularity-bar (spotify-get-track-popularity song))))
  106. entries)))
  107. (when (eq 1 current-page)
  108. (setq-local tabulated-list-entries nil))
  109. (setq-local tabulated-list-entries (append tabulated-list-entries (nreverse entries)))
  110. (setq-local spotify-current-page current-page)
  111. (spotify-track-search-set-list-format)
  112. (tabulated-list-init-header)
  113. (tabulated-list-print t)))
  114. (provide 'spotify-track-search)