Advertisement
MeKLiN2

hunter stumble java

Mar 22nd, 2024
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 53.65 KB | None | 0 0
  1. // ==UserScript==
  2. // @name Hunter
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.92
  5. // @description Blacklist
  6. // @author MeKLiN
  7. // @match https://stumblechat.com/room/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=stumblechat.com
  9. // @grant none
  10. // @license MIT
  11. // @downloadURL https://update.greasyfork.org/scripts/490493/Hunter.user.js
  12. // @updateURL https://update.greasyfork.org/scripts/490493/Hunter.meta.js
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17. const handleUserMap = {}; // Initialize handleUserMap as an empty object
  18. // Define yourHandle variable
  19. const yourHandle = "myHandle"; // Replace "myHandle" with the actual handle
  20.  
  21. function parseWebSocketMessage(message) {
  22. const parsedMessage = JSON.parse(message);
  23. if (parsedMessage.stumble === "joined") {
  24. const userList = parsedMessage.userlist;
  25. if (userList && userList.length > 0) {
  26. userList.forEach(user => {
  27. const username = user.username || user.nick;
  28. handleUserMap[user.handle] = username;
  29. addUserToUserList({ handle: user.handle, username });
  30. });
  31. }
  32. const joinMessage = "A user or users joined the chat."; // Example join message
  33. displayWebSocketMessage(joinMessage);
  34. } else if (parsedMessage.stumble === "join") {
  35. const { handle, username } = parsedMessage;
  36. handleUserMap[handle] = username;
  37. addUserToUserList({ handle, username });
  38. const joinMessage = `${username} joined the chat.`;
  39. displayWebSocketMessage(joinMessage);
  40. } else if (parsedMessage.stumble === "quit") {
  41. const handle = parsedMessage.handle;
  42. const username = handleUserMap[handle];
  43. if (username) {
  44. delete handleUserMap[handle];
  45. removeUserFromUserList(handle);
  46. const quitMessage = `${username} left the chat.`;
  47. displayWebSocketMessage(quitMessage);
  48. }
  49. } else if (parsedMessage.stumble === "msg" && (parsedMessage.text === "#join" || parsedMessage.text === "#icon")) {
  50. // Handle additional changes to the user list for specific "msg" messages
  51. // This block will only execute for "msg" messages that contain "#join" or "#icon"
  52. // Adjust the logic as needed based on your specific requirements
  53. }
  54. }
  55.  
  56. // WebSocket Listener: Override WebSocket constructor to intercept WebSocket creation
  57. const originalWebSocket = window.WebSocket;
  58. window.WebSocket = function(url, protocols) {
  59. console.log('WebSocket URL:', url);
  60.  
  61. // Call original WebSocket constructor
  62. const ws = new originalWebSocket(url, protocols);
  63.  
  64. // Event listener for receiving messages
  65. ws.addEventListener('message', event => {
  66. const parsedMessage = JSON.parse(event.data);
  67. // Check if the message is a "joined" message
  68. if (parsedMessage.stumble === "joined") {
  69. // Extracting our own handle from the "self" object in the message
  70. const selfHandle = parsedMessage.self.handle;
  71. // Update handleUserMap and custom user list when a user joins
  72. const userList = parsedMessage.userlist;
  73. if (userList && userList.length > 0) {
  74. userList.forEach(user => {
  75. // Check if the user being added is ourselves
  76. const isSelf = user.handle === selfHandle;
  77. // If it's our own user, update handleUserMap and display our own handle in the user list
  78. if (isSelf) {
  79. // Update handleUserMap with our own handle and username
  80. handleUserMap[user.handle] = user.username || user.nick;
  81. // Add our own handle to the custom user list with purple icon
  82. addUserToUserList({
  83. username: user.username,
  84. handle: user.handle,
  85. active: true, // We just joined, so we're considered active
  86. icon: "🟣" // Purple icon for our own user entry
  87. }, "self");
  88. } else {
  89. // If it's not our own user, proceed as usual and add them to the user list
  90. updateUserListAndMapOnJoin(user);
  91. }
  92. });
  93. }
  94. } else if (parsedMessage.stumble === "join") {
  95. // Handle join messages
  96. const { handle, username } = parsedMessage;
  97. // Check if the user being added is not ourselves
  98. if (handle !== yourHandle) {
  99. handleUserMap[handle] = username;
  100. addUserToUserList({ handle, username }, "join");
  101. }
  102. } else if (parsedMessage.stumble === "quit") {
  103. // Handle quit messages
  104. const handle = parsedMessage.handle;
  105. const username = handleUserMap[handle];
  106. if (username) {
  107. delete handleUserMap[handle];
  108. removeUserFromUserList(handle);
  109. setTimeout(() => {
  110. removeUserFromUserList(handle);
  111. }, 30000); // 30 seconds delay
  112. addUserToUserList({ handle, username }, "quit");
  113. }
  114. } else if (parsedMessage.stumble === "msg") {
  115. // Handle message messages
  116. const { handle, text } = parsedMessage;
  117. const username = handleUserMap[handle] || handle;
  118. displayWebSocketMessage(event.data);
  119. }
  120.  
  121. // Check if the message is a system message
  122. if (parsedMessage.stumble === "system") {
  123. const systemMessage = parsedMessage.message;
  124.  
  125. // Check if the system message contains the client version
  126. if (systemMessage.startsWith('"Client Version:')) {
  127. // Save the user list to a file
  128. console.log("sysmsgdetected");
  129. }
  130. }
  131. });
  132.  
  133. return ws;
  134. };
  135.  
  136. // Function to create user list div
  137. function createUserListDiv() {
  138. const userListDiv = document.createElement("div");
  139. userListDiv.id = "userList";
  140. userListDiv.style.position = "absolute"; // Change to absolute positioning
  141. userListDiv.style.top = "100px"; // Adjust top position as needed
  142. userListDiv.style.left = "10px"; // Adjust left position as needed
  143. userListDiv.style.height = "calc(100% - 100px)"; // Adjust height to fill remaining space
  144. userListDiv.style.overflowY = "auto";
  145. userListDiv.style.color = "#ffffff";
  146. userListDiv.style.padding = "10px";
  147. userListDiv.style.zIndex = "2"; // Set a higher z-index value
  148. userListDiv.style.display = "none"; // Hide the custom user list by default
  149. return userListDiv;
  150. }
  151.  
  152. // Function to append new content to users.txt file
  153. function appendToUserListFile(newContent) {
  154. // Create a Blob object containing the new content
  155. const blob = new Blob([newContent], { type: "text/plain" });
  156.  
  157. // Create a temporary anchor element to trigger the download
  158. const a = document.createElement("a");
  159. const url = URL.createObjectURL(blob);
  160. a.href = url;
  161. a.download = "users.txt";
  162.  
  163. // Simulate a click on the anchor element to start the download
  164. document.body.appendChild(a);
  165. a.click();
  166.  
  167. // Remove the temporary anchor element
  168. document.body.removeChild(a);
  169.  
  170. // Release the Object URL
  171. URL.revokeObjectURL(url);
  172. }
  173.  
  174. // Function to save user list to users.txt file
  175. function saveUserListToFile() {
  176. // Extracting user information from handleUserMap
  177. const users = [];
  178. for (const handle in handleUserMap) {
  179. const username = handleUserMap[handle];
  180. users.push(`${username} (${handle}) B`); // Append 'B' to the handle
  181. }
  182.  
  183. // Convert the user list to a string
  184. const userListString = users.join("\n");
  185.  
  186. // Append the new content to the existing users.txt file
  187. appendToUserListFile(userListString);
  188. }
  189.  
  190. // Function to display the user list (handle map)
  191. function displayUserList() {
  192. const userList = document.getElementById("userListDisplay");
  193. if (userList) {
  194. // Clear the user list before updating
  195. userList.innerHTML = "";
  196. // Iterate over the handleUserMap and display each handle and username
  197. for (const handle in handleUserMap) {
  198. const username = handleUserMap[handle];
  199. const listItem = document.createElement("li");
  200. listItem.textContent = `${username} (${handle})`;
  201. userList.appendChild(listItem);
  202. }
  203. }
  204. }
  205.  
  206. // Function to create and append the pop-up window overlay with input menu and close button
  207. function createUserOverlay() {
  208. const overlay = document.createElement("div");
  209. overlay.id = "overlay";
  210. overlay.style.position = "fixed";
  211. overlay.style.top = "50%";
  212. overlay.style.width = "80%"; // container width
  213. overlay.style.left = "50%";
  214. overlay.style.transform = "translate(-50%, -50%)";
  215. overlay.style.backgroundColor = "rgba(0, 0, 0, 0.5)";
  216. overlay.style.zIndex = "9999";
  217. overlay.style.padding = "20px";
  218. overlay.style.textAlign = "center";
  219.  
  220. const closeButton = document.createElement("button");
  221. closeButton.textContent = "Close";
  222. closeButton.style.position = "absolute";
  223. closeButton.style.top = "10px";
  224. closeButton.style.right = "10px";
  225. closeButton.addEventListener("click", () => {
  226. overlay.remove(); // Remove the overlay when the close button is clicked
  227. });
  228. overlay.appendChild(closeButton);
  229.  
  230. const userListContainer = document.createElement("div");
  231. userListContainer.style.display = "flex";
  232. userListContainer.style.justifyContent = "space-between"; // Align columns to left and right edges
  233. overlay.appendChild(userListContainer);
  234.  
  235. const userListHandleMap = document.createElement("ul");
  236. userListHandleMap.id = "userListHandleMap";
  237. userListHandleMap.style.listStyleType = "none";
  238. userListHandleMap.style.padding = "0";
  239. userListHandleMap.style.width = "50%"; // Adjust the percentage based on your layout needs
  240. userListHandleMap.style.color = "lime";
  241. userListHandleMap.style.backgroundColor = "black";
  242. userListContainer.appendChild(userListHandleMap);
  243.  
  244. // Second column for data from loadUsersFromFile() function
  245. const userListLoadedFromFile = document.createElement("ul");
  246. userListLoadedFromFile.id = "userListLoadedFromFile"; // Add an id to reference the user list later
  247. userListLoadedFromFile.style.listStyleType = "none";
  248. userListLoadedFromFile.style.padding = "0";
  249. userListLoadedFromFile.style.color = "cyan"; // Set font color to cyan
  250. userListLoadedFromFile.style.backgroundColor = "black"; // Set background color to black
  251. userListLoadedFromFile.style.flex = "1"; // Use flex to make the column expand to fill available space
  252. userListLoadedFromFile.style.marginLeft = "10px"; // Add margin to separate from the first column
  253. userListContainer.appendChild(userListLoadedFromFile);
  254.  
  255. function populateUserListHandleMap() {
  256. userListHandleMap.innerHTML = "";
  257. for (const handle in handleUserMap) {
  258. if (handleUserMap.hasOwnProperty(handle)) {
  259. const listItem = document.createElement("li");
  260. listItem.textContent = `${handleUserMap[handle]} (${handle})`;
  261. listItem.style.marginBottom = "5px";
  262. userListHandleMap.appendChild(listItem);
  263. }
  264. }
  265. }
  266.  
  267. function populateUserListLoadedFromFile(loadedUsers) {
  268. userListLoadedFromFile.innerHTML = "";
  269. loadedUsers.forEach(user => {
  270. const listItem = document.createElement("li");
  271. listItem.textContent = `${user.username} (${user.handle})`;
  272. listItem.style.marginBottom = "5px";
  273. userListLoadedFromFile.appendChild(listItem);
  274. });
  275. }
  276.  
  277. populateUserListHandleMap();
  278.  
  279. const inputLabel = document.createElement("label");
  280. inputLabel.textContent = "Add 'B' to user handles:";
  281. inputLabel.style.color = "#ffffff";
  282. inputLabel.style.marginTop = "20px";
  283. overlay.appendChild(inputLabel);
  284.  
  285. const inputField = document.createElement("input");
  286. inputField.id = "handleInput";
  287. inputField.type = "text";
  288. inputField.style.margin = "10px auto";
  289. inputField.style.display = "block";
  290. overlay.appendChild(inputField);
  291.  
  292. const applyButton = document.createElement("button");
  293. applyButton.textContent = "Apply";
  294. applyButton.style.margin = "10px auto";
  295. applyButton.style.display = "block";
  296. overlay.appendChild(applyButton);
  297.  
  298. document.body.appendChild(overlay);
  299. }
  300.  
  301.  
  302.  
  303. // Function to create and append the input box overlay with user list display
  304. function createTartOverlay() {
  305. const overlay = document.createElement("div");
  306. overlay.id = "overlay";
  307. overlay.style.position = "fixed";
  308. overlay.style.bottom = "50px";
  309. overlay.style.left = "0px";
  310. overlay.style.zIndex = "9999";
  311. overlay.style.display = "flex";
  312. overlay.style.flexDirection = "column";
  313. overlay.style.alignItems = "flex-start";
  314.  
  315. const userList = document.createElement("ul");
  316. userList.id = "userList";
  317. userList.style.listStyleType = "none";
  318. overlay.appendChild(userList);
  319.  
  320. const inputField = document.createElement("input");
  321. inputField.id = "commandInput";
  322. inputField.type = "text";
  323. inputField.placeholder = "Type command here...";
  324. inputField.style.margin = "10px";
  325. inputField.style.width = "200px"; // Adjust width as needed
  326. overlay.appendChild(inputField);
  327.  
  328. // Listen for input changes
  329. inputField.addEventListener("input", () => {
  330. const command = inputField.value.trim();
  331. if (command.startsWith("#ban")) {
  332. const handle = command.replace("#ban", "").trim();
  333. if (handle !== "") {
  334. addBToHandleOrUsername(handle);
  335. inputField.value = ""; // Clear input field after processing command
  336. }
  337. }
  338. // Add more command listeners here as needed
  339. });
  340.  
  341. document.body.appendChild(overlay);
  342. }
  343.  
  344. // Function to create buttons for other overlays
  345. function createButtonsForOverlays() {
  346. // Create button for Tart overlay
  347. const tartButton = document.createElement("button");
  348. tartButton.textContent = "Open Tart Overlay";
  349. tartButton.style.position = "fixed";
  350. tartButton.style.bottom = "50px";
  351. tartButton.style.left = "210px"; // Adjust position as needed
  352. tartButton.style.zIndex = "9999";
  353. tartButton.addEventListener("click", createTartOverlay);
  354. document.body.appendChild(tartButton);
  355.  
  356. // Create button for User overlay
  357. const userButton = document.createElement("button");
  358. userButton.textContent = "Open User Overlay";
  359. userButton.style.position = "fixed";
  360. userButton.style.bottom = "50px";
  361. userButton.style.left = "420px"; // Adjust position as needed
  362. userButton.style.zIndex = "9999";
  363. userButton.addEventListener("click", createUserOverlay);
  364. document.body.appendChild(userButton);
  365. }
  366.  
  367. // Call the function to create buttons for other overlays
  368. createButtonsForOverlays();
  369.  
  370. // Function to create and append the input box overlay
  371. function createBox() {
  372. const overlay = document.createElement("div");
  373. overlay.id = "overlay";
  374. overlay.style.position = "fixed";
  375. overlay.style.bottom = "50px";
  376. overlay.style.left = "0px";
  377. overlay.style.zIndex = "9999";
  378.  
  379. const inputField = document.createElement("input");
  380. inputField.id = "commandInput";
  381. inputField.type = "text";
  382. inputField.placeholder = "Type command here...";
  383. inputField.style.margin = "10px";
  384. inputField.style.width = "200px"; // Adjust width as needed
  385. overlay.appendChild(inputField);
  386.  
  387. let commandBuffer = ""; // Buffer to store the command until Enter is pressed
  388.  
  389. // Listen for input changes
  390. inputField.addEventListener("input", () => {
  391. commandBuffer = inputField.value.trim(); // Update command buffer with current input
  392. });
  393.  
  394. // Listen for keydown event
  395. inputField.addEventListener("keydown", (event) => {
  396. if (event.key === "Enter") {
  397. // Process the command when Enter key is pressed
  398. if (commandBuffer.startsWith("#ban ")) {
  399. const usernameOrHandle = commandBuffer.replace("#ban ", "").trim();
  400. if (usernameOrHandle !== "") {
  401. addBToHandleOrUsername(usernameOrHandle);
  402. inputField.value = ""; // Clear input field after processing command
  403. } else {
  404. alert("Username or handle not provided!");
  405. }
  406. } else {
  407. alert("Invalid command! Please use '#ban usernameOrHandle'");
  408. }
  409. commandBuffer = ""; // Clear the command buffer after processing
  410. }
  411. });
  412.  
  413. document.body.appendChild(overlay);
  414. }
  415.  
  416. // Call the function to create the input box overlay
  417. createBox();
  418.  
  419. function addBToHandleOrUsername(handleOrUsername) {
  420. let handle = handleOrUsername;
  421. let found = false;
  422.  
  423. // Check if the handle exists in the handleUserMap
  424. if (handleUserMap.hasOwnProperty(handleOrUsername)) {
  425. handle = handleOrUsername;
  426. found = true;
  427. }
  428.  
  429. if (found) {
  430. // Add 'B' next to the handle number
  431. handleUserMap[handle] += " B";
  432. // Update the user list display
  433. displayUserList();
  434. // Save the updated user list to the file
  435. saveUserListToFile();
  436. } else {
  437. alert("User not found!");
  438. }
  439. }
  440.  
  441. // Function to load users from the users.txt file
  442. function loadUsersFromFile() {
  443. const fileInput = document.createElement('input');
  444. fileInput.type = 'file';
  445. fileInput.accept = '.txt';
  446.  
  447. fileInput.addEventListener('change', function() {
  448. const file = fileInput.files[0];
  449. const reader = new FileReader();
  450.  
  451. reader.onload = function(event) {
  452. const fileContent = event.target.result;
  453. // Update handleUserMap with user data from the loaded file
  454. updateHandleUserMap(fileContent);
  455. // Display loaded users
  456. console.log("Loaded Users:");
  457. for (const handle in handleUserMap) {
  458. if (handleUserMap.hasOwnProperty(handle)) {
  459. console.log(`${handleUserMap[handle]} (${handle})`);
  460. }
  461. }
  462. // Define and populate loadedUsers based on handleUserMap
  463. const loadedUsers = Object.keys(handleUserMap).map(handle => ({
  464. handle: handle,
  465. username: handleUserMap[handle]
  466. }));
  467. // Example usage of addBToHandleOrUsername with loadedUsers
  468. addBToHandleOrUsername("handleOrUsername", loadedUsers);
  469. };
  470.  
  471. reader.readAsText(file);
  472. });
  473.  
  474. fileInput.click();
  475. }
  476.  
  477. // Function to update handleUserMap with user data from the loaded file
  478. function updateHandleUserMap(fileContent) {
  479. // Split the file content into lines
  480. const lines = fileContent.split('\n');
  481.  
  482. // Iterate over each line to parse user data
  483. lines.forEach(line => {
  484. const userData = line.trim().split(' '); // Splitting by space to separate username and handle
  485. if (userData.length === 2) {
  486. const username = userData[0].trim();
  487. const handle = userData[1].trim();
  488.  
  489. // Check if the handle already exists in the handleUserMap
  490. if (!handleUserMap.hasOwnProperty(handle)) {
  491. // Update user map with the new username and handle
  492. handleUserMap[handle] = username;
  493. }
  494. }
  495. });
  496. }
  497.  
  498.  
  499. // Function to update the user list display
  500. function updateUserListDisplay() {
  501. // Get the user list element
  502. const userList = document.getElementById("userList");
  503. if (userList) {
  504. // Update the display with modified handleUserMap
  505. userList.innerHTML = ""; // Clear the user list
  506. for (const handle in handleUserMap) {
  507. const username = handleUserMap[handle];
  508. // Append the user to the user list with 'B' if present
  509. const listItem = document.createElement("li");
  510. listItem.textContent = `${username} (${handle})`;
  511. userList.appendChild(listItem);
  512. }
  513. }
  514. }
  515.  
  516. // WebSocket listener for handling messages
  517. function handleWebSocketMessage(message) {
  518. const parsedMessage = JSON.parse(message);
  519. const ownHandle = getOwnHandle(); // Function to get the user's own handle number
  520.  
  521. if (parsedMessage.stumble === "msg" && ownHandle === parsedMessage.handle) {
  522. const text = parsedMessage.text;
  523. if (text.startsWith("#ban")) {
  524. // Extract the handle from the message
  525. const handleToBan = text.replace("#ban", "").trim();
  526. if (handleToBan !== "") {
  527. // Check if the handle exists in the handleUserMap
  528. if (handleUserMap.hasOwnProperty(handleToBan)) {
  529. // Add 'B' next to the handle number
  530. handleUserMap[handleToBan] += " B";
  531. // Update the user list display
  532. updateUserListDisplay();
  533. // Update the users.txt file
  534. saveUserListToFile();
  535. } else {
  536. alert("Handle not found!");
  537. }
  538. } else {
  539. alert("Invalid handle!");
  540. }
  541. }
  542. }
  543. }
  544. // Function to get the user's own handle number (implement your own logic)
  545. function getOwnHandle() {
  546. // Implement your logic to retrieve the user's own handle number
  547. // For demonstration purposes, return a hardcoded value
  548. return "123456"; // Replace with your actual handle number
  549. }
  550. // Function to set up WebSocket listener
  551. function setupWebSocketListener() {
  552. // Override WebSocket constructor to intercept WebSocket creation
  553. const originalWebSocket = window.WebSocket;
  554. window.WebSocket = function(url, protocols) {
  555. console.log('WebSocket URL:', url);
  556.  
  557. // Call original WebSocket constructor
  558. const ws = new originalWebSocket(url, protocols);
  559.  
  560. // Event listener for receiving messages
  561. ws.addEventListener('message', event => {
  562. handleWebSocketMessage(event.data);
  563. });
  564.  
  565. return ws;
  566. };
  567. }
  568.  
  569. // Call functions to set up overlay, WebSocket listener, and initial user list display
  570.  
  571. setupWebSocketListener();
  572. updateUserListDisplay();
  573.  
  574. // Function to display WebSocket messages and update user list
  575. function displayWebSocketMessage(message) {
  576. const parsedMessage = JSON.parse(message);
  577. if (parsedMessage.stumble === "join") {
  578. // Handle join messages: Extract handle and username from the message
  579. const { handle, username } = parsedMessage;
  580. // Map handle to username in handleUserMap
  581. handleUserMap[handle] = username;
  582. // Add the user to the custom user list with the appropriate icon (join user)
  583. addUserToUserList({ handle, username }, "join");
  584. } else if (parsedMessage.stumble === "msg") {
  585. // Handle message messages: Extract handle and text from the message
  586. const { handle, text } = parsedMessage;
  587. // Retrieve username from handleUserMap or use handle if not found
  588. const username = handleUserMap[handle] || handle;
  589. // Display the message in the WebSocket messages div
  590. const webSocketMessagesDiv = document.getElementById("webSocketMessages");
  591. if (webSocketMessagesDiv) {
  592. // Append the message with a newline character
  593. webSocketMessagesDiv.textContent += `${username}: ${text}\n`;
  594. // Scroll to the bottom of the messages div
  595. webSocketMessagesDiv.scrollTop = webSocketMessagesDiv.scrollHeight;
  596. }
  597.  
  598. // Additional logic for handling commands
  599. if (text === "#join") {
  600. console.log("join");
  601. // Add your logic here
  602. } else if (text === "#icon") {
  603. console.log("icon");
  604. // Add your logic here
  605. }
  606. } else if (parsedMessage.stumble === "joined") {
  607. // Handle joined messages: Add users to handleUserMap and custom user list
  608. const userList = parsedMessage.userlist;
  609. if (userList && userList.length > 0) {
  610. userList.forEach(user => {
  611. // Extract username from either "username" or "nick"
  612. const username = user.username || user.nick;
  613. // Map handle to username in handleUserMap
  614. handleUserMap[user.handle] = username;
  615. // Add the user to the custom user list with the appropriate icon
  616. addUserToUserList({ handle: user.handle, username }, "joined");
  617. });
  618. }
  619. } else if (parsedMessage.stumble === "quit") {
  620. // Handle quit messages: Remove users from handleUserMap and custom user list
  621. const handle = parsedMessage.handle;
  622. const username = handleUserMap[handle];
  623. if (username) {
  624. // Remove the handle from handleUserMap
  625. delete handleUserMap[handle];
  626. // Remove the user from the custom user list
  627. removeUserFromUserList(handle);
  628. }
  629. }
  630. }
  631.  
  632.  
  633. // Function to add user to user list with appropriate icon based on user type
  634. function addUserToUserList(user, userType) {
  635. const userList = document.getElementById("userList");
  636. if (!userList) return;
  637.  
  638. const userItem = document.createElement("div");
  639. userItem.textContent = `${user.username}`;
  640.  
  641. // Define the default dot color and icon
  642. let dotColor = "red"; // Default dot color
  643. let icon = "🔴"; // Default icon for inactive users
  644.  
  645. // Set dot color and icon based on user type
  646. if (userType === "self") {
  647. dotColor = "purple"; // Purple for self user
  648. icon = "🟣"; // Purple circle icon
  649. } else if (userType === "join") {
  650. dotColor = "blue"; // Blue for join user
  651. icon = "🔵"; // Blue circle icon
  652. } else if (userType === "joined") { // "self" user type listener for user list"
  653. dotColor = "green"; // Green for joined user
  654. icon = "🟢"; // Green circle icon
  655. }
  656.  
  657. // Add colored dot based on user status
  658. const dot = document.createElement("span");
  659. dot.textContent = icon;
  660. dot.style.color = dotColor;
  661. userItem.appendChild(dot);
  662.  
  663. // Add custom icon for the user
  664. if (user.icon) {
  665. const customIcon = document.createElement("span");
  666. customIcon.textContent = user.icon;
  667. customIcon.style.marginLeft = "5px"; // Adjust margin as needed
  668. userItem.appendChild(customIcon);
  669. }
  670.  
  671. userList.appendChild(userItem); // Append user item to the user list
  672.  
  673. // If user is not active and not yourself, show popup for 5 seconds
  674. if (!user.active && user.handle !== yourHandle) {
  675. const popup = document.createElement("div");
  676. popup.textContent = "WELCOME TO STUMBLECHAT YEOPARDY!";
  677. popup.style.fontSize = "48px";
  678. popup.style.position = "fixed";
  679. popup.style.top = "50%";
  680. popup.style.left = "50%";
  681. popup.style.transform = "translate(-50%, -50%)";
  682. popup.style.backgroundColor = "rgba(0, 0, 0, 0.5)";
  683. popup.style.color = "white";
  684. popup.style.padding = "10px";
  685. popup.style.borderRadius = "5px";
  686. document.body.appendChild(popup);
  687. }
  688. }
  689. // Function to update handleUserMap and add users to custom user list
  690. function updateUserListAndMapOnJoin(user) {
  691. // Update handleUserMap with the new user
  692. handleUserMap[user.handle] = user.username || user.nick; // Derive username from handle or nick
  693. // Add the new user to the custom user list
  694. addUserToUserList(user);
  695. }
  696.  
  697. // Call the function to update the user list
  698. function updateUserListOnMessage(userList) {
  699. return function(message) {
  700. const parsedMessage = JSON.parse(message);
  701. if (parsedMessage.stumble === "join" || parsedMessage.stumble === "msg" || parsedMessage.stumble === "joined") {
  702. // Add user to user list
  703. addUserToUserList(parsedMessage);
  704. }
  705. };
  706. }
  707.  
  708. // Function to create WebSocket messages div
  709. function createWebSocketMessagesDiv() {
  710. const div = document.createElement("div");
  711. div.id = "webSocketMessages";
  712. div.style.position = "relative";
  713. div.style.height = "25%";
  714. div.style.paddingLeft = "2px";
  715. div.style.visibility = "visible"; // Ensure the div is visible
  716. div.style.willChange = "transform";
  717. div.style.boxSizing = "border-box";
  718. div.style.overflowX = "hidden";
  719. div.style.overflowY = "auto";
  720. div.style.color = "#ffffff"; // Set font color to white
  721. div.style.padding = "10px"; // Example padding
  722. div.style.zIndex = "2"; // Set a higher z-index value for the WebSocket messages div
  723.  
  724. // Additional styles for specific scenarios
  725. div.style.display = "flex";
  726. div.style.flexDirection = "column";
  727. div.style.justifyContent = "flex-end";
  728. div.style.fontSize = "18px";
  729.  
  730. div.style.whiteSpace = "pre-wrap"; // Allow text to wrap within the container
  731. div.style.wordWrap = "break-word"; // Allow long words to break and wrap
  732.  
  733. // Locate the chat-position div
  734. const chatPositionDiv = document.getElementById("chat-position");
  735. if (chatPositionDiv) {
  736. // Append custom div to the chat-position div
  737. chatPositionDiv.appendChild(div);
  738. } else {
  739. // If chat-position div not found, append to document body as fallback
  740. document.body.appendChild(div);
  741. }
  742. }
  743.  
  744. // Call the function to create the WebSocket messages div
  745. createWebSocketMessagesDiv();
  746.  
  747. // Call the function to create the user list div
  748. const userListDiv = createUserListDiv();
  749. const chatContainer = document.getElementById("chat-container");
  750. if (chatContainer) {
  751. chatContainer.appendChild(userListDiv); // Append to chat container instead
  752. } else {
  753. document.body.appendChild(userListDiv);
  754. }
  755.  
  756. // Function to remove user from custom user list
  757. function removeUserFromUserList(handle) {
  758. const userList = document.getElementById("userList");
  759. if (userList) {
  760. const userElements = userList.querySelectorAll("div");
  761. userElements.forEach(userElement => {
  762. if (userElement.textContent.includes(`(${handle})`)) {
  763. userElement.remove();
  764. }
  765. });
  766. }
  767. }
  768.  
  769. // Function to toggle visibility of custom user list
  770. function toggleCustomUserList() {
  771. const userListDiv = document.getElementById("userList");
  772. if (userListDiv) {
  773. userListDiv.style.display = userListDiv.style.display === "none" ? "block" : "none";
  774. }
  775. }
  776.  
  777. // Add a button to toggle visibility of custom user list
  778. const toggleButton = document.createElement("button");
  779. toggleButton.textContent = "U";
  780. toggleButton.style.position = "fixed";
  781. toggleButton.style.top = "10px";
  782. toggleButton.style.left = "10px";
  783. toggleButton.addEventListener("click", toggleCustomUserList);
  784. document.body.appendChild(toggleButton);
  785.  
  786. // Function to clear messages
  787. function clr() {
  788. const webSocketMessagesDiv = document.getElementById("webSocketMessages");
  789. if (webSocketMessagesDiv) {
  790. webSocketMessagesDiv.innerHTML = "";
  791. }
  792. }
  793.  
  794. // Function to create fadeaway popup text with "WELCOME" message
  795. function showWelcomePopupText() {
  796. const popup = document.createElement("div");
  797. popup.textContent = "WELCOME";
  798. popup.classList.add("fadeaway-popup");
  799. document.body.appendChild(popup);
  800.  
  801. // Remove the popup after 3 seconds
  802. setTimeout(() => {
  803. popup.remove();
  804. }, 3000); // 3 seconds delay
  805. }
  806.  
  807. // Function to create SVG animation
  808. function createSVGAnimation() {
  809. // Create SVG element
  810. const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
  811. svg.setAttribute("width", "100");
  812. svg.setAttribute("height", "100");
  813.  
  814. // Create rectangle inside SVG
  815. const rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
  816. rect.setAttribute("width", "100");
  817. rect.setAttribute("height", "100");
  818. rect.setAttribute("fill", "blue");
  819. svg.appendChild(rect);
  820.  
  821. // Append SVG to body
  822. document.body.appendChild(svg);
  823.  
  824. // Animate SVG
  825. const animation = document.createElementNS("http://www.w3.org/2000/svg", "animate");
  826. animation.setAttribute("attributeName", "x");
  827. animation.setAttribute("from", "-100");
  828. animation.setAttribute("to", "100%");
  829. animation.setAttribute("dur", "5s");
  830. animation.setAttribute("repeatCount", "indefinite");
  831. rect.appendChild(animation);
  832. }
  833. // Call the function to show the welcome popup with SVG animation
  834. showWelcomePopupText();
  835. // Call the function to create SVG animation
  836. createSVGAnimation();
  837.  
  838. function IrcMode() {
  839. const chatContent = document.getElementById("chat-content");
  840. if (chatContent) {
  841. // Remove the chat-content div from the DOM
  842. chatContent.remove();
  843. // Move the webSocketMessagesDiv and the form input to fixed position
  844. const webSocketMessagesDiv = document.getElementById("webSocketMessages");
  845. const formInput = document.getElementById("input");
  846. if (webSocketMessagesDiv && formInput) {
  847. webSocketMessagesDiv.style.position = "fixed";
  848. webSocketMessagesDiv.style.top = "0px";
  849. webSocketMessagesDiv.style.height = "90%"; // Adjust height to 90%
  850. webSocketMessagesDiv.style.overflowY = "auto"; // Add scrollbar
  851. formInput.style.position = "fixed";
  852. formInput.style.bottom = "0px";
  853. }
  854. // Create Save Text button
  855. createSaveTextButton();
  856. }
  857. // Disable the room.js functionality
  858. disableRoomJS();
  859. }
  860.  
  861. // Function to save text content without <br> elements
  862. async function saveText() {
  863. console.log("Save Text button clicked."); // Debugging: Log button click
  864. const webSocketMessagesDiv = document.getElementById("webSocketMessages");
  865. if (webSocketMessagesDiv) {
  866. console.log("webSocketMessagesDiv found:", webSocketMessagesDiv); // Debugging: Log webSocketMessagesDiv
  867. const textContent = webSocketMessagesDiv.textContent.replaceAll('\n', '\r\n');
  868. console.log("Text content:", textContent); // Debugging: Log extracted text content
  869. try {
  870. // Use File System Access API to prompt user to save text content to a file
  871. const handle = await window.showSaveFilePicker({
  872. types: [{
  873. description: 'Text Files',
  874. accept: {
  875. 'text/plain': ['.txt']
  876. }
  877. }]
  878. });
  879. const writable = await handle.createWritable();
  880. await writable.write(textContent);
  881. await writable.close();
  882. console.log("Text content saved."); // Debugging: Log text saving success
  883. } catch (error) {
  884. console.error("Error saving text content:", error); // Log error if saving fails
  885. }
  886. } else {
  887. console.log("webSocketMessagesDiv not found."); // Debugging: Log if webSocketMessagesDiv is not found
  888. }
  889. }
  890.  
  891. // Function to create Save Text button
  892. function createSaveTextButton() {
  893. const saveTextButton = document.createElement("button");
  894. saveTextButton.id = "saveTextButton";
  895. saveTextButton.textContent = "Save Text";
  896. saveTextButton.style.position = "fixed"; // Position fixed
  897. saveTextButton.style.bottom = "10px"; // Adjust bottom position
  898. saveTextButton.style.left = "10px"; // Adjust left position
  899. saveTextButton.style.background = "black";
  900. saveTextButton.style.color = "lime";
  901. saveTextButton.style.border = "none";
  902. saveTextButton.style.padding = "5px 10px";
  903. saveTextButton.style.cursor = "pointer";
  904. saveTextButton.type = "button"; // Specify that it's a button and not submit
  905. saveTextButton.addEventListener("click", saveText);
  906. document.body.appendChild(saveTextButton); // Append to document body
  907. }
  908.  
  909. // Function to remove Save Text button
  910. function removeSaveTextButton() {
  911. const saveTextButton = document.getElementById("saveTextButton");
  912. if (saveTextButton) {
  913. saveTextButton.remove();
  914. }
  915. }
  916.  
  917. // Call the function to remove the Save Text button initially
  918. removeSaveTextButton();
  919.  
  920. // Function to disable room.js functionality
  921. function disableRoomJS() {
  922. // Remove the event listener for message reception
  923. window.removeEventListener('messageReceived', handleMessageReceived);
  924. }
  925.  
  926. // Example function that handles incoming messages in room.js
  927. function handleMessageReceived(event) {
  928. // Logic to process incoming messages
  929. }
  930.  
  931. // Modify the handleKeyPress function to handle button clicks as well
  932. function handleKeyPress(event) {
  933. if ((event.key === 'Enter' || event.code === 'Enter') && !event.shiftKey) {
  934. event.preventDefault(); // Prevent the default behavior (creating a new line)
  935. // Call your message sending function here
  936. sendMessage();
  937. // Reset the input box's content
  938. resetInputBox();
  939. }
  940. }
  941.  
  942. // Function to insert predefined text and simulate Enter key press
  943. function insertPredefinedTextAndPressEnter() {
  944. // Insert predefined text
  945. const textArea = document.getElementById("textarea");
  946. textArea.value += "(╭☞ ͡ ͡°͜ ʖ ͡ ͡ )╭☞";
  947.  
  948. // Simulate Enter key press
  949. const event = new KeyboardEvent('keypress', {
  950. key: 'Enter',
  951. code: 'Enter',
  952. keyCode: 13,
  953. which: 13,
  954. bubbles: true
  955. });
  956. textArea.dispatchEvent(event);
  957. }
  958.  
  959. // Create a button to insert predefined text and press Enter
  960. function createInsertTextButton() {
  961. const insertTextButton = document.createElement("button");
  962. insertTextButton.textContent = "☞";
  963. insertTextButton.style.background = "black";
  964. insertTextButton.style.color = "lime";
  965. insertTextButton.style.border = "none";
  966. insertTextButton.style.padding = "5px 10px";
  967. insertTextButton.style.cursor = "pointer";
  968. insertTextButton.type = "button"; // Specify that it's a button and not submit
  969. insertTextButton.addEventListener("click", insertPredefinedTextAndPressEnter);
  970. const textArea = document.getElementById("textarea");
  971. textArea.parentElement.appendChild(insertTextButton);
  972. }
  973.  
  974. // Call the function to create the insert text button
  975. createInsertTextButton();
  976.  
  977. // Function to reset the input box's content
  978. function resetInputBox() {
  979. const textArea = document.getElementById("textarea");
  980. if (textArea) {
  981. textArea.value = ""; // Clear the textarea
  982. }
  983. }
  984.  
  985. function createPopup() {
  986. const popup = document.createElement("div");
  987. popup.id = "messagePopup";
  988. popup.style.position = "fixed";
  989. popup.style.top = "50%";
  990. popup.style.left = "50%";
  991. popup.style.transform = "translate(-50%, -50%)";
  992. popup.style.background = "#fff";
  993. popup.style.padding = "20px";
  994. popup.style.border = "1px solid #ccc";
  995. popup.style.boxShadow = "0 0 10px rgba(0, 0, 0, 0.1)";
  996. popup.style.zIndex = "9999";
  997.  
  998. const textarea = document.createElement("textarea");
  999. textarea.id = "popupTextarea";
  1000. textarea.placeholder = "Type a message";
  1001. textarea.maxLength = "500";
  1002. textarea.style.width = "100%";
  1003. textarea.style.marginBottom = "10px";
  1004. popup.appendChild(textarea);
  1005.  
  1006. const sendButton = document.createElement("button");
  1007. sendButton.textContent = "Send";
  1008. sendButton.style.background = "black";
  1009. sendButton.style.color = "lime";
  1010. sendButton.style.border = "none";
  1011. sendButton.style.padding = "5px 10px";
  1012. sendButton.style.cursor = "pointer";
  1013. sendButton.addEventListener("click", sendMessage);
  1014. popup.appendChild(sendButton);
  1015.  
  1016. document.body.appendChild(popup);
  1017. }
  1018.  
  1019. function openPopup() {
  1020. const popup = document.getElementById("messagePopup");
  1021. if (popup) {
  1022. popup.style.display = "block";
  1023. } else {
  1024. createPopup();
  1025. }
  1026. }
  1027.  
  1028. function closePopup() {
  1029. const popup = document.getElementById("messagePopup");
  1030. if (popup) {
  1031. popup.style.display = "none";
  1032. }
  1033. }
  1034.  
  1035. function sendMessage() {
  1036. const textArea = document.getElementById("popupTextarea");
  1037. if (textArea) {
  1038. const message = textArea.value.trim();
  1039. if (message !== "") {
  1040. // Modify your logic here to match the behavior of their Message.send function
  1041. // For example, if you're directly sending to the WebSocket:
  1042. StumbleChat.WebSocket.send(JSON.stringify({
  1043. "stumble": "msg",
  1044. "text": message
  1045. }));
  1046. // Clear the textarea after sending the message
  1047. textArea.value = "";
  1048. closePopup();
  1049. }
  1050. }
  1051. }
  1052.  
  1053. function clrall() {
  1054. const chatContent = document.getElementById("chat-content");
  1055. const webSocketMessagesDiv = document.getElementById("webSocketMessages");
  1056. if (chatContent && webSocketMessagesDiv) {
  1057. // Clear all child elements of chatContent
  1058. chatContent.innerHTML = "";
  1059. // Move webSocketMessagesDiv to the bottom
  1060. chatContent.appendChild(webSocketMessagesDiv);
  1061. // Adjust height of webSocketMessagesDiv
  1062. webSocketMessagesDiv.style.height = "75%";
  1063. }
  1064. }
  1065.  
  1066. // Function to toggle compact view
  1067. function toggleCompactView() {
  1068. const messages = document.querySelectorAll('.message .content');
  1069. messages.forEach(message => {
  1070. message.classList.toggle('compact');
  1071. });
  1072. }
  1073.  
  1074. // Function to create and populate handle-username dropdown menu
  1075. function createHandleUsernameDropdown() {
  1076. const handleUsernameDropdown = document.createElement("select");
  1077. handleUsernameDropdown.id = "handleUsernameDropdown";
  1078. handleUsernameDropdown.style.margin = "0 5px";
  1079. handleUsernameDropdown.innerHTML = '<option value="" disabled selected>who</option>';
  1080. for (const handle in handleUserMap) {
  1081. const option = document.createElement("option");
  1082. option.value = handle;
  1083. option.textContent = handleUserMap[handle];
  1084. handleUsernameDropdown.appendChild(option);
  1085. }
  1086. return handleUsernameDropdown;
  1087. }
  1088.  
  1089. // Create top buttons
  1090. function createTopButtons() {
  1091. const topButtonsDiv = document.createElement("div");
  1092. topButtonsDiv.id = "topButtons";
  1093. topButtonsDiv.style.position = "fixed";
  1094. topButtonsDiv.style.top = "10px";
  1095. topButtonsDiv.style.left = "50%";
  1096. topButtonsDiv.style.transform = "translateX(-50%)";
  1097. topButtonsDiv.style.zIndex = "9999";
  1098.  
  1099. // Clear WebSocket messages button
  1100. const clrButton = document.createElement("button");
  1101. clrButton.textContent = "clr";
  1102. clrButton.style.background = "black";
  1103. clrButton.style.color = "lime";
  1104. clrButton.addEventListener("click", clr);
  1105. topButtonsDiv.appendChild(clrButton);
  1106.  
  1107. // Clear WebSocket messages button
  1108. const clrallButton = document.createElement("button");
  1109. clrallButton.textContent = "clrall";
  1110. clrallButton.style.background = "black";
  1111. clrallButton.style.color = "lime";
  1112. clrallButton.addEventListener("click", clr);
  1113. topButtonsDiv.appendChild(clrallButton);
  1114.  
  1115. // Delete chat and switch to IRC only mode
  1116. const IrcModeButton = document.createElement("button");
  1117. IrcModeButton.textContent = "irc";
  1118. IrcModeButton.style.background = "black";
  1119. IrcModeButton.style.color = "lime";
  1120. IrcModeButton.addEventListener("click", IrcMode);
  1121. topButtonsDiv.appendChild(IrcModeButton);
  1122.  
  1123. // Dropdown menu for handle-username mapping
  1124. const handleUsernameDropdown = createHandleUsernameDropdown();
  1125. topButtonsDiv.appendChild(handleUsernameDropdown);
  1126.  
  1127. // Color picker button
  1128. const colorPickerButton = document.createElement("button");
  1129. colorPickerButton.textContent = "Color";
  1130. colorPickerButton.style.background = "black";
  1131. colorPickerButton.style.color = "lime";
  1132. colorPickerButton.style.margin = "0 5px";
  1133. colorPickerButton.addEventListener("click", () => {
  1134. openColorPickerPopup();
  1135. });
  1136. topButtonsDiv.appendChild(colorPickerButton);
  1137.  
  1138. // Font size dropdown
  1139. const fontSizeDropdown = document.createElement("select");
  1140. fontSizeDropdown.id = "fontSizeDropdown";
  1141. fontSizeDropdown.style.margin = "0 5px";
  1142. for (let i = 1; i <= 20; i++) {
  1143. const option = document.createElement("option");
  1144. option.value = i;
  1145. option.textContent = i;
  1146. fontSizeDropdown.appendChild(option);
  1147. }
  1148. fontSizeDropdown.addEventListener("change", () => {
  1149. const selectedFontSize = fontSizeDropdown.value;
  1150. applyFontSize(selectedFontSize);
  1151. });
  1152. topButtonsDiv.appendChild(fontSizeDropdown);
  1153.  
  1154. // Append top buttons div to document body
  1155. document.body.appendChild(topButtonsDiv);
  1156. }
  1157.  
  1158. // Function to apply font size to WebSocket messages
  1159. function applyFontSize(fontSize) {
  1160. const webSocketMessagesDiv = document.getElementById("webSocketMessages");
  1161. if (webSocketMessagesDiv) {
  1162. webSocketMessagesDiv.style.fontSize = `${fontSize}px`;
  1163. }
  1164. }
  1165.  
  1166. // Call the function to create top buttons
  1167. createTopButtons();
  1168.  
  1169. // Function to open color picker popup
  1170. function openColorPickerPopup() {
  1171. const popup = document.createElement("div");
  1172. popup.id = "colorPickerPopup";
  1173. popup.style.position = "fixed";
  1174. popup.style.top = "50%";
  1175. popup.style.left = "50%";
  1176. popup.style.transform = "translate(-50%, -50%)";
  1177. popup.style.background = "#1f1f1f";
  1178. popup.style.padding = "20px";
  1179. popup.style.border = "2px solid #ffffff";
  1180. popup.style.zIndex = "99999";
  1181.  
  1182. const backgroundLabel = document.createElement("label");
  1183. backgroundLabel.textContent = "Background Color:";
  1184. backgroundLabel.style.color = "#ffffff";
  1185. popup.appendChild(backgroundLabel);
  1186.  
  1187. const backgroundColorInput = document.createElement("input");
  1188. backgroundColorInput.type = "color";
  1189. backgroundColorInput.id = "backgroundColorInput";
  1190. backgroundColorInput.style.marginRight = "10px";
  1191. backgroundColorInput.value = "#000000";
  1192. popup.appendChild(backgroundColorInput);
  1193.  
  1194. const fontColorLabel = document.createElement("label");
  1195. fontColorLabel.textContent = "Font Color:";
  1196. fontColorLabel.style.color = "#ffffff";
  1197. popup.appendChild(fontColorLabel);
  1198.  
  1199. const fontColorInput = document.createElement("input");
  1200. fontColorInput.type = "color";
  1201. fontColorInput.id = "fontColorInput";
  1202. fontColorInput.style.marginRight = "10px";
  1203. fontColorInput.value = "#ffffff";
  1204. popup.appendChild(fontColorInput);
  1205.  
  1206. const applyButton = document.createElement("button");
  1207. applyButton.textContent = "Apply";
  1208. applyButton.style.background = "black";
  1209. applyButton.style.color = "lime";
  1210. applyButton.style.marginTop = "10px";
  1211. applyButton.addEventListener("click", () => {
  1212. applyColors(backgroundColorInput.value, fontColorInput.value);
  1213. popup.remove();
  1214. });
  1215. popup.appendChild(applyButton);
  1216.  
  1217. const closeButton = document.createElement("button");
  1218. closeButton.textContent = "Close";
  1219. closeButton.style.background = "black";
  1220. closeButton.style.color = "lime";
  1221. closeButton.style.marginTop = "10px";
  1222. closeButton.style.marginLeft = "10px";
  1223. closeButton.addEventListener("click", () => {
  1224. popup.remove();
  1225. });
  1226. popup.appendChild(closeButton);
  1227.  
  1228. document.body.appendChild(popup);
  1229. }
  1230.  
  1231. // Function to apply selected colors to WebSocket log
  1232. function applyColors(backgroundColor, fontColor) {
  1233. const webSocketMessagesDiv = document.getElementById("webSocketMessages");
  1234. if (webSocketMessagesDiv) {
  1235. webSocketMessagesDiv.style.backgroundColor = backgroundColor;
  1236. webSocketMessagesDiv.style.color = fontColor;
  1237. }
  1238. }
  1239.  
  1240. /* Additional compacting styles */
  1241. /*@-moz-document url-prefix("https://stumblechat.com/room/") {*/
  1242. // Compact message styles
  1243. const compactStyles = `
  1244. .message .nickname ~ .content {
  1245. display: inline-block;
  1246. top: -7px;
  1247. position: relative;
  1248. margin-left: 2px;
  1249. margin-right: 1em;
  1250. }
  1251. .content + .content {
  1252. display: inline-block!important;
  1253. margin-right: 1em;
  1254. }
  1255. .message .nickname ~ .content span {
  1256. line-height: 1.5em;
  1257. }
  1258. `;
  1259.  
  1260. // Apply compact styles to the document
  1261. const style = document.createElement('style');
  1262. style.textContent = compactStyles;
  1263. document.head.appendChild(style);
  1264. /*}*/
  1265.  
  1266.  
  1267. // Function to handle click events for the new button
  1268. function handleLoadButtonClick() {
  1269. // Add functionality for the new button here
  1270. console.log('Load button clicked');
  1271. }
  1272.  
  1273. // Function to handle click events for the new button
  1274. function handleDisplayThingsButtonClick() {
  1275. // Add functionality for the new button here
  1276. console.log('Load button clicked');
  1277. }
  1278.  
  1279. // Create a new button configuration
  1280. const DisplayThingsButtonConfig = { name: 'd', text: 'display', clickHandler: handleDisplayThingsButtonClick };
  1281.  
  1282. // Create a new button configuration
  1283. const LoadButtonConfig = { name: 'n', text: 'Load', clickHandler: handleLoadButtonClick };
  1284.  
  1285. // Function to create generic buttons
  1286. function createGenericButtons() {
  1287. // Define button configurations
  1288. const buttonConfigurations = [
  1289. { name: 'c', text: 'Compact', clickHandler: toggleCompactView },
  1290. { name: 's', text: 'Save', clickHandler: () => {
  1291. // Functionality to save handle-username map to memory or file
  1292. console.log("Save button clicked");
  1293. saveUserListToFile();
  1294. }},
  1295. { name: 'L', text: 'Load Users', clickHandler: loadUsersFromFile }, // Button to load users from file
  1296. LoadButtonConfig, // Add the new button configuration here
  1297. { name: 'D', text: 'Display Things', clickHandler: handleDisplayThingsButtonClick } // Button to load users from file
  1298. ];
  1299.  
  1300. // Get the container for the buttons
  1301. const container = document.getElementById('topButtons');
  1302.  
  1303. // Loop through each button configuration and generate a button
  1304. buttonConfigurations.forEach(config => {
  1305. // Create a button element
  1306. const button = document.createElement('button');
  1307. button.textContent = config.text; // Use button text as text content
  1308. button.style.background = "black";
  1309. button.style.color = "lime";
  1310. button.style.width = "50px"; // Set button width
  1311. button.style.height = "20px"; // Set button height
  1312. button.style.margin = "0 5px"; // Set button margin
  1313.  
  1314. // Add event listener based on configuration
  1315. button.addEventListener('click', config.clickHandler);
  1316.  
  1317. // Append the button to the container in the DOM
  1318. container.appendChild(button);
  1319. });
  1320. }
  1321.  
  1322. // Call the function to create generic buttons
  1323. createGenericButtons();
  1324.  
  1325.  
  1326. // Function to create a new button and append it to the container
  1327. function createDisconnectButton() {
  1328. const container = document.getElementById('topButtons');
  1329.  
  1330. // Create the button element
  1331. const newButton = document.createElement('button');
  1332. newButton.textContent = 'DC'; // Change the text as needed
  1333. newButton.style.background = 'black';
  1334. newButton.style.color = 'lime';
  1335. newButton.style.width = '100px'; // Set the button width
  1336. newButton.style.height = '30px'; // Set the button height
  1337. newButton.style.margin = '0 5px'; // Set the button margin
  1338.  
  1339. // Add event listener to the new button
  1340. newButton.addEventListener('click', () => {
  1341. // Add functionality for the new button here
  1342. console.log('New button clicked');
  1343. });
  1344.  
  1345. // Append the new button to the container
  1346. container.appendChild(newButton);
  1347. }
  1348.  
  1349. // Call the function to create the new button
  1350. createDisconnectButton();
  1351.  
  1352. // Function to load users from the users.txt file
  1353. function displayThings() {
  1354. const users = [];
  1355. // Placeholder for file content, replace this with your file reading logic
  1356. // Example: You can use XMLHttpRequest, fetch API, or any other method to read the file
  1357. // For simplicity, I'll use fetch API assuming users.txt is in the same directory
  1358. fetch('users.txt')
  1359. .then(response => response.text())
  1360. .then(fileContent => {
  1361. // Split the file content into lines
  1362. const lines = fileContent.split('\n');
  1363.  
  1364. // Iterate over each line to parse user data
  1365. lines.forEach(line => {
  1366. const userData = line.trim().split(' '); // Splitting by space to separate username and handle
  1367. if (userData.length === 2) {
  1368. const username = userData[0].trim();
  1369. const handle = userData[1].trim();
  1370. users.push({ username, handle });
  1371. // Update user map
  1372. handleUserMap[handle] = username;
  1373. }
  1374. });
  1375.  
  1376. // Display loaded users
  1377. console.log("Loaded Users:");
  1378. users.forEach(user => {
  1379. console.log(`${user.username} (${user.handle})`);
  1380. });
  1381. })
  1382. .catch(error => {
  1383. console.error('Error loading users from file:', error);
  1384. });
  1385.  
  1386. return users;
  1387. }
  1388.  
  1389. })();
  1390.  
  1391.  
  1392.  
  1393.  
  1394.  
  1395.  
  1396.  
  1397.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement