idthi / clien.net Top Comments

// ==UserScript==
// @name        clien.net Top Comments
// @description Reorder comments by number of Likes
// @namespace   https://openuserjs.org/scripts/idthi/
// @match       https://www.clien.net/service/board/*
// @grant       GM_addStyle
// @version     1.0
// @author      deth
// @updateURL   https://openuserjs.org/meta/idthi/clien.net_Top_Comments.meta.js
// @downloadURL https://openuserjs.org/install/idthi/clien.net_Top_Comments.user.js
// @copyright   2022, idthi (https://openuserjs.org/users/idthi)
// @license     MIT
// ==/UserScript==

// jshint esversion: 11

GM_addStyle(`
span.hearts { letter-spacing: -0.2em; }
`);

const comments = [...document.querySelectorAll("div.comment_row")];

const get_likes = x => parseInt(x?.querySelector("button.comment_symph>strong")?.innerText) || 0;
comments.forEach(x => x.likes = get_likes(x));

{
  // https://en.wikipedia.org/wiki/Braille_Patterns
  const box_chars = ["","⡀","⡄","⡆","⡇","⣇","⣧","⣷","⣿"];
  const max_top_comment = 64;
  [...comments]
    .sort((x, y) => y.likes - x.likes)
    .slice(0, max_top_comment)
    .filter(x => x.likes > 1)
    .forEach((x, i) => {
      const hearts = document.createElement("span");
      hearts.classList.add("hearts");
      const len = box_chars.length - 1;
      hearts.innerText
        = box_chars[len].repeat(x.likes / len)
        + box_chars[x.likes % len];
      hearts.style.color = `hsl(${Math.min(i, 16) / 16.0 * 270.0}deg 100% 50%)`;
      x.querySelector("div.comment_content_symph")?.appendChild(hearts);
    });
}

{
  const sorted = comments
    .reduce((acc, x) => {
      if (x.classList.contains("re") && acc.length > 0) {
        const last = acc.at(-1);
        last.replies.push(x);
        last.likes = Math.max(x.likes, last.likes);
      } else {
        acc.push({ comment: x, likes: x.likes, replies: [] });
      }
      return acc;
    }, [])
    .sort((xs, ys) => ys.likes - xs.likes)
    .flatMap(xs => [xs.comment, ...xs.replies.sort((x, y) => y.likes - x.likes)]);
  sorted[0]?.parentNode?.append(...sorted);
}