RED - collages by year

click to load entire collage sorted by year + live search

// ==UserScript==
// @name        RED - collages by year
// @namespace   userscript1
// @match       https://redacted.ch/collages.php*
// @match       https://redacted.ch/collage.php*
// @grant       none
// @version     0.5.5
// @description click to load entire collage sorted by year + live search
// ==/UserScript==

(function() {    // ------------

// Artist collages have no year
if (document.querySelector('.box_category a').
    href.endsWith('collages.php?action=search&cats[7]=1') ) {
  return;
}

const params = new URLSearchParams(location.search);
const id = params.get('id');
const urlAPI = 'https://redacted.ch/ajax.php?action=collage&id=';
const urlTorrent = '/torrents.php?id=';
const urlArtist = '/artist.php?id=';
const types = [];
types[1] = {
  1: 'Album',
  3: 'Soundtrack',
	5: 'EP',
	6: 'Anthology',
	7: 'Compilation',
	9: 'Single',
	11: 'Live album',
	13: 'Remix',
	14: 'Bootleg',
	15: 'Interview',
	16: 'Mixtape',
	17: 'Demo',
	18: 'Concert Recording',
	19: 'DJ Mix',
	21: 'Unknown' 
	};
types[2] = {0: 'Application'};
types[3] = {0: 'E-Book'};
types[4] = {0: 'Audiobook'};
types[5] = {0: 'E-Learning'};
types[6] = {0: 'Comedy'};
types[7] = {0: 'Comic'};

var input;
var trList;

var newCode = `<div id="byyear-box" class="box">
   <div id="byyear" class="head">
      <strong>By year</strong>
        [<a style="cursor: pointer;" onclick="document.getElementById('byyear-box').scrollIntoView(false);">end</a>]
    </div>
    <div id="byyear-target" />
  </div>
  `;
var elm = document.getElementById('coverart');
if (elm === null) { return; }  // don't try to run on collage edit pages, etc.
elm.insertAdjacentHTML('beforebegin', newCode);

const header = document.getElementById('byyear');
header.style.cursor = 'pointer';
header.addEventListener('click', gogo);

document.head.insertAdjacentHTML("beforeend", `<style> 
  .byyear-marker {border-top: solid 2px;}
  .byyear-line2 {font-size: 0.8em; opacity: 50%;}
  .byyear-taglist {font-style: italic;}
  #byyear-target td:first-child {width: 1%;}
  </style>
  `);

function gogo() {
  header.removeEventListener('click', gogo);
  header.style.cursor = '';
  
  if (id) {
    document.body.style.cursor = 'progress';
    var req = new XMLHttpRequest();
    req.addEventListener('load', processData);
    req.open('GET', urlAPI + id);
    req.send();
  }
}

function processData() {
  var table = document.createElement('table');
  var groups = JSON.parse(this.responseText).response.torrentgroups;
  groups.sort(sortByProperty('year'));
  
  for (let j of groups) {
    if (j.musicInfo && j.musicInfo.dj.length) {
        j.musicInfo.artists = j.musicInfo.dj;
    }
    var artists = (j.musicInfo) ? processArtists(j.musicInfo.artists) : '';    
    var tags = (j.tagList) ? processTags(j.tagList) : '';
    try {
      var type = types[Number(j.categoryId)][Number(j.releaseType)];
    } catch {
      type = 'type?';
    }
    
    var row = document.createElement('tr');
    row.innerHTML = `<td> ${j.year} </td>
      <td> ${artists} </td> 
      <td>
        <strong> <a target="_blank" href="${urlTorrent}${j.id}">${j.name}</a> </strong>
        <div class="byyear-line2">[${type}] <span class="byyear-taglist">${tags}</span></div>
      </td>
      `;
    
    table.appendChild(row);
  }
  groups = null;
  
  let elm = document.getElementById('byyear-target');
  elm.appendChild(table);
  trList = elm.getElementsByTagName('tr');
  
  newCode = `<input type="text" id="filterInput" placeholder="search for.." />
    Results: <span id="filterCount"></span>
    `;
  elm.insertAdjacentHTML('beforebegin', newCode);
  input = document.getElementById('filterInput');
  input.addEventListener('keyup', filterFunction);
  
  markYears();
  document.body.style.cursor = '';
}

function processTags(str) {
  str = str.replace(/ /g, ', ');
  return str.replace(/_/g, '.');
}

function processArtists(artists) {
  if (artists.length > 3) { return 'Various Artists'; }
  return artists.map(a => `<a target="_blank" href="${urlArtist}${a.id}">${a.name}</a>`)
        .join(', ');
}

  
function filterFunction() {
  var count = 0;
	var filter = input.value.toUpperCase();
  
	for (let tr of trList) {
    var txtValue = tr.textContent || tr.innerText;
    var txtValueNormalized = removeAccents(txtValue);
    if (txtValue.toUpperCase().includes(filter)
       || txtValueNormalized.toUpperCase().includes(filter) ) {
      tr.style.display = '';
      count++;
    } else {
      tr.style.display = 'none';
    }
  }
  markYears();
  document.getElementById('filterCount').innerText = count;
}


function markYears() {
  var yearCheck;
  
  for (let tr of trList) {
    if (tr.style.display == 'none')  { continue; }
    
    var year = tr.firstChild.textContent;
    if (year != yearCheck) {
      tr.classList.add('byyear-marker');
    } else {
      tr.classList.remove('byyear-marker');
    }
    
    yearCheck = year;
  }
}


function removeAccents(str) {
  return str.normalize('NFD').replace(/[\u0300-\u036f]/g, "");
}


function sortByProperty(property){  
   return function(a,b){  
      if(a[property] > b[property])  
         return 1;  
      else if(a[property] < b[property])  
         return -1;  
  
      return 0;  
   }  
}
  
})();  // ----------------