Meklin Shutdownchat Script

Modified Shutdownchat, unmatched scripts, brace to be thunderstruck

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

  1. // ==UserScript==
  2. // @name Meklin Shutdownchat Script
  3. // @version 1.7
  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. // Declare global variables
  20. var blocked_uuids = JSON.parse(localStorage.getItem('blocked_uuids')) || [];
  21. var observer;
  22. var customChatmsg;
  23. var customInputWindow;
  24. var customInputWindow2;
  25. var customInputWindow3;
  26. var customInputWindow4; // Declare only once
  27. var clonedGridboxTools;
  28.  
  29. // Your function or script logic
  30. function initializeScript() {
  31. // Create customInputWindow4
  32. customInputWindow4 = document.createElement("div");
  33. customInputWindow4.className = "your-custom-class";
  34.  
  35. // Clone gridbox
  36. function cloneGridbox() {
  37. var gridboxTools = document.querySelector('.gridbox_tools');
  38. var clonedGridboxTools = gridboxTools.cloneNode(true);
  39. // Append the new button to the custom input window
  40. customInputWindow4.appendChild(clonedGridboxTools);
  41.  
  42. // ... other logic related to cloneGridbox ...
  43.  
  44. // Append the custom input window to the body
  45. document.body.appendChild(customInputWindow4);
  46. }
  47.  
  48. // ... other script logic ...
  49.  
  50. // Call the cloneGridbox function when needed
  51. cloneGridbox();
  52. }
  53.  
  54. // Call the function to initialize the script
  55. initializeScript();
  56.  
  57. // Function to show a notification
  58. function showNotification(message) {
  59. var notification = document.createElement("div");
  60. notification.style.position = "fixed";
  61. notification.style.top = "10px";
  62. notification.style.left = "10px";
  63. notification.style.backgroundColor = "#000000";
  64. notification.style.padding = "10px";
  65. notification.style.border = "1px solid #ccc";
  66. notification.style.borderRadius = "5px";
  67. notification.style.fontSize = "12px";
  68. notification.style.color = "#C0FF00";
  69. notification.style.opacity = 1;
  70. notification.style.transition = "opacity 2s ease-in-out";
  71. notification.innerHTML = message;
  72. document.body.appendChild(notification);
  73. // Set a timeout to fade out the notification
  74. setTimeout(function () {
  75. notification.style.opacity = 0;
  76. }, 5000); // Adjust the timeout value as needed
  77. // Remove the notification from the DOM after fading out
  78. setTimeout(function () {
  79. document.body.removeChild(notification);
  80. }, 6000); // Adjust the timeout value to match the fade-out duration
  81. }
  82. // Function to create a button to clear the JSON local saved cache
  83. function createClearCacheButton() {
  84. console.log("createClearCacheButton function is called");
  85.  
  86. var clearCacheButton = document.createElement("button");
  87. clearCacheButton.innerText = "clr";
  88. clearCacheButton.style.position = "fixed";
  89. clearCacheButton.style.top = "50px";
  90. clearCacheButton.style.left = "10px";
  91. clearCacheButton.addEventListener("click", function () {
  92. // Clear the JSON local saved cache
  93. localStorage.removeItem('blocked_uuids');
  94. showNotification("Cache cleared. Please refresh the page.");
  95. });
  96. // Check if the body is available
  97. if (document.body) {
  98. // Append the clearCacheButton to the body
  99. document.body.appendChild(clearCacheButton);
  100. } else {
  101. // If the body is not available, wait for DOMContentLoaded event
  102. document.addEventListener("DOMContentLoaded", function () {
  103. // Append the clearCacheButton to the body
  104. document.body.appendChild(clearCacheButton);
  105. });
  106. }
  107. }
  108. // Function to create a button to collapse the view
  109. function createCollapseButton() {
  110. console.log("createCollapseButton function is called");
  111. var collapseButton = document.createElement("button");
  112. // Set the inner HTML with an SVG and additional text
  113. collapseButton.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
  114. <path fill="none" d="M0 0h24v24H0z"/>
  115. <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"/>
  116. </svg>min`;
  117. // Adjust the font size of the text
  118. collapseButton.style.fontSize = "12px"; // Adjust the font size as needed
  119. collapseButton.style.position = "fixed";
  120. collapseButton.style.top = "90px";
  121. collapseButton.style.left = "10px";
  122. // Function to append the button to the body
  123. function appendButtonToBody() {
  124. document.body.appendChild(collapseButton);
  125. }
  126. // Check if the body is available
  127. if (document.body) {
  128. // Append the collapseButton to the body
  129. appendButtonToBody();
  130. } else {
  131. // If the body is not available, wait for DOMContentLoaded event
  132. document.addEventListener("DOMContentLoaded", appendButtonToBody);
  133. }
  134. collapseButton.addEventListener("click", function () {
  135. // Toggle visibility of the chatbox
  136. var chatbox = document.querySelector('.chatbox');
  137. chatbox.style.display = (chatbox.style.display === 'none' || chatbox.style.display === '') ? 'block' : 'none';
  138. });
  139. // Get the chatbox element after creating the button
  140. var chatbox = document.querySelector('.chatbox');
  141. // Check if the chatbox element is found
  142. if (chatbox) {
  143. // Initialize the observer if not already initialized
  144. if (!observer) {
  145. observer = new MutationObserver(function (mutations) {
  146. // Handle mutations
  147. console.log("Mutations:", mutations);
  148. // You can add your logic to handle mutations here
  149. });
  150. // Start observing the chatbox
  151. observer.observe(chatbox, { childList: true });
  152. }
  153. // Log the chatbox element to the console
  154. console.log("Chatbox element:", chatbox);
  155. }
  156. }
  157. function getNickname(fcuserSpan) {
  158. if (!fcuserSpan) return;
  159. // Check if fcuserSpan is a direct child of p
  160. var isDirectChild = fcuserSpan.parentNode.nodeName === "P";
  161. var nickname;
  162. if (isDirectChild) {
  163. nickname = fcuserSpan.innerText.replace(/[:\-]/g, '').trim();
  164. } else {
  165. // If not a direct child, assume it's under an anchor tag (a) in the user list
  166. nickname = fcuserSpan.parentNode.querySelector('.fcuser').innerText.replace(/[:\-]/g, '').trim();
  167. }
  168. return nickname;
  169. }
  170. // Function to handle the new chat messages
  171. function handleNewChatMessages() {
  172. // Get the chatbox element
  173. console.log("Attempting to get chatbox element");
  174. var chatbox = document.querySelector('.chatbox');
  175. // Check if the chatbox element is found
  176. if (!chatbox) {
  177. console.error("Chatbox element not found. Cannot add event listener.");
  178. return;
  179. }
  180. console.log("Chatbox element found. Proceeding with event listener setup.");
  181. // Use the existing observer if not already initialized
  182. if (!observer) {
  183. observer = new MutationObserver(function (mutations) {
  184. // Handle mutations
  185. mutations.forEach(function (mutation) {
  186. mutation.addedNodes.forEach(function (node) {
  187. handleChatMessage(node);
  188. console.log("Mutations:", mutations);
  189. // You can add your logic to handle mutations here
  190. });
  191. });
  192. });
  193. // Start observing the chatbox if observer is defined
  194. if (typeof observer !== 'undefined' && observer !== null) {
  195. observer.observe(chatbox, { childList: true });
  196. } else {
  197. console.error("Observer not defined. Cannot add event listener.");
  198. }
  199. }
  200. // Continue with handling new chat messages
  201. var chatboxElems = chatbox.getElementsByTagName('p');
  202. for (var i = 0; i < chatboxElems.length; i++) {
  203. var chatElem = chatboxElems[i];
  204. if (!chatElem.handled) {
  205. chatElem.handled = true;
  206. // Additional logic for handling specific types of messages
  207. // Remove text containing 'roll'
  208. if (chatElem.textContent.toLowerCase().includes('roll')) {
  209. chatElem.style.display = 'none'; // hide the message
  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. // Check if the message is a system message
  217. var systemMessage = chatElem.classList.contains('system');
  218. if (systemMessage) {
  219. // Add a button to hide the system message
  220. addHideButtonToSystemMessage(chatElem);
  221. } else {
  222. // Check if the user is ignored
  223. var fcuserSpan = chatElem.querySelector('.nm.fcuser, .nm.fcmod, .user');
  224. var uuid = fcuserSpan ? fcuserSpan.dataset.uuid : null;
  225. console.log("fcuserSpan:", fcuserSpan); // Add this line to log fcuserSpan
  226. console.log("uuid:", uuid); // Add this line to log uuid
  227. if (uuid) {
  228. // Check if the user is ignored
  229. var isIgnored = blocked_uuids.includes(uuid);
  230. // Modify the appearance based on whether the user is ignored or not
  231. if (isIgnored) {
  232. chatElem.style.display = 'none'; // hide the message
  233. } else {
  234. // Add an "ignore" button to the user menu
  235. addIgnoreButtonToUserMenu(uuid);
  236. }
  237. }
  238. }
  239. }
  240. }
  241. }
  242. // Function to add a button to hide system messages
  243. function addHideButtonToSystemMessage(chatElem) {
  244. var hideButton = document.createElement('button');
  245. hideButton.textContent = 'Hide';
  246. hideButton.style.marginLeft = '5px';
  247. hideButton.addEventListener('click', function () {
  248. chatElem.style.display = 'none'; // hide the system message
  249. });
  250. // Append the button to the system message
  251. chatElem.appendChild(hideButton);
  252. }
  253. // Function to add an "ignore" button to the user menu
  254. function addIgnoreButtonToUserMenu(chatElem) {
  255. // Check if the user menu exists
  256. var userMenu = document.querySelector('.usermenu');
  257. if (userMenu && chatElem && chatElem.querySelector) {
  258. // Check if the user is already ignored
  259. var uuid = chatElem.querySelector('.nm.fcuser, .nm.fcmod')?.dataset.uuid;
  260. var isIgnored = blocked_uuids.includes(uuid);
  261. // Create a button for either ignoring or unignoring the user
  262. var ignoreButton = document.createElement('button');
  263. ignoreButton.textContent = isIgnored ? 'Unignore' : 'Ignore';
  264. // Add an event listener to handle ignoring/unignoring the user
  265. ignoreButton.addEventListener('click', function () {
  266. if (isIgnored) {
  267. // Unignore the user
  268. unignoreUser(uuid);
  269. } else {
  270. // Ignore the user
  271. ignoreUser(uuid);
  272. }
  273. });
  274. // Append the button to the user menu
  275. userMenu.appendChild(ignoreButton);
  276. } else {
  277. console.error("Invalid userMenu, chatElem, or querySelector is not supported. Conditions: userMenu=" + userMenu + ", chatElem=" + chatElem + ", chatElem.querySelector=" + (chatElem ? chatElem.querySelector : null));
  278. }
  279. }
  280. // Function to observe mutations in the chatbox
  281. function observeChatboxMutations() {
  282. var chatbox = document.querySelector('.chatbox')
  283. if (chatbox instanceof Node && !observer) {
  284. // Create a mutation observer to monitor changes in the chatbox
  285. observer = new MutationObserver(function (mutations) {
  286. mutations.forEach(function (mutation) {
  287. mutation.addedNodes.forEach(function (node) {
  288. if (node.nodeName === "P" && node.dataset.t === "c") {
  289. // Your logic for handling new chat messages goes here
  290. console.log("Processing Chatbox Now");
  291. }
  292. });
  293. });
  294. });
  295. // Start observing the chatbox
  296. observer.observe(chatbox, { childList: true });
  297. } else {
  298. console.error("Chatbox element not found or is not a valid Node. Cannot add event listener.");
  299. }
  300. }
  301. // Function to ignore a user
  302. function ignoreUser(uuid) {
  303. // Add your logic here to handle ignoring a user
  304. // For example, you can add the user's UUID to the blocked_uuids array
  305. blocked_uuids.push(uuid);
  306. // Save the updated blocked_uuids to localStorage
  307. localStorage.setItem('blocked_uuids', JSON.stringify(blocked_uuids));
  308. // You can also add additional logic as needed
  309. console.log("Ignoring user with UUID:", uuid);
  310. }
  311. // Function to unignore a user
  312. function unignoreUser(uuid) {
  313. blocked_uuids = blocked_uuids.filter(function (blockedUuid) {
  314. return blockedUuid !== uuid;
  315. });
  316. // Add additional logic as needed
  317. console.log("Unignoring user with UUID:", uuid);
  318. }
  319. // Function to get the user UUID from a chat message
  320. function getUserUUIDFromChatMessage(messageNode) {
  321. var uuidElement = messageNode.querySelector('.nm.fcuser, .nm.fcmod');
  322. if (uuidElement) {
  323. return uuidElement.dataset.uuid;
  324. } else {
  325. console.error("UUID element not found in the chat message:", messageNode);
  326. return null;
  327. }
  328. }
  329. // Function to handle different types of chat messages
  330. function handleChatMessage(node) {
  331. // Check if the node is a chat message
  332. if (node.nodeName === "P" && node.dataset.t === "c") {
  333. // Get the uuid of the user who sent the message
  334. var uuid = getUserUUIDFromChatMessage(node);
  335. if (uuid) {
  336. console.log("Found message with UUID:", uuid);
  337. // Check if the uuid is in the blocked list
  338. if (blocked_uuids.includes(uuid)) {
  339. console.log("Blocking message with UUID:", uuid);
  340. // Hide the message
  341. node.style.display = "none";
  342. } else {
  343. // Alter messages of the type .fs_3
  344. if (node.classList.contains('fs_3')) {
  345. node.style.fontSize = '12px';
  346. node.style.color = 'white';
  347. }
  348. // Add an "ignore" button to the user menu
  349. addIgnoreButtonToUserMenu(node);
  350. }
  351. }
  352. } else if (node.nodeName === "P" && node.querySelector(".sysmsg.fcsys")) {
  353. // Handle system messages
  354. handleSystemMessage(node);
  355. }
  356. }
  357. // Function to handle system messages
  358. function handleSystemMessage(systemNode) {
  359. // Move system messages to the bottom right in their own DIV
  360. var systemDiv = document.createElement("div");
  361. systemDiv.className = "system-message";
  362. systemDiv.style.position = "fixed";
  363. systemDiv.style.bottom = "10px";
  364. systemDiv.style.right = "10px";
  365. systemDiv.style.backgroundColor = "#f0f0f0";
  366. systemDiv.style.padding = "10px";
  367. systemDiv.appendChild(systemNode.cloneNode(true));
  368. document.body.appendChild(systemDiv);
  369. // Get the chatbox element after creating the button
  370. var chatbox = document.querySelector('.chatbox');
  371. // Check if the chatbox element is found
  372. if (chatbox) {
  373. // Initialize the observer if not already initialized
  374. if (!observer) {
  375. observer = new MutationObserver(function (mutations) {
  376. // Handle mutations
  377. console.log("Mutations:", mutations);
  378. // You can add your logic to handle mutations here
  379. });
  380. // Start observing the chatbox
  381. observer.observe(chatbox, { childList: true });
  382. }
  383. }
  384. }
  385. // Function to block/unblock a user
  386. function blockUser(uuid) {
  387. console.log("blockUser function is called");
  388. var index = blocked_uuids.indexOf(uuid);
  389. if (index !== -1) {
  390. // User is already blocked, so unblock
  391. blocked_uuids.splice(index, 1);
  392. showNotification("User unblocked!");
  393. } else {
  394. // User is not blocked, so block
  395. blocked_uuids.push(uuid);
  396. showNotification("User blocked!");
  397. }
  398. // Save the updated blocked_uuids to localStorage
  399. localStorage.setItem('blocked_uuids', JSON.stringify(blocked_uuids));
  400. }
  401. // usermenu block button event listener:
  402. document.querySelector('.usermenu button[data-btntype="block"]').addEventListener('click', function() {
  403. console.log("User menu block button clicked");
  404. // Get the parent element of the button, assuming it contains user-related data
  405. var userContainer = this.closest('.user-container');
  406. // Assuming the user UUID is stored in a data attribute called data-uuid
  407. var userUUID = userContainer ? userContainer.dataset.uuid : null;
  408. // Check if userUUID is not null before blocking
  409. if (userUUID) {
  410. // Now you have the user UUID, and you can proceed to block the user
  411. blockUser(userUUID);
  412. } else {
  413. console.error("User UUID not found. Unable to block user.");
  414. }
  415. });
  416. // Function to create an ignore button in the user menu
  417. function createIgnoreButton() {
  418. console.log("createIgnoreButton function is called");
  419. // Check if the ignore button is already created
  420. var ignoreButton = document.querySelector('.usermenu button[data-btntype="ignore"]');
  421. if (!ignoreButton) {
  422. ignoreButton = document.createElement("button");
  423. ignoreButton.innerText = "Ignore";
  424. ignoreButton.setAttribute("data-btntype", "ignore"); // Set a new attribute for identification
  425. ignoreButton.style.display = "block";
  426. ignoreButton.style.marginTop = "5px"; // Adjust the styling as needed
  427. // Insert the ignore button into the user menu
  428. var userMenu = document.querySelector('.usermenu');
  429. if (userMenu) {
  430. userMenu.insertBefore(ignoreButton, userMenu.firstChild);
  431. // Add click event directly to the button
  432. ignoreButton.addEventListener("click", function () {
  433. // Log to console to check if the button click is being registered
  434. console.log("Ignore button clicked");
  435. // Invoke the function to get the user UUID from the user list
  436. var userUUID = getUserUUIDFromUserList();
  437. // Check if the user UUID is found
  438. if (userUUID) {
  439. blockUser(userUUID);
  440. } else {
  441. console.error("User UUID not found. Ignoring user without blocking.");
  442. }
  443. });
  444. } else {
  445. console.error("User menu not found.");
  446. }
  447. }
  448. }
  449. // Function to get the user UUID from the chat log
  450. function getUserUUIDFromChatLog() {
  451. var chatLog = document.querySelector('.chatbox');
  452. if (chatLog) {
  453. // Find the first chat message in the log
  454. var firstChatMessage = chatLog.querySelector('p[data-t="c"]');
  455. if (firstChatMessage) {
  456. // Get the UUID from the first chat message
  457. var uuidElement = firstChatMessage.querySelector('.nm.fcuser, .nm.fcmod');
  458. if (uuidElement) {
  459. return uuidElement.dataset.uuid;
  460. } else {
  461. // Handle the case where UUID element is not found
  462. console.error("UUID element not found in the first chat message:", firstChatMessage);
  463. return null;
  464. }
  465. } else {
  466. // Handle the case where no chat messages are found
  467. console.error("No chat messages found in the chat log.");
  468. return null;
  469. }
  470. } else {
  471. // Handle the case where the chatbox element is not found
  472. console.error("Chatbox element not found.");
  473. return null;
  474. }
  475. }
  476. // Function to get the user UUID from the user list within FreeChat context
  477. function getUserUUIDFromUserList() {
  478. var userContainer = document.querySelector("#chat > div.fc > div.gridbox_list > div.userlist p.user.fcuser[data-uuid]");
  479. if (userContainer) {
  480. return userContainer.dataset.uuid;
  481. } else {
  482. // If user container is not found, set up a MutationObserver to wait for changes
  483. var observer = new MutationObserver(function (mutations) {
  484. userContainer = document.querySelector("#chat > div.fc > div.gridbox_list > div.userlist p.user.fcuser[data-uuid]");
  485. if (userContainer) {
  486. console.log("User container found after mutation.");
  487. console.log("User UUID: ", userContainer.dataset.uuid);
  488. // Stop observing once the user container is found
  489. observer.disconnect();
  490. }
  491. });
  492. // Start observing changes in the user list
  493. observer.observe(document.querySelector("#chat > div.fc > div.gridbox_list > div.userlist"), { childList: true, subtree: true });
  494. console.error("User container not found in the user list within FreeChat context. Waiting for mutations...");
  495. return null;
  496. }
  497. }
  498. // Create the ignore list div once and append the content dynamically
  499. var ignoreListDiv = document.createElement("div");
  500. ignoreListDiv.style.position = "fixed";
  501. ignoreListDiv.style.top = "135px"; // Move to the top
  502. ignoreListDiv.style.left = "10px";
  503. ignoreListDiv.style.backgroundColor = "white"; // Adjust styling as needed
  504. ignoreListDiv.style.padding = "10px";
  505. ignoreListDiv.style.border = "1px solid black"; // Add border for visibility
  506. ignoreListDiv.style.fontSize = "12px"; // Set font size to 12px
  507. // Create a heading for the ignore list
  508. var ignoreListHeading = document.createElement("h3");
  509. ignoreListHeading.innerText = "Ignore List";
  510. ignoreListDiv.appendChild(ignoreListHeading);
  511. // Create a list to display ignored users
  512. var ignoreList = document.createElement("ul");
  513. ignoreList.style.listStyleType = "none"; // Remove default list styling
  514. ignoreListDiv.appendChild(ignoreList);
  515. // Append the ignore list div to the body
  516. document.body.appendChild(ignoreListDiv);
  517. // Function to create a list item with the ignore list entry and remove button
  518. function createIgnoreListItem(uuid, username) {
  519. var listItem = document.createElement("li");
  520. listItem.innerText = `${username} (${uuid})`;
  521. // Create a remove button for each entry
  522. var removeButton = document.createElement("button");
  523. removeButton.innerText = "Remove";
  524. removeButton.addEventListener("click", function () {
  525. // Remove the entry when the button is clicked
  526. removeIgnoreEntry(uuid);
  527. });
  528. // Append the remove button to the list item
  529. listItem.appendChild(removeButton);
  530. // Append the list item to the ignore list
  531. ignoreList.appendChild(listItem);
  532. }
  533. // Function to refresh the ignore list display
  534. function refreshIgnoreList() {
  535. // Clear the existing content
  536. ignoreList.innerHTML = "";
  537.  
  538. // Populate the ignore list with entries and remove buttons
  539. blocked_uuids.forEach(function (uuid) {
  540. createIgnoreListItem(uuid);
  541. });
  542. }
  543. // Populate the ignore list with entries and remove buttons
  544. blocked_uuids.forEach(function (uuid) {
  545. createIgnoreListItem(uuid);
  546. });
  547. // Function to handle removing an entry from the ignore list
  548. function removeIgnoreEntry(uuid) {
  549. var index = blocked_uuids.indexOf(uuid);
  550. if (index !== -1) {
  551. // Remove the entry from the ignore list
  552. blocked_uuids.splice(index, 1);
  553. // Refresh the ignore list display after removal
  554. refreshIgnoreList();
  555. }
  556. }
  557. // Function to save blocked_uuids to a text file
  558. function saveToTextFile() {
  559. var textToSave = blocked_uuids.join('\n');
  560. var blob = new Blob([textToSave], { type: 'text/plain' });
  561. var link = document.createElement('a');
  562. link.download = 'ignore_list.txt';
  563. link.href = window.URL.createObjectURL(blob);
  564. link.onclick = function () {
  565. document.body.removeChild(link);
  566. };
  567. link.style.display = 'none';
  568. document.body.appendChild(link);
  569. link.click();
  570. }
  571. // Function to load blocked_uuids from a text file
  572. function loadFromTextFile() {
  573. var input = document.createElement('input');
  574. input.type = 'file';
  575. input.accept = '.txt';
  576. input.onchange = function (event) {
  577. var file = event.target.files[0];
  578. if (file) {
  579. var reader = new FileReader();
  580. reader.onload = function (e) {
  581. // Parse the content of the file and update blocked_uuids
  582. blocked_uuids = e.target.result.split('\n').map(function (uuid) {
  583. return uuid.trim();
  584. });
  585. // Update the ignore list display
  586. refreshIgnoreList();
  587. };
  588. reader.readAsText(file);
  589. }
  590. };
  591. input.click();
  592. }
  593. // Function to create a button to save and load ignore list
  594. function createSaveLoadButtons() {
  595. var saveButton = document.createElement("button");
  596. saveButton.innerText = "Save to Text File";
  597. saveButton.addEventListener("click", function () {
  598. saveToTextFile();
  599. });
  600. var loadButton = document.createElement("button");
  601. loadButton.innerText = "Load from Text File";
  602. loadButton.addEventListener("click", function () {
  603. loadFromTextFile();
  604. });
  605. var buttonContainer = document.createElement("div");
  606. buttonContainer.style.marginTop = "10px";
  607. buttonContainer.appendChild(saveButton);
  608. buttonContainer.appendChild(loadButton);
  609.  
  610. // Append the button container to the ignore list div
  611. ignoreListDiv.appendChild(buttonContainer);
  612. }
  613. // Function to create buttons, including the collapse button
  614. function createButtons() {
  615. // Create a container for the buttons
  616. var buttonContainer = document.createElement("div");
  617. buttonContainer.style.position = "fixed";
  618. buttonContainer.style.top = "10px";
  619. buttonContainer.style.left = "10px";
  620. document.body.appendChild(buttonContainer);
  621. // Function to create a button
  622. function createButton(text, clickHandler) {
  623. var button = document.createElement("button");
  624. button.innerText = text;
  625. button.addEventListener("click", clickHandler);
  626. buttonContainer.appendChild(button);
  627. }
  628. // Create the collapse button
  629. createButton("Collapse", function () {
  630. var chatbox = document.querySelector('.chatbox');
  631. chatbox.style.display = (chatbox.style.display === 'none' || chatbox.style.display === '') ? 'block' : 'none';
  632. });
  633. // Create the clear cache button
  634. createButton("Clear Cache", function () {
  635. localStorage.removeItem('blocked_uuids');
  636. showNotification("Cache cleared. Please refresh the page.");
  637. });
  638. // Create the button to hide system messages
  639. createButton("Hide System", function () {
  640. // Get all system messages
  641. var systemMessages = document.querySelectorAll('.chatbox .system');
  642. // Toggle visibility of system messages
  643. systemMessages.forEach(function (systemMessage) {
  644. systemMessage.style.display = (systemMessage.style.display === 'none' || systemMessage.style.display === '') ? 'block' : 'none';
  645. });
  646. });
  647. }
  648. // Function to create and style the gridbox_tools clone input window
  649. function createCustomInputWindow() {
  650. // Create the custom input window
  651. var customInputWindow1 = document.createElement("div");
  652. customInputWindow.className = "gridbox_tools";
  653. customInputWindow.innerHTML = `
  654. <div class="tb">
  655. <!-- Add other elements here similar to the default menu -->
  656. <input type="text" autocomplete="off" class="chatmsg fs_1" style="color: rgb(221, 221, 221);" maxlength="500">
  657. <button class="sendbtn material-icons">Send</button>
  658. </div>
  659. `;
  660. // Append the custom input window to the body
  661. document.body.appendChild(customInputWindow);
  662. // Style the text input
  663. var customChatmsg = customInputWindow.querySelector(".chatmsg");
  664. customChatmsg.style.flex = "1";
  665. customChatmsg.style.padding = "5px";
  666. // Style the send button
  667. var customSendbtn = customInputWindow.querySelector(".sendbtn");
  668. customSendbtn.innerText = "msg"; // Customize the button text as needed
  669. // Add event listener for the send button
  670. customSendbtn.addEventListener("click", function () {
  671. handleCustomButtonClick(customChatmsg.value.trim());
  672. });
  673. }
  674. // Function to create and style additional custom input window
  675. function createAdditionalCustomInputWindow() {
  676. // Create the custom input window
  677. var customInputWindow2 = document.createElement("div");
  678. customInputWindow2.className = "command-input-window";
  679. customInputWindow2.innerHTML = `
  680. <input type="text" autocomplete="off" class="custom-chatmsg" placeholder="Type your command...">
  681. <button class="custom-sendbtn material-icons">Send</button>
  682. <button class="custom-sendbtn2">Send 2</button>
  683. `;
  684. // Style the custom input window
  685. customInputWindow2.style.position = "fixed";
  686. customInputWindow2.style.bottom = "10px";
  687. customInputWindow2.style.left = "10px";
  688. customInputWindow2.style.display = "flex";
  689. customInputWindow2.style.alignItems = "center";
  690. // Append the custom input window to the body
  691. document.body.appendChild(customInputWindow2);
  692. // Style the text input
  693. var customChatmsg = customInputWindow2.querySelector(".custom-chatmsg");
  694. customChatmsg.style.flex = "1";
  695. customChatmsg.style.padding = "5px";
  696. // Style the send buttons
  697. var customSendbtn = customInputWindow2.querySelector(".custom-sendbtn");
  698. customSendbtn.innerText = "cmd"; // Customize the button text as needed
  699. var customSendbtn2 = customInputWindow2.querySelector(".custom-sendbtn2");
  700. customSendbtn2.innerText = "msg"; // Customize the button text as needed
  701. var sendButtons = [customSendbtn, customSendbtn2];
  702. // Create a third button for saying hello
  703. var customSendbtn3 = document.createElement("button");
  704. customSendbtn3.innerText = "hi"; // Customize the button text as needed
  705. // Append the button to the custom input window
  706. customInputWindow2.appendChild(customSendbtn3);
  707. // Add an event listener for the "Send" button
  708. customSendbtn.addEventListener("click", function () {
  709. handleCustomButtonClick(customChatmsg.value.trim());
  710. });
  711. // Add a click event listener to the "Hello" button
  712. customSendbtn3.addEventListener("click", function () {
  713. // Your logic for handling the "Hello" button goes here
  714. var command = customChatmsg.value.trim();
  715. // Clear the input field after processing the command
  716. customChatmsg.value = "";
  717. // Simulate a click on the button
  718. customSendbtn3.click();
  719. });
  720. // Create the button element
  721. var customSendBtn = document.createElement("button");
  722. customSendBtn.className = "sendbtn"; // Add the desired class name
  723. customSendBtn.innerHTML = '<svg width="24" height="24" viewBox="0 0 24 24"><path d="M3 3h18v2H3V3zm0 4h12v2H3V7zm0 4h18v2H3v-2zm0 4h12v2H3v-2z"></path></svg>';
  724. // Replace the innerHTML with your SVG code or use an external SVG file
  725. // Append the button to the desired container (e.g., document.body)
  726. document.body.appendChild(customSendBtn);
  727. // Append the third button to the custom input window
  728. customInputWindow2.appendChild(customSendbtn3);
  729. // Style all send buttons
  730. sendButtons.forEach(function (btn) {
  731. btn.style.cursor = "pointer";
  732. btn.style.padding = "5px";
  733. // Add event listener for each button
  734. btn.addEventListener("click", function () {
  735. handleButtonClick(btn);
  736. console.log("handleButtonClick clicked!");
  737. });
  738. });
  739. // Append the new button to the custom input window
  740. customInputWindow2.appendChild(customSendbtn2);
  741. // Add an event listener for the new "Message" button
  742. customSendbtn2.addEventListener("click", function () {
  743. // Your logic for handling the command goes here
  744. var command = customChatmsg.value.trim();
  745. // Clear the input field after processing the command
  746. customChatmsg.value = "";
  747. });
  748. // Append the new button to the custom input window
  749. customInputWindow2.appendChild(customSendbtn2);
  750. // Function to handle default "Send" button click
  751. function handleDefaultSendButtonClick(btn, customChatmsg) {
  752. var command = customChatmsg.value.trim();
  753. // Your logic for handling the command with the default "Send" button goes here
  754. // Use btn to identify which button triggered the click event
  755. // Clear the input field after processing the command
  756. customChatmsg.value = "";
  757. }
  758. // Add an event listener for the original "Send" button
  759. var defaultSendBtn = customInputWindow.querySelector(".sendbtn");
  760. defaultSendBtn.addEventListener("click", function () {
  761. handleButtonClick(defaultSendBtn);
  762. });
  763. // Function to handle button clicks
  764. function handleButtonClick(btn, customChatmsg) {
  765. var command = customChatmsg.value.trim();
  766. // Your logic for handling the command goes here
  767. // Use btn to identify which button triggered the click event
  768. // Clear the input field after processing the command
  769. customChatmsg.value = "";
  770. }
  771. function handleCustomButtonClick(command) {
  772. // Your logic for handling the command goes here
  773. // This might involve calling the necessary functions from furtherchat.js
  774. // Ensure the logic aligns with the existing chat system
  775. // Clear the input field after processing the command
  776. customChatmsg.value = "";
  777. }
  778. // Wrap function calls inside DomContentLoaded event listener ensuring page load
  779. document.addEventListener('DOMContentLoaded', function () {
  780. // Function to be called after DOMContentLoaded
  781. function afterDOMContentLoaded() {
  782. // Call the initial function to start handling new chat messages
  783. handleNewChatMessages();
  784. // Call the function to observe mutations in the chatbox
  785. observeChatboxMutations();
  786. // Call the function to create the ignore list button
  787. createIgnoreListButton();
  788. // Call the function to create buttons
  789. createButtons();
  790. // Call the function to create the save and load buttons
  791. createSaveLoadButtons();
  792. // Call the function to create the ignore button in the user menu
  793. createIgnoreButton();
  794. // Call the function to create the clear cache button
  795. createClearCacheButton();
  796. // Call the function to create the collapse button
  797. createCollapseButton();
  798. // Clone gridbox
  799. cloneGridbox();
  800. // Create the custom input window
  801. createCustomInputWindow();
  802. // Create additional custom input window
  803. createAdditionalCustomInputWindow();
  804. // Now, you should be able to access customInputWindow
  805. console.log(customInputWindow);
  806. // Call the function to ignore a user
  807. ignoreUser('example_uuid');
  808. // Call the function to observe mutations in the chatbox
  809. observeChatboxMutations();
  810. }
  811. // Use MutationObserver to detect when userlist and chatbox are added to the DOM
  812. var observer = new MutationObserver(function (mutations) {
  813. mutations.forEach(function (mutation) {
  814. mutation.addedNodes.forEach(function (node) {
  815. if (node.classList && (node.classList.contains('userlist') || node.classList.contains('chatbox'))) {
  816. // Userlist or chatbox added to the DOM, stop observing and call functions
  817. observer.disconnect();
  818. afterDOMContentLoaded();
  819. }
  820. });
  821. });
  822. });
  823. // Start observing the body for added nodes
  824. observer.observe(document.body, { childList: true, subtree: true });
  825. // Check if userlist and chatbox are already present
  826. var userlist = document.querySelector('.userlist');
  827. var chatbox = document.querySelector('.chatbox');
  828. if (userlist && chatbox) {
  829. // Function to create a button to view the ignore list
  830. function createIgnoreListButton() {
  831. console.log("createIgnoreListButton function is called");
  832. var ignoreListButton = document.createElement("button");
  833. 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`;
  834. ignoreListButton.style.position = "fixed";
  835. ignoreListButton.style.top = "100px";
  836. ignoreListButton.style.left = "10px";
  837. ignoreListButton.addEventListener("click", function () {
  838. // Display the ignore list (you can customize this part)
  839. alert("Ignore List:\n" + blocked_uuids.join(", "));
  840. });
  841. document.body.appendChild(ignoreListButton);
  842. }
  843. createIgnoreListButton(); // Call the function to create the button
  844. } else {
  845. console.error("The userlist element is not found.");
  846. }
  847. // Proceed with querying for .fcuser elements
  848. var users = userlist.querySelectorAll(".fcuser");
  849. users.forEach(function (user) {
  850. // Your code for each user
  851. var uuid = user.dataset.uuid;
  852. // Create the block button
  853. var muteButton = document.createElement("button");
  854. muteButton.innerText = "Mute";
  855. muteButton.addEventListener("click", function() {
  856. muteUser(uuid);
  857. });
  858. // Create the ignore button with a unique class
  859. var ignoreButton = document.createElement("button");
  860. ignoreButton.innerText = "Ignore";
  861. ignoreButton.setAttribute("data-btntype", "ignore"); // Set a new attribute for identification
  862. 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>`;
  863. ignoreButton.style.marginLeft = "5px";
  864. ignoreButton.style.cursor = "pointer";
  865. // Add a unique class to the ignore button
  866. ignoreButton.classList.add("ignoreButtonClass");
  867. ignoreButton.addEventListener("click", function () {
  868. // Dynamically fetch the user UUID when the "Ignore" button is clicked
  869. var clickedUserUUID = user.dataset.uuid;
  870. blockUser(clickedUserUUID);
  871. });
  872. // Create a container div for the buttons
  873. var buttonContainer = document.createElement("div");
  874. buttonContainer.style.display = "flex";
  875. buttonContainer.style.alignItems = "center";
  876. // Append the buttons to the container
  877. buttonContainer.appendChild(blockButton);
  878. buttonContainer.appendChild(ignoreButton);
  879. // Append the container to the user element
  880. user.parentElement.appendChild(buttonContainer);
  881. });
  882. });
  883. // Function to create and style the combined input window
  884. function createCombinedInputWindow() {
  885. // Create the custom input window
  886. var customInputWindow3 = document.createElement("div");
  887. customInputWindow.className = "combined-input-window";
  888. // Append the custom input window to the body
  889. document.body.appendChild(customInputWindow);
  890. // <!-- Add other elements here similar to the default menu -->
  891. customInputWindow.innerHTML = `
  892. <div class="tb">
  893. <input type="text" autocomplete="off" class="chatmsg fs_1" style="color: rgb(221, 221, 221);" maxlength="500">
  894. <button class="sendbtn material-icons">Send</button>
  895. <button class="custom-sendbtn2">Send 2</button>
  896. </div>
  897. `;
  898. // Move the following code inside the createCombinedInputWindow function
  899. var additionalButtonsHTML = `
  900. <select class="sizesel">
  901. <option value="0">smaller</option>
  902. <option value="1">normal</option>
  903. <option value="2">bigger</option>
  904. <option value="3">more bigger</option>
  905. </select>
  906. <button style="display: inline-block;">YouTube Player</button>
  907. <div class="fccb">
  908. <input type="checkbox">
  909. <label><span class="material-icons"></span>Kageshi Mode</label>
  910. </div>
  911. <input type="text" autocomplete="off" class="chatmsg fs_1" maxlength="700" style="color: rgb(221, 221, 221);">
  912. <button class="sendbtn material-icons"></button>
  913. `;
  914. customInputWindow.querySelector('.tb').innerHTML += additionalButtonsHTML;
  915. // Event listener for your "Command" button
  916. var customSendbtn2 = customInputWindow.querySelector(".custom-sendbtn2");
  917. customSendbtn2.addEventListener("click", function () {
  918. // Call the backend function or method for "Send 2"
  919. // Adjust the logic as needed
  920. send2ButtonClick();
  921. });
  922. // Event listener for your additional buttons
  923. var additionalButtons = customInputWindow.querySelectorAll(".your-additional-buttons-class");
  924. additionalButtons.forEach(function (button) {
  925. button.addEventListener("click", function () {
  926. // Call the backend function or method associated with the clicked button
  927. // Adjust the logic as needed
  928. yourAdditionalButtonClick(button);
  929. });
  930. });
  931. // Additional styling or event listeners for the combined input window if needed
  932. }
  933. // Create the combined input window
  934. createCombinedInputWindow();
  935. // Function to handle the "Send 2" button click
  936. function send2ButtonClick() {
  937. // Your logic for handling "Send 2" goes here
  938. console.log("Send 2 button clicked!");
  939. }
  940. // Function to handle additional button clicks
  941. function yourAdditionalButtonClick(button) {
  942. // Determine which button was clicked based on its properties or class, and call the corresponding backend method
  943. if (button.classList.contains("your-specific-button-class")) {
  944. // Call the backend method for the specific button
  945. console.log("Your specific button clicked!");
  946. } else {
  947. // Handle other buttons if needed
  948. }
  949. }
  950. // Append the custom input window to the body
  951. document.body.appendChild(customInputWindow);
  952. // Style the text input
  953. var customChatmsg = customInputWindow.querySelector(".chatmsg");
  954. customChatmsg.style.flex = "1";
  955. customChatmsg.style.padding = "5px";
  956. // Style the send button
  957. var customSendbtn = customInputWindow.querySelector(".sendbtn");
  958. customSendbtn.innerText = "msg"; // Customize the button text as needed
  959. // Add event listener for the send button
  960. customSendbtn.addEventListener("click", function () {
  961. handleCustomButtonClick(customChatmsg.value.trim());
  962. });
  963. // Assuming you have a reference to your combined input window
  964. var combinedInputWindow = document.querySelector(".combined-input-window");
  965. // Event listener for your "Command" button
  966. var customSendbtn2 = combinedInputWindow.querySelector(".custom-sendbtn2");
  967. customSendbtn2.addEventListener("click", function () {
  968. // Call the backend function or method for "Send 2"
  969. // Adjust the logic as needed
  970. send2ButtonClick();
  971. });
  972. // Event listener for your additional buttons
  973. var additionalButtons = combinedInputWindow.querySelectorAll(".your-additional-buttons-class");
  974. additionalButtons.forEach(function (button) {
  975. button.addEventListener("click", function () {
  976. // Call the backend function or method associated with the clicked button
  977. // Adjust the logic as needed
  978. yourAdditionalButtonClick(button);
  979. });
  980. });
  981. }
  982. // Declare customInputWindow4 at the beginning of your code
  983. var customInputWindow4 = document.createElement("div");
  984. customInputWindow4.className = "your-custom-class"; // Fix the typo here
  985. // Clone gridbox
  986. function cloneGridbox() {
  987. var gridboxTools = document.querySelector('.gridbox_tools');
  988. var clonedGridboxTools = gridboxTools.cloneNode(true);
  989. // Append the new button to the custom input window
  990. customInputWindow4.appendChild(clonedGridboxTools);
  991. // Append the new button to the custom input window
  992. var customSendbtn2 = customInputWindow4.querySelector(".custom-sendbtn2");
  993. customSendbtn2.addEventListener("click", function () {
  994. // Your logic for handling the "Send 2" command goes here
  995. var command = customChatmsg.value.trim();
  996. // Clear the input field after processing the command
  997. customChatmsg.value = "";
  998. });
  999. // Additional styling or event listeners for the combined input window if needed
  1000. // Move this block inside the createCombinedInputWindow function
  1001. // Add additional buttons and elements from your HTML code
  1002. var additionalButtonsHTML = `
  1003. <select class="sizesel">
  1004. <option value="0">smaller</option>
  1005. <option value="1">normal</option>
  1006. <option value="2">bigger</option>
  1007. <option value="3">more bigger</option>
  1008. </select>
  1009. <button style="display: inline-block;">YouTube Player</button>
  1010. <div class="fccb">
  1011. <input type="checkbox">
  1012. <label><span class="material-icons"></span>Kageshi Mode</label>
  1013. </div>
  1014. <input type="text" autocomplete="off" class="chatmsg fs_1" maxlength="700" style="color: rgb(221, 221, 221);">
  1015. <button class="sendbtn material-icons"></button>
  1016. `;
  1017. clonedGridboxTools.querySelector('.tb').innerHTML += additionalButtonsHTML;
  1018. // Append the custom input window to the body
  1019. document.body.appendChild(customInputWindow4);
  1020. }
  1021. //fc_cam.prototype.setkmode = function(t) {
  1022. // this.kageshi_mode = t,
  1023. // null === this.video || null === this.user || this.you || this.paused || this.kageshi_mode && (this.pausecam(this.user),
  1024. // this.ws.sendpbuf(1200798, this.pb.roots.default.fc.p_1200798.encode({
  1025. // cn: this.camno
  1026. // }, null).finish()))
  1027. //}
  1028. function fc_coolbox(t, e, n, i, s, o, c) {
  1029. this.ws = t;
  1030. this.pb = e;
  1031. this.cb = s;
  1032. this.msglimit = o;
  1033. this.pmctrl = n;
  1034. this.layout = i;
  1035. this.yt_cb = c;
  1036. this.font_colour = "#FF0000";
  1037. this.font_size = 1;
  1038. this.elem = document.createElement("div");
  1039. this.elem.className = "tb";
  1040. // Create the color picker
  1041. this.text_cp = document.createElement("input");
  1042. this.text_cp.className = "jscolor";
  1043. this.text_cp.setAttribute("data-jscolor", "{position:'top',hash:false,value:'" + this.font_colour + "',borderRadius:'1px',borderColor:'" + this.ws.theme.lncol + "',controlBorderColor:'" + this.ws.theme.lncol + "',backgroundColor:'" + this.ws.theme.bgcol + "'}");
  1044. this.text_cp.onchange = this.cp_change.bind(this);
  1045. this.elem.appendChild(this.text_cp);
  1046. // Create the font size selector
  1047. this.sel_fs = document.createElement("select");
  1048. this.sel_fs.className = "sizesel";
  1049. this.sel_fs.onchange = this.fs_change.bind(this);
  1050. for (let i = 0; i < 4; i++) {
  1051. let option = document.createElement("option");
  1052. option.innerHTML = (i === 0) ? "smaller" : (i === 1) ? "normal" : (i === 2) ? "bigger" : "more bigger";
  1053. option.value = i;
  1054. this.sel_fs.appendChild(option);
  1055. }
  1056. this.sel_fs.selectedIndex = this.font_size;
  1057. this.elem.appendChild(this.sel_fs);
  1058. // Create the YouTube Player button
  1059. this.btn_ytpl = document.createElement("button");
  1060. this.btn_ytpl.innerHTML = "YouTube Player";
  1061. this.btn_ytpl.onclick = this.yt_click.bind(this);
  1062. this.btn_ytpl.style.display = "none";
  1063. this.elem.appendChild(this.btn_ytpl);
  1064. // Create the Kageshi Mode checkbox
  1065. //this.cb_kmode = new fc_checkbox(false, "Kageshi Mode");
  1066. //this.cb_kmode.addonclick(this.kmode_click.bind(this));
  1067. //this.elem.appendChild(this.cb_kmode.elem);
  1068. // Create the input for messages
  1069. this.text_msg = document.createElement("input");
  1070. this.text_msg.setAttribute("type", "text");
  1071. this.text_msg.setAttribute("autocomplete", "off");
  1072. this.text_msg.className = "chatmsg fs_" + this.font_size;
  1073. this.text_msg.style.color = this.font_colour;
  1074. this.text_msg.value = "";
  1075. this.text_msg.onkeyup = this.msg_keyup.bind(this);
  1076. this.text_msg.autocomplete = "off";
  1077. this.elem.appendChild(this.text_msg);
  1078. // Create the Send button
  1079. this.btn_send = document.createElement("button");
  1080. this.btn_send.className = "sendbtn material-icons";
  1081. this.btn_send.onclick = this.send_click.bind(this);
  1082. this.elem.appendChild(this.btn_send);
  1083. // Append additional buttons for Hello, Message, and Command
  1084. this.btn_hello = document.createElement("button");
  1085. this.btn_hello.innerHTML = "Hello";
  1086. this.btn_hello.onclick = this.hello_click.bind(this);
  1087. this.elem.appendChild(this.btn_hello);
  1088. this.btn_msg = document.createElement("button");
  1089. this.btn_msg.innerHTML = "Message";
  1090. this.btn_msg.onclick = this.msg_click.bind(this);
  1091. this.elem.appendChild(this.btn_msg);
  1092. this.btn_cmd = document.createElement("button");
  1093. this.btn_cmd.innerHTML = "Command";
  1094. this.btn_cmd.onclick = this.cmd_click.bind(this);
  1095. this.elem.appendChild(this.btn_cmd);
  1096. }