Improve 8bcDump

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

目前為 2017-03-29 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name        Improve 8bcDump
// @namespace   Improve8bcDump
// @description Improve the interface of the public 8bitcollective archive on brkbrkbrk.com.
// @include     http://brkbrkbrk.com/8bcdump/
// @include     https://brkbrkbrk.com/8bcdump/
// @include     http://www.brkbrkbrk.com/8bcdump/
// @include     https://www.brkbrkbrk.com/8bcdump/
// @version     0.3.2
// @grant       none
// ==/UserScript==

(function() {
  console.log('Improve8bcDump v0.3.2 is active.');

  // Fix a wrong attribute on the page's external stylesheet.
  var stylesheet = document.querySelector('link[type="text/stylesheet"]');
  stylesheet.setAttribute('type', 'text/css');

  // The currently playing song should appear bold in the last played list.
  
  var newStyles = document.createElement('style');
  newStyles.textContent += '.lastPlayed li:first-child { font-weight: bold; }';
  newStyles.textContent += '.lastPlayed li:first-child:after { content: " (playing)" }';
  document.body.appendChild(newStyles);
  
  // Create a stack for the last played songs.
  // The stack is realized in an <ol>, contained in parentElement.
  
  function LastPlayedList(maxLength, parentElement) {
    // Create a heading for the last played list
    var heading = document.createElement('h2');
    heading.textContent = 'Last played';
    parentElement.appendChild(heading);
    
    // Create the list itself
    var list = document.createElement('ol');
    list.classList.add('lastPlayed');
    parentElement.appendChild(list);
    
    // Push songs through the stack
    this.push = function(song) {
      var nodes = list.childNodes;
      
      if (nodes.length == maxLength) {
        list.removeChild(nodes[nodes.length - 1]);
      }
      
      var newItem = document.createElement('li');
      newItem.textContent = song;
      
      list.insertBefore(newItem, nodes[0]);
    }

    this.currentSong = function() {
      var nodes = list.childNodes;
      return list.childNodes[0].textContent;
    };
  }
  
  // Create a list at the bottom of the page to hold the last 10 songs
  var lastPlayedDiv = document.createElement('div');
  document.body.appendChild(lastPlayedDiv);
  var lastPlayedList = new LastPlayedList(10, lastPlayedDiv);
  
  // The player at the bottom of the page should also show the filename when playing songs,
  // and the song's information should be added to the last played list.
  
  // Override the existing updateID3 method

  var updateID3 = function(id3) {
    var filename = document.getElementById(window.index).textContent;
    var songDesc = 'Title: ' + id3.title + ', Artist: ' + id3.artist + ', Album: ' + id3.album + ', Filename: ' + filename;
    
    window.liID3.textContent = songDesc;

    lastPlayedList.push(songDesc);
  }

  window.updateID3 = window.tP.nextID3CB = updateID3;

  // Due to timing issues, make sure the liID3 is in sync with the accurate last played list

  setInterval(function() {
    window.liID3.textContent = lastPlayedList.currentSong();
  }, 100);


  // Add more buttons to the player interface

  // The <audio> element
  var audio = window.tP.el;

  var tPControls = document.querySelector('ul.tpControls');

  var ffLi = document.createElement('li');
  ffLi.classList.add('ff');

  // The player control buttons use Font Awesome icons
  var fastForwardButton = document.createElement('i');
  fastForwardButton.classList.add('fa', 'fa-fast-forward');

  ffLi.style.marginLeft = '0.25em';

  ffLi.appendChild(fastForwardButton);
  tPControls.appendChild(ffLi);

  // Shuffle button uses a checkbox
  var shuffleLi = document.createElement('li');
  shuffleLi.classList.add('shuffle');

  var shuffleButton = document.createElement('input');
  shuffleButton.setAttribute('type', 'checkbox');

  var shuffleText = document.createTextNode('Shuffle?');
  shuffleLi.style.marginLeft = '1em';

  shuffleLi.appendChild(shuffleText);
  shuffleLi.appendChild(shuffleButton);
  tPControls.appendChild(shuffleLi);

  // The fast forward button triggers the 'ended' event on the audio player.
  fastForwardButton.addEventListener('click', function() {
    audio.dispatchEvent(new CustomEvent('ended'));
  });

  // The <a> of the song currently being played
  var currentSongLinkEl = function() {
    return document.getElementById(window.index).querySelector('a');
  };

  var randomSongLinkEl = function() {
    var xs = window.archiveAs;
    return xs[Math.floor(Math.random() * xs.length)];
  };

  audio.addEventListener('ended', function() {
    // Manually triggering a click event on the next song fixes an issue with updating the ID3 information.
    // This is a hack -- since Javascript doesn't provide an interface for removing the old event listeners,
    // I'll just wait 50ms to ensure mine runs last.
    // At this point, window.index has already been incremented, so currentSongLinkEl() will point to an unplayed song.
    setTimeout(function() {
      var nextSong = shuffleButton.checked ? randomSongLinkEl() : currentSongLinkEl();
      nextSong.click();
    }, 50);
  });
}());