Greasy Fork 支持简体中文。

Meklin Shutdownchat Script

Modified Shutdownchat, unmatched scripts, brace to be thunderstruck

目前為 2024-01-02 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Meklin Shutdownchat Script
  3. // @version 1.6
  4. // @description Modified Shutdownchat, unmatched scripts, brace to be thunderstruck
  5. // @author MeKLiN
  6. // @namespace https://greasyfork.org/en/scripts/483405-meklin-shutdownchat-script
  7. // @match https://www.shutdown.chat/rooms*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=shutdown.chat
  9. // @license MIT
  10. // @grant none
  11. // @exclude https://www.shutdown.chat/profiles*
  12. // @exclude https://www.shutdown.chat/manage*
  13. // @run-at document-start
  14. // @require https://cdnjs.cloudflare.com/ajax/libs/jshint/2.9.7/jshint.js
  15. // @require https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.5/es6-shim.min.js
  16. // ==/UserScript==
  17. console.log("MSS 1.1 STARTED");
  18. debugger;
  19.  
  20. // Function to show a notification
  21. function showNotification(message) {
  22. var notification = document.createElement("div");
  23. notification.style.position = "fixed";
  24. notification.style.top = "10px";
  25. notification.style.left = "10px";
  26. notification.style.backgroundColor = "#000000";
  27. notification.style.padding = "10px";
  28. notification.style.border = "1px solid #ccc";
  29. notification.style.borderRadius = "5px";
  30. notification.style.fontSize = "12px";
  31. notification.style.color = "#C0FF00";
  32. notification.style.opacity = 1;
  33. notification.style.transition = "opacity 2s ease-in-out";
  34. notification.innerHTML = message;
  35.  
  36. document.body.appendChild(notification);
  37.  
  38. // Set a timeout to fade out the notification
  39. setTimeout(function () {
  40. notification.style.opacity = 0;
  41. }, 5000); // Adjust the timeout value as needed
  42.  
  43. // Remove the notification from the DOM after fading out
  44. setTimeout(function () {
  45. document.body.removeChild(notification);
  46. }, 6000); // Adjust the timeout value to match the fade-out duration
  47. }
  48.  
  49. // Function to create a button to clear the JSON local saved cache
  50. function createClearCacheButton() {
  51. console.log("createClearCacheButton function is called");
  52.  
  53. var clearCacheButton = document.createElement("button");
  54. clearCacheButton.innerText = "clr";
  55. clearCacheButton.style.position = "fixed";
  56. clearCacheButton.style.top = "50px";
  57. clearCacheButton.style.left = "10px";
  58. clearCacheButton.addEventListener("click", function () {
  59. // Clear the JSON local saved cache
  60. localStorage.removeItem('blocked_uuids');
  61. showNotification("Cache cleared. Please refresh the page.");
  62. });
  63.  
  64. // Check if the body is available
  65. if (document.body) {
  66. // Append the clearCacheButton to the body
  67. document.body.appendChild(clearCacheButton);
  68. } else {
  69. // If the body is not available, wait for DOMContentLoaded event
  70. document.addEventListener("DOMContentLoaded", function () {
  71. // Append the clearCacheButton to the body
  72. document.body.appendChild(clearCacheButton);
  73. });
  74. }
  75. }
  76.  
  77. // Call the function to create the clear cache button
  78. createClearCacheButton();
  79.  
  80. // Function to create a button to collapse the view
  81. function createCollapseButton() {
  82. console.log("createCollapseButton function is called");
  83. var collapseButton = document.createElement("button");
  84.  
  85. // Set the inner HTML with an SVG and additional text
  86. collapseButton.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
  87. <path fill="none" d="M0 0h24v24H0z"/>
  88. <path d="M8 4v5l-2.5-1.5L3 9V4l5-2zm8 0l5 2v5l-2.5-1.5L16 9V4zM3 11l3.5-1.5L8 11V9L3 7zm13 0l3.5-1.5L21 11V9l-5-2z"/>
  89. </svg>min`;
  90.  
  91. // Adjust the font size of the text
  92. collapseButton.style.fontSize = "12px"; // Adjust the font size as needed
  93.  
  94. collapseButton.style.position = "fixed";
  95. collapseButton.style.top = "90px";
  96. collapseButton.style.left = "10px";
  97.  
  98. // Function to append the button to the body
  99. function appendButtonToBody() {
  100. document.body.appendChild(collapseButton);
  101. }
  102.  
  103. // Check if the body is available
  104. if (document.body) {
  105. // Append the collapseButton to the body
  106. appendButtonToBody();
  107. } else {
  108. // If the body is not available, wait for DOMContentLoaded event
  109. document.addEventListener("DOMContentLoaded", appendButtonToBody);
  110. }
  111.  
  112. collapseButton.addEventListener("click", function () {
  113. // Toggle visibility of the chatbox
  114. var chatbox = document.querySelector('.chatbox');
  115. chatbox.style.display = (chatbox.style.display === 'none' || chatbox.style.display === '') ? 'block' : 'none';
  116. });
  117.  
  118. // Get the chatbox element after creating the button
  119. var chatbox = document.querySelector('.chatbox');
  120.  
  121. // Check if the chatbox element is found
  122. if (chatbox) {
  123. // Initialize the observer if not already initialized
  124. if (!observer) {
  125. observer = new MutationObserver(function (mutations) {
  126. // Handle mutations
  127. console.log("Mutations:", mutations);
  128. // You can add your logic to handle mutations here
  129. });
  130.  
  131. // Start observing the chatbox
  132. observer.observe(chatbox, { childList: true });
  133. }
  134.  
  135. // Log the chatbox element to the console
  136. console.log("Chatbox element:", chatbox);
  137. }
  138. }
  139.  
  140.  
  141.  
  142. // Call the function to create the collapse button
  143. createCollapseButton();
  144.  
  145. var blocked_uuids = JSON.parse(localStorage.getItem('blocked_uuids')) || [];
  146.  
  147. function getNickname(fcuserSpan) {
  148. if (!fcuserSpan) return;
  149.  
  150. // Check if fcuserSpan is a direct child of p
  151. var isDirectChild = fcuserSpan.parentNode.nodeName === "P";
  152. var nickname;
  153.  
  154. if (isDirectChild) {
  155. nickname = fcuserSpan.innerText.replace(/[:\-]/g, '').trim();
  156. } else {
  157. // If not a direct child, assume it's under an anchor tag (a) in the user list
  158. nickname = fcuserSpan.parentNode.querySelector('.fcuser').innerText.replace(/[:\-]/g, '').trim();
  159. }
  160.  
  161. return nickname;
  162. }
  163.  
  164. // Function to handle the new chat messages
  165. function handleNewChatMessages() {
  166. // Get the chatbox element
  167. console.log("Attempting to get chatbox element");
  168. var chatbox = document.querySelector('.chatbox');
  169.  
  170. // Check if the chatbox element is found
  171. if (!chatbox) {
  172. console.error("Chatbox element not found. Cannot add event listener.");
  173. return;
  174. }
  175. console.log("Chatbox element found. Proceeding with event listener setup.");
  176.  
  177. // Use the existing observer if not already initialized
  178. if (!observer) {
  179. observer = new MutationObserver(function (mutations) {
  180. // Handle mutations
  181. mutations.forEach(function (mutation) {
  182. mutation.addedNodes.forEach(function (node) {
  183. handleChatMessage(node);
  184. console.log("Mutations:", mutations);
  185. // You can add your logic to handle mutations here
  186. });
  187. });
  188. });
  189.  
  190. // Start observing the chatbox if observer is defined
  191. if (typeof observer !== 'undefined' && observer !== null) {
  192. observer.observe(chatbox, { childList: true });
  193. } else {
  194. console.error("Observer not defined. Cannot add event listener.");
  195. }
  196. }
  197.  
  198. // Continue with handling new chat messages
  199. var chatboxElems = chatbox.getElementsByTagName('p');
  200. for (var i = 0; i < chatboxElems.length; i++) {
  201. var chatElem = chatboxElems[i];
  202. if (!chatElem.handled) {
  203. chatElem.handled = true;
  204.  
  205. // Additional logic for handling specific types of messages
  206. // Remove text containing 'roll'
  207. if (chatElem.textContent.toLowerCase().includes('roll')) {
  208. chatElem.style.display = 'none'; // hide the message
  209. }
  210.  
  211. // Alter messages of the type .fs_3
  212. if (chatElem.classList.contains('fs_3')) {
  213. chatElem.style.fontSize = '12px';
  214. chatElem.style.color = 'white';
  215. }
  216.  
  217. // Check if the message is a system message
  218. var systemMessage = chatElem.classList.contains('system');
  219. if (systemMessage) {
  220. // Add a button to hide the system message
  221. addHideButtonToSystemMessage(chatElem);
  222. } else {
  223. // Check if the user is ignored
  224. var fcuserSpan = chatElem.querySelector('.nm.fcuser, .nm.fcmod, .user');
  225. var uuid = fcuserSpan ? fcuserSpan.dataset.uuid : null;
  226. console.log("fcuserSpan:", fcuserSpan); // Add this line to log fcuserSpan
  227. console.log("uuid:", uuid); // Add this line to log uuid
  228.  
  229. if (uuid) {
  230. // Check if the user is ignored
  231. var isIgnored = blocked_uuids.includes(uuid);
  232.  
  233. // Modify the appearance based on whether the user is ignored or not
  234. if (isIgnored) {
  235. chatElem.style.display = 'none'; // hide the message
  236. } else {
  237. // Add an "ignore" button to the user menu
  238. addIgnoreButtonToUserMenu(uuid);
  239. }
  240. }
  241. }
  242. }
  243. }
  244. }
  245.  
  246.  
  247.  
  248.  
  249. // Function to add a button to hide system messages
  250. function addHideButtonToSystemMessage(chatElem) {
  251. var hideButton = document.createElement('button');
  252. hideButton.textContent = 'Hide';
  253. hideButton.style.marginLeft = '5px';
  254. hideButton.addEventListener('click', function () {
  255. chatElem.style.display = 'none'; // hide the system message
  256. });
  257.  
  258. // Append the button to the system message
  259. chatElem.appendChild(hideButton);
  260. }
  261.  
  262. // Function to add an "ignore" button to the user menu
  263. function addIgnoreButtonToUserMenu(chatElem) {
  264. // Check if the user menu exists
  265. var userMenu = document.querySelector('.usermenu');
  266.  
  267. if (userMenu && chatElem && chatElem.querySelector) {
  268. // Check if the user is already ignored
  269. var uuid = chatElem.querySelector('.nm.fcuser, .nm.fcmod')?.dataset.uuid;
  270. var isIgnored = blocked_uuids.includes(uuid);
  271.  
  272. // Create a button for either ignoring or unignoring the user
  273. var ignoreButton = document.createElement('button');
  274. ignoreButton.textContent = isIgnored ? 'Unignore' : 'Ignore';
  275.  
  276. // Add an event listener to handle ignoring/unignoring the user
  277. ignoreButton.addEventListener('click', function () {
  278. if (isIgnored) {
  279. // Unignore the user
  280. unignoreUser(uuid);
  281. } else {
  282. // Ignore the user
  283. ignoreUser(uuid);
  284. }
  285. });
  286.  
  287. // Append the button to the user menu
  288. userMenu.appendChild(ignoreButton);
  289. } else {
  290. console.error("Invalid userMenu, chatElem, or querySelector is not supported. Conditions: userMenu=" + userMenu + ", chatElem=" + chatElem + ", chatElem.querySelector=" + (chatElem ? chatElem.querySelector : null));
  291. }
  292. }
  293.  
  294. // Declare observer in the global scope
  295. var observer;
  296.  
  297. document.addEventListener('DOMContentLoaded', function () {
  298. // Your entire script goes here
  299.  
  300. // Function to observe mutations in the chatbox
  301. function observeChatboxMutations() {
  302. var chatbox = document.querySelector('.chatbox');
  303.  
  304. if (chatbox instanceof Node) {
  305. // Check if the observer is already initialized
  306. if (!observer) {
  307. // Create a mutation observer to monitor changes in the chatbox
  308. observer = new MutationObserver(function (mutations) {
  309. mutations.forEach(function (mutation) {
  310. mutation.addedNodes.forEach(function (node) {
  311. if (node.nodeName === "P" && node.dataset.t === "c") {
  312. // Your logic for handling new chat messages goes here
  313. }
  314. });
  315. });
  316. });
  317. // Start observing the chatbox
  318. observer.observe(chatbox, { childList: true });
  319. }
  320. } else {
  321. console.error("Chatbox element not found or is not a valid Node. Cannot add event listener.");
  322. }
  323. }
  324.  
  325. // Call the initial function to start handling new chat messages
  326. handleNewChatMessages();
  327.  
  328. // Call the function to observe mutations in the chatbox
  329. observeChatboxMutations();
  330. });
  331.  
  332. // Function to ignore a user
  333. function ignoreUser(uuid) {
  334. // Add your logic here to handle ignoring a user
  335. // For example, you can add the user's UUID to the blocked_uuids array
  336. blocked_uuids.push(uuid);
  337.  
  338. // Save the updated blocked_uuids to localStorage
  339. localStorage.setItem('blocked_uuids', JSON.stringify(blocked_uuids));
  340.  
  341. // You can also add additional logic as needed
  342. console.log("Ignoring user with UUID:", uuid);
  343. }
  344.  
  345. // Function to unignore a user
  346. function unignoreUser(uuid) {
  347. blocked_uuids = blocked_uuids.filter(function (blockedUuid) {
  348. return blockedUuid !== uuid;
  349. });
  350. // Add additional logic as needed
  351. console.log("Unignoring user with UUID:", uuid);
  352. }
  353.  
  354. // Call the initial function to start handling new chat messages
  355. handleNewChatMessages();
  356.  
  357. // Function to get the user UUID from a chat message
  358. function getUserUUIDFromChatMessage(messageNode) {
  359. var uuidElement = messageNode.querySelector('.nm.fcuser, .nm.fcmod');
  360. if (uuidElement) {
  361. return uuidElement.dataset.uuid;
  362. } else {
  363. console.error("UUID element not found in the chat message:", messageNode);
  364. return null;
  365. }
  366. }
  367.  
  368. // Function to handle different types of chat messages
  369. function handleChatMessage(node) {
  370. // Check if the node is a chat message
  371. if (node.nodeName === "P" && node.dataset.t === "c") {
  372. // Get the uuid of the user who sent the message
  373. var uuid = getUserUUIDFromChatMessage(node);
  374. if (uuid) {
  375. console.log("Found message with UUID:", uuid);
  376.  
  377. // Check if the uuid is in the blocked list
  378. if (blocked_uuids.includes(uuid)) {
  379. console.log("Blocking message with UUID:", uuid);
  380. // Hide the message
  381. node.style.display = "none";
  382. } else {
  383. // Alter messages of the type .fs_3
  384. if (node.classList.contains('fs_3')) {
  385. node.style.fontSize = '12px';
  386. node.style.color = 'white';
  387. }
  388.  
  389. // Add an "ignore" button to the user menu
  390. addIgnoreButtonToUserMenu(node);
  391. }
  392. }
  393. } else if (node.nodeName === "P" && node.querySelector(".sysmsg.fcsys")) {
  394. // Handle system messages
  395. handleSystemMessage(node);
  396. }
  397. }
  398.  
  399. // Function to handle system messages
  400. function handleSystemMessage(systemNode) {
  401. // Move system messages to the bottom right in their own DIV
  402. var systemDiv = document.createElement("div");
  403. systemDiv.className = "system-message";
  404. systemDiv.style.position = "fixed";
  405. systemDiv.style.bottom = "10px";
  406. systemDiv.style.right = "10px";
  407. systemDiv.style.backgroundColor = "#f0f0f0";
  408. systemDiv.style.padding = "10px";
  409. systemDiv.appendChild(systemNode.cloneNode(true));
  410. document.body.appendChild(systemDiv);
  411.  
  412. // Get the chatbox element after creating the button
  413. var chatbox = document.querySelector('.chatbox');
  414.  
  415. // Check if the chatbox element is found
  416. if (chatbox) {
  417. // Initialize the observer if not already initialized
  418. if (!observer) {
  419. observer = new MutationObserver(function (mutations) {
  420. // Handle mutations
  421. console.log("Mutations:", mutations);
  422. // You can add your logic to handle mutations here
  423. });
  424.  
  425. // Start observing the chatbox
  426. observer.observe(chatbox, { childList: true });
  427. }
  428. }
  429. }
  430.  
  431. // Function to block/unblock a user
  432. function blockUser(uuid) {
  433. console.log("blockUser function is called");
  434. var index = blocked_uuids.indexOf(uuid);
  435. if (index !== -1) {
  436. // User is already blocked, so unblock
  437. blocked_uuids.splice(index, 1);
  438. showNotification("User unblocked!");
  439. } else {
  440. // User is not blocked, so block
  441. blocked_uuids.push(uuid);
  442. showNotification("User blocked!");
  443. }
  444.  
  445. // Save the updated blocked_uuids to localStorage
  446. localStorage.setItem('blocked_uuids', JSON.stringify(blocked_uuids));
  447. }
  448.  
  449. // Function to create a button to view the ignore list
  450. function createIgnoreListButton() {
  451. console.log("createIgnoreListButton function is called");
  452. var ignoreListButton = document.createElement("button");
  453. ignoreListButton.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M20 18V8a6 6 0 0 0-12 0v10h12zM12 2C6.48 2 2 6.48 2 12v10h2V12a5.978 5.978 0 0 1 5.985-6H12V2zm8.293 2.293a1 1 0 0 1 1.414 0l1.414 1.414a1 1 0 0 1 0 1.414L19.414 10l3.707 3.707a1 1 0 0 1 0 1.414l-1.414 1.414a1 1 0 0 1-1.414 0L18 13.414l-3.707 3.707a1 1 0 0 1-1.414 0l-1.414-1.414a1 1 0 0 1 0-1.414L14.586 12 10.88 8.293a1 1 0 0 1 0-1.414L12.294 5.465a1 1 0 0 1 1.414 0z"/></svg>lst`;
  454. ignoreListButton.style.position = "fixed";
  455. ignoreListButton.style.top = "10px";
  456. ignoreListButton.style.left = "10px";
  457. ignoreListButton.addEventListener("click", function () {
  458. // Display the ignore list (you can customize this part)
  459. alert("Ignore List:\n" + blocked_uuids.join(", "));
  460. });
  461.  
  462. document.body.appendChild(ignoreListButton);
  463. }
  464.  
  465. // Call the function to create the ignore list button
  466. createIgnoreListButton();
  467.  
  468.  
  469. // Get the user list element
  470. var userlist = document.querySelector(".userlist");
  471.  
  472. // Create the block and ignore buttons and append them to each user
  473. var users = userlist.querySelectorAll(".fcuser");
  474. users.forEach(function (user) {
  475. var uuid = user.dataset.uuid;
  476.  
  477. // Create the block button
  478. var blockButton = document.createElement("button");
  479. blockButton.innerText = "Block";
  480. blockButton.addEventListener("click", function() {
  481. blockUser(uuid);
  482. });
  483.  
  484. // Create the ignore button with a unique class
  485. var ignoreButton = document.createElement("button");
  486. ignoreButton.innerText = "Ignore";
  487. ignoreButton.setAttribute("data-btntype", "ignore"); // Set a new attribute for identification
  488. ignoreButton.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"/><path d="M20 18V8a6 6 0 0 0-12 0v10h12zM12 2C6.48 2 2 6.48 2 12v10h2V12a5.978 5.978 0 0 1 5.985-6H12V2zm8.293 2.293a1 1 0 0 1 1.414 0l1.414 1.414a1 1 0 0 1 0 1.414L19.414 10l3.707 3.707a1 1 0 0 1 0 1.414l-1.414 1.414a1 1 0 0 1-1.414 0L18 13.414l-3.707 3.707a1 1 0 0 1-1.414 0l-1.414-1.414a1 1 0 0 1 0-1.414L14.586 12 10.88 8.293a1 1 0 0 1 0-1.414L12.294 5.465a1 1 0 0 1 1.414 0z"/></svg>`;
  489. ignoreButton.style.marginLeft = "5px";
  490. ignoreButton.style.cursor = "pointer";
  491. // Add a unique class to the ignore button
  492. ignoreButton.classList.add("ignoreButtonClass");
  493.  
  494. ignoreButton.addEventListener("click", function () {
  495. // Dynamically fetch the user UUID when the "Ignore" button is clicked
  496. var clickedUserUUID = user.dataset.uuid;
  497. blockUser(clickedUserUUID);
  498. });
  499.  
  500. // Create a container div for the buttons
  501. var buttonContainer = document.createElement("div");
  502. buttonContainer.style.display = "flex";
  503. buttonContainer.style.alignItems = "center";
  504.  
  505. // Append the buttons to the container
  506. buttonContainer.appendChild(blockButton);
  507. buttonContainer.appendChild(ignoreButton);
  508.  
  509. // Append the container to the user element
  510. user.parentElement.appendChild(buttonContainer);
  511. });
  512.  
  513. // usermenu block button event listener:
  514. document.querySelector('.usermenu button[data-btntype="block"]').addEventListener('click', function() {
  515. console.log("User menu block button clicked");
  516.  
  517. // Get the parent element of the button, assuming it contains user-related data
  518. var userContainer = this.closest('.user-container');
  519.  
  520. // Assuming the user UUID is stored in a data attribute called data-uuid
  521. var userUUID = userContainer ? userContainer.dataset.uuid : null;
  522.  
  523. // Check if userUUID is not null before blocking
  524. if (userUUID) {
  525. // Now you have the user UUID, and you can proceed to block the user
  526. blockUser(userUUID);
  527. } else {
  528. console.error("User UUID not found. Unable to block user.");
  529. }
  530. });
  531.  
  532. // Function to create an ignore button in the user menu
  533. function createIgnoreButton() {
  534. console.log("createIgnoreButton function is called");
  535.  
  536. // Check if the ignore button is already created
  537. var ignoreButton = document.querySelector('.usermenu button[data-btntype="ignore"]');
  538.  
  539. if (!ignoreButton) {
  540. ignoreButton = document.createElement("button");
  541. ignoreButton.innerText = "Ignore";
  542. ignoreButton.setAttribute("data-btntype", "ignore"); // Set a new attribute for identification
  543. ignoreButton.style.display = "block";
  544. ignoreButton.style.marginTop = "5px"; // Adjust the styling as needed
  545.  
  546. // Insert the ignore button into the user menu
  547. var userMenu = document.querySelector('.usermenu');
  548. if (userMenu) {
  549. userMenu.insertBefore(ignoreButton, userMenu.firstChild);
  550.  
  551. // Add click event directly to the button
  552. ignoreButton.addEventListener("click", function () {
  553. // Log to console to check if the button click is being registered
  554. console.log("Ignore button clicked");
  555.  
  556. // Invoke the function to get the user UUID from the user list
  557. var userUUID = getUserUUIDFromUserList();
  558.  
  559. // Check if the user UUID is found
  560. if (userUUID) {
  561. blockUser(userUUID);
  562. } else {
  563. console.error("User UUID not found. Ignoring user without blocking.");
  564. }
  565. });
  566. } else {
  567. console.error("User menu not found.");
  568. }
  569. }
  570. }
  571.  
  572. // Call the function to create the ignore button in the user menu
  573. createIgnoreButton();
  574.  
  575. // Function to get the user UUID from the chat log
  576. function getUserUUIDFromChatLog() {
  577. var chatLog = document.querySelector('.chatbox');
  578. if (chatLog) {
  579. // Find the first chat message in the log
  580. var firstChatMessage = chatLog.querySelector('p[data-t="c"]');
  581. if (firstChatMessage) {
  582. // Get the UUID from the first chat message
  583. var uuidElement = firstChatMessage.querySelector('.nm.fcuser, .nm.fcmod');
  584. if (uuidElement) {
  585. return uuidElement.dataset.uuid;
  586. } else {
  587. // Handle the case where UUID element is not found
  588. console.error("UUID element not found in the first chat message:", firstChatMessage);
  589. return null;
  590. }
  591. } else {
  592. // Handle the case where no chat messages are found
  593. console.error("No chat messages found in the chat log.");
  594. return null;
  595. }
  596. } else {
  597. // Handle the case where the chatbox element is not found
  598. console.error("Chatbox element not found.");
  599. return null;
  600. }
  601. }
  602.  
  603. // Function to get the user UUID from the user list within FreeChat context
  604. function getUserUUIDFromUserList() {
  605. var userContainer = document.querySelector("#chat > div.fc > div.gridbox_list > div.userlist p.user.fcuser[data-uuid]");
  606.  
  607. if (userContainer) {
  608. return userContainer.dataset.uuid;
  609. } else {
  610. // If user container is not found, set up a MutationObserver to wait for changes
  611. var observer = new MutationObserver(function (mutations) {
  612. userContainer = document.querySelector("#chat > div.fc > div.gridbox_list > div.userlist p.user.fcuser[data-uuid]");
  613. if (userContainer) {
  614. console.log("User container found after mutation.");
  615. console.log("User UUID: ", userContainer.dataset.uuid);
  616. // Stop observing once the user container is found
  617. observer.disconnect();
  618. }
  619. });
  620.  
  621. // Start observing changes in the user list
  622. observer.observe(document.querySelector("#chat > div.fc > div.gridbox_list > div.userlist"), { childList: true, subtree: true });
  623.  
  624. console.error("User container not found in the user list within FreeChat context. Waiting for mutations...");
  625. return null;
  626. }
  627. }
  628.  
  629. // Create the ignore list div once and append the content dynamically
  630. var ignoreListDiv = document.createElement("div");
  631. ignoreListDiv.style.position = "fixed";
  632. ignoreListDiv.style.bottom = "10px"; // Move to the bottom
  633. ignoreListDiv.style.left = "10px";
  634. ignoreListDiv.style.backgroundColor = "white"; // Adjust styling as needed
  635. ignoreListDiv.style.padding = "10px";
  636. ignoreListDiv.style.border = "1px solid black"; // Add border for visibility
  637. ignoreListDiv.style.fontSize = "12px"; // Set font size to 12px
  638.  
  639.  
  640. // Create a heading for the ignore list
  641. var ignoreListHeading = document.createElement("h3");
  642. ignoreListHeading.innerText = "Ignore List";
  643. ignoreListDiv.appendChild(ignoreListHeading);
  644.  
  645. // Create a list to display ignored users
  646. var ignoreList = document.createElement("ul");
  647. ignoreList.style.listStyleType = "none"; // Remove default list styling
  648. ignoreListDiv.appendChild(ignoreList);
  649.  
  650. // Append the ignore list div to the body
  651. document.body.appendChild(ignoreListDiv);
  652.  
  653. // Function to create a list item with the ignore list entry and remove button
  654. function createIgnoreListItem(uuid, username) {
  655. var listItem = document.createElement("li");
  656. listItem.innerText = `${username} (${uuid})`;
  657.  
  658. // Create a remove button for each entry
  659. var removeButton = document.createElement("button");
  660. removeButton.innerText = "Remove";
  661. removeButton.addEventListener("click", function () {
  662. // Remove the entry when the button is clicked
  663. removeIgnoreEntry(uuid);
  664. });
  665.  
  666. // Append the remove button to the list item
  667. listItem.appendChild(removeButton);
  668.  
  669. // Append the list item to the ignore list
  670. ignoreList.appendChild(listItem);
  671. }
  672.  
  673.  
  674. // Function to refresh the ignore list display
  675. function refreshIgnoreList() {
  676. // Clear the existing content
  677. ignoreList.innerHTML = "";
  678.  
  679. // Populate the ignore list with entries and remove buttons
  680. blocked_uuids.forEach(function (uuid) {
  681. createIgnoreListItem(uuid);
  682. });
  683. }
  684.  
  685. // Populate the ignore list with entries and remove buttons
  686. blocked_uuids.forEach(function (uuid) {
  687. createIgnoreListItem(uuid);
  688. });
  689.  
  690. // Function to handle removing an entry from the ignore list
  691. function removeIgnoreEntry(uuid) {
  692. var index = blocked_uuids.indexOf(uuid);
  693. if (index !== -1) {
  694. // Remove the entry from the ignore list
  695. blocked_uuids.splice(index, 1);
  696. // Refresh the ignore list display after removal
  697. refreshIgnoreList();
  698. }
  699. }
  700.  
  701.  
  702. // Function to save blocked_uuids to a text file
  703. function saveToTextFile() {
  704. var textToSave = blocked_uuids.join('\n');
  705. var blob = new Blob([textToSave], { type: 'text/plain' });
  706. var link = document.createElement('a');
  707. link.download = 'ignore_list.txt';
  708. link.href = window.URL.createObjectURL(blob);
  709. link.onclick = function () {
  710. document.body.removeChild(link);
  711. };
  712. link.style.display = 'none';
  713. document.body.appendChild(link);
  714. link.click();
  715. }
  716.  
  717. // Function to load blocked_uuids from a text file
  718. function loadFromTextFile() {
  719. var input = document.createElement('input');
  720. input.type = 'file';
  721. input.accept = '.txt';
  722. input.onchange = function (event) {
  723. var file = event.target.files[0];
  724. if (file) {
  725. var reader = new FileReader();
  726. reader.onload = function (e) {
  727. // Parse the content of the file and update blocked_uuids
  728. blocked_uuids = e.target.result.split('\n').map(function (uuid) {
  729. return uuid.trim();
  730. });
  731. // Update the ignore list display
  732. refreshIgnoreList();
  733. };
  734. reader.readAsText(file);
  735. }
  736. };
  737. input.click();
  738. }
  739.  
  740. // Function to create a button to save and load ignore list
  741. function createSaveLoadButtons() {
  742. var saveButton = document.createElement("button");
  743. saveButton.innerText = "Save to Text File";
  744. saveButton.addEventListener("click", function () {
  745. saveToTextFile();
  746. });
  747.  
  748. var loadButton = document.createElement("button");
  749. loadButton.innerText = "Load from Text File";
  750. loadButton.addEventListener("click", function () {
  751. loadFromTextFile();
  752. });
  753.  
  754. var buttonContainer = document.createElement("div");
  755. buttonContainer.style.marginTop = "10px";
  756. buttonContainer.appendChild(saveButton);
  757. buttonContainer.appendChild(loadButton);
  758.  
  759. // Append the button container to the ignore list div
  760. ignoreListDiv.appendChild(buttonContainer);
  761. }
  762.  
  763. // Call the function to create the save and load buttons
  764. createSaveLoadButtons();
  765.  
  766.  
  767. // Function to create buttons, including the collapse button
  768. function createButtons() {
  769. // Create a container for the buttons
  770. var buttonContainer = document.createElement("div");
  771. buttonContainer.style.position = "fixed";
  772. buttonContainer.style.top = "10px";
  773. buttonContainer.style.left = "10px";
  774. document.body.appendChild(buttonContainer);
  775.  
  776. // Function to create a button
  777. function createButton(text, clickHandler) {
  778. var button = document.createElement("button");
  779. button.innerText = text;
  780. button.addEventListener("click", clickHandler);
  781. buttonContainer.appendChild(button);
  782. }
  783.  
  784. // Create the collapse button
  785. createButton("Collapse", function () {
  786. var chatbox = document.querySelector('.chatbox');
  787. chatbox.style.display = (chatbox.style.display === 'none' || chatbox.style.display === '') ? 'block' : 'none';
  788. });
  789.  
  790. // Create the clear cache button
  791. createButton("Clear Cache", function () {
  792. localStorage.removeItem('blocked_uuids');
  793. showNotification("Cache cleared. Please refresh the page.");
  794. });
  795.  
  796. // Create the button to hide system messages
  797. createButton("Hide System", function () {
  798. // Get all system messages
  799. var systemMessages = document.querySelectorAll('.chatbox .system');
  800.  
  801. // Toggle visibility of system messages
  802. systemMessages.forEach(function (systemMessage) {
  803. systemMessage.style.display = (systemMessage.style.display === 'none' || systemMessage.style.display === '') ? 'block' : 'none';
  804. });
  805. });
  806. }
  807.  
  808. // Call the function to create buttons
  809. createButtons();
  810.  
  811.  
  812. // Wait for the DOM to be fully loaded before setting up the MutationObserver
  813. document.addEventListener('DOMContentLoaded', function () {
  814. // Call the initial function to start handling new chat messages
  815. handleNewChatMessages();
  816.  
  817. // Call the function to observe mutations in the chatbox
  818. observeChatboxMutations();
  819. });