move-youtube-comments-to-sidebar

Make the Youtube comments section visible from the sidebar

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name move-youtube-comments-to-sidebar
// @version 1.0.1
// @license MIT
// @name:ja YouTubeのコメント欄をサイドバーで見れるようにする
// @author yakisova41
// @description Make the Youtube comments section visible from the sidebar
// @description:ja YouTubeのコメント欄をサイドバーから見れるようにします。
// @match https://www.youtube.com/*
// @namespace https://yakisova.com
// @icon data:image/png;base64,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
// ==/UserScript==

(() => {
  var __create = Object.create;
  var __defProp = Object.defineProperty;
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  var __getOwnPropNames = Object.getOwnPropertyNames;
  var __getProtoOf = Object.getPrototypeOf;
  var __hasOwnProp = Object.prototype.hasOwnProperty;
  var __esm = (fn, res) => function __init() {
    return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
  };
  var __commonJS = (cb, mod) => function __require() {
    return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
  };
  var __copyProps = (to, from, except, desc) => {
    if (from && typeof from === "object" || typeof from === "function") {
      for (let key of __getOwnPropNames(from))
        if (!__hasOwnProp.call(to, key) && key !== except)
          __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
    }
    return to;
  };
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
    // If the importer is in node compatibility mode or this is not an ESM
    // file that has been converted to a CommonJS file using a Babel-
    // compatible transform (i.e. "__esModule" has not been set), then set
    // "default" to the CommonJS "module.exports" for node compatibility.
    isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
    mod
  ));

  // src/findElement.ts
  var findElement;
  var init_findElement = __esm({
    "src/findElement.ts"() {
      findElement = (selector) => {
        return new Promise((resolve) => {
          const interval = setInterval(() => {
            const elem = document.querySelector(selector);
            if (elem !== null) {
              clearInterval(interval);
              resolve(elem);
            }
          });
        });
      };
    }
  });

  // src/css/style.css
  var require_style = __commonJS({
    "src/css/style.css"(exports, module) {
      (function() {
        if (!document.getElementById("7e1065fb51bb77ce35a77cffc916cbd9c74a211ded1e7f6c59e5d2b931e3a9eb")) {
          var e = document.createElement("style");
          e.id = "7e1065fb51bb77ce35a77cffc916cbd9c74a211ded1e7f6c59e5d2b931e3a9eb";
          e.textContent = `.mycsButton_cbfc566d866c2a43bc5bcf5094735b68_1{background:var(--yt-spec-badge-chip-background);border:none;color:var(--yt-spec-text-primary);font-size:14px;line-height:36px;height:36px;padding:0 16px;margin-left:8px;border-radius:18px;cursor:pointer;font-family:"Roboto; Arial; sans-serif;";position:relative;display:flex;justify-content:center;align-items:center}.mycsButton_cbfc566d866c2a43bc5bcf5094735b68_1>svg{fill:var(--yt-spec-text-primary)}.mycsButtonDown_cbfc566d866c2a43bc5bcf5094735b68_1{border-radius:18px;position:absolute;width:100%;height:100%;top:0;left:0}.mycsButton_cbfc566d866c2a43bc5bcf5094735b68_1:hover{background:var(--yt-spec-mono-tonal-hover)}.mycsButtonDown_cbfc566d866c2a43bc5bcf5094735b68_1:active{background:var(--yt-spec-touch-response);opacity:.1}.mycsCommentArea_cbfc566d866c2a43bc5bcf5094735b68_1{width:100%}.mycsCommentAreaSecondaryInner_cbfc566d866c2a43bc5bcf5094735b68_1{height:var(--ytd-watch-flexy-chat-max-height);margin-bottom:20px}.mycsCommentAreaBelow_cbfc566d866c2a43bc5bcf5094735b68_1{height:calc(100vh - 56.25vw - var(--ytd-margin-6x) - 56px);margin:20px 0}.mycsCommentInner_cbfc566d866c2a43bc5bcf5094735b68_1{width:100%;height:100%;border-radius:12px;border:solid 1px var(--ytd-searchbox-legacy-button-border-color)}.mycsComments_cbfc566d866c2a43bc5bcf5094735b68_1{overflow-y:scroll;overscroll-behavior:contain;padding:0 20px;height:100%}.mycsComments_cbfc566d866c2a43bc5bcf5094735b68_1::-webkit-scrollbar-thumb{height:56px;border-radius:8px;border:4px solid transparent;background-clip:content-box;background-color:var(--yt-spec-icon-disabled)}.mycsComments_cbfc566d866c2a43bc5bcf5094735b68_1::-webkit-scrollbar{background:transparent;width:16px}.mycsHidden_cbfc566d866c2a43bc5bcf5094735b68_1{display:none}`;
          document.head.appendChild(e);
        }
      })();
      module.exports = JSON.parse('{"mycsButton":"mycsButton_cbfc566d866c2a43bc5bcf5094735b68_1","mycsButtonDown":"mycsButtonDown_cbfc566d866c2a43bc5bcf5094735b68_1","mycsCommentArea":"mycsCommentArea_cbfc566d866c2a43bc5bcf5094735b68_1","mycsCommentAreaSecondaryInner":"mycsCommentAreaSecondaryInner_cbfc566d866c2a43bc5bcf5094735b68_1","mycsCommentAreaBelow":"mycsCommentAreaBelow_cbfc566d866c2a43bc5bcf5094735b68_1","mycsCommentInner":"mycsCommentInner_cbfc566d866c2a43bc5bcf5094735b68_1","mycsComments":"mycsComments_cbfc566d866c2a43bc5bcf5094735b68_1","mycsHidden":"mycsHidden_cbfc566d866c2a43bc5bcf5094735b68_1"}');
    }
  });

  // src/addButton.ts
  var import_style, addButton_default;
  var init_addButton = __esm({
    "src/addButton.ts"() {
      init_findElement();
      import_style = __toESM(require_style());
      addButton_default = async (eventElement) => {
        const button = document.createElement("button");
        button.className = import_style.default.mycsButton;
        button.innerHTML = button.innerHTML + `<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24" viewBox="0 0 24 24" width="24"><path d="M8,7h8v2H8V7z M8,13h5v-2H8V13z M5,3v13h10h0.41l0.29,0.29L19,19.59V3H5 M4,2h16v20l-5-5H4V2L4,2z"></path></svg>`;
        const buttonDown = document.createElement("div");
        button.appendChild(buttonDown);
        buttonDown.className = import_style.default.mycsButtonDown;
        const buttonsParent = await findElement(
          "ytd-menu-renderer.ytd-watch-metadata"
        );
        buttonsParent.appendChild(button);
        button.onclick = (e) => {
          eventElement.dispatchEvent(
            new CustomEvent("toggleClick", {
              detail: e
            })
          );
        };
      };
    }
  });

  // src/createComments.ts
  async function createComments() {
    const root = document.createElement("div");
    root.classList.add(import_style2.default.mycsCommentArea);
    root.innerHTML = `<div class=${import_style2.default.mycsCommentInner}><div class=${import_style2.default.mycsComments}></div></div>`;
    const commentsOuter = root.querySelector(`.${import_style2.default.mycsComments}`);
    const comments = await findElement("ytd-comments#comments");
    return {
      root,
      commentsOuter,
      comments
    };
  }
  async function smallMode(root) {
    const panels = await findElement("#primary-inner > #below > #panels");
    panels.before(root);
    root.classList.add(import_style2.default.mycsCommentAreaBelow);
    root.classList.remove(import_style2.default.mycsCommentAreaSecondaryInner);
  }
  async function bigMode(root) {
    const panels = await findElement("#secondary-inner > #panels");
    panels.before(root);
    root.classList.add(import_style2.default.mycsCommentAreaSecondaryInner);
    root.classList.remove(import_style2.default.mycsCommentAreaBelow);
  }
  var import_style2, createComments_default;
  var init_createComments = __esm({
    "src/createComments.ts"() {
      import_style2 = __toESM(require_style());
      init_findElement();
      createComments_default = async (eventElement) => {
        const { root, comments, commentsOuter } = await createComments();
        if (window.innerWidth > 1015) {
          bigMode(root);
        } else {
          smallMode(root);
        }
        let innerWidthTmp = 0;
        window.addEventListener("resize", () => {
          setTimeout(async () => {
            if (innerWidthTmp > 1015 && window.innerWidth < 1015) {
              await smallMode(root);
              const related = commentsOuter.querySelector("#related");
              findElement("#primary-inner > #below").then(
                (e) => e.appendChild(related)
              );
            } else if (innerWidthTmp < 1015 && window.innerWidth > 1015) {
              bigMode(root);
            }
            innerWidthTmp = window.innerWidth;
          }, 1);
        });
        eventElement.addEventListener(
          "toggleComments",
          async (e) => {
            if (e.detail) {
              root.classList.add(import_style2.default.mycsHidden);
              const commentParent = await findElement(
                "#primary-inner > #below"
              );
              commentParent.appendChild(comments);
            } else {
              root.classList.remove(import_style2.default.mycsHidden);
              commentsOuter.appendChild(comments);
            }
          }
        );
      };
    }
  });

  // src/main.ts
  function pageChangeListener(eventelement) {
    let beforeHref = "";
    const observer = new MutationObserver(() => {
      const href = location.href;
      if (href !== beforeHref) {
        eventelement.dispatchEvent(
          new CustomEvent("pageChange", {
            detail: {
              beforeHref,
              newHref: href
            }
          })
        );
      }
      beforeHref = href;
    });
    observer.observe(document.querySelector("body"), {
      childList: true,
      subtree: true
    });
  }
  function main() {
    const mycs = document.createElement("div");
    let isButtonCreated = false;
    let isCommentsCreated = false;
    let commentsHide = true;
    pageChangeListener(mycs);
    mycs.addEventListener(
      "pageChange",
      async (e) => {
        const { newHref } = e.detail;
        const pageName = newHref.split("/")[3].split("?")[0];
        if (pageName === "watch") {
          console.log(isButtonCreated);
          if (!isButtonCreated) {
            isButtonCreated = true;
            await addButton_default(mycs);
          }
          if (!isCommentsCreated) {
            isCommentsCreated = true;
            await createComments_default(mycs);
          }
          commentsHide = true;
          mycs.dispatchEvent(
            new CustomEvent("toggleComments", {
              detail: commentsHide
            })
          );
        }
      }
    );
    mycs.addEventListener("toggleClick", () => {
      if (commentsHide) {
        commentsHide = false;
      } else {
        commentsHide = true;
      }
      mycs.dispatchEvent(
        new CustomEvent("toggleComments", {
          detail: commentsHide
        })
      );
    });
  }
  var init_main = __esm({
    "src/main.ts"() {
      init_addButton();
      init_createComments();
    }
  });

  // src/index.ts
  var require_src = __commonJS({
    "src/index.ts"() {
      init_main();
      main();
    }
  });
  require_src();
})();