Greasy Fork

MangaDex Search Page Enhancements

Adds follow buttons to the search page

// ==UserScript==
// @name         MangaDex Search Page Enhancements
// @namespace    Violentmonkey Scripts
// @version      1.0.0
// @description  Adds follow buttons to the search page
// @author       You
// @match        https://mangadex.com/?page=search&title=**
// @grant        none
// ==/UserScript==

(() => {
  'use strict';

  let d = document,
      th = d.createElement('th'),
      tableHead = d.querySelector('.table > thead > tr'),
      tableItems = d.querySelectorAll('.table > tbody > tr')

  getFollowedSeries().then(seriesFollowed => {
    insertAfter(th, tableHead.children[1])

    tableItems.forEach(item => {
      let id = item.children[1].firstElementChild.getAttribute('href').split('/')[2],
          td = d.createElement('td'),
          button = d.createElement('button')

      button.classList.add('btn', 'btn-xs')
      button.type = 'button'
      button.dataset.id = id
      button.addEventListener('click', e => toggleFollow(e))

      if (!seriesFollowed.includes(id)) {
        btnFollow(button)
        button.dataset.followed = false
      } else {
        btnUnfollow(button)
        button.dataset.followed = true
      }

      td.appendChild(button)
      insertAfter(td, item.children[1])
    })
  })

  let xhrRequest = url => {
    return new Promise((resolve, reject) => {
      $.ajax({
        url: url,
        type: 'GET',
        success: data => resolve(data),
        error: data => reject(data),
        contentType: false,
        processData: false

      });
    })
  }

  function toggleFollow(e) {
    let btn = e.target

    if (btn.dataset.followed === 'false') {
      btn.innerText = 'Following...'

      xhrRequest('/ajax/actions.ajax.php?function=manga_follow&id=' + btn.dataset.id)
        .then(data => {
          $("#message_container").html(data).show().delay(1500).fadeOut()
          btnUnfollow(btn)
        })
        .catch(e => {throw Error(e)})
    } else {
      btn.innerText = 'Unfolowing...'

      xhrRequest('/ajax/actions.ajax.php?function=manga_unfollow&id=' + btn.dataset.id)
        .then(data => {
          $("#message_container").html(data).show().delay(1500).fadeOut()
          btnFollow(btn)
        })
        .catch(e => {throw Error(e)})
    }
  }

  function btnFollow (btn) {
    btn.dataset.followed = false
    btn.innerText = 'Follow'
    btn.classList.add('btn-success')
    btn.classList.remove('btn-danger')
  }

  function btnUnfollow (btn) {
    btn.dataset.followed = true
    btn.innerText = 'Unfollow'
    btn.classList.add('btn-danger')
    btn.classList.remove('btn-success')
  }

  function getPage(url) {
    return new Promise((resolve, reject) => {
      let xhr = new XMLHttpRequest()
      xhr.open('GET', url)
      xhr.onload = () => {
        if (xhr.status >= 200 && xhr.status < 300) {
          resolve(xhr.response)
        } else {
          reject(xhr.statusText)
        }
      }
      xhr.onerror = () => reject(xhr.statusText)
      xhr.responseType = 'document'
      xhr.send()
    })
  }

  function getFollowedSeries() {
    return getPage('https://mangadex.com/follows')
      .then(data => {
      let followedItems = data.querySelectorAll('#manga_followed .table > tbody > tr'),
          listOfFollows = []

      followedItems.forEach(item => {
        listOfFollows.push(item.children[1].firstElementChild.getAttribute('href').split('/')[2])
      })

      return listOfFollows
    })
  }

  function insertAfter(el, referenceNode) {
    referenceNode.parentNode.insertBefore(el, referenceNode.nextSibling);
  }
})()