Emerald Auto Next

Auto-start new chat on disconnect and keep chat input focused.

  1. // ==UserScript==
  2. // @name Emerald Auto Next
  3. // @namespace https://greasyfork.org/
  4. // @version 1.3
  5. // @description Auto-start new chat on disconnect and keep chat input focused.
  6.  
  7. // @author Zach
  8. // @license Apache-2.0
  9. // @icon https://emeraldchat.com/logo7.svg
  10.  
  11. // @match https://emeraldchat.com/app
  12.  
  13. // @grant none
  14.  
  15. // @compatible Firefox
  16. // @compatible Violentmonkey
  17.  
  18. // ==/UserScript==
  19.  
  20. 'use strict';
  21.  
  22. function randomTimeout(min, max) {
  23. const minMs = min * 1000;
  24. const maxMs = max * 1000;
  25. return Math.floor(Math.random() * (maxMs - minMs + 1)) + minMs;
  26. }
  27.  
  28. function simulateClick(element) {
  29. const mouseDown = new MouseEvent('mousedown', { bubbles: true, cancelable: true });
  30. const mouseUp = new MouseEvent('mouseup', { bubbles: true, cancelable: true });
  31. const clickEvent = new MouseEvent('click', { bubbles: true, cancelable: true });
  32.  
  33. element.dispatchEvent(mouseDown);
  34. element.dispatchEvent(mouseUp);
  35. element.dispatchEvent(clickEvent);
  36. }
  37.  
  38. function giveKarma() {
  39. const [good, bad] = document.querySelectorAll("a.ui-button-match-mega");
  40. if (!good || !bad) return;
  41.  
  42. const messages = document.querySelectorAll("#messages > .room-component-message-container").length;
  43. if (messages > 3) {
  44. simulateClick(good);
  45. }
  46. else {
  47. simulateClick(bad);
  48. }
  49. }
  50.  
  51. function nextChat() {
  52. const startButton = document.querySelector(".ui-button-match");
  53. if (!startButton) return;
  54.  
  55. setTimeout(() => {
  56. if (startButton.textContent === "Start") {
  57. simulateClick(startButton);
  58. }
  59. }, randomTimeout());
  60. }
  61.  
  62. function focusChat() {
  63. const chatInput = document.getElementById("room-input");
  64. if (!chatInput) return;
  65.  
  66. document.body.addEventListener("keydown", (event) => {
  67. if (!document.querySelector("#ui-hatch > *, #ui-hatch-2 > *, #interests") && event.key !== "`") {
  68. chatInput.focus();
  69. }
  70. }, { once: true });
  71. }
  72.  
  73. function observeChanges() {
  74. const container = document.getElementById("container");
  75. if (!container) return;
  76.  
  77. let shouldExecute = true;
  78.  
  79. const observer = new MutationObserver(() => {
  80. giveKarma();
  81. if (shouldExecute) nextChat();
  82. focusChat();
  83. });
  84.  
  85. observer.observe(container, { childList: true, subtree: true });
  86.  
  87. document.addEventListener("keydown", (event) => {
  88. if (event.key === "`") {
  89. event.preventDefault();
  90. shouldExecute = !shouldExecute;
  91. }
  92. });
  93. }
  94.  
  95.  
  96. observeChanges();