Improve 8bcDump

Improve the interface of the public 8bitcollective archive on brkbrkbrk.com.

当前为 2017-03-29 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Improve 8bcDump
  3. // @namespace Improve8bcDump
  4. // @description Improve the interface of the public 8bitcollective archive on brkbrkbrk.com.
  5. // @include http://brkbrkbrk.com/8bcdump/
  6. // @include https://brkbrkbrk.com/8bcdump/
  7. // @include http://www.brkbrkbrk.com/8bcdump/
  8. // @include https://www.brkbrkbrk.com/8bcdump/
  9. // @version 0.3.3
  10. // @grant none
  11. // @author Jack Willis
  12. // @license MIT; https://opensource.org/licenses/MIT
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. console.log('Improve8bcDump v0.3.3 is active.');
  17.  
  18. // Fix a wrong attribute on the page's external stylesheet.
  19. var stylesheet = document.querySelector('link[type="text/stylesheet"]');
  20. stylesheet.setAttribute('type', 'text/css');
  21.  
  22. // The currently playing song should appear bold in the last played list.
  23. var newStyles = document.createElement('style');
  24. newStyles.textContent += '.lastPlayed li:first-child { font-weight: bold; }';
  25. newStyles.textContent += '.lastPlayed li:first-child:after { content: " (playing)" }';
  26. document.body.appendChild(newStyles);
  27. // Create a stack for the last played songs.
  28. // The stack is realized in an <ol>, contained in parentElement.
  29. function LastPlayedList(maxLength, parentElement) {
  30. // Create a heading for the last played list
  31. var heading = document.createElement('h2');
  32. heading.textContent = 'Last played';
  33. parentElement.appendChild(heading);
  34. // Create the list itself
  35. var list = document.createElement('ol');
  36. list.classList.add('lastPlayed');
  37. parentElement.appendChild(list);
  38. // Push songs through the stack
  39. this.push = function(song) {
  40. var nodes = list.childNodes;
  41. if (nodes.length == maxLength) {
  42. list.removeChild(nodes[nodes.length - 1]);
  43. }
  44. var newItem = document.createElement('li');
  45. newItem.textContent = song;
  46. list.insertBefore(newItem, nodes[0]);
  47. }
  48.  
  49. this.currentSong = function() {
  50. return list.childNodes[0].textContent;
  51. };
  52. }
  53. // Create a list at the bottom of the page to hold the last 20 songs
  54. var lastPlayedDiv = document.createElement('div');
  55. document.body.appendChild(lastPlayedDiv);
  56. var lastPlayedList = new LastPlayedList(20, lastPlayedDiv);
  57. // The player at the bottom of the page should also show the filename when playing songs,
  58. // and the song's information should be added to the last played list.
  59. // Override the existing updateID3 method
  60.  
  61. var updateID3 = function(id3) {
  62. var filename = document.getElementById(window.index).textContent;
  63. var songDesc = 'Title: ' + id3.title + ', Artist: ' + id3.artist + ', Album: ' + id3.album + ', Filename: ' + filename;
  64. window.liID3.textContent = songDesc;
  65.  
  66. lastPlayedList.push(songDesc);
  67. }
  68.  
  69. window.updateID3 = window.tP.nextID3CB = updateID3;
  70.  
  71. // Due to timing issues, make sure the liID3 is in sync with the accurate last played list
  72.  
  73. setInterval(function() {
  74. window.liID3.textContent = lastPlayedList.currentSong();
  75. }, 100);
  76.  
  77. // Add more buttons to the player interface
  78.  
  79. // The <audio> element
  80. var audio = window.tP.el;
  81.  
  82. var tPControls = document.querySelector('ul.tpControls');
  83.  
  84. var ffLi = document.createElement('li');
  85. ffLi.classList.add('ff');
  86.  
  87. // The player control buttons use Font Awesome icons
  88. var fastForwardButton = document.createElement('i');
  89. fastForwardButton.classList.add('fa', 'fa-fast-forward');
  90.  
  91. ffLi.style.marginLeft = '0.25em';
  92.  
  93. ffLi.appendChild(fastForwardButton);
  94. tPControls.appendChild(ffLi);
  95.  
  96. // Shuffle button uses a checkbox
  97. var shuffleLi = document.createElement('li');
  98. shuffleLi.classList.add('shuffle');
  99.  
  100. var shuffleButton = document.createElement('input');
  101. shuffleButton.setAttribute('type', 'checkbox');
  102.  
  103. var shuffleText = document.createTextNode('Shuffle?');
  104. shuffleLi.style.marginLeft = '1em';
  105.  
  106. shuffleLi.appendChild(shuffleText);
  107. shuffleLi.appendChild(shuffleButton);
  108. tPControls.appendChild(shuffleLi);
  109.  
  110. // The fast forward button triggers the 'ended' event on the audio player.
  111. fastForwardButton.addEventListener('click', function() {
  112. audio.dispatchEvent(new CustomEvent('ended'));
  113. });
  114.  
  115. // The <a> of the song currently being played
  116. var currentSongLinkEl = function() {
  117. return document.getElementById(window.index).querySelector('a');
  118. };
  119.  
  120. var randomSongLinkEl = function() {
  121. var xs = window.archiveAs;
  122. return xs[Math.floor(Math.random() * xs.length)];
  123. };
  124.  
  125. audio.addEventListener('ended', function() {
  126. // Manually triggering a click event on the next song fixes an issue with updating the ID3 information.
  127. // This is a hack -- since Javascript doesn't provide an interface for removing the old event listeners,
  128. // I'll just wait 50ms to ensure mine runs last.
  129. // At this point, window.index has already been incremented, so currentSongLinkEl() will point to an unplayed song.
  130. setTimeout(function() {
  131. var nextSong = shuffleButton.checked ? randomSongLinkEl() : currentSongLinkEl();
  132. nextSong.click();
  133. }, 50);
  134. });
  135. }());