Torn.com Enhanced Chat Buttons

Add customizable buttons to Torn.com chat

  1. // ==UserScript==
  2. // @name Torn.com Enhanced Chat Buttons
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description Add customizable buttons to Torn.com chat
  6. // @author Callz [2188704]
  7. // @match https://www.torn.com/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. const buttonCSS = `
  15. .custom-chat-button {
  16. background-color: #007BFF;
  17. color: white;
  18. padding: 2px 7px;
  19. text-align: center;
  20. text-decoration: none;
  21. display: inline-block;
  22. font-size: 14px;
  23. margin: 4px 6px;
  24. cursor: pointer;
  25. border-radius: 5px;
  26. border: none;
  27. transition: background-color 0.3s ease;
  28. min-width: 80px;
  29. overflow: hidden;
  30. white-space: nowrap;
  31. }
  32.  
  33. .custom-chat-button:hover {
  34. background-color: #0056b3;
  35. }
  36.  
  37. .custom-ui-panel label {
  38. font-size: 20px;
  39. margin-bottom: 20px;
  40. }
  41.  
  42. .custom-ui-panel {
  43. position: fixed;
  44. top: 50%;
  45. left: 50%;
  46. transform: translate(-50%, -50%);
  47. background-color: #f5f5f5;
  48. padding: 20px;
  49. color: black;
  50. border-radius: 10px;
  51. box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
  52. z-index: 9999999999;
  53. max-width: 70%;
  54. }
  55.  
  56. .custom-ui-panel h3 {
  57. font-size: 20px;
  58. margin-bottom: 20px;
  59. }
  60.  
  61. .custom-ui-panel input[type="text"],
  62. .custom-ui-panel select,
  63. .custom-ui-panel textarea {
  64. width: 90%;
  65. padding: 10px;
  66. margin-top:10px;
  67. margin-bottom: 15px;
  68. border: 1px solid #ccc;
  69. border-radius: 5px;
  70. font-size: 16px;
  71. }
  72.  
  73. .custom-ui-panel input[type="color"] {
  74. padding: 0;
  75. }
  76.  
  77. .custom-ui-panel button {
  78. background-color: #007BFF;
  79. color: white;
  80. border: none;
  81. padding: 10px 16px;
  82. border-radius: 5px;
  83. cursor: pointer;
  84. margin: 10px 5px;
  85. font-size: 16px;
  86. transition: background-color 0.3s ease;
  87. }
  88.  
  89. .custom-ui-panel button#close-ui {
  90. background-color: #ccc;
  91. margin-right: 10px;
  92. }
  93.  
  94. .custom-ui-panel button#close-ui:hover {
  95. background-color: #999;
  96. }
  97.  
  98. .custom-ui-panel textarea {
  99. height: 100px;
  100. resize: vertical;
  101. }
  102. .custom-ui-panel hr {
  103. margin: 20px 0;
  104. border: 0;
  105. border-top: 1px solid #ccc;
  106. }
  107. #chat-config-button {
  108. color:green;
  109. }
  110. #button-configs {
  111. max-height: 200px;
  112. overflow-y: scroll;
  113. }
  114.  
  115.  
  116. `;
  117.  
  118. function addCSS(cssString) {
  119. const style = document.createElement('style');
  120. style.textContent = cssString;
  121. document.head.append(style);
  122. }
  123.  
  124. function getButtonConfigurations() {
  125. const defaultConfig = { buttons: [] };
  126. const config = localStorage.getItem('chatButtonConfig');
  127. return config ? JSON.parse(config) : defaultConfig;
  128. }
  129.  
  130. function saveButtonConfigurations(config) {
  131. localStorage.setItem('chatButtonConfig', JSON.stringify(config));
  132. console.log('Saved configuration:', config);
  133. }
  134.  
  135. function createUIPanel() {
  136. const panel = document.createElement('div');
  137. panel.className = 'custom-ui-panel';
  138. panel.innerHTML = `
  139. <h3>Chat Button Configuration</h3>
  140. <div id="button-configs"></div>
  141. <hr> <!-- Divider -->
  142. <div>
  143. <input type="text" id="button-text" placeholder="Button Text">
  144. <label for="button-color">Background Color:</label>
  145. <input type="color" id="button-color">
  146. <select id="button-condition">
  147. <option value="TradeChat">Trade Chat</option>
  148. <option value="HospitalChat">Hospital Chat</option>
  149. <option value="FactionChat">Faction Chat</option>
  150. <option value="CompanyChat">Company Chat</option>
  151. <option value="GlobalChat">Global Chat</option>
  152. <option value="UserChat">User Chat</option>
  153. </select>
  154. <textarea id="button-text-content" placeholder="Add the text here that should be pasted in chat. You can use {name} to get the name of the active chat"></textarea>
  155. <button id="add-button">Add Button</button>
  156. <button id="edit-button" style="display: none;">Edit Button</button>
  157. </div>
  158. <button id="close-ui">Close</button>
  159.  
  160. `;
  161. document.body.appendChild(panel);
  162.  
  163. document.getElementById('add-button').addEventListener('click', addNewButtonConfig);
  164. document.getElementById('edit-button').addEventListener('click', editButtonConfig);
  165. document.getElementById('close-ui').addEventListener('click', closeUI);
  166. populateButtonConfigs();
  167. }
  168.  
  169. function populateButtonConfigs() {
  170. const configsContainer = document.getElementById('button-configs');
  171. configsContainer.innerHTML = '';
  172. const configs = getButtonConfigurations();
  173.  
  174. configs.buttons.forEach((buttonConfig, index) => {
  175. let configDiv = document.createElement('div');
  176. configDiv.innerHTML = `
  177. <div>Text: ${buttonConfig.buttonText}</div>
  178. <div>Color: ${buttonConfig.backgroundColor}</div>
  179. <div>Condition: ${buttonConfig.condition}</div>
  180. <div>Message: ${buttonConfig.text}</div>
  181. `;
  182.  
  183. let editButton = document.createElement('button');
  184. editButton.textContent = 'Edit';
  185. editButton.addEventListener('click', function() { selectForEdit(index); });
  186. configDiv.appendChild(editButton);
  187.  
  188. let deleteButton = document.createElement('button');
  189. deleteButton.textContent = 'Delete';
  190. deleteButton.addEventListener('click', function() { deleteButtonConfig(index); });
  191. configDiv.appendChild(deleteButton);
  192.  
  193. configsContainer.appendChild(configDiv);
  194. });
  195. }
  196.  
  197. window.selectForEdit = function(index) {
  198. const config = getButtonConfigurations().buttons[index];
  199. document.getElementById('button-text').value = config.buttonText;
  200. document.getElementById('button-color').value = config.backgroundColor;
  201. document.getElementById('button-condition').value = config.condition;
  202. document.getElementById('button-text-content').value = config.text;
  203.  
  204. document.getElementById('edit-button').style.display = 'block';
  205. document.getElementById('edit-button').setAttribute('data-edit-index', index);
  206. };
  207.  
  208. window.deleteButtonConfig = function(index) {
  209. let config = getButtonConfigurations();
  210. config.buttons.splice(index, 1);
  211. saveButtonConfigurations(config);
  212. populateButtonConfigs();
  213. };
  214.  
  215. function addNewButtonConfig() {
  216. const buttonText = document.getElementById('button-text').value;
  217. const backgroundColor = document.getElementById('button-color').value;
  218. const condition = document.getElementById('button-condition').value;
  219. const text = document.getElementById('button-text-content').value;
  220.  
  221. let config = getButtonConfigurations();
  222. config.buttons.push({ buttonText, backgroundColor, condition, text });
  223. saveButtonConfigurations(config);
  224. populateButtonConfigs();
  225. }
  226.  
  227. function editButtonConfig() {
  228. const index = parseInt(document.getElementById('edit-button').getAttribute('data-edit-index'), 10);
  229. const buttonText = document.getElementById('button-text').value;
  230. const backgroundColor = document.getElementById('button-color').value;
  231. const condition = document.getElementById('button-condition').value;
  232. const text = document.getElementById('button-text-content').value;
  233.  
  234. let config = getButtonConfigurations();
  235. config.buttons[index] = { buttonText, backgroundColor, condition, text };
  236. saveButtonConfigurations(config);
  237. populateButtonConfigs();
  238. }
  239.  
  240. function closeUI() {
  241. const panel = document.querySelector('.custom-ui-panel');
  242. if (panel) {
  243. panel.remove();
  244. }
  245. }
  246.  
  247. function createConfigButton() {
  248. const settingsPanel = document.querySelector('.settings-panel___IZSDs');
  249. if (settingsPanel && !document.querySelector('#chat-config-button')) {
  250. let configButton = document.createElement('button');
  251. configButton.id = 'chat-config-button';
  252. configButton.textContent = 'Edit Chat Buttons';
  253. configButton.addEventListener('click', createUIPanel);
  254. configButton.style = '/* Add specific styles for the button here */';
  255. settingsPanel.appendChild(configButton);
  256. }
  257. }
  258.  
  259. addCSS(buttonCSS);
  260.  
  261. const chatContainerObserver = new MutationObserver(function(mutations) {
  262. mutations.forEach(function(mutation) {
  263. createConfigButton();
  264. applyButtonConfigurations();
  265. });
  266. });
  267.  
  268. const chatContainer = document.querySelector('#chatRoot');
  269. if (chatContainer) {
  270. chatContainerObserver.observe(chatContainer, { childList: true, subtree: true });
  271. }
  272.  
  273. function applyButtonConfigurations() {
  274. const configs = getButtonConfigurations();
  275. document.querySelectorAll('.chat-box___mHm01').forEach(chatBox => {
  276. configs.buttons.forEach(buttonConfig => {
  277. const conditionFunc = conditions[buttonConfig.condition];
  278. if (conditionFunc && conditionFunc(chatBox) && !chatBox.querySelector(`[data-button-text="${buttonConfig.buttonText}"]`)) {
  279. let button = document.createElement('button');
  280. button.className = 'custom-chat-button';
  281. button.innerText = buttonConfig.buttonText;
  282. button.style.backgroundColor = buttonConfig.backgroundColor;
  283. button.setAttribute('data-button-text', buttonConfig.buttonText);
  284. button.addEventListener('click', () => addCustomText(chatBox, buttonConfig.text));
  285.  
  286. const filterContainer = chatBox.querySelector('.tt-chat-filter');
  287. filterContainer.insertBefore(button, filterContainer.firstChild);
  288. }
  289. });
  290. });
  291. }
  292.  
  293. const conditions = {
  294. TradeChat: chatBox => chatBox.querySelector('.chat-box-header__name___jIjjM').textContent === 'Trade',
  295. HospitalChat: chatBox => chatBox.querySelector('.chat-box-header__name___jIjjM').textContent === 'Hospital',
  296. FactionChat: chatBox => chatBox.querySelector('.chat-box-header__name___jIjjM').textContent === 'Faction',
  297. CompanyChat: chatBox => chatBox.querySelector('.chat-box-header__name___jIjjM').textContent === 'Company',
  298. GlobalChat: chatBox => chatBox.querySelector('.chat-box-header__name___jIjjM').textContent === 'Global',
  299. UserChat: chatBox => chatBox.querySelector('.chat-box-header__options___nTsMU'),
  300. };
  301.  
  302. function addCustomText(chatBox, messageTemplate) {
  303. const chatTextarea = chatBox.querySelector('.chat-box-footer__textarea___liho_');
  304. const nameElement = chatBox.querySelector('.typography___Dc5WV');
  305. const name = nameElement ? nameElement.textContent.trim() : 'Trader';
  306. const message = messageTemplate.replace('{name}', name);
  307.  
  308. if(chatTextarea) {
  309. chatTextarea.value = message;
  310. }
  311. }
  312.  
  313. applyButtonConfigurations();
  314.  
  315. })();