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(); })();