NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name CatWar notification
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Уведомления для лс и чата игровой
// @author 5haddam
// @match https://*.catwar.su/cw3/
// @icon https://www.google.com/s2/favicons?sz=64&domain=catwar.su
// @grant none
// @require https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js
// @license MIT; https://opensource.org/licenses/MIT
// @copyright 2023, 5haddam (https://openuserjs.org/users/5haddam) Мечтательнолапый (https://catwar.su/cat1524802)
// @updateURL https://openuserjs.org/meta/5haddam/CatWar_notification.meta.js
// @downloadURL https://openuserjs.org/install/5haddam/CatWar_notification.user.js
// ==/UserScript==
// ==OpenUserJS==
// @author 5haddam
// ==/OpenUserJS==
(function() {
'use strict';
let userChoice = localStorage.getItem('userChoice');
let volume = localStorage.getItem('volume');
let userChoiceLS = localStorage.getItem('userChoiceLS');
let volumeLS = localStorage.getItem('volumeLS');
let menuIsOpen = false;
const audioChatNotification = new Audio('https://zvukitop.com/wp-content/uploads/2021/09/zvuk-soobsheniya-vk-1.mp3?_=6');
const audioLSNotification = new Audio('https://zvukitop.com/wp-content/uploads/2021/09/zvuk-soobsheniya-vk-1.mp3?_=6');
let processedElementsCounter = 0;
userChoice === 'ping' ? processedElementsCounter = [...document.getElementsByClassName('myname')].length : null;
const chatMsgElement = document.querySelector('#chat_msg');
let previousElementCount = chatMsgElement.childElementCount;
const handleNewElements = (mutationsList) => {
for (const mutation of mutationsList) {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach((node) => {
if (userChoice === 'all') {
const currentElementCount = chatMsgElement.childElementCount;
if (currentElementCount > previousElementCount) {
previousElementCount = currentElementCount;
audioChatNotification.volume = volume;
audioChatNotification.play();
}
} else if (userChoice === 'ping') {
const allMyNameElements = document.getElementsByClassName('myname').length;
if (node instanceof HTMLElement && node.classList.contains('myname') && allMyNameElements > processedElementsCounter) {
processedElementsCounter = allMyNameElements;
audioChatNotification.volume = volume;
audioChatNotification.play();
}
}
});
}
}
};
function chooseNotificationType() {
const chatForm = document.querySelector('#chat_form');
const body = document.querySelector('body');
const selectButton = document.createElement('div');
selectButton.id = 'notificationType';
selectButton.innerHTML = 'Настройки уведомлений';
chatForm.append(selectButton);
selectButton.addEventListener('click', (e) => {
e.stopPropagation();
if (!menuIsOpen) {
showMenu();
addStylesMenu();
}
});
function showMenu() {
menuIsOpen = true;
const notificationTypeMenu = document.createElement('div');
notificationTypeMenu.id = 'notificationTypeMenu';
function addNotificationTypes() {
const notificationAll = document.createElement('input');
const notificationPing = document.createElement('input');
const notificationNone = document.createElement('input');
const notificationAllLabel = document.createElement('label');
const notificationPingLabel = document.createElement('label');
const notificationNoneLabel = document.createElement('label');
const notificationAllDiv = document.createElement('div');
const notificationPingDiv = document.createElement('div');
const notificationNoneDiv = document.createElement('div');
notificationAll.type = 'radio';
notificationPing.type = 'radio';
notificationNone.type = 'radio';
notificationAll.name = 'notificationType';
notificationPing.name = 'notificationType';
notificationNone.name = 'notificationType';
notificationAll.id = 'all';
notificationPing.id = 'ping';
notificationNone.id = 'none';
notificationAll.value = 'all';
notificationPing.value = 'ping';
notificationNone.value = 'none';
notificationAllLabel.setAttribute('for', 'all');
notificationPingLabel.setAttribute('for', 'ping');
notificationNoneLabel.setAttribute('for', 'none');
notificationAllLabel.innerText = 'Все уведомления';
notificationPingLabel.innerText = 'Только упоминания';
notificationNoneLabel.innerText = 'Нет уведомлений';
const chatNotification = {
'all': () => { notificationAll.checked = true },
'ping': () => { notificationPing.checked = true },
'none': () => { notificationNone.checked = true },
}
chatNotification[userChoice]();
notificationAllDiv.append(notificationAll, notificationAllLabel);
notificationPingDiv.append(notificationPing, notificationPingLabel);
notificationNoneDiv.append(notificationNone, notificationNoneLabel);
notificationTypeMenu.append(notificationAllDiv, notificationPingDiv, notificationNoneDiv);
addVolumeControl();
notificationAllLabel.addEventListener('click', (e) => e.stopPropagation());
notificationPingLabel.addEventListener('click', (e) => e.stopPropagation());
notificationNoneLabel.addEventListener('click', (e) => e.stopPropagation());
notificationAllDiv.addEventListener('click', (e) => {
e.stopPropagation();
const selectedNotificationType = 'all';
saveUserChoice(selectedNotificationType);
userChoice = selectedNotificationType;
notificationAll.checked = true;
});
notificationPingDiv.addEventListener('click', (e) => {
e.stopPropagation();
const selectedNotificationType = 'ping';
saveUserChoice(selectedNotificationType);
userChoice = selectedNotificationType;
notificationPing.checked = true;
processedElementsCounter = [...document.getElementsByClassName('myname')].length;
});
notificationNoneDiv.addEventListener('click', (e) => {
e.stopPropagation();
const selectedNotificationType = 'none';
saveUserChoice(selectedNotificationType);
userChoice = selectedNotificationType;
notificationNone.checked = true;
});
}
function addNotificationLS() {
const notificationTitleLS = document.createElement('div');
notificationTitleLS.innerText = 'ЛС';
notificationTypeMenu.append(notificationTitleLS);
const notificationOn = document.createElement('input');
const notificationOff = document.createElement('input');
const notificationOnLabel = document.createElement('label');
const notificationOffLabel = document.createElement('label');
const notificationOnDiv = document.createElement('div');
const notificationOffDiv = document.createElement('div');
notificationOn.type = 'radio';
notificationOff.type = 'radio';
notificationOn.name = 'notificationTypeLS';
notificationOff.name = 'notificationTypeLS';
notificationOn.id = 'on';
notificationOff.id = 'off';
notificationOn.value = 'on';
notificationOff.value = 'off';
notificationOnLabel.setAttribute('for', 'on');
notificationOffLabel.setAttribute('for', 'off');
notificationOnLabel.innerText = 'Уведомления вкл';
notificationOffLabel.innerText = 'Уведомления выкл';
const chatNotificationLS = {
'on': () => { notificationOn.checked = true },
'off': () => { notificationOff.checked = true },
}
chatNotificationLS[userChoiceLS]();
notificationOnDiv.append(notificationOn, notificationOnLabel);
notificationOffDiv.append(notificationOff, notificationOffLabel);
notificationTypeMenu.append(notificationOnDiv, notificationOffDiv);
addVolumeControlLS();
notificationOnDiv.addEventListener('click', (e) => {
e.stopPropagation();
const selectedNotificationType = 'on';
saveUserChoiceLS(selectedNotificationType);
userChoiceLS = selectedNotificationType;
notificationOn.checked = true;
});
notificationOffDiv.addEventListener('click', (e) => {
e.stopPropagation();
const selectedNotificationType = 'off';
saveUserChoiceLS(selectedNotificationType);
userChoiceLS = selectedNotificationType;
notificationOff.checked = true;
});
notificationOnLabel.addEventListener('click', (e) => e.stopPropagation());
notificationOffLabel.addEventListener('click', (e) => e.stopPropagation());
};
notificationTypeMenu.addEventListener('click', (e) => e.stopPropagation());
addNotificationTypes();
addNotificationLS();
body.addEventListener('click', (e) => {
notificationTypeMenu.remove();
menuIsOpen = false;
});
chatForm.after(notificationTypeMenu);
function addVolumeControl() {
const volumeInput = document.createElement('input');
const volumeLabel = document.createElement('label');
const volumeDiv = document.createElement('div');
volumeInput.type = 'range';
volumeInput.min = '0';
volumeInput.max = '1';
volumeInput.step = '0.1';
volumeInput.value = volume;
volumeInput.style.width = '100px';
volumeLabel.setAttribute('for', 'volume');
volumeLabel.innerText = 'Громкость:';
volumeDiv.append(volumeLabel, volumeInput);
notificationTypeMenu.append(volumeDiv);
volumeInput.addEventListener('input', (e) => {
volume = e.target.value;
audioChatNotification.volume = volume;
saveUserVolume(volume);
});
}
function addVolumeControlLS() {
const volumeInput = document.createElement('input');
const volumeLabel = document.createElement('label');
const volumeDiv = document.createElement('div');
volumeInput.type = 'range';
volumeInput.min = '0';
volumeInput.max = '1';
volumeInput.step = '0.1';
volumeInput.value = volumeLS;
volumeInput.style.width = '100px';
volumeLabel.setAttribute('for', 'volumeLS');
volumeLabel.innerText = 'Громкость:';
volumeDiv.append(volumeLabel, volumeInput);
notificationTypeMenu.append(volumeDiv);
volumeInput.addEventListener('input', (e) => {
volumeLS = e.target.value;
audioLSNotification.volume = volumeLS;
saveUserVolumeLS(volumeLS);
});
}
function getSelectedNotificationType() {
const selectedNotificationType = document.querySelector('input[name="notificationType"]:checked');
return selectedNotificationType ? selectedNotificationType.value : '';
}
function saveUserChoice(choice) {
localStorage.setItem('userChoice', choice);
}
function saveUserChoiceLS(choice) {
localStorage.setItem('userChoiceLS', choice);
}
function saveUserVolume(volume) {
localStorage.setItem('volume', volume);
}
function saveUserVolumeLS(volume) {
localStorage.setItem('volumeLS', volume);
}
}
}
document.querySelector('#newls').addEventListener('DOMCharacterDataModified', (e) => {
const targetElement = e.target;
const newText = targetElement.textContent.trim();
if (newText !== '') {
audioLSNotification.volume = volumeLS;
audioLSNotification.play();
}
});
function addStylesButton() {
const chatForm = document.querySelector('#chat_form');
const notificationType = document.querySelector('#notificationType');
// Стили для #chat_form
chatForm.style.position = 'relative';
// Стили для #notificationType
notificationType.style.width = '200px';
notificationType.style.height = '18px';
notificationType.style.backgroundColor = 'var(--bg-color0)';
notificationType.style.borderRadius = '5px';
notificationType.style.border = '0.5px solid var(--bg-color4)';
notificationType.style.color = 'var(--tx-color2)';
notificationType.style.right = '220px';
notificationType.style.top = '24px';
notificationType.style.position = 'absolute';
notificationType.style.textAlign = 'center';
}
function addStylesMenu() {
const notificationTypeMenu = document.querySelector('#notificationTypeMenu');
// Стили для #notificationTypeMenu
notificationTypeMenu.style.width = '200px';
notificationTypeMenu.style.height = '250px';
notificationTypeMenu.style.backgroundColor = 'var(--bg-color0)';
notificationTypeMenu.style.borderRadius = '5px';
notificationTypeMenu.style.border = '0.5px solid var(--bg-color4)';
notificationTypeMenu.style.color = 'var(--tx-color2)';
notificationTypeMenu.style.right = '29px';
notificationTypeMenu.style.top = '66px';
notificationTypeMenu.style.position = 'absolute';
// Стили для #notificationTypeMenu > div:not(:last-child)
const menuDivs = notificationTypeMenu.querySelectorAll('div:not(:last-child)');
menuDivs.forEach((div) => {
div.style.borderBottom = '0.5px solid var(--bg-color4)';
});
// Стили для #notificationTypeMenu > div
const allMenuDivs = notificationTypeMenu.querySelectorAll('div');
allMenuDivs.forEach((div) => {
div.style.height = '30px';
div.style.display = 'flex';
div.style.alignItems = 'center';
});
}
const observerChat = new MutationObserver(handleNewElements);
observerChat.observe(document.body, { childList: true, subtree: true });
chooseNotificationType();
addStylesButton();
})();