Greasy Fork

Anisongs

Adds Anisongs to anime entries on AniList

目前为 2018-11-25 提交的版本。查看 最新版本

// ==UserScript==
// @name Anisongs
// @namespace Morimasa
// @author Morimasa
// @description Adds Anisongs to anime entries on AniList
// @match https://anilist.co/*
// @version 1.00
// @grant GM_xmlhttpRequest
// ==/UserScript==

const options = {
  cacheName: 'anison'
}
let last = {id:0}
let target;

const insert = (list, parent) => {
  if (list===undefined || list.length===0){
    console.info("OP/ED is empty");
    return;
  } 
  list.forEach((title, i)=>{
    let node = document.createElement('p');
    node.innerText = `${i+1}. ${title}`;
    node.setAttribute('data-v-4e418c9e','');
    node.classList = "tag";
    parent.appendChild(node);
  })
}

const createTargetDiv = (text, target, pos) => {
  let el = document.createElement('div');
  el.appendChild(document.createElement('h2'));
  el.children[0].innerText = text;
  target.insertBefore(el, target.children[pos]);
  return el;
}

const placeData = data => {
  let op = createTargetDiv('Openings', target, 2)
  let ed = createTargetDiv('Endings', target, 3)
  insert(data.opening_themes, op);
  insert(data.ending_themes, ed);
}

const handleData = data => {
  let resp = JSON.parse(data.responseText);
  placeData(resp)
  addCache(last.id, {opening_themes: resp.opening_themes, ending_themes: resp.ending_themes, time: +new Date()})
}

const getMal = id => {
  if (id===null) return console.info("No MAL id in API")
  GM_xmlhttpRequest({
    method: "GET",
    url: `https://api.jikan.moe/v3/anime/${id}/`,
    headers: {
        "Accept": "application/json"
    },
    onload: handleData
  })
}

const getMalId = () => {
    const query = `query($id:Int){Media(id:$id){idMal}}`
    let vars = {id: parseInt(window.location.pathname.split("/")[2])};
	const options = {
		method: 'POST',
		body: JSON.stringify({query: query, variables: vars}),
		headers: new Headers({
			'Content-Type': 'application/json'
		})
	};
	return fetch('https://graphql.anilist.co/', options)
	.then(res => res.json())
	.then(res => getMal(res.data.Media.idMal))
	.catch(error => console.error(`Error: ${error}`));
}

const addCache = (id, data) => {
  //localStorage.setItem(id, JSON.stringify(object));
  let cache = JSON.parse(localStorage.getItem(options.cacheName)) || {};
  cache[id] = data
  localStorage.setItem(options.cacheName, JSON.stringify(cache));
}

const getCache = id => {
  //return JSON.parse(localStorage.getItem(id))
  let cache = localStorage.getItem(options.cacheName);
  if (cache==null)
    return {time:0}
  else
    return JSON.parse(cache)[id] || {time:0};
}

var observer = new MutationObserver(() => {
    if (window.location.href.includes('/anime/', 18)) {
      let currentid = window.location.href.split("/")[4];
      let location = window.location.pathname.split("/").pop();
      if (location!=='') last.id=0;
      target = document.querySelectorAll('.grid-section-wrap')[1];
      if(last.id!==currentid && location=='' && target!==undefined){
        last.id = currentid;
        let cache = getCache(currentid);
        let daypassed = (cache.time + 86400000)<+new Date();
        if (daypassed){
          getMalId();
          console.info("OP/ED loaded from API");
        }
        else{
          placeData(cache);
          console.info("OP/ED loaded from Cache");
        }
      }
   } 
});
observer.observe(document.getElementById('app'), {childList: true, subtree: true});