Affinity to You

Shows the "Affinity to You" that all users who have commented on any topic on MAL have with you!

目前為 2021-04-03 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Affinity to You
// @namespace    AffinityShow
// @version      0.8
// @description  Shows the "Affinity to You" that all users who have commented on any topic on MAL have with you!
// @author       hacker09
// @match        https://myanimelist.net/forum/?topicid=*
// @icon         https://www.google.com/s2/favicons?domain=myanimelist.net
// @run-at       document-end
// @grant        none
// ==/UserScript==

(function() {
  'use strict';
  var TimesExecuted = 0; //Create a new global variable
  var UserAffinityList = []; //Create a new global array
  var MALUserParsedList = new Map(); //Creates a new map to later add all non-dup mal usernames on the page
  var ScriptUsername = document.querySelector("a.header-profile-link").innerText; //Gets the script username

  if (document.querySelector("#quickReply") !== null) //If the topic isn't locked
  { //Starts the if condition
    var AffinityList = document.createElement("button"); //Creates a btn element
    AffinityList.setAttribute("style", "display: none; background-color: snow; margin-left: 10px;"); //The CSS for the "button"
    AffinityList.setAttribute("id", "AffinityList"); //Adds an ID to the button
    AffinityList.setAttribute("class", "inputButton"); //Adds a class to the button
    document.querySelector("#quickReply").prepend(AffinityList); //Append the button above the text box element

    var ShowAffinityList = document.createElement("input"); //Creates an a element
    ShowAffinityList.setAttribute("style", "background-color: #4165ba;"); //The CSS for the input btn
    ShowAffinityList.setAttribute("id", "ShowAffinityList"); //Adds an ID to the input btn
    ShowAffinityList.setAttribute("class", "inputButton"); //Adds a class to the input btn
    ShowAffinityList.setAttribute("value", "      Show Affinity list"); //Adds the input btn default text
    ShowAffinityList.setAttribute("readonly", "readonly"); //Make the input btn default text not editable
    document.querySelector("#quickReply").prepend(ShowAffinityList); //Append the input btn above the text box element

    document.querySelector("#ShowAffinityList").onclick = function() { //When the Show Affinity button is clicked
      var AffinityList = document.querySelector("#AffinityList"); //Store the Affinity List to a variable
      if (AffinityList.style.display === 'none') { //If the Affinity list is hidden
        AffinityList.style.display = ''; //Hide the Affinity List
        document.querySelector("#ShowAffinityList").value = "      Hide Affinity list"; //Change the Show Affinity List text to Hide Affinity List
      } else { //If the Affinity list is being shown
        AffinityList.style.display = 'none'; //Show the Affinity List
        document.querySelector("#ShowAffinityList").value = "      Show Affinity list"; //Change the Hide Affinity List text to Show Affinity List
      } //Finishes the else condition
    }; //Finishes the onclick event listener
  } //Finishes the if condition

  MALUserParsedList.set(ScriptUsername, {}); //Add the script username to the map,so that the script won't fetch the script user profile
  MALUserParsedList.set('removed-user', {}); //Add the 'removed-user' username to the map,so that the script won't fetch the non existent user profile

  window.onscroll = function() { //Starts the onscroll event listener
    TimesExecuted += 1; //Sum the total amount of times that the mouse was moved
    if (TimesExecuted === 1) //If it's the first time that the mouse was moved
    { //Starts the if condition
      document.querySelectorAll('td.forum_boardrow2 > div > div > a > strong').forEach(async function(UserName) { //Execute this function for each username on the topic page
        if (!MALUserParsedList.has(UserName.innerText)) { //If the username isn't already on the map
          MALUserParsedList.set(UserName.innerText, {}); //Add the username on the map

          const html = await (await fetch('https://myanimelist.net/profile/' + UserName.innerText)).text(); //Gets the fetch response
          var newDocument = new DOMParser().parseFromString(html, 'text/html'); //Parses the fetch response
          var AffinityPercentage; //Make the variable global
          if (newDocument.querySelector("span[class*='bar-inner']") !== null) //If the element containing the affinity % exists
          { //Starts the if condition
            AffinityPercentage = newDocument.querySelector("span[class*='bar-inner']").innerText.replace('--', '-').trim(); //Gets the affinity %
          } //Finishes the if condition
          else //If the element containing the affinity % doesn't exist
          { //Starts the else condition
            AffinityPercentage = ' Unknown'; //Sets the affinity % to Unknown
          } //Finishes the else condition

          if (AffinityPercentage.match('-') === null && AffinityPercentage.match('Unknown') === null) //If the - symbol doesn't exist and if the affinity isn't Unknown
          { //Starts the if condition
            UserAffinityList.push('<a href="' + UserName.parentElement.href + '" target="_blank" title="Click to open the ' + UserName.innerText + '\'s Profile">' + UserName.innerText + ' ' + AffinityPercentage + '</a>'); //Store all the topic User Names and links

            AffinityPercentage = '<a href="https://myanimelist.net/sharedanime.php?u1=' + UserName.innerText + '&u2=' + ScriptUsername + '" target="_blank" title="Click to open the Shared Anime page between you and ' + UserName.innerText + '"><strong style="color:blue; font-weight: normal;">Affinity to You ' + AffinityPercentage + '</strong></a>'; //Make the text blue
          } //Finishes the if condition
          else //If the - symbol DOESN'T exist
          { //Starts the else condition
            AffinityPercentage = '<a href="https://myanimelist.net/sharedanime.php?u1=' + UserName.innerText + '&u2=' + ScriptUsername + '" target="_blank" title="Click to open the Shared Anime page between you and ' + UserName.innerText + '"><strong style="color:red; font-weight: normal;">Affinity to You ' + AffinityPercentage + '</strong>'; //Make the text red
          } //Finishes the else condition

          window.jQuery('td.forum_boardrow2 > div > div > a > strong:contains("' + UserName.innerText + '")').parent().parent().parent().after(AffinityPercentage); //Add the affinity % to every topic reply that matches the fetched profile username
        } //Finishes the if condition

        if (document.querySelector("#quickReply") !== null) //If the topic isn't locked
        { //Starts the if condition
          document.querySelector("#AffinityList").innerHTML = UserAffinityList.sort(function(a, b) { //Add the sorted list to the button element
            var aA = parseFloat(a.match(/\d+(?:\.\d+)?(?=%)/)); //Get only the Affinity % numbers
            var bA = parseFloat(b.match(/\d+(?:\.\d+)?(?=%)/)); //Get only the Affinity % numbers
            return bA > aA ? 1 : -1; //Compare the Affinity % and sort the array
          }).join('<br><br>'); //Finishes the sorting condition and add "spaces" between the links
        } //Finishes the if condition

      }); //Finishes the async function
    } //Finishes the if condition
  }; //Finishes the onscroll event listener
})();