Greasy Fork

Greasy Fork is available in English.

Mangadex API v5 reader

(shitty) frontend for the v5 mangadex api

当前为 2021-05-08 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        Mangadex API v5 reader
// @namespace   Violentmonkey Scripts
// @match       https://mangadex.org/index.html
// @grant       none
// @version     1.0
// @author      UnnamedMinecrafter
// @description (shitty) frontend for the v5 mangadex api
// ==/UserScript==

let cache = new Map();
let fetchJSON = async(url)=>{
  let cached = cache.get(url);
  if(cached) return cached;
  
	let response = await fetch(url);
	let data = await response.json();
  cache.set(url,data);
  return data;
};
let getImageUrlsFromChapterID = async(chapterID)=>{
	let chapter = await fetchJSON(`https://api.mangadex.org/chapter/${chapterID}`);
  let server = await fetchJSON(`https://api.mangadex.org/at-home/server/${chapterID}`);
  console.log(chapter)
  let urls = chapter.data.attributes.dataSaver.map(s=>`${server.baseUrl}/data-saver/${chapter.data.attributes.hash}/${s}`)
  return urls;
};
let getChaptersFromMangaID = async(mangaID)=>{
	let chapters = await fetchJSON(`https://api.mangadex.org/manga/${mangaID}/feed`);
  return chapters.results;
};
let getGroupNamesFromChapter = async(chapter)=>{
  let groupIDs = chapter.relationships.filter(e=>e.type==="scanlation_group").map(e=>e.id);
  let groups = await Promise.all(groupIDs.map(id=>fetchJSON(`https://api.mangadex.org/group/${id}`)));
  console.log(...groups)
  return groups.map(g=>g.data.attributes.name);
};
let search = async(title)=>{
  let url = new URL("https://api.mangadex.org/manga");
  url.search = new URLSearchParams({
    title
  });
  let result = await fetchJSON(url);
  return result;
};

let div = document.createElement("div");
div.innerHTML = `
<style>
body {
  margin: 0px;
  padding: 0px;
}
img:not([src^="data:"]) {
  width: 100%;
}
input#search {
  width: 100%;
}
</style>
<input id="search" type="search" placeholder="manga title">
<div id="search-results"></div>
`;
document.body.insertBefore(div,document.body.childNodes[0])
let searchResults = document.querySelector("#search-results");

document.querySelector("#search").addEventListener("input",async(e)=>{
  console.log(e.target.value);
  let query = e.target.value;
  let result = await search(query);
  
  searchResults.innerHTML = "";
  for(let e of result.results) {
    console.log(e);
    let id = e.data.id;
    let title = e.data.attributes.title.en;
    
    let manga = document.createElement("div");
    manga.innerText = title;
    manga.addEventListener("click",()=>{
      displayManga(id);
    });
    searchResults.appendChild(manga);
  }
  //document.querySelector("#search-results").innerText = JSON.stringify(result);
});

const displayManga = async(id)=>{
  let chapters = await getChaptersFromMangaID(id);
  searchResults.innerHTML = "";
  
  for(let e of chapters) {
    let chapter = document.createElement("div");
    console.log(e)
    
    let names = await getGroupNamesFromChapter(e);
    chapter.innerText = `${e.data.attributes.volume||0}.${e.data.attributes.chapter} ${e.data.attributes.title} by ${names.join(" ")}`;
    chapter.addEventListener("click",()=>{
      displayChapter(e.data.id);
    });
    searchResults.appendChild(chapter);
  }
};

const displayChapter = async(id)=>{
  let imageIDs = await getImageUrlsFromChapterID(id);
  searchResults.innerHTML = "";
  for(let e of imageIDs) {
    let image = document.createElement("img");
    image.src = e;
    searchResults.appendChild(image);
  }
};