// ==UserScript==
// @name Mangadex API v5 reader
// @namespace Violentmonkey Scripts
// @match https://mangadex.org/index.html
// @grant none
// @version 1.1
// @author UnnamedMinecrafter
// @description 5/8/2021, 10:46:50 AM
// @downloadURL none
// ==/UserScript==
;
const login = async(username,password)=>{
let response = await fetch("https://api.mangadex.org/auth/login",{method:"POST",body:JSON.stringify({
username,
password
})});
let data = await response.json();
if(data.result==="ko") alert("wrong password!");
window.sessionToken = data.token.session;
};
let cache = new Map();
let fetchJSON = async(url)=>{
let cached = cache.get(url);
if(cached) return cached;
let response = await fetch(url,sessionToken?{
headers: {
Authorization: sessionToken
}
}:undefined);
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;
};
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);
}
};
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 displayMangaList = async(mangaList)=>{
searchResults.innerHTML = "";
for(let e of mangaList) {
console.log(e);
let id = e.data.id;
let title = e.data.attributes.title.en;
let lastChapter = "";
if(e.data.attributes.lastChapter && e.data.attributes.lastChapter!=="0") lastChapter = `[last read: ${e.data.attributes.lastVolume||0}.${e.data.attributes.lastChapter}]`;
let manga = document.createElement("div");
manga.innerText = `${title} ${lastChapter}`;
manga.addEventListener("click",()=>{
displayManga(id);
});
searchResults.appendChild(manga);
}
};
let div = document.createElement("div");
div.innerHTML = `