Greasy Fork is available in English.
"파트너 스트리머이며 방송 매니저가 아닌 채팅"의 닉네임과 메시지를 연두색으로 표시, 은신한 닉네임 가독성 개선, 닉네임 백그라운드 컬러 제거
当前为
// ==UserScript==
// @name Chzzk_Live: Chatting Plus
// @namespace Chzzk_Live: Chatting Plus
// @version 1.3
// @description "파트너 스트리머이며 방송 매니저가 아닌 채팅"의 닉네임과 메시지를 연두색으로 표시, 은신한 닉네임 가독성 개선, 닉네임 백그라운드 컬러 제거
// @author DOGJIP
// @match https://chzzk.naver.com/*
// @grant none
// @run-at document-end
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const LIGHT_GREEN = "rgb(102,200,102)";
let chatObserver = null;
// 유틸: 닉네임 색상이 너무 어두운 경우 스타일 제거
function fixUnreadableNicknameColor(nicknameElem) {
if (!nicknameElem) return;
const computedColor = window.getComputedStyle(nicknameElem).color;
const rgbaMatch = computedColor.match(/rgba?\((\d+), ?(\d+), ?(\d+)(?:, ?([0-9.]+))?\)/);
if (!rgbaMatch) return;
const r = parseInt(rgbaMatch[1], 10);
const g = parseInt(rgbaMatch[2], 10);
const b = parseInt(rgbaMatch[3], 10);
const a = rgbaMatch[4] !== undefined ? parseFloat(rgbaMatch[4]) : 1;
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
const visibility = brightness * a;
if (visibility < 50) {
nicknameElem.style.color = ''; // 기본색으로 복원
}
}
// 유틸: 닉네임 백그라운드 색상 제거
function removeBackgroundColor(nicknameElem) {
if (!nicknameElem) return;
const bgTarget = nicknameElem.querySelector('[style*="background-color"]');
if (bgTarget) {
bgTarget.style.removeProperty('background-color');
}
}
function processChatMessage(messageElem) {
if (messageElem.getAttribute('data-partner-processed') === 'true') return;
const isPartner = messageElem.querySelector('[class*="name_icon__zdbVH"]') !== null;
const badgeImgs = messageElem.querySelectorAll('.badge_container__a64XB img');
let isManager = false;
let isStreamer = false;
badgeImgs.forEach(img => {
if (img.src.includes("manager.png")) isManager = true;
if (img.src.includes("streamer.png")) isStreamer = true;
});
const nicknameElem = messageElem.querySelector('.live_chatting_username_nickname__dDbbj');
const textElem = messageElem.querySelector('.live_chatting_message_text__DyleH');
// 항상 닉네임 가독성 개선 시도
fixUnreadableNicknameColor(nicknameElem);
// 항상 닉네임 백그라운드 색상 제거 시도
removeBackgroundColor(nicknameElem);
// 조건: 파트너이면서 매니저가 아니며, 스트리머 본인도 아님
if (isPartner && !isManager && !isStreamer) {
if (nicknameElem) nicknameElem.style.color = LIGHT_GREEN;
if (textElem) textElem.style.color = LIGHT_GREEN;
}
messageElem.setAttribute('data-partner-processed', 'true');
}
function setupChatObserver() {
if (chatObserver) chatObserver.disconnect();
const chatContainer = document.querySelector('[class*="live_chatting_list_wrapper__"]');
if (!chatContainer) {
setTimeout(setupChatObserver, 500);
return;
}
const existingMessages = chatContainer.querySelectorAll('[class^="live_chatting_message_chatting_message__"]');
existingMessages.forEach(msg => processChatMessage(msg));
chatObserver = new MutationObserver(mutations => {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (node.nodeType !== 1) return;
if (node.className?.includes('live_chatting_message_chatting_message__')) {
processChatMessage(node);
} else {
node.querySelectorAll?.('[class^="live_chatting_message_chatting_message__"]').forEach(processChatMessage);
}
});
});
});
chatObserver.observe(chatContainer, { childList: true, subtree: true });
}
function setupSPADetection() {
let lastUrl = location.href;
const onUrlChange = () => {
if (location.href !== lastUrl) {
lastUrl = location.href;
setTimeout(setupChatObserver, 1000);
}
};
const wrapHistoryMethod = (method) => {
const original = history[method];
history[method] = function (...args) {
original.apply(this, args);
onUrlChange();
};
};
wrapHistoryMethod("pushState");
wrapHistoryMethod("replaceState");
window.addEventListener("popstate", onUrlChange);
}
function init() {
setupChatObserver();
setupSPADetection();
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();