您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
colorize nicknames in Trovo chat
当前为
// ==UserScript== // @name trovonicknamecolorizer // @namespace http://tampermonkey.net/ // @version 0.2.6 // @description colorize nicknames in Trovo chat // @author yyko // @match https://trovo.live/* // @icon https://www.google.com/s2/favicons?domain=trovo.live // @run-at document-end // @grant none // ==/UserScript== (function() { 'use strict'; const maxAttemptsCount = 20; const attmeptDelay = 2000; const colorMap = new Map([ ["red","#FF0000"],//красный ["blue","#0000FF"],//синий ["green","#008000"],//зелёный ["firebrick","#B22222"],//кирпичный ["coral","#FF7F50"],//коралловый ["yellowgreen","#9ACD32"],//лайм ["orangered","#FF4500"],//красно-оранжевый ["seagreen","#2E8B57"],//морская волна ["goldenrod","#DAA520"],//красное золото ["chocolate","#D2691E"],//шоколадный ["cadetblue","#5F9EA0"],//серо-голубой ["dodgerblue","#1E90FF"],//васильковый ["hotpink","#FF69B4"],//ярко-розовый ["blueviolet","#8A2BE2"],//индиго ["springgreen","#00FF7F"],//салатовый ]); const colorNames = Array.from(colorMap.keys()); // Palette icon made by Google (https://www.flaticon.com/authors/google) const colorizerSvg = '<svg aria-hidden="true" class="svg-icon btn-icon size24" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="24" height="24"><path d="M12 1.5C6.202 1.5 1.5 6.202 1.5 12S6.202 22.5 12 22.5a1.748 1.748 0 0 0 1.295-2.923 1.733 1.733 0 0 1-.437-1.16c0-.969.781-1.75 1.75-1.75h2.059a5.835 5.835 0 0 0 5.833-5.834C22.5 5.677 17.798 1.5 12 1.5zM5.583 12c-.968 0-1.75-.782-1.75-1.75s.782-1.75 1.75-1.75c.969 0 1.75.782 1.75 1.75S6.552 12 5.583 12zm3.5-4.667c-.968 0-1.75-.781-1.75-1.75 0-.968.782-1.75 1.75-1.75.969 0 1.75.782 1.75 1.75 0 .969-.781 1.75-1.75 1.75zm5.834 0c-.969 0-1.75-.781-1.75-1.75 0-.968.781-1.75 1.75-1.75.968 0 1.75.782 1.75 1.75 0 .969-.782 1.75-1.75 1.75zm3.5 4.667c-.969 0-1.75-.782-1.75-1.75s.781-1.75 1.75-1.75c.968 0 1.75.782 1.75 1.75S19.385 12 18.417 12z" style="stroke-width:.0546871"/></svg>'; const classPrefix='clrz_'; // local storage tools function mapToStr(map){ return JSON.stringify(Object.fromEntries(map)); } function strToMap(str){ return new Map(Object.entries(JSON.parse(str))); } function loadData(entryName='users'){ let data = localStorage.getItem(entryName); if(data){ return strToMap(data); }else{ return null; } } function saveData(data,entryName='users'){ localStorage.setItem(entryName,mapToStr(data)); } // -- // users tools let users = loadData(); if(users){ if(localStorage.getItem('tncts_localUsers')){ localStorage.removeItem('tncts_localUsers'); } }else{ users = new Map(); } let settings = loadData('colorizerSettings'); if(!settings){ settings = new Map([['baseLock',false],['interfaceState',true]]); } function addUser(name){ let userColor = getRandomColorName(); createUserClass(name,userColor); changeUserColor(name,userColor); return userColor; } function delUser(name){ users.delete(name); saveData(users); } // -- // color tools function getRandomColorName(){ return colorNames[Math.round(Math.random()*colorNames.length)]; } function getUserColor(name){ return users.get(name); } function changeUserColor(name,colorName){ let ccr=checkColor(colorName); if(ccr){ let cv; if(ccr==1){ cv=colorMap.get(colorName.toLocaleLowerCase()); }else if(ccr==2){ cv=colorName; } changeUserClass(name,cv); users.set(name,cv); saveData(users); } } function checkColor(colorName){ if(colorMap.has(colorName)){ return 1; }else if(colorName.match(/^#[0-9a-f]{3}$|^#[0-9a-f]{4}$|^#[0-9a-f]{6}$|^#[0-9a-f]{8}$/)){ return 2; }else{ return false; } } // -- // stylesheet let ss; let bayav=new Map(); let ssav=false; function initSS(shappend=true){ ss=ss||document.createElement('style'); if(shappend) document.head.appendChild(ss); ssav=true; return ss; } function disableSS(){ ss.remove(); ssav=false; } function createUserClass(name,color){ ss.innerHTML=ss.innerHTML+`.${classPrefix}${name}{color:${color} !important;}`; bayav.set(name,color); } function changeUserClass(name,newcolor){ ss.innerHTML.replace(`.${classPrefix}${name}{color:${getUserColor(name)} !important;}`,"$`"+`.${classPrefix}${name}{color:${newcolor} !important;}`+"$'"); } function getUserClassName(name){ return `${classPrefix}${name}`; } // -- // iterface function getSettingsButtonElement(){ let featureBox=document.getElementsByClassName('input-feature-box')[0]; if(featureBox){ return featureBox.getElementsByClassName('cat-button normal icon')[0]; } } let cbtn; function createColorizerButton(){ let sbe=getSettingsButtonElement(); if(sbe){ cbtn=sbe.cloneNode(false); cbtn.setAttribute('data-enclave','colorizer'); cbtn.innerHTML=colorizerSvg; cbtn.color='white'; if(settings.get('interfaceState')){ cbtn.classList.add('active'); } getSettingsButtonElement().after(cbtn); cbtn.addEventListener('click',toggleInterface); } } let enabled=false; function toggleInterface(){ enabled=settings.get('interfaceState'); if(enabled){ // on disable interface cbtn.classList.remove('active'); disableSS(); }else{ // on enable interface cbtn.classList.add('active'); initSS(); } settings.set('interfaceState',!enabled); //aka migration if(settings.has('baseLock')) settings.delete('baseLock'); //-- saveData(settings,'colorizerSettings'); } // -- // ***, ****** ******* ***** let guiShouldBeCreated=true; // *-- function onmessage(mutations,observer){ if(guiShouldBeCreated){ guiShouldBeCreated=false; createColorizerButton(); } for(let mutation of mutations){ for(let msgel of mutation.addedNodes){ let nameel=msgel.getElementsByClassName('nickname-box')[0]; let name; if(nameel){ name=nameel.getElementsByClassName('nick-name')[0].title; if(!users.has(name)) addUser(name); else if(!bayav.has(name)) createUserClass(name,getUserColor(name)); // команда на изменение цвета let msgtextel=msgel.getElementsByClassName('content')[0]; if(msgtextel){ let msgtext=msgtextel.innerText; let res=msgtext.match(/^!color (.*)/); if(res){ let colorValue=res[1]; if(checkColor(colorValue)){ changeUserColor(name,res[1]); }else{ console.warn('color is not available'); } } } // применение цвета к новому сообщению nameel.classList.add(getUserClassName(name)); } } } } // initialization let launched=false; let chatElement; let chatObserver; const obsConfig={childList:true}; function setChatElement(){ chatElement = document.getElementsByClassName('chat-list')[0]; return chatElement; } let attemptsLeft = maxAttemptsCount; let attemptsTimer; function initChat(){ if(setChatElement()){ chatObserver = new MutationObserver(onmessage); chatObserver.observe(chatElement,obsConfig); console.warn('started'); launched=true; }else{ if(attemptsLeft>0){ console.warn('attempts left to start: ',attemptsLeft); attemptsLeft--; attemptsTimer=setTimeout(initChat,attmeptDelay); }else{ console.warn('cant find chat element'); } } } function init(){ initChat(); if(launched){ initSS(enabled); let baseElement = document.getElementsByClassName('base-container')[0]; if(baseElement){ let baseObserver = new MutationObserver(restart); baseObserver.observe(baseElement,obsConfig); }else{ console.warn('cant find base-container'); } } } function restart(){ console.warn('restarted'); attemptsLeft=maxAttemptsCount; if(launched){ chatObserver.disconnect(); if(cbtn){ cbtn.remove(); guiShouldBeCreated=true; } launched=false; initChat(); } } init(); // -- })();