Improvements to the usability of chats 2.0.
当前为
// ==UserScript==
// @name [TORN] Better Chat
// @namespace dekleinekobini.betterchat
// @license none
// @version 0.1
// @description Improvements to the usability of chats 2.0.
// @author DeKleineKobini [2114440]
// @match https://www.torn.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=torn.com
// @run-at document-body
// @grant GM_addStyle
// ==/UserScript==
"use strict";
const settings = {
messages: {
hideAvatars: true,
compact: true,
fixLongName: true,
leftAlignedText: true, // left align all text, prefixed by the name (supports the mini-profile as well), even for private chats
},
box: {
groupRight: true, // opening chat logic to put private chat left of group chats
hideAvatars: true,
},
};
/*
chat name colours
return hyperlink capability
timestamps - multiple toggles of a) timestamp on hover b) timestamp before name and c) no timestamp
*/
(() => {
setupStyles();
setupChatModifier();
})();
function includeStyle(styleRules) {
if (typeof GM_addStyle !== "undefined") {
GM_addStyle(styleRules);
} else {
const styleElement = document.createElement("style");
styleElement.setAttribute("type", "text/css");
styleElement.innerHTML = styleRules;
document.head.appendChild(styleElement);
}
}
function setupStyles() {
if (settings.messages.hideAvatars) {
includeStyle(`
[class*='chat-box-body__avatar___'] {
display: none;
}
`);
}
if (settings.messages.compact) {
includeStyle(`
[class*='chat-box-body__sender-group___'] {
margin-right: 0 !important;
}
[class*='chat-box-body__wrapper___'] {
margin-bottom: 0px !important;
}
[class*='chat-box-body___'] > div:last-child {
margin-bottom: 8px !important;
}
`);
}
if (settings.messages.fixLongName) {
includeStyle(`
[class*='chat-box-body__sender-button___'] {
max-width: unset !important;
}
`);
}
if (settings.box.groupRight) {
includeStyle(`
[class*='group-chat-box___'] {
gap: 3px;
}
[class*='group-chat-box__chat-box-wrapper___'] {
margin-right: 0 !important;
}
`);
}
if (settings.messages.leftAlignedText) {
includeStyle(`
[class*='chat-box-body__sender___'] {
display: unset !important;
font-weight: 700;
}
[class*='chat-box-body__sender-separator___'] {
display: unset !important;
margin-right: 4px;
}
[class*='chat-box-body__message-box___'] {
background: none !important;
border-radius: none !important;
color: initial !important;
padding: 0 !important;
}
[class*='chat-box-body__message-box--self___'] {
background: none !important;
border-radius: none !important;
color: initial !important;
padding: 0 !important;
}
[class*='chat-box-body__wrapper--self___'] {
justify-content: normal !important;
}
[class*='chat-box-body__wrapper--self___'] > [class*='chat-box-body__message___'],
[class*='chat-box-body__message___'] {
color: var(--chat-text-color) !important;
}
`);
}
if (settings.box.hideAvatars) {
includeStyle(`
[class*='avatar__avatar-status-wrapper___'] > img {
display: none;
}
`);
}
}
async function setupChatModifier() {
const group = await new Promise((resolve) => {
new MutationObserver((_, observer) => {
const group = findByClass(document, "group-chat-box___");
if (group) {
observer.disconnect();
resolve(group);
}
}).observe(document, {childList: true, subtree: true});
});
group.childNodes.forEach(processChat)
new MutationObserver((mutations) => {
mutations.flatMap((mutation) => [...mutation.addedNodes]).forEach(processChat);
}).observe(group, {childList: true});
}
function processChat(chatNode) {
if (settings.box.groupRight) {
const avatarElement = findByClass(chatNode, "chat-box-header__avatar___", "> *");
const isGroup = avatarElement.tagName.toLowerCase() === "svg";
if (isGroup) {
chatNode.style.order = "1";
}
}
const bodyElement = findByClass(chatNode, "chat-box-body___");
bodyElement.childNodes.forEach(processMessage);
new MutationObserver((mutations) => {
mutations.flatMap((mutation) => [...mutation.addedNodes]).forEach(processMessage);
}).observe(chatNode, {childList: true});
new MutationObserver(() => {
bodyElement.childNodes.forEach(processMessage);
}).observe(bodyElement, {childList: true});
}
function processMessage(messageNode) {
// TODO - Handle message here if needed.
}
function findByClass(node, className, subSelector = "") {
return node.querySelector(`[class*='${className}'] ${subSelector}`.trim())
}