Youtube live, Simple Chat Stylizer

Possible to change config in source code. Keep to display moderator chat in a while.

目前為 2020-10-12 提交的版本,檢視 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Youtube live, Simple Chat Stylizer
// @name:ja      Youtube live, シンプルチャットスタイル
// @description  Possible to change config in source code. Keep to display moderator chat in a while.
// @description:ja スクリプトのソース内で設定変更できます。モデレータチャットを一定時間、表示し続けます。
// @namespace    http://tampermonkey.net/
// @version      0.6
// @author       You
// @match        https://www.youtube.com/live_chat*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    /*
    // ================
    // my config
    // ================
    // font size
    var chatFontSize = 15;
    // if true, add char frame to message
    var isEnableCharFrame = false;
    // if true, author name is hide
    var isHideAuthorName = false;
    // if true, author name is display to right side in chat window
    var isAuthorNameRightSide = true;
    var authorNameMaxWidth = 100;
    // if true, user thumbnail is hide
    var isHideThumbnail = false;
    // if true, member badge is hide
    var isHideBadge = false;
    // if true, input panel is hide (you can't post chat / super chat)
    var isHideFooter = false;
    // if true, header is hide
    var isHideHeader = true;
    // if true, show/hidden toggle button is hide
    var isHideToggleButton = false;
    // if true, common emotes is hide
    var isHideCommonEmotes = true;
    // if false, moderator chat is not fixed to bottom
    var isFixModarator = true;
    // number of seconds moderator chat is display
    var moderatorChatTimeout = 20;
*/

    // ================
    // config
    // ================
    // font size
    var chatFontSize = 13;
    // if true, add char frame to message
    var isEnableCharFrame = false;
    // if true, author name is hide
    var isHideAuthorName = false;
    // if true, author name is display to right side in chat window
    var isAuthorNameRightSide = true;
    var authorNameMaxWidth = 100;
    // if true, user thumbnail is hide
    var isHideThumbnail = false;
    // if true, member badge is hide
    var isHideBadge = false;
    // if true, input panel is hide (you can't post chat / super chat)
    var isHideFooter = false;
    // if true, header is hide
    var isHideHeader = true;
    // if true, show/hidden toggle button is hide
    var isHideToggleButton = false;
    // if true, common emotes is hide
    var isHideCommonEmotes = true;
    // if false, moderator chat is not fixed to bottom
    var isFixModarator = true;
    // number of seconds moderator chat is display
    var moderatorChatTimeout = 20;
    // ================

    setTimeout(function () {
        var stylesheet = "";

        // bold, font-size
        stylesheet += "#message.yt-live-chat-text-message-renderer { font-weight: bold; font-size: " + chatFontSize +"px; }";
        if (isEnableCharFrame) {
            stylesheet += "#message.yt-live-chat-text-message-renderer { color: #ffffff; letter-spacing : 4px; text-shadow : 2px 2px 1px #003366, -2px 2px 1px #003366, 2px -2px 1px #003366, -2px -2px 1px #003366, 2px 0px 1px #003366, 0px  2px 1px #003366, -2px  0px 1px #003366, 0px -2px 1px #003366; }";
            stylesheet += "yt-live-chat-renderer { background: #0000; } #item-scroller { overflow-y: hidden !important; }";
        }

        // simple #input-panel styles
        stylesheet += "yt-live-chat-message-input-renderer { padding: 4px 16px; }";
        // stylesheet += "#input-panel #container { position: relative; }";
        // stylesheet += "#input-panel #container > #buttons { position: absolute; top: 0; right: 0; transform: scale(0.8); margin: 0; }";

        if (isHideAuthorName) {
            stylesheet += "#author-name.yt-live-chat-author-chip { display: none; }";
        } else if (isAuthorNameRightSide) {
            stylesheet += "#content #author-name.yt-live-chat-author-chip { position: absolute; right: 10px; top: 0px; opacity: 0.7; transform: scale(0.8); }";
        } else {
            stylesheet += "#author-name.yt-live-chat-author-chip { max-width: " + authorNameMaxWidth + "px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }";
        }
        if (isHideThumbnail) {
            stylesheet += "#author-photo { display: none !important; }";
        }
        if (isHideBadge) {
            stylesheet += "#chat-badges { display: none !important; }";
        }
        if (isHideFooter) {
            stylesheet += "#panel-pages { display: none !important; }";
        }
        if (isHideHeader) {
            stylesheet += "yt-live-chat-header-renderer { display: none !important; }";
        }
        if (isHideToggleButton) {
            stylesheet += "#show-hide-button.ytd-live-chat-frame { display: none !important; }";
        }
        if (isHideCommonEmotes) {
            stylesheet += "yt-emoji-picker-renderer #category-buttons { display: none !important; }";
            var emoteCategories = ["UCkszU2WH9gy1mb0dV-11UJg/CIW60IPp_dYCFcuqTgodEu4IlQ", "😀", "🐵", "🍇", "🌍", "🎃", "👓", "🏧"];
            for (var i = 0; i < emoteCategories.length; i++) {
                stylesheet += "[aria-activedescendant='" + emoteCategories[i] + "'] { display: none; }";
            }
        }

        // moderator chats is fixed to bottom in chat window
        stylesheet += "#moderator-chat-container { position: absolute; bottom: 0; background: #fff; left: 0; right: 0; z-index: 10000; }";

        // reload button
        stylesheet += "#chat-reload-button { display: inline-block; position: absolute; right: 0; bottom: 0; color: #fff; background: #1E90FF; opacity: 0; padding: 3px; transition: opacity .2s linear; cursor: pointer; z-index: 10001; }";
        stylesheet += "yt-live-chat-app:hover #chat-reload-button { opacity: 1; }";

        // apply style
        var $style = document.createElement("style");
        $style.innerText = stylesheet;
        document.body.appendChild($style);

        // fix moderator chat
        var $container = document.createElement("div");
        $container.id = "moderator-chat-container";
        document.querySelector("yt-live-chat-item-list-renderer #contents").appendChild($container);

        // reload button
        var $reload = document.createElement("a");
        $reload.id = "chat-reload-button";
        $reload.innerText = "Reload";
        $reload.onclick = reloadButtonOnClick;
        document.querySelector("yt-live-chat-app > #contents").appendChild($reload);

        setInterval(observeModerator, 2000);
    }, 5000);

    function reloadButtonOnClick() {
        location.href = location.href;
    }

    function appendModeratorChat($chat) {
        document.querySelector("#moderator-chat-container").appendChild($chat);
        setTimeout(function () {
            $chat.remove();
        }, moderatorChatTimeout * 1000);
    }

    function observeModerator() {
        var $chats;
        if (isFixModarator) {
            $chats = document.querySelectorAll("yt-live-chat-text-message-renderer[author-type='moderator'], yt-live-chat-text-message-renderer[author-type='owner']");
        } else {
            $chats = document.querySelectorAll("yt-live-chat-text-message-renderer[author-type='owner']");
        }
        for (var i = 0; i < $chats.length; i++) {
            appendModeratorChat($chats[i]);
        }
    }
})();