Adds more filters to Crunchyroll's anime list page
// ==UserScript==
// @name Crunchyroll More Filters
// @name:pt-BR Mais Filtros Crunchyroll
// @namespace http://tampermonkey.net/
// @author Trapstar
// @description Adds more filters to Crunchyroll's anime list page
// @description:pt-BR Adiciona mais filtros na página de lista de animes do Crunchyroll
// @match https://www.crunchyroll.com/*/videos/*
// @match http://www.crunchyroll.com/*/videos/*
// @icon https://www.crunchyroll.com/favicons/favicon-32x32.png
// @version 1.0.2
// @license MIT
// @copyright 2023
// ==/UserScript==
(function () {
'use strict';
let added = false;
let selectedMethod = 0
let animeCardArray = []
function getRatingCount(element) {
const text = element.textContent;
const match = text.match(/\((\d+(\.\d+)?)k\)/);
if (match) {
return parseFloat(match[1]) * 1000;
}
return 0;
}
function ordenarPorAvaliacao() {
console.log("[Crunchyroll More Filters] Reordenando por Mais Avaliados]")
selectedMethod = 1
const animeCards = document.querySelectorAll('.erc-browse-cards-collection .browse-card');
animeCardArray = Array.from(animeCards);
animeCardArray.sort((a, b) => {
const ratingCountA = getRatingCount(a.querySelector('.star-rating-short-static__votes-count--h9Sun'));
const ratingCountB = getRatingCount(b.querySelector('.star-rating-short-static__votes-count--h9Sun'));
return ratingCountB - ratingCountA;
});
const cardCollection = document.querySelector('.erc-browse-cards-collection');
cardCollection.innerHTML = '';
animeCardArray.forEach((card) => {
cardCollection.appendChild(card);
});
}
function ordernarPorEstrelas() {
console.log("[Crunchyroll More Filters] Reordenando por Mais Estrelas]")
selectedMethod = 2
const animeCards = document.querySelectorAll('.erc-browse-cards-collection .browse-card');
animeCardArray = Array.from(animeCards);
animeCardArray.sort((a, b) => {
const ratingCountA = parseFloat(a.querySelector('.star-rating-short-static__rating--bdAfR').textContent);
const ratingCountB = parseFloat(b.querySelector('.star-rating-short-static__rating--bdAfR').textContent);
return ratingCountB - ratingCountA;
});
const cardCollection = document.querySelector('.erc-browse-cards-collection');
cardCollection.innerHTML = '';
animeCardArray.forEach((card) => {
cardCollection.appendChild(card);
});
}
function ordenarPorAvaliacaoProporcional() {
console.log("[Crunchyroll More Filters] Reordenando por Mais Avaliados Proporcionalmente]")
selectedMethod = 3
const animeCards = document.querySelectorAll('.erc-browse-cards-collection .browse-card');
animeCardArray = Array.from(animeCards);
animeCardArray.sort((a, b) => {
const ratingCountA = getRatingCount(a.querySelector('.star-rating-short-static__votes-count--h9Sun'));
const ratingCountB = getRatingCount(b.querySelector('.star-rating-short-static__votes-count--h9Sun'));
const ratingA = parseFloat(a.querySelector('.star-rating-short-static__rating--bdAfR').textContent);
const ratingB = parseFloat(b.querySelector('.star-rating-short-static__rating--bdAfR').textContent);
const pesoAvaliacao = 0.7;
const pesoEstrelas = 0.3;
const pontuacaoA = (ratingCountA * pesoAvaliacao) + (ratingA * pesoEstrelas);
const pontuacaoB = (ratingCountB * pesoAvaliacao) + (ratingB * pesoEstrelas);
return pontuacaoB - pontuacaoA;
});
const cardCollection = document.querySelector('.erc-browse-cards-collection');
cardCollection.innerHTML = '';
animeCardArray.forEach((card) => {
cardCollection.appendChild(card);
});
}
function adicionarBotao(texto, funcao) {
const button = document.createElement('div');
button.id = 'btn' + texto;
button.className = 'select-content__option--gq8Uo';
button.tabIndex = 0;
button.innerHTML = `
<span class="text--gq6o- text--is-m--pqiL- middle-truncation--x7S4D">
<span class="middle-truncation__text--xv72L">${texto}</span>
<span aria-hidden="true" class="middle-truncation__truncated-text--rur5E middle-truncation__truncated-text--is-hidden--LRE6O">
<span class="middle-truncation__text-start--3XiZ9">${texto}</span>
<span class="middle-truncation__dots--Ywbi7">...</span>
<span class="middle-truncation__text-end--Vl77q">${texto}</span>
</span>
</span>
`;
button.addEventListener('click', function () {
funcao();
});
const targetElement = document.querySelector('.dropdown-content__children--HW28H');
if (targetElement) {
targetElement.appendChild(button);
}
}
function observarDOM() {
const targetElement = document.querySelector('.dropdown-content__children--HW28H');
if (selectedMethod !== 0) {
const animeCards = document.querySelectorAll('.erc-browse-cards-collection .browse-card');
const animeCardArray2 = Array.from(animeCards);
if (animeCardArray.length !== animeCardArray2.length) {
switch (selectedMethod) {
case 1:
ordenarPorAvaliacao();
break;
case 2:
ordernarPorEstrelas();
break;
case 3:
ordenarPorAvaliacaoProporcional();
break;
}
}
}
if (targetElement) {
if (added) {
return;
}
added = true;
setTimeout(() => {
console.log("[Crunchyroll More Filters] Adding buttons]")
adicionarBotao('Most Proportionally Rated', ordenarPorAvaliacaoProporcional);
adicionarBotao('Most Rated', ordenarPorAvaliacao);
adicionarBotao('Most Stars', ordernarPorEstrelas);
}, 1);
} else {
added = false;
}
}
observarDOM()
const observer = new MutationObserver(observarDOM);
observer.observe(document.body, { childList: true, subtree: true });
})();