ChatGPT Enhanced Customizer

Customize ChatGPT with advanced background, UI styling, text controls, and presets

  1. // ==UserScript==
  2. // @name ChatGPT Enhanced Customizer
  3. // @namespace https://github.com/elixirsneededx/ChatGPT-Enhanced-Customizer-TamperMonkey-
  4. // @version 3.0
  5. // @description Customize ChatGPT with advanced background, UI styling, text controls, and presets
  6. // @license MIT
  7. // @copyright 2024, elixirsneededx (https://github.com/elixirsneededx) @elixirsneededx on discord.
  8. // @author @elixirsneededx on discord
  9. // @match http*://chat.openai.com/*
  10. // @match http*://chatgpt.com/*
  11. // @connect https://greasyfork.org
  12. // @grant GM_addStyle
  13. // @grant GM_registerMenuCommand
  14. // ==/UserScript==
  15.  
  16. (function () {
  17. 'use strict';
  18.  
  19. // Custom Styles
  20. GM_addStyle(`
  21. #customization-gui {
  22. position: fixed;
  23. top: 10px;
  24. right: 10px;
  25. background: black;
  26. padding: 15px;
  27. border-radius: 10px;
  28. z-index: 10000;
  29. font-family: Arial, sans-serif;
  30. color: white;
  31. display: flex;
  32. flex-direction: column;
  33. gap: 10px;
  34. }
  35. #customization-gui h1, #customization-gui p {
  36. margin: 0;
  37. }
  38. #customization-gui h1 {
  39. font-size: 20px;
  40. color: #ff00ff;
  41. }
  42. #customization-gui p {
  43. font-size: 14px;
  44. color: #ff00ff;
  45. }
  46. #customization-gui label {
  47. margin-bottom: 5px;
  48. }
  49. #customization-gui select, #customization-gui input[type="color"], #customization-gui input[type="file"] {
  50. width: 100%;
  51. padding: 5px;
  52. border-radius: 4px;
  53. background-color: black;
  54. color: white;
  55. border: 1px solid #ffffff;
  56. }
  57. .custom-bg-image, .reopen-gui {
  58. width: 40px;
  59. height: 40px;
  60. background-size: cover;
  61. background-position: center;
  62. cursor: pointer;
  63. position: fixed;
  64. bottom: 10px;
  65. right: 10px;
  66. z-index: 10000;
  67. }
  68. .reopen-gui {
  69. display: none;
  70. background-image: url('https://static.vecteezy.com/system/resources/thumbnails/023/060/823/small_2x/chatgpt-concept-artificial-intelligence-chatbot-neon-logo-on-black-background-free-vector.jpg');
  71. }
  72. .row {
  73. display: flex;
  74. flex-direction: row;
  75. gap: 10px;
  76. }
  77. .column {
  78. display: flex;
  79. flex-direction: column;
  80. gap: 10px;
  81. }
  82. #close-button {
  83. position: absolute;
  84. top: 5px;
  85. right: 5px;
  86. background: red;
  87. border: none;
  88. color: white;
  89. padding: 2px 6px;
  90. border-radius: 4px;
  91. cursor: pointer;
  92. }
  93. `);
  94.  
  95. // Create and append the GUI
  96. const gui = document.createElement('div');
  97. gui.id = 'customization-gui';
  98. gui.innerHTML = `
  99. <button id="close-button">X</button>
  100. <h1>ChatGPTEnhancer3.0</h1>
  101. <div class="column">
  102. <div class="row">
  103. <label for="bgColorPicker">Background Color:</label>
  104. <input type="color" id="bgColorPicker" value="#ffffff" />
  105. </div>
  106. <div class="row">
  107. <label for="headerColorPicker">Header Color:</label>
  108. <input type="color" id="headerColorPicker" value="#f0f0f0" />
  109. </div>
  110. <div class="row">
  111. <label for="sidebarColorPicker">Sidebar Color:</label>
  112. <input type="color" id="sidebarColorPicker" value="#ffffff" />
  113. </div>
  114. </div>
  115. <div class="column">
  116. <label for="fontSelect">Font:</label>
  117. <select id="fontSelect">
  118. <option value="Arial">Arial</option>
  119. <option value="Courier New">Courier New</option>
  120. <option value="Georgia">Georgia</option>
  121. <option value="Tahoma">Tahoma</option>
  122. <option value="Verdana">Verdana</option>
  123. <option value="Comic Sans MS">Comic Sans MS</option>
  124. <option value="Times New Roman">Times New Roman</option>
  125. <option value="Trebuchet MS">Trebuchet MS</option>
  126. <option value="Lucida Console">Lucida Console</option>
  127. <option value="Algerian">Algerian</option>
  128. </select>
  129. <label for="fileInput">Custom Background:</label>
  130. <input type="file" id="fileInput" accept=".mp4,.mp3,.gif,.png,.jpeg,.jpg" />
  131. </div>
  132. <div class="column">
  133. <label for="presetSelect">Presets:</label>
  134. <select id="presetSelect">
  135. <option value="default">Select a preset...</option>
  136. <option value="Anime Style">Anime Style</option>
  137. <option value="Slinky Style">Slinky Style</option>
  138. <option value="Bluematrix Style">Bluematrix Style</option>
  139. </select>
  140. </div>
  141. <p> @elixirsneededx on Discord - main developer</p>
  142. <p> @jokeysalt on Discord - presets/designer</p>
  143. <p> vital/@sacrificialmvp on Discord - motivation/design</p>
  144. `;
  145. document.body.appendChild(gui);
  146.  
  147. // Handle closing and reopening the GUI
  148. const closeButton = document.getElementById('close-button');
  149. const reopenGuiButton = document.createElement('div');
  150. reopenGuiButton.classList.add('reopen-gui');
  151. document.body.appendChild(reopenGuiButton);
  152.  
  153. closeButton.addEventListener('click', () => {
  154. gui.style.display = 'none';
  155. reopenGuiButton.style.display = 'block';
  156. });
  157.  
  158. reopenGuiButton.addEventListener('click', () => {
  159. gui.style.display = 'flex';
  160. reopenGuiButton.style.display = 'none';
  161. });
  162.  
  163. // Handle background color changes
  164. const bgColorPicker = document.getElementById('bgColorPicker');
  165. bgColorPicker.addEventListener('input', () => {
  166. document.body.style.backgroundColor = bgColorPicker.value;
  167. localStorage.setItem('bgColor', bgColorPicker.value);
  168. });
  169. const savedBgColor = localStorage.getItem('bgColor');
  170. if (savedBgColor) {
  171. bgColorPicker.value = savedBgColor;
  172. document.body.style.backgroundColor = savedBgColor;
  173. }
  174.  
  175. // Handle header color changes
  176. const headerColorPicker = document.getElementById('headerColorPicker');
  177. headerColorPicker.addEventListener('input', () => {
  178. const header = document.querySelector('.sticky.top-0.z-10');
  179. if (header) {
  180. header.style.backgroundColor = headerColorPicker.value;
  181. localStorage.setItem('headerColor', headerColorPicker.value);
  182. }
  183. });
  184. const savedHeaderColor = localStorage.getItem('headerColor');
  185. if (savedHeaderColor) {
  186. headerColorPicker.value = savedHeaderColor;
  187. const header = document.querySelector('.sticky.top-0.z-10');
  188. if (header) {
  189. header.style.backgroundColor = savedHeaderColor;
  190. }
  191. }
  192.  
  193. // Handle sidebar color changes
  194. const sidebarColorPicker = document.getElementById('sidebarColorPicker');
  195. sidebarColorPicker.addEventListener('input', () => {
  196. const color = sidebarColorPicker.value;
  197. GM_addStyle(`
  198. .bg-token-sidebar-surface-primary {
  199. background-color: ${color} !important;
  200. }
  201. `);
  202. localStorage.setItem('sidebarColor', color);
  203. });
  204. const savedSidebarColor = localStorage.getItem('sidebarColor');
  205. if (savedSidebarColor) {
  206. sidebarColorPicker.value = savedSidebarColor;
  207. GM_addStyle(`
  208. .bg-token-sidebar-surface-primary {
  209. background-color: ${savedSidebarColor} !important;
  210. }
  211. `);
  212. }
  213.  
  214. // Handle font changes
  215. const fontSelect = document.getElementById('fontSelect');
  216. fontSelect.addEventListener('change', () => {
  217. document.body.style.fontFamily = fontSelect.value;
  218. localStorage.setItem('fontFamily', fontSelect.value);
  219. });
  220. const savedFontFamily = localStorage.getItem('fontFamily');
  221. if (savedFontFamily) {
  222. fontSelect.value = savedFontFamily;
  223. document.body.style.fontFamily = savedFontFamily;
  224. }
  225.  
  226. // Handle custom background uploads
  227. const fileInput = document.getElementById('fileInput');
  228. fileInput.addEventListener('change', () => {
  229. const file = fileInput.files[0];
  230. if (file) {
  231. applyCustomBackground(file);
  232. localStorage.setItem('customBackground', URL.createObjectURL(file));
  233. localStorage.setItem('customBackgroundType', file.type);
  234. }
  235. });
  236. const savedCustomBackground = localStorage.getItem('customBackground');
  237. const savedCustomBackgroundType = localStorage.getItem('customBackgroundType');
  238. if (savedCustomBackground && savedCustomBackgroundType) {
  239. applyCustomBackground({ type: savedCustomBackgroundType, src: savedCustomBackground });
  240. }
  241.  
  242. function applyCustomBackground(file) {
  243. const chatArea = document.querySelector('main');
  244. if (!chatArea) return;
  245.  
  246. const fileURL = file.src || URL.createObjectURL(file);
  247.  
  248. if (file.type.includes('video') || file.type.includes('audio')) {
  249. chatArea.innerHTML = `<video autoplay loop muted style="position: absolute; width: 100%; height: 100%; object-fit: cover;"><source src="${fileURL}" type="${file.type}"></video>`;
  250. } else if (file.type.includes('image')) {
  251. chatArea.style.backgroundImage = `url(${fileURL})`;
  252. chatArea.style.backgroundSize = 'cover';
  253. chatArea.style.backgroundPosition = 'center';
  254. }
  255. }
  256.  
  257. // Handle preset changes
  258. const presetSelect = document.getElementById('presetSelect');
  259. presetSelect.addEventListener('change', () => {
  260. applyPreset(presetSelect.value);
  261. });
  262.  
  263. function applyPreset(name) {
  264. if (name === 'Anime Style') {
  265. document.body.style.backgroundImage = 'url(https://raw.githubusercontent.com/elixirsneededx/ChatGPT-Enhanced-Customizer-TamperMonkey-/main/anime-preset.jpg)';
  266. document.body.style.backgroundSize = 'cover';
  267. document.body.style.backgroundPosition = 'center';
  268. bgColorPicker.value = '#ff1493';
  269. fontSelect.value = 'Algerian';
  270. document.body.style.fontFamily = 'Algerian';
  271. localStorage.setItem('preset', 'Anime Style');
  272. } else if (name === 'Slinky Style') {
  273. document.body.style.backgroundImage = 'url(https://raw.githubusercontent.com/elixirsneededx/ChatGPT-Enhanced-Customizer-TamperMonkey-/main/slinky-preset.gif)';
  274. document.body.style.backgroundSize = 'cover';
  275. document.body.style.backgroundPosition = 'center';
  276. bgColorPicker.value = '#00ffff';
  277. fontSelect.value = 'Comic Sans MS';
  278. document.body.style.fontFamily = 'Comic Sans MS';
  279. localStorage.setItem('preset', 'Slinky Style');
  280. } else if (name === 'Bluematrix Style') {
  281. document.body.style.backgroundImage = 'url(https://raw.githubusercontent.com/elixirsneededx/ChatGPT-Enhanced-Customizer-TamperMonkey-/main/bluematrix-preset.gif)';
  282. document.body.style.backgroundSize = 'cover';
  283. document.body.style.backgroundPosition = 'center';
  284. bgColorPicker.value = '#00008b';
  285. fontSelect.value = 'Times New Roman';
  286. document.body.style.fontFamily = 'Times New Roman';
  287. localStorage.setItem('preset', 'Bluematrix Style');
  288. } else if (name === 'default') {
  289. localStorage.removeItem('preset');
  290. window.location.reload();
  291. }
  292. }
  293.  
  294. // Load preset on page load
  295. const savedPreset = localStorage.getItem('preset');
  296. if (savedPreset) {
  297. presetSelect.value = savedPreset;
  298. applyPreset(savedPreset);
  299. }
  300.  
  301. })();