PTH Torrent quickview

Add a hover that shows the album art and files for a torrent from the artist page

目前為 2017-02-20 提交的版本,檢視 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         PTH Torrent quickview
// @version      0.5
// @description  Add a hover that shows the album art and files for a torrent from the artist page
// @author       Chameleon
// @include      http*://redacted.ch/artist.php?id=*
// @include      http*://redacted.ch/torrents.php?id=*
// @grant        none
// @namespace https://greasyfork.org/users/87476
// ==/UserScript==

(function() {
  'use strict';

  var torrents = document.getElementsByClassName('torrent_row');
  for(var i=0; i<torrents.length; i++)
  {
    var t=torrents[i];
    var torrentLink=t.getElementsByTagName('a');
    torrentLink=torrentLink[torrentLink.length-1];
    var groupid=parseInt(torrentLink.href.split('id=')[1].split('&')[0]);
    var torrentid=torrentLink.href.split('torrentid=');
    if(torrentid.length > 1)
      torrentid = torrentid[1];
    else
      torrentid=torrentLink.outerHTML.split("#torrent_")[1].split("'")[0];

    t.addEventListener('mouseover', mouseOver.bind(undefined, t, torrentid, groupid), false);
    t.addEventListener('mouseout', mouseOut.bind(undefined, t, torrentid), false);
  }
})();

function mouseOver(tr, torrentid, groupid, event)
{
  if(event.shiftKey)
    return;
  var div=document.getElementById('quickview_'+torrentid);
  if(!div)
  {
    div=document.createElement('div');
    document.body.appendChild(div);
    div.setAttribute('id', 'quickview_'+torrentid);
    var rect=tr.getBoundingClientRect();
    var top=rect.top+window.scrollY-50;
    var width=500;
    var leftOffset=50;
    var left=rect.left+window.scrollX-width+leftOffset-20;
    if(left < leftOffset)
      left=leftOffset;
    div.setAttribute('style', 'position: absolute; top: '+top+'px; left: '+left+'px; width: '+(width-leftOffset)+'px; background: black; border-radius: 10px; padding: 10px;');
    div.innerHTML = 'Loading data';
    div.addEventListener('mouseout', mouseOut.bind(undefined, tr, torrentid), false);
  }

  var dataDiv=document.getElementById('quickviewData_'+groupid);
  if(!dataDiv)
  {
    loadData(groupid, torrentid, div);
    return;
  }

  showData(dataDiv);
}

function loadData(groupid, torrentid, messageDiv)
{
  var dataDiv = document.getElementById('quickviewData_'+groupid);
  if(!dataDiv)
  {
    dataDiv = document.createElement('div');
    dataDiv.setAttribute('id', 'quickviewData_'+groupid);
    dataDiv.setAttribute('style', 'display: none;');
    document.body.appendChild(dataDiv);
    dataDiv.setAttribute('loading', 'true');
  }

  if(window.location.href.indexOf('torrents.php') == -1)
  {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', '/torrents.php?id='+groupid);
    xhr.onreadystatechange = xhr_func.bind(undefined, messageDiv, xhr, gotGroup.bind(undefined, groupid, torrentid, dataDiv), loadData.bind(undefined, groupid, torrentid, messageDiv));
    xhr.send();
  }
  else
  {
    gotGroup(groupid, torrentid, dataDiv, document.body.innerHTML);
  }
}

function gotGroup(groupid, torrentid, dataDiv, response)
{
  var div=document.implementation.createHTMLDocument();
  div.body.innerHTML = response;
  var result={};

  var h2=div.getElementsByTagName('h2')[0];
  result.artist = h2.getElementsByTagName('a')[0].innerHTML;
  result.album = h2.getElementsByTagName('span')[0].innerHTML;
  result.year = parseInt(h2.textContent.split('[')[1]);
  var art = div.getElementById('cover_div_0');
  if(art)
    result.albumArt = art.getElementsByTagName('img')[0].src;
  result.torrents = [];
  var details = div.getElementsByClassName('torrentdetails');
  for(var i=0; i<details.length; i++)
  {
    var d=details[i];
    var torrent = {};
    torrent.id = d.getAttribute('id').split('_')[1];
    torrent.files = [];
    var file_trs = div.getElementById('files_'+torrent.id).getElementsByTagName('tr');
    for(var j=1; j<file_trs.length; j++)
    {
      var f=file_trs[j].getElementsByTagName('td');
      var file={name:f[0].innerHTML, size:f[1].innerHTML};
      torrent.files.push(file);
    }
    result.torrents.push(torrent);
  }

  dataDiv.setAttribute('data', JSON.stringify(result));
  dataDiv.setAttribute('loading', 'false');

  showData(dataDiv);
}

function showData(dataDiv)
{
  if(dataDiv.getAttribute('loading') == 'true')
    return;
  var data=JSON.parse(dataDiv.getAttribute('data'));
  for(var i=0; i<data.torrents.length; i++)
  {
    var t=data.torrents[i];
    var div = document.getElementById('quickview_'+t.id);
    if(!div)
      continue;
    showAlbum(data, t, div);
  }
}

function showAlbum(data, t, div)
{
  div.innerHTML = '';
  var header = document.createElement('div');
  div.appendChild(header);
  header.setAttribute('style', 'height: 200px;');
  if(data.albumArt)
  {
    var img=document.createElement('img');
    img.src=data.albumArt;
    header.appendChild(img);
    img.setAttribute('style', 'width: 180px;');
  }
  var meta = document.createElement('div');
  header.appendChild(meta);
  meta.setAttribute('style', 'width: 250px; height: 200px; float: right; text-align: left;');
  meta.innerHTML = '<span style="font-size:1.2em; font-style:bold;">'+data.album+'</span><br />'+data.artist+'<br />'+data.year;

  var torrents = document.createElement('div');
  div.appendChild(torrents);
  for(var i=0; i<t.files.length; i++)
  {
    var f=t.files[i];
    var d=document.createElement('div');
    torrents.appendChild(d);
    var span = document.createElement('span');
    span.setAttribute('style', 'display: inline-block; text-align: left; white-space: nowrap;');
    d.appendChild(span);
    span.innerHTML = f.name;
    span.title=span.textContent;
    span.innerHTML = f.name+'...';
    var count=0;
    if(span.clientWidth >= 350)
    {
      while(span.clientWidth >= 350)
      {
        span.innerHTML = span.innerHTML.slice(0, -4)+'...';
        count++;
        if(count > 100)
          break;
      }
    }
    else
    {
      span.innerHTML = span.innerHTML.slice(0, -3);
    }

    var span = document.createElement('span');
    d.appendChild(span);
    span.innerHTML = f.size;
    span.setAttribute('style', 'float: right;');
  }
}

function mouseOut(tr, torrentid, event)
{
  var div=document.getElementById('quickview_'+torrentid);
  if(event.relatedTarget == tr || isDescendant(div, event.relatedTarget) || event.relatedTarget == div)
    return;

  document.body.removeChild(div);
}

function xhr_func(messageDiv, xhr, func, repeatFunc)
{
  if(xhr.readyState == 4)
  {
    if(xhr.status == 200)
      func(xhr.responseText);
    else
    {
      messageDiv.innerHTML = 'Error: '+xhr.status+'<br />retrying in 1 second';
      window.setTimeout(repeatFunc, 1000);
    }
  }
}

function isDescendant(parent, child)
{
  var node = child.parentNode;
  while(node != null)
  {
    if(node == parent)
      return true;
    node = node.parentNode;
  }
  return false;
}