LemonChat Dark Mode

Adds a dark theme toggle to LemonChat

  1. // ==UserScript==
  2. // @name LemonChat Dark Mode
  3. // @namespace http://lemonchat.app/
  4. // @version 1.0
  5. // @description Adds a dark theme toggle to LemonChat
  6. // @author JuliaBanana
  7. // @match https://lemonchat.app/*
  8. // @icon https://lemonchat.app/img/favicon.ico
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. const darkThemeStyle = document.createElement('style');
  15. darkThemeStyle.id = 'dark-theme-style';
  16. darkThemeStyle.textContent = `
  17. body.dark-theme {
  18. background-color: #121212 !important;
  19. color: #e0e0e0 !important;
  20. }
  21.  
  22. body.dark-theme .text-left.text-black.mb-2 {
  23. color: #a0a0a0 !important;
  24. }
  25.  
  26. body.dark-theme header {
  27. background: linear-gradient(135deg, #303f9f 0%, #512da8 50%, #303f9f 100%) !important;
  28. }
  29.  
  30. body.dark-theme main {
  31. background-color: #121212 !important;
  32. }
  33.  
  34. body.dark-theme #video-container {
  35. background-color: #1e1e1e !important;
  36. }
  37.  
  38. body.dark-theme #remote-video-container {
  39. background-color: #000000 !important;
  40. }
  41.  
  42. body.dark-theme #self-video-container {
  43. background-color: #333333 !important;
  44. }
  45.  
  46. body.dark-theme #chat_container {
  47. background-color: #1e1e1e !important;
  48. border-color: #333333 !important;
  49. }
  50.  
  51. body.dark-theme #system_msg {
  52. color: #a0a0a0 !important;
  53. }
  54.  
  55. body.dark-theme hr {
  56. border-color: #333333 !important;
  57. }
  58.  
  59. body.dark-theme #msg_container > div {
  60. background-color: #2a2a2a !important;
  61. color: #e0e0e0 !important;
  62. }
  63.  
  64. body.dark-theme #input_container {
  65. background-color: #1e1e1e !important;
  66. border-color: #333333 !important;
  67. }
  68.  
  69. body.dark-theme #text {
  70. background-color: #2a2a2a !important;
  71. color: #e0e0e0 !important;
  72. border-color: #444444 !important;
  73. }
  74.  
  75. body.dark-theme #text::placeholder {
  76. color: #909090 !important;
  77. }
  78.  
  79. body.dark-theme #emoji {
  80. color: #909090 !important;
  81. }
  82.  
  83. body.dark-theme .bg-gradient-to-r.from-indigo-500 {
  84. background-image: linear-gradient(to right, #303f9f, #512da8) !important;
  85. }
  86.  
  87. body.dark-theme #loginModal .bg-white,
  88. body.dark-theme #settingsModal .bg-white,
  89. body.dark-theme #premiumModal .bg-white {
  90. background-color: #1e1e1e !important;
  91. color: #e0e0e0 !important;
  92. }
  93.  
  94. body.dark-theme .text-gray-700,
  95. body.dark-theme .text-gray-600,
  96. body.dark-theme .text-gray-500 {
  97. color: #b0b0b0 !important;
  98. }
  99.  
  100. body.dark-theme .bg-white {
  101. background-color: #1e1e1e !important;
  102. }
  103.  
  104. body.dark-theme .bg-gray-200,
  105. body.dark-theme .bg-gray-100,
  106. body.dark-theme .bg-indigo-50 {
  107. background-color: #333333 !important;
  108. }
  109.  
  110. body.dark-theme .border-gray-200 {
  111. border-color: #333333 !important;
  112. }
  113.  
  114. body.dark-theme #settingsModal .border-indigo-100 {
  115. border-color: #444444 !important;
  116. }
  117.  
  118. body.dark-theme emoji-picker {
  119. --background: #2a2a2a !important;
  120. --color: #e0e0e0 !important;
  121. --border-color: #444444 !important;
  122. --category-border-color: #444444 !important;
  123. --input-border-color: #444444 !important;
  124. --input-font-color: #e0e0e0 !important;
  125. --input-placeholder-color: #909090 !important;
  126. }
  127. `;
  128. document.head.appendChild(darkThemeStyle);
  129.  
  130. const existingToggle = document.getElementById('theme-toggle-container');
  131. if (existingToggle) {
  132. existingToggle.remove();
  133. }
  134.  
  135. const toggleContainer = document.createElement('div');
  136. toggleContainer.id = 'theme-toggle-container';
  137. toggleContainer.style.cssText = `
  138. position: fixed;
  139. top: 20px;
  140. left: 50%;
  141. transform: translateX(-50%);
  142. z-index: 9999;
  143. display: flex;
  144. align-items: center;
  145. background-color: rgba(0, 0, 0, 0.7);
  146. padding: 8px 12px;
  147. border-radius: 20px;
  148. box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
  149. transition: all 0.3s ease;
  150. `;
  151.  
  152. const themeLabel = document.createElement('span');
  153. themeLabel.id = 'theme-label';
  154. themeLabel.style.cssText = `
  155. color: white;
  156. margin-right: 8px;
  157. font-size: 14px;
  158. font-weight: bold;
  159. `;
  160. themeLabel.textContent = 'Dark Mode';
  161.  
  162. const switchLabel = document.createElement('label');
  163. switchLabel.style.cssText = `
  164. position: relative;
  165. display: inline-block;
  166. width: 44px;
  167. height: 24px;
  168. margin: 0;
  169. `;
  170.  
  171. const checkbox = document.createElement('input');
  172. checkbox.type = 'checkbox';
  173. checkbox.id = 'theme-toggle-checkbox';
  174. checkbox.style.cssText = `
  175. opacity: 0;
  176. width: 0;
  177. height: 0;
  178. `;
  179.  
  180. const toggleBg = document.createElement('span');
  181. toggleBg.id = 'toggle-background';
  182. toggleBg.style.cssText = `
  183. position: absolute;
  184. cursor: pointer;
  185. top: 0;
  186. left: 0;
  187. right: 0;
  188. bottom: 0;
  189. background-color: #ccc;
  190. transition: .4s;
  191. border-radius: 24px;
  192. `;
  193.  
  194. const toggleCircle = document.createElement('span');
  195. toggleCircle.id = 'toggle-circle';
  196. toggleCircle.style.cssText = `
  197. position: absolute;
  198. content: '';
  199. height: 16px;
  200. width: 16px;
  201. left: 4px;
  202. bottom: 4px;
  203. background-color: white;
  204. transition: .4s;
  205. border-radius: 50%;
  206. transform: translateX(0px);
  207. `;
  208.  
  209. switchLabel.appendChild(checkbox);
  210. switchLabel.appendChild(toggleBg);
  211. switchLabel.appendChild(toggleCircle);
  212.  
  213. toggleContainer.appendChild(themeLabel);
  214. toggleContainer.appendChild(switchLabel);
  215.  
  216. document.body.appendChild(toggleContainer);
  217.  
  218. function toggleTheme(isDark) {
  219. if (isDark) {
  220. document.body.classList.add('dark-theme');
  221. } else {
  222. document.body.classList.remove('dark-theme');
  223. }
  224.  
  225. toggleCircle.style.transform = isDark ? 'translateX(20px)' : 'translateX(0px)';
  226. toggleBg.style.backgroundColor = isDark ? '#6366F1' : '#ccc';
  227. themeLabel.textContent = isDark ? 'Dark Mode' : 'Light Mode';
  228.  
  229. localStorage.setItem('lemonchat-dark-theme', isDark ? 'true' : 'false');
  230. }
  231.  
  232. checkbox.addEventListener('change', function() {
  233. toggleTheme(this.checked);
  234. });
  235.  
  236. themeLabel.addEventListener('click', function(e) {
  237. e.preventDefault();
  238. checkbox.checked = !checkbox.checked;
  239. toggleTheme(checkbox.checked);
  240. });
  241.  
  242. toggleContainer.addEventListener('click', function(e) {
  243. if (e.target !== checkbox) {
  244. e.preventDefault();
  245. checkbox.checked = !checkbox.checked;
  246. toggleTheme(checkbox.checked);
  247. }
  248. });
  249.  
  250. const savedTheme = localStorage.getItem('lemonchat-dark-theme');
  251. const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
  252. const defaultDark = savedTheme ? savedTheme === 'true' : prefersDark;
  253.  
  254. checkbox.checked = defaultDark;
  255. toggleTheme(defaultDark);
  256. })();