Skip to content

Commit 2968a2e

Browse files
committed
feat(discourse-topic-quick-switcher): Added dark mode toggle in settings (v0.4.3)
1 parent 5928210 commit 2968a2e

3 files changed

Lines changed: 149 additions & 45 deletions

File tree

discourse-topic-quick-switcher/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ This script is designed for all Discourse forums and has been tested on the foll
120120
- Improved dark mode settings dialog styling and contrast
121121
- Optimized site-specific key generation for better performance (pre-initialized at script load)
122122
- Settings are now site-specific (each website maintains its own settings independently)
123+
- Added dark mode toggle in settings with three options: Auto (default), Light, and Dark
124+
- Enhanced save button styling with prominent primary button design and smooth animations
123125

124126
### v0.3.x
125127

discourse-topic-quick-switcher/README.zh-CN.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ const CONFIG = {
119119
- 改进深色模式设置对话框样式和对比度
120120
- 优化站点特定键生成以提升性能(在脚本加载时预初始化)
121121
- 设置改为按网站生效(每个网站独立维护自己的设置)
122+
- 在设置中添加深色模式切换功能,提供三种选择:自动(默认)、浅色和深色
123+
- 增强保存按钮样式,采用突出的主要按钮设计和流畅动画效果
122124

123125
### v0.3.x
124126

discourse-topic-quick-switcher/discourse-topic-quick-switcher.user.js

Lines changed: 145 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// @namespace https://github.com/utags
55
// @homepageURL https://github.com/utags/userscripts#readme
66
// @supportURL https://github.com/utags/userscripts/issues
7-
// @version 0.4.2
7+
// @version 0.4.3
88
// @description Enhance Discourse forums with instant topic switching, current topic highlighting, and quick navigation to previous/next topics
99
// @description:zh-CN 增强 Discourse 论坛体验,提供即时话题切换、当前话题高亮和上一个/下一个话题的快速导航功能
1010
// @author Pipecraft
@@ -53,6 +53,7 @@
5353
let userSettings = {
5454
language: CONFIG.DEFAULT_LANGUAGE,
5555
showNavigationButtons: true,
56+
darkMode: 'auto', // auto, light, dark
5657
}
5758

5859
// Pre-initialized site-specific keys (calculated once at script load)
@@ -89,6 +90,10 @@
8990
save: 'Save',
9091
cancel: 'Cancel',
9192
showNavigationButtons: 'Show navigation buttons',
93+
darkMode: 'Dark Mode',
94+
darkModeAuto: 'Auto',
95+
darkModeLight: 'Light',
96+
darkModeDark: 'Dark',
9297
},
9398
'zh-CN': {
9499
viewTopicList: '查看话题列表(按 ` 键)',
@@ -117,6 +122,10 @@
117122
save: '保存',
118123
cancel: '取消',
119124
showNavigationButtons: '显示导航按钮',
125+
darkMode: '深色模式',
126+
darkModeAuto: '自动',
127+
darkModeLight: '浅色',
128+
darkModeDark: '深色',
120129
},
121130
}
122131

@@ -197,6 +206,15 @@
197206
</select>
198207
</div>
199208
209+
<div class="dtqs-setting-item">
210+
<label for="dtqs-dark-mode-select">${t('darkMode')}</label>
211+
<select id="dtqs-dark-mode-select">
212+
<option value="auto" ${userSettings.darkMode === 'auto' ? 'selected' : ''}>${t('darkModeAuto')}</option>
213+
<option value="light" ${userSettings.darkMode === 'light' ? 'selected' : ''}>${t('darkModeLight')}</option>
214+
<option value="dark" ${userSettings.darkMode === 'dark' ? 'selected' : ''}>${t('darkModeDark')}</option>
215+
</select>
216+
</div>
217+
200218
<div class="dtqs-setting-item checkbox-item">
201219
<label for="dtqs-show-nav-buttons">
202220
<input type="checkbox" id="dtqs-show-nav-buttons" ${userSettings.showNavigationButtons ? 'checked' : ''}>
@@ -225,6 +243,10 @@
225243
const languageSelect = document.getElementById('dtqs-language-select')
226244
userSettings.language = languageSelect.value
227245

246+
// Save dark mode setting
247+
const darkModeSelect = document.getElementById('dtqs-dark-mode-select')
248+
userSettings.darkMode = darkModeSelect.value
249+
228250
// Save navigation buttons setting
229251
const showNavButtons = document.getElementById('dtqs-show-nav-buttons')
230252
userSettings.showNavigationButtons = showNavButtons.checked
@@ -235,6 +257,9 @@
235257
// Update language
236258
currentLanguage = userSettings.language
237259

260+
// Update dark mode
261+
detectDarkMode()
262+
238263
// Close dialog
239264
closeSettingsDialog()
240265

@@ -337,74 +362,101 @@
337362
}
338363

339364
/**
340-
* Detect dark mode
365+
* Detect dark mode based on user settings
341366
*/
342367
function detectDarkMode() {
343-
// Check system dark mode
344-
if (CONFIG.AUTO_DARK_MODE && window.matchMedia) {
345-
// Check system preference
346-
const systemDarkMode = window.matchMedia(
347-
'(prefers-color-scheme: dark)'
348-
).matches
368+
let shouldUseDarkMode = false
369+
370+
// Check user's dark mode preference
371+
switch (userSettings.darkMode) {
372+
case 'dark':
373+
// Force dark mode
374+
shouldUseDarkMode = true
375+
console.log('[DTQS] Dark mode: Force enabled by user setting')
376+
break
349377

350-
// Check if the Discourse site is in dark mode
351-
const discourseBodyClass =
352-
document.body.classList.contains('dark-scheme') ||
353-
document.documentElement.classList.contains('dark-scheme') ||
354-
document.body.dataset.colorScheme === 'dark' ||
355-
document.documentElement.dataset.colorScheme === 'dark' ||
356-
document.documentElement.dataset.themeType === 'dark' ||
357-
// linux.do
358-
document.querySelector('header picture > source')?.media === 'all'
378+
case 'light':
379+
// Force light mode
380+
shouldUseDarkMode = false
381+
console.log('[DTQS] Dark mode: Force disabled by user setting')
382+
break
359383

360-
// Enable dark mode if the system or site uses it
361-
isDarkMode = systemDarkMode || discourseBodyClass
384+
case 'auto':
385+
default:
386+
// Auto mode - check system and site preferences
387+
if (window.matchMedia) {
388+
// Check system preference
389+
const systemDarkMode = window.matchMedia(
390+
'(prefers-color-scheme: dark)'
391+
).matches
392+
393+
// Check if the Discourse site is in dark mode
394+
const discourseBodyClass =
395+
document.body.classList.contains('dark-scheme') ||
396+
document.documentElement.classList.contains('dark-scheme') ||
397+
document.body.dataset.colorScheme === 'dark' ||
398+
document.documentElement.dataset.colorScheme === 'dark' ||
399+
document.documentElement.dataset.themeType === 'dark' ||
400+
// linux.do
401+
document.querySelector('header picture > source')?.media === 'all'
402+
403+
// Enable dark mode if the system or site uses it
404+
shouldUseDarkMode = systemDarkMode || discourseBodyClass
405+
406+
console.log(
407+
`[DTQS] Dark mode (auto): System: ${systemDarkMode}, Site: ${discourseBodyClass}, Final: ${shouldUseDarkMode}`
408+
)
409+
}
410+
break
411+
}
362412

363-
console.log(
364-
`[DTQS] Dark mode detection - System: ${systemDarkMode}, Site: ${discourseBodyClass}, Final: ${isDarkMode}`
365-
)
413+
// Update global dark mode state
414+
isDarkMode = shouldUseDarkMode
366415

367-
// Add or remove dark mode class
368-
if (isDarkMode) {
369-
document.body.classList.add('topic-list-viewer-dark-mode')
370-
} else {
371-
document.body.classList.remove('topic-list-viewer-dark-mode')
372-
}
416+
// Add or remove dark mode class
417+
if (isDarkMode) {
418+
document.body.classList.add('topic-list-viewer-dark-mode')
419+
} else {
420+
document.body.classList.remove('topic-list-viewer-dark-mode')
373421
}
374422
}
375423

376424
/**
377425
* Set up dark mode listener
378426
*/
379427
function setupDarkModeListener() {
380-
if (CONFIG.AUTO_DARK_MODE && window.matchMedia) {
428+
if (window.matchMedia) {
381429
// Listen for system dark mode changes
382430
const darkModeMediaQuery = window.matchMedia(
383431
'(prefers-color-scheme: dark)'
384432
)
385433

386-
// Add change listener
387-
if (darkModeMediaQuery.addEventListener) {
388-
darkModeMediaQuery.addEventListener('change', (e) => {
434+
// Add change listener (only trigger if user is in auto mode)
435+
const handleSystemChange = (e) => {
436+
if (userSettings.darkMode === 'auto') {
389437
detectDarkMode()
390-
})
438+
}
439+
}
440+
441+
if (darkModeMediaQuery.addEventListener) {
442+
darkModeMediaQuery.addEventListener('change', handleSystemChange)
391443
} else if (darkModeMediaQuery.addListener) {
392444
// Fallback for older browsers
393-
darkModeMediaQuery.addListener((e) => {
394-
detectDarkMode()
395-
})
445+
darkModeMediaQuery.addListener(handleSystemChange)
396446
}
397447

398-
// Listen for Discourse theme changes
448+
// Listen for Discourse theme changes (only trigger if user is in auto mode)
399449
const observer = new MutationObserver((mutations) => {
400-
mutations.forEach((mutation) => {
401-
if (
402-
mutation.attributeName === 'class' ||
403-
mutation.attributeName === 'data-color-scheme'
404-
) {
405-
detectDarkMode()
406-
}
407-
})
450+
if (userSettings.darkMode === 'auto') {
451+
mutations.forEach((mutation) => {
452+
if (
453+
mutation.attributeName === 'class' ||
454+
mutation.attributeName === 'data-color-scheme'
455+
) {
456+
detectDarkMode()
457+
}
458+
})
459+
}
408460
})
409461

410462
// Observe class changes on body and html elements
@@ -1630,12 +1682,37 @@
16301682
border: 1px solid #ccc;
16311683
background: #f5f5f5;
16321684
cursor: pointer;
1685+
font-weight: 500;
1686+
transition: all 0.2s ease;
16331687
}
16341688
16351689
.dtqs-buttons button:hover {
16361690
background: #e5e5e5;
16371691
}
16381692
1693+
/* Primary save button styling */
1694+
.dtqs-buttons #dtqs-settings-save {
1695+
background: #007bff;
1696+
border-color: #007bff;
1697+
color: white;
1698+
font-weight: 600;
1699+
box-shadow: 0 2px 4px rgba(0, 123, 255, 0.2);
1700+
}
1701+
1702+
.dtqs-buttons #dtqs-settings-save:hover {
1703+
background: #0056b3;
1704+
border-color: #0056b3;
1705+
box-shadow: 0 3px 6px rgba(0, 123, 255, 0.3);
1706+
transform: translateY(-1px);
1707+
}
1708+
1709+
.dtqs-buttons #dtqs-settings-save:active {
1710+
background: #004085;
1711+
border-color: #004085;
1712+
transform: translateY(0);
1713+
box-shadow: 0 1px 2px rgba(0, 123, 255, 0.2);
1714+
}
1715+
16391716
/* Settings Dialog Dark Mode Styles */
16401717
.topic-list-viewer-dark-mode #dtqs-settings-overlay {
16411718
background: rgba(0, 0, 0, 0.7);
@@ -1687,6 +1764,29 @@
16871764
background: #2a2a2a;
16881765
}
16891766
1767+
/* Primary save button styling for dark mode */
1768+
.topic-list-viewer-dark-mode .dtqs-buttons #dtqs-settings-save {
1769+
background: #1976d2;
1770+
border-color: #1976d2;
1771+
color: white;
1772+
font-weight: 600;
1773+
box-shadow: 0 2px 4px rgba(25, 118, 210, 0.3);
1774+
}
1775+
1776+
.topic-list-viewer-dark-mode .dtqs-buttons #dtqs-settings-save:hover {
1777+
background: #1565c0;
1778+
border-color: #1565c0;
1779+
box-shadow: 0 3px 6px rgba(25, 118, 210, 0.4);
1780+
transform: translateY(-1px);
1781+
}
1782+
1783+
.topic-list-viewer-dark-mode .dtqs-buttons #dtqs-settings-save:active {
1784+
background: #0d47a1;
1785+
border-color: #0d47a1;
1786+
transform: translateY(0);
1787+
box-shadow: 0 1px 2px rgba(25, 118, 210, 0.3);
1788+
}
1789+
16901790
.topic-nav-container {
16911791
display: grid;
16921792
grid-template-columns: 1fr auto 1fr;

0 commit comments

Comments
 (0)