Change background color on ChatGPT

With this script you can change ChatGPT background color and even use a custom image!

  1. // ==UserScript==
  2. // @name Change background color on ChatGPT
  3. // @name:es Cambiar color de fondo en ChatGPT
  4. // @name:en-US Change background color on ChatGPT
  5. // @name:ja ChatGPTの背景色を変更
  6. // @name:ru Изменить цвет фона в ChatGPT
  7. // @name:ko ChatGPT 배경색 변경
  8. // @name:it Cambia colore di sfondo su ChatGPT
  9. // @name:de Hintergrundfarbe in ChatGPT ändern
  10. // @name:fr Changer la couleur de fond sur ChatGPT
  11. // @namespace http://tampermonkey.net/
  12. // @version 1.0
  13. // @description With this script you can change ChatGPT background color and even use a custom image!
  14. // @description:es Con este script puedes cambiar el color de fondo de ChatGPT e incluso usar una imagen personalizada.
  15. // @description:en-US With this script you can change ChatGPT background color and even use a custom image!
  16. // @description:ja このスクリプトを使用すると、ChatGPTの背景色を変更したり、カスタム画像を使用したりできます。
  17. // @description:ru С помощью этого скрипта вы можете изменить цвет фона ChatGPT и даже использовать собственное изображение!
  18. // @description:ko 이 스크립트를 사용하면 ChatGPT 배경색을 변경하고 사용자 지정 이미지를 사용할 수도 있습니다!
  19. // @description:it Con questo script puoi cambiare il colore di sfondo di ChatGPT e persino usare un'immagine personalizzata!
  20. // @description:de Mit diesem Skript können Sie die Hintergrundfarbe von ChatGPT ändern und sogar ein benutzerdefiniertes Bild verwenden!
  21. // @description:fr Avec ce script, vous pouvez changer la couleur de fond de ChatGPT et même utiliser une image personnalisée !
  22. // @author Mr-Zanzibar
  23. // @match *://chatgpt.com/*
  24. // @license MIT
  25. // @grant none
  26. // ==/UserScript==
  27.  
  28. (function() {
  29. // Constants & Storage
  30. const STORAGE_KEY_BACKGROUND = 'chatgptBackground';
  31. let isDragging = false;
  32. let offsetX, offsetY;
  33.  
  34. // Translations
  35. const translations = {
  36. en: {
  37. backgroundColorLabel: 'Background Color:',
  38. resetButton: 'Reset',
  39. imagePrompt: 'Set this image as background?',
  40. invalidImage: 'Please select a valid image file.',
  41. disclaimer: 'ChatGPT can make errors. Script by <a href="https://github.com/Mr-Zanzibar" target="_blank">Mr-Zanzibar</a>'
  42. },
  43. es: {
  44. backgroundColorLabel: 'Color de fondo:',
  45. resetButton: 'Restablecer',
  46. imagePrompt: '¿Establecer esta imagen como fondo?',
  47. invalidImage: 'Por favor, seleccione un archivo de imagen válido.',
  48. disclaimer: 'ChatGPT puede cometer errores. Script por <a href="https://github.com/Mr-Zanzibar" target="_blank">Mr-Zanzibar</a>'
  49. },
  50. ja: {
  51. backgroundColorLabel: '背景色:',
  52. resetButton: 'リセット',
  53. imagePrompt: 'この画像を背景に設定しますか?',
  54. invalidImage: '有効な画像ファイルを選択してください。',
  55. disclaimer: 'ChatGPTはエラーを起こす可能性があります。スクリプトは<a href="https://github.com/Mr-Zanzibar" target="_blank">Mr-Zanzibar</a>によるものです。'
  56. },
  57. ru: {
  58. backgroundColorLabel: 'Цвет фона:',
  59. resetButton: 'Сбросить',
  60. imagePrompt: 'Установить это изображение в качестве фона?',
  61. invalidImage: 'Пожалуйста, выберите действительный файл изображения.',
  62. disclaimer: 'ChatGPT может допускать ошибки. Скрипт от <a href="https://github.com/Mr-Zanzibar" target="_blank">Mr-Zanzibar</a>'
  63. },
  64. ko: {
  65. backgroundColorLabel: '배경색:',
  66. resetButton: '초기화',
  67. imagePrompt: '이 이미지를 배경으로 설정하시겠습니까?',
  68. invalidImage: '올바른 이미지 파일을 선택하십시오.',
  69. disclaimer: 'ChatGPT는 오류를 일으킬 수 있습니다. 스크립트 작성자: <a href="https://github.com/Mr-Zanzibar" target="_blank">Mr-Zanzibar</a>'
  70. },
  71. it: {
  72. backgroundColorLabel: 'Colore di sfondo:',
  73. resetButton: 'Ripristina',
  74. imagePrompt: 'Impostare questa immagine come sfondo?',
  75. invalidImage: 'Seleziona un file immagine valido.',
  76. disclaimer: 'ChatGPT può commettere errori. Script di <a href="https://github.com/Mr-Zanzibar" target="_blank">Mr-Zanzibar</a>'
  77. },
  78. de: {
  79. backgroundColorLabel: 'Hintergrundfarbe:',
  80. resetButton: 'Zurücksetzen',
  81. imagePrompt: 'Dieses Bild als Hintergrund festlegen?',
  82. invalidImage: 'Bitte wählen Sie eine gültige Bilddatei aus.',
  83. disclaimer: 'ChatGPT kann Fehler machen. Skript von <a href="https://github.com/Mr-Zanzibar" target="_blank">Mr-Zanzibar</a>'
  84. },
  85. fr: {
  86. backgroundColorLabel: 'Couleur de fond :',
  87. resetButton: 'Réinitialiser',
  88. imagePrompt: 'Définir cette image comme arrière-plan ?',
  89. invalidImage: 'Veuillez sélectionner un fichier image valide.',
  90. disclaimer: 'ChatGPT peut faire des erreurs. Script par <a href="https://github.com/Mr-Zanzibar" target="_blank">Mr-Zanzibar</a>'
  91. }
  92. };
  93.  
  94. // Get Browser Language
  95. const userLang = navigator.language || navigator.userLanguage;
  96. const lang = userLang.split('-')[0]; // Extract main language code (e.g., 'en' from 'en-US')
  97. const currentTranslations = translations[lang] || translations['en']; // Fallback to English
  98.  
  99. // Background Functions
  100. function setBackground(background, type = 'color') {
  101. localStorage.setItem(STORAGE_KEY_BACKGROUND, JSON.stringify({ background, type }));
  102. document.body.style.backgroundColor = type === 'color' ? background : 'transparent';
  103. document.body.style.backgroundImage = type === 'color' ? 'none' : `url(${background})`;
  104. }
  105.  
  106. // UI Element Creation
  107. function createButton(text, onClick, style = {}) {
  108. const button = document.createElement('button');
  109. button.textContent = text;
  110. button.onclick = onClick;
  111. Object.assign(button.style, {
  112. margin: '5px 0', padding: '8px 12px', border: 'none', borderRadius: '5px',
  113. cursor: 'pointer', fontSize: '14px', ...style
  114. });
  115. return button;
  116. }
  117.  
  118. function createColorPicker() {
  119. const container = document.createElement('div');
  120. container.style.marginBottom = '10px';
  121.  
  122. const label = document.createElement('label');
  123. label.textContent = currentTranslations.backgroundColorLabel;
  124. label.htmlFor = 'colorPickerInput';
  125. container.appendChild(label);
  126.  
  127. const input = document.createElement('input');
  128. input.id = 'colorPickerInput';
  129. input.type = 'color';
  130. input.value = savedBackground?.type === 'color' ? savedBackground.background : '#ffffff';
  131. input.addEventListener('input', () => setBackground(input.value, 'color'));
  132. container.appendChild(input);
  133. return container;
  134. }
  135.  
  136. // Drag and Drop Functionality (Encapsulated)
  137. function handleDragStart(e) {
  138. isDragging = true;
  139. offsetX = e.clientX - container.getBoundingClientRect().left;
  140. offsetY = e.clientY - container.getBoundingClientRect().top;
  141. }
  142.  
  143. function handleDrag(e) {
  144. if (isDragging) {
  145. const maxX = window.innerWidth - container.offsetWidth;
  146. const maxY = window.innerHeight - container.offsetHeight;
  147.  
  148. let newX = e.clientX - offsetX;
  149. let newY = e.clientY - offsetY;
  150.  
  151. container.style.left = Math.max(0, Math.min(newX, maxX)) + 'px';
  152. container.style.top = Math.max(0, Math.min(newY, maxY)) + 'px';
  153. }
  154. }
  155.  
  156. function handleDragEnd() {
  157. isDragging = false;
  158. }
  159.  
  160. function createImageInput() {
  161. const input = document.createElement('input');
  162. input.type = 'file';
  163. input.accept = 'image/*';
  164. input.onchange = (event) => {
  165. const file = event.target.files[0];
  166. if (!file.type.startsWith('image/')) {
  167. alert(currentTranslations.invalidImage);
  168. return;
  169. }
  170.  
  171. const reader = new FileReader();
  172. reader.onloadend = () => {
  173. const previewImg = document.createElement('img');
  174. previewImg.src = reader.result;
  175. previewImg.style.maxWidth = '200px';
  176. previewImg.style.maxHeight = '200px';
  177. previewImg.style.marginBottom = '5px';
  178. container.insertBefore(previewImg, input);
  179.  
  180. if (confirm(currentTranslations.imagePrompt)) {
  181. setBackground(reader.result, 'image');
  182. }
  183. previewImg.remove();
  184. };
  185. reader.readAsDataURL(file);
  186. };
  187. return input;
  188. }
  189.  
  190. // Main Container Setup
  191. const container = document.createElement('div');
  192. container.id = 'background-options-container';
  193. Object.assign(container.style, {
  194. position: 'fixed', top: '10px', right: '10px', zIndex: '9999',
  195. backgroundColor: 'rgba(255,255,255,0.8)', padding: '15px', borderRadius: '5px'
  196. });
  197. container.addEventListener('mousedown', handleDragStart);
  198. document.addEventListener('mousemove', handleDrag);
  199. document.addEventListener('mouseup', handleDragEnd);
  200.  
  201. // Load Saved Settings
  202. const savedBackground = JSON.parse(localStorage.getItem(STORAGE_KEY_BACKGROUND));
  203. if (savedBackground) {
  204. setBackground(savedBackground.background, savedBackground.type);
  205. }
  206.  
  207. // Disclaimer (With Link Handling)
  208. const disclaimerElement = document.querySelector('.text-center.text-xs');
  209. if (disclaimerElement) {
  210. disclaimerElement.innerHTML = `ChatGPT can make errors. Script by <a href="https://github.com/Mr-Zanzibar" target="_blank">Mr-Zanzibar</a>`;
  211. const linkElement = disclaimerElement.querySelector('a');
  212. linkElement.addEventListener('mouseover', () => linkElement.style.textDecoration = 'underline');
  213. linkElement.addEventListener('mouseout', () => linkElement.style.textDecoration = 'none');
  214. }
  215.  
  216. // UI Elements
  217. container.appendChild(createColorPicker()); // Color Picker
  218. container.appendChild(createImageInput());
  219. container.appendChild(createButton(currentTranslations.resetButton, () => {
  220. localStorage.removeItem(STORAGE_KEY_BACKGROUND);
  221. location.reload();
  222. }, { backgroundColor: '#ff0000', color: 'white' })); // Reset Button
  223.  
  224. document.body.appendChild(container);
  225. })();