您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Fixes some Tinychat beta room annoyances and adds useful features.
当前为
// ==UserScript== // @name Tinychat Enhancement Suite // @namespace https://greasyfork.org/en/users/27283-mutationobserver // @version 2017-09-08--5 // @description Fixes some Tinychat beta room annoyances and adds useful features. // @author MutationObserver // @match https://tinychat.com/room/* // @exclude https://tinychat.com/room/*?1 // @grant GM_setValue // @grant GM_getValue // @grant GM_listValues // ==/UserScript== /* jshint -W097 */ //'use strict'; var webappElem = document.querySelector("tinychat-webrtc-app").shadowRoot; var chatlogElem = webappElem.querySelector("tinychat-chatlog").shadowRoot; var titleElem = webappElem.querySelector("tinychat-title").shadowRoot; var sidemenuElem = webappElem.querySelector("tinychat-sidemenu").shadowRoot; var videolistElem = webappElem.querySelector("tinychat-videolist").shadowRoot; var chatlistElem = sidemenuElem.querySelector("tinychat-chatlist").shadowRoot; var userlistElem = sidemenuElem.querySelector("tinychat-userlist").shadowRoot; var chatlogCSS = chatlogElem.querySelector("#chat-wrapper"); var sidemenuCSS = sidemenuElem.querySelector("label.switcher"); var webappCSS = webappElem.querySelector("#toast"); var chatlistCSS = chatlistElem.querySelector("#header > span"); var userlistCSS = userlistElem.querySelector("#header > span"); var titleCSS = titleElem.querySelector("#room-header"); var videolistCSS = videolistElem.querySelector("#videolist"); var audioPop = new Audio('/webrtc/2.0.20-420/sound/pop.mp3'); var giftsElemWidth = 150; function waitForSettings() { settingsVisible = false; if (titleElem.querySelector("#room-header-gifts") != null) { clearInterval(settingsWaitInterval); giftsElemWidth = titleElem.querySelector("#room-header-gifts").offsetWidth; if (titleElem.querySelector("#room-header-gifts-items") == null) { giftsElemWidth1000 = giftsElemWidth + 45; } else { giftsElemWidth1000 = giftsElemWidth; } titleElem.querySelector("#titleCSS").innerHTML += ` #tes-settings { right: ` + giftsElemWidth + `px; } @media screen and (max-width: 1000px) { #tes-settings { right: ` + giftsElemWidth1000 + `px; } } `; settingsElem = titleElem.querySelector("#room-header-gifts").insertAdjacentHTML("beforebegin", ` <div id="tes-settings"> <div id="tes-settingsBox" class="hidden"> <p id="title"><a href="https://greasyfork.org/en/scripts/32964-tinychat-enhancement-suite" target="_blank">Tinychat Enhancement Suite</a></p> <div id="tes-settings-mentions" class="tes-setting-container"> <span class="label"> Alert phrases <span class="info" data-title='A comma-separated list of phrases you would like alerts and highlights for. Example of 3 phrases: "hello,Google Chrome,sky"'>?</span> </span> <input><button class="save">save</button> </div><!-- <div id="tes-settings-font" class="tes-setting-container"> <input type="checkbox"> <span class="label"> Improve font <span class="info" data-title='The default font is too thin some browsers'>?</span> </span> </div> <div id="tes-settings-messageanim" class="tes-setting-container"> <input type="checkbox"> <span class="label"> No message animation </span> </div>--> </div> <div id="tes-settingsGear" title="Tinychat Enhancement Suite settings"><span>✱</span></div> </div> `); titleElem.getElementById("tes-settingsGear").addEventListener("click", toggleSettings); titleElem.querySelector("#tes-settings #tes-settings-mentions button.save").addEventListener("click", function(){mentionsManager("save");} ); settingMentions = []; mentionsManager("load"); } } function toggleSettings() { if (settingsVisible == true) { titleElem.getElementById("tes-settingsBox").classList.add("hidden"); titleElem.getElementById("tes-settings").classList.remove("tes-open"); settingsVisible = false; } else { titleElem.getElementById("tes-settingsBox").classList.remove("hidden"); titleElem.getElementById("tes-settings").classList.add("tes-open"); settingsVisible = true; } } var settingsWaitInterval = setInterval(waitForSettings,1000); function mentionsManager(mode) { var inputElem = titleElem.querySelector("#tes-settings #tes-settings-mentions input"); // phrases = inputElem.value.split(","); var phrase = inputElem.value; if (mode == "save") { GM_setValue("tes-Mentions", phrase); settingMentions = phrase.split(","); } if (mode == "load") { var loadedMentions = GM_getValue("tes-Mentions"); inputElem.value = loadedMentions; settingMentions = loadedMentions.split(","); } return; var phrase = phrase.toString(); if (mode == "save") { settingMentions.push(phrases); GM_setValue("tes-Mentions", JSON.stringify(setting_Mentions)); console.log("Mention add:" + phrases); } if (mode == "load") { var mentions = JSON.parse(GM_getValue("tes-Mentions")); console.log("Mention load:" + mentions); settingMentions = mentions; inputElem.value = settingMentions.join(); } } injectCSS(); function injectCSS(cssName) { // if (cssName == "titleCSS") titleCSS.insertAdjacentHTML("beforeend", ` <style id="titleCSS"> @keyframes ease-to-left { 0% {right: -50px; opacity: 0;} 100% {right: 0; opacity: 1;} } @keyframes ease-to-right { 0% {right:auto;} 100% {right:0;} } @keyframes ease-to-bottom-21px { 0% {top:-300px; opacity: 0;} 100% {top:0; opacity: 1;} } #tes-settings > div { /*animation: ease-to-bottom-21px .2s ease 0s 1;*/ position: relative; top: 0; height: 100px; } @media screen and (max-width: 1000px) { #tes-settings > div { height: 92px; } } #tes-settings .hidden { display: none; } #tes-settings #title { font-weight: bold; } #tes-settings { animation: ease-to-bottom-21px .2s ease 0s 1; /*max-height: 10%;*/ margin-right: 15px; font-size: 11px; flex: none; overflow: hidden; z-index: 9; position: absolute; top: 13px; right: ` + (giftsElemWidth + 10).toString() + `px; } @media screen and (max-width: 1000px) { #tes-settings { right: ` + (giftsElemWidth + 40).toString() + `px; } } #tes-settings:hover { overflow: visible; } #tes-settingsGear { font-size: 70px; color: #38cd57; color: #53b6ef; float: right; } #tes-settingsGear:hover { cursor: pointer; color: #7ccefe; } .tes-open #tes-settingsGear { background: white; border-bottom-right-radius: 15px; border-top-right-radius: 15px; border: #ddd 1px solid; border-left: 0; /*transition: all .2s linear;*/ } #tes-settingsGear span { display: block; transition: transform 0.4s ease-in-out; } .tes-open #tes-settingsGear span { transform: rotate(-90deg); } #tes-settingsBox { background: white; padding: 0px 10px 0px 10px; float: left; border: #53b6ef 1px solid; border-top-left-radius: 12px; border-bottom-left-radius: 12px; animation: ease-to-left .2s ease 0s 1; right: 0; } #tes-settingsBox.hidden { animation: ease-to-right .2s ease 0s 1; display: visible; /*position: relative; right: -1000px;*/ } /*** Inline with header ***/ #tes-settingsBox { border-bottom: 0; border-top-left-radius: 0px; border-bottom-left-radius: 0px; } #tes-settings { top: -1px; } #tes-settingsGear { display: table; } #tes-settingsGear span { display: table-cell; vertical-align: middle; } /*** ************* ***/ #tes-settings .tes-setting-container input[type=checkbox] { margin: 0; margin-right: 1px; float: left; } #tes-settings .label{ margin-right: 4px; } #tes-settings .info{ margin-left: 3px; color: #0d94e3; font-weight: bold; border: #0d94e3 1px solid; border-radius: 16px; height: 1em; width: 1em; text-align: center; display: inline-block; } #tes-settings .info:hover:after{ font-weight: normal; padding: 4px 7px 4px 7px; border-radius: 7px; color: white; background: #61787f; content: attr(data-title); display: inline-block; position: absolute; top: 52px; left: 0; } /*#tes-settings .label:hover:before{ border: solid; border-color: #61787f transparent; border-width: 0px 6px 6px 6px; top: 10px; content: ""; left: 8%; position: relative; display: inline-block; }*/ #tes-settings a:visited, #tes-settings a:link { text-decoration: none; color: inherit; } #tes-settings a:hover { color: #53b6ef; } #room-header { min-height: 10%; /* 105px */ max-height: 10%; } @media screen and (max-width: 600px) { #room-header { min-height: inherit; max-height: inherit; } } #room-header-info { padding: 0; } #room-header-info-text { height: auto; } @media screen and (max-width: 600px) { #room-header-info-text { height: inherit; } } #room-header-avatar { margin: 2px 10px 0 35px; height: 90px; min-width: 90px; max-width: 90px; } #room-header-avatar:hover { border-radius: unset; } #room-header-gifts { padding: 10px 10px; } </style> `); videolistCSS.insertAdjacentHTML("beforeend", ` <style id="videolistCSS"> #videos-header { height: 10px; min-height: 10px; } #Fvideolist * { width: 75%!important; display: contents; float: right; flex-direction: column; } #Fvideos { flex-direction: unset; flex-wrap: unset; } </style> `); chatlistCSS.insertAdjacentHTML("afterend", ` <style id="chatlistCSS"> #chatlist > div > span { padding-left: 1%; } </style> `); userlistCSS.insertAdjacentHTML("afterend", ` <style id="userlistCSS"> #userlist > div > span { padding-left: 1%; } .list-item > span > span { right: auto; padding: 0 5px; } .list-item > span > .nickname { padding-right: 3px; } .list-item > span > img, .list-item > span[data-status="extreme"]:before, .list-item > span[data-status="gold"]:before, .list-item > span[data-status="pro"]:before { left: auto; right: 0; } .list-item > span > span[data-moderator="1"]:before { filter: hue-rotate(226deg) saturate(4000%); } </style> `); document.querySelector("body").insertAdjacentHTML("beforeend", ` <style id="bodyCSS"> #nav-static-wrapper { width: 2px; opacity: .7; } @media screen and (max-width: 1000px) { #nav-static-wrapper { width: 82px; opacity: 1; } } #content { padding: 0; } body { font-family: sans-serif; } #header-user { left: 115px; } @media screen and (max-width: 1000px) { #header-user { left: 21px; } } @media screen and (max-width: 600px) { #header-user { left: auto; right: 54px; } } </style> `); messageCSS = ` .tes-mention-message { color: red; } `; chatlogCSS.insertAdjacentHTML("beforeend", ` <style id="chatlogCSS"> #chat-content > .message { padding-bottom: 0; padding-top: 0!important; margin-bottom: 0; min-height: 0px!important; } /* #chat-content > .message:hover { background: rgba(0, 0, 0, 0.03); } */ #chat-content > .message.common { margin-bottom: 5px; } #chat-content > .message.system { padding: 0; } #chat-instant > a:first-child, #chat-content > .message > a:first-child { top: auto; } #chat-position #input:before { background: none; } #chat-instant > a > .avatar, #chat-content > .message > a > .avatar { border-radius: unset; } #timestamp { font-size: 11px; color: silver; float: right; } #chat-content > .message > .nickname { overflow: initial; line-height: initial; } #chat-content div.message.common:last-of-type { margin-bottom: 10px; } </style> `); sidemenuCSS.innerHTML += ` <style id="sidemenuCSS"> #sidemenu { min-width: 162px; max-width: 10%; left: auto; } @media screen and (max-width: 1000px) { #sidemenu { left: -188px; } } #sidemenu-content { padding-left: 1%; } #live-directory-wrapper { padding: 0; } #user-info { padding: 0 3px; height: auto; } </style> `; webappCSS.innerHTML += ` <style id="webappCSS"> #room { padding: 0; padding-left: 142px; } @media screen and (max-width: 1000px) { :host > #room { padding-left: 82px; } } @media screen and (max-width: 600px) { :host > #room { padding-left: 0; } } </style> `; } var scrollbox = chatlogElem.querySelector("#chat"); var unreadbubble = chatlogElem.querySelector("#input-unread"); var autoScrollStatus = true; function updateScroll() { scrollbox.scrollTop = scrollbox.scrollHeight; scrollbox.scrollTop = scrollbox.scrollTop + 5; } function userHasScrolled(e) { var scrollwheelAmount = e.deltaY; if (scrollwheelAmount < 0) { autoScrollStatus = false; } if (autoScrollStatus === false && scrollbox.scrollHeight - scrollbox.scrollTop == scrollbox.offsetHeight) { autoScrollStatus = true; } } function newMessageAdded() { if (autoScrollStatus === true) { updateScroll(); } timestampAdd(); messageParser(); } messageCount = 0; function messageParser() { latestMessageElem = chatlogElem.querySelector("#chat-content div.message.common:last-of-type"); if (latestMessageElem != null) { latestMessageElem.setAttribute("id", "msg-"+messageCount); messageCount++; tcMessageHtmlElem = latestMessageElem.querySelector("tc-message-html").shadowRoot; latestMessageContentElem = tcMessageHtmlElem.querySelector("#html"); var node = document.createElement("style"); var textnode = document.createTextNode(messageCSS); node.appendChild(textnode); tcMessageHtmlElem.appendChild(node); latestMessageContent = latestMessageContentElem.innerHTML; for (i=0; i < settingMentions.length; i++) { if (latestMessageContent.toLowerCase().includes(settingMentions[i].toLowerCase())) { latestMessageContentElem.classList.add("tes-mention-message"); audioPop.play(); break; } } } } var x = new MutationObserver(function (e) { if (e[0].addedNodes) newMessageAdded(); }); x.observe(chatlogElem.querySelector("#chat-content"), { childList: true }); var x = new MutationObserver(function (e) { if (e[0].addedNodes) newCamAdded(); }); x.observe(videolistElem.querySelector(".videos-items:last-child"), { childList: true }); var scrollboxEvent = scrollbox.addEventListener("wheel", userHasScrolled); var unreadbubble = unreadbubble.addEventListener("click", function(){autoScrollStatus = true;} ); function timestampAdd() { var queryString = "#chat-content div.message.common:last-of-type .nickname"; var SHOW_SECONDS = true; var date = new Date(); var hours = date.getHours(); var minutes = date.getMinutes().toString(); var secs = date.getSeconds().toString(); if (hours > 12) { hours = (hours % 12 || 12); var period = "pm"; } else { var period = "am"; } if (hours == "0") { hours = "12"; } if (minutes == "0") { minutes = "00"; } if (minutes.length == 1) { minutes = "0" + minutes; } if (secs.length == 1) { secs = "0" + secs; } if (SHOW_SECONDS == true) { var timestamp = hours + ":" + minutes + ":" + secs + "" + period; } else { var timestamp = hours + ":" + minutes + period; } if (chatlogElem.querySelector(queryString) != null) { var recentMsgNickname = chatlogElem.querySelector(queryString); recentMsgNickname.insertAdjacentHTML("afterend", "<span id='timestamp'> " + timestamp + "</span>"); } } // var newCamAddedInterval = setInterval(newCamAdded, 1000); // var camAddedCounter = 0; // newCamAdded(); function newCamAdded() { return; // camAddedCounter += 1; // if (camAddedCounter == 10) { // clearInterval(newCamAddedInterval); // } console.log("Cam added"); var queryString = ".videos-items:last-child > .js-video"; if (videolistElem.querySelector(queryString) != null) { var camElems = videolistElem.querySelectorAll(queryString); // console.log("found"); } else { return; } for (i=0; i < camElems.length; i++) { if ( camElems[i].hasAttribute("id") == true ) { continue; } var camItem = camElems[i].querySelector("tc-video-item").shadowRoot; var camName = camItem.querySelector(".nickname").getAttribute("title"); camElems[i].setAttribute("id", "camUser-"+camName); console.log("Cam: " + camName); } }