chsa13 / shikiPlus

// ==UserScript==
// @name         shikiPlus
// @author       chsa13
// @description  script add viewer and playeer on shikimori
// @namespace    http://shikimori.me/
// @version      1
// @match        *://shikimori.org/*
// @match        *://shikimori.one/*
// @match        *://shikimori.me/*
// @icon         https://www.google.com/s2/favicons?domain=shikimori.me
// @license      MIT
// @copyright    Copyright © 2024 chsa13. All rights reserved.
// @downloadURL  https://openuserjs.org/src/scripts/chsa13/shikiPlus.user.js
// @updateURL    https://openuserjs.org/meta/chsa13/shikiPlus.meta.js
// ==/UserScript==

let RonobeLibLink = "https://ranobelib.me/ru/"
let MangaLibLink = "https://test-front.mangalib.me/ru/"
let AnimeLibLink = "https://anilib.me/ru/anime/"
let LibSocialApiLink = 'https://api.lib.social/api'

function launchFullScreen(element) {
  if (element.requestFullScreen) {
    element.requestFullScreen();
  }
  else if (element.webkitRequestFullScreen) {
    element.webkitRequestFullScreen();
  }
  else if (element.mozRequestFullScreen) {
    element.mozRequestFullScreen();
  }
}

function ready(fn) {
  document.addEventListener('page:load', fn);
  document.addEventListener('turbolinks:load', fn);
  if (document.attachEvent ? document.readyState === "complete" : document.readyState !== "loading") fn();
  else document.addEventListener('DOMContentLoaded', fn);
}
async function sleep(timeMs) {
  await new Promise(resolve => setTimeout(resolve, timeMs));
}
async function GetResourceAsync(uri, config = {}) {
  return await new Promise((resolve, reject) => {
    $.ajax(Object.assign({
      url: uri,
      dataType: 'json',
      async: true,
      cache: false,
      success: function (res) {
        resolve(res);
      },
      error: function (xhr) {
        reject(xhr);
      }
    }, config));
  });
}
async function ranobelib(hrefs) {
  let sets = document.createElement("div")
  sets.style.cssText = `
    width: 100%;
    height: 40px;
    display: flex;
  `
  document.querySelector('.b-db_entry').appendChild(sets)
  let sweatcher = document.createElement("div")
  sweatcher.style.cssText = `
    height: 40px;
    background-color: grey;
    display: flex;
  `
  if (hrefs.length >= 2) sets.appendChild(sweatcher)
  var fr = document.createElement("iframe");
  for (let i in hrefs) {
    let btm = document.createElement("div")
    btm.style.cssText = `
      width: 40px;
      height: 40px;
      background-color: green;
      display: flex;
    `
    btm.textContent = (String(i))
    sweatcher.appendChild(btm)
    btm.addEventListener("click", () => {
      fr.src = RonobeLibLink + hrefs[i] + "/read/v01/c01"
    })
  }
  fr.src = RonobeLibLink + hrefs[0] + "/read/v01/c01"
  console.log(RonobeLibLink + hrefs[0] + "/read/v01/c01")
  fr.setAttribute('allowFullScreen', 'allowfullscreen')
  fr.style.cssText = `
    width: 100%;
    height: unset;
    aspect-ratio: 1.36;
    min-height: 650px;
    border: none;
  `;
  let blackdiv = document.createElement("div")
  blackdiv.style.cssText = `
    position: absolute;
    background-color: black;
    width: 100%;
    height: unset;
    aspect-ratio: 1.36;
    min-height: 650px;
    border: none;
  `
  let e = document.createElement("div")
  e.style.cssText = `
    width: 40%;
    height: 40px;
    background-color: blue;

  `
  sets.appendChild(e)
  e.addEventListener("click", () => {
    launchFullScreen(fr)
  })
  /*   document.querySelector('.b-db_entry').appendChild(blackdiv) */
  fr.onload = async function () {
    blackdiv.remove()
  }
  document.querySelector('.b-db_entry').appendChild(fr)
}
async function mangalib(hrefs) {
  let sets = document.createElement("div")
  sets.style.cssText = `
    width: 100%;
    height: 40px;
    display: flex;
  `
  document.querySelector('.b-db_entry').appendChild(sets)
  let sweatcher = document.createElement("div")
  sweatcher.style.cssText = `
    width: 50%;
    height: 40px;
    background-color: grey;
    display: flex;
  `
  if (hrefs.length >= 2) sets.appendChild(sweatcher)
  var fr = document.createElement("iframe");
  for (let i in hrefs) {
    let btm = document.createElement("div")
    btm.style.cssText = `
    width: 40px;
    height: 40px;
    background-color: green;
    display: flex;
  `
    btm.textContent = (String(i))
    sweatcher.appendChild(btm)
    btm.addEventListener("click", () => {
      fr.src = MangaLibLink + hrefs[i] + "/read/0v1/c01"
    })
  }
  fr.src = MangaLibLink + hrefs[0] + "/read/v01/c01"
  launchFullScreen(fr)
  fr.setAttribute('allowFullScreen', 'allowfullscreen')
  fr.style.cssText = `
      width: 100%;
      height: unset;
      aspect-ratio: 1.36;
      min-height: 650px;
      border: none;
  `;
  let blackdiv = document.createElement("div")
  blackdiv.style.cssText = `
      position: absolute;
      background-color: black;
      width: 100%;
      height: unset;
      aspect-ratio: 1.36;
      min-height: 650px;
      border: none;
  `

  document.querySelector('.b-db_entry').appendChild(blackdiv)
  let e = document.createElement("div")
  e.style.cssText = `
    width: 40%;
    height: 40px;
    background-color: blue;

  `
  sets.appendChild(e)
  e.addEventListener("click", () => {
    launchFullScreen(fr)
  })
  fr.onload = async function () {
    blackdiv.remove()
  }
  document.querySelector('.b-db_entry').appendChild(fr)
}
async function animelib(href) {
  var fr = document.createElement("iframe");
  fr.src = AnimeLibLink + href.split("?")[0] + "/watch";
  fr.setAttribute('allowFullScreen', 'allowfullscreen')
  fr.style.cssText = `
      width: 100%;
      height: unset;
      aspect-ratio: 1.36;
      min-height: 650px;
      border: none;
  `;
  let blackdiv = document.createElement("div")
  blackdiv.style.cssText = `
      position: absolute;
      background-color: black;
      width: 100%;
      height: unset;
      aspect-ratio: 1.36;
      min-height: 650px;
      border: none;
  `
  document.querySelector('.b-db_entry').appendChild(blackdiv)
  fr.onload = async function () {
    blackdiv.remove()

  }
  document.querySelector('.b-db_entry').appendChild(fr)
}

async function addBtn() {
  let btn = document.createElement("div")
  let clickFunc = function () {
    1 == 1
  }
  let href = ""
  if (location.href.includes("/animes/")) {
    let id = document.querySelector('.b-user_rate').getAttribute('data-target_id')
    let title = document.querySelector("meta[property='og:title']").getAttribute('content')
    try {
      title = title.split(" ")[0]
    }
    catch {
      1 == 1
    }
    console.log(title)
    let response = await GetResourceAsync(LibSocialApiLink + "/anime?q=" + title)
    href = ""
    console.log(response)
    for (let i in response.data) {
      if (id == response.data[i].shikimori_href.split("/")[4]) {
        href = response.data[i].slug_url
      }
    }
    clickFunc = animelib
    console.log(href)
  }
  else if (location.href.includes("/mangas/")) {
    let as = document.querySelectorAll(".mangalib > a")
    href = []
    for (let i in as) {
      if (as[i].href) {
        i = (as[i].href.split("?")[0].replace("https://mangalib.me/", "").replace("ru/", "").replace("book/", "").replace("ranobes/", "").replace("ranobe/", "").replace("manga/", "").replace("mangas/", ""))
        console.log(i)
        let response = await GetResourceAsync(LibSocialApiLink + "/manga?q=" + i.replace("-", " ").slice(0, 4) + "&site_id[]=1")
        console.log(LibSocialApiLink + "/manga?q=" + i.replace("-", " "))
        for (let u in response.data) {
          console.log(i, response.data[u].slug)
          if (i == response.data[u].slug_url || i == response.data[u].slug) {
            i = response.data[u].slug_url
          }
        }
        console.log(response)
        href.push(i)
      }
    }
    clickFunc = mangalib
  }
  else if (location.href.includes("/ranobe/")) {
    let as = document.querySelectorAll(".ranobelib > a")
    href = []
    for (let i in as) {
      if (as[i].href) {
        i = (as[i].href.split("?")[0].replace("https://ranobelib.me/", "").replace("ru/", "").replace("book/", "").replace("ranobes/", "").replace("ranobe/", "").replace("manga/", "").replace("mangas/", ""))
        console.log(i)
        let response = await GetResourceAsync(LibSocialApiLink + "/manga?q=" + i.replaceAll("-", " ").slice(0, 4) + "&site_id[]=3")
        console.log(LibSocialApiLink + "/manga?q=" + i.replace("-", " ").split(" ")[0])
        for (let u in response.data) {
          console.log(i, response.data[u].slug)
          if (i == response.data[u].slug_url || i == response.data[u].slug) {
            i = response.data[u].slug_url
          }
        }
        console.log(response)
        href.push(i)
      }
    }
    console.log(href)
    clickFunc = ranobelib
  }
  btn.addEventListener("click", async () => {
    btn.remove()
    console.log(href)
    clickFunc(href)
  })
  btn.style.cssText = `
        border-radius: 10px;
        opacity: 0.75;
        text-align: center;
        font-size: 25px;
        width: 100%;
        height: 40px;
        background-color: #e0ff9a;
        cursor: pointer;
    `
  btn.textContent = "Play"
  if (href || href.length) document.querySelectorAll('.c-image').forEach(e => e.appendChild(btn))
}
ready(addBtn)