mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 22:45:41 +00:00
feat(themes): add follow-system mode to the theme scheduler (#1163)
* feat(themes): add follow-system mode to the theme scheduler The theme scheduler can now switch the day/night theme pair by the OS light/dark preference instead of a clock schedule. A segmented control picks the trigger; in system mode the time inputs are hidden and the two theme pickers read as Light/Dark. The OS theme is read via the native Tauri window theme API (theme() + onThemeChanged) rather than the Web prefers-color-scheme media query, which is unreliable through WebKitGTK on Linux. Live updates land instantly where the platform forwards them; on Linux setups that don't, a hint notes the change applies after an app restart. * docs(changelog): add follow-system theme mode entry (#1163) CHANGELOG Added entry, contributor credit and What's New highlight for the theme scheduler's new system-theme mode.
This commit is contained in:
@@ -92,31 +92,66 @@ export function ThemesTab() {
|
||||
const dayM = theme.timeDayStart.split(':')[1];
|
||||
const nightH = theme.timeNightStart.split(':')[0];
|
||||
const nightM = theme.timeNightStart.split(':')[1];
|
||||
const isSystem = theme.schedulerMode === 'system';
|
||||
return (
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(160px, 1fr))', gap: '1rem', marginTop: '1rem' }}>
|
||||
<div className="form-group">
|
||||
<label className="settings-label" style={{ marginBottom: 6 }}>{t('settings.themeSchedulerDayTheme')}</label>
|
||||
<CustomSelect value={theme.themeDay} onChange={theme.setThemeDay} options={themeOptions} />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="settings-label" style={{ marginBottom: 6 }}>{t('settings.themeSchedulerDayStart')}</label>
|
||||
<div style={{ display: 'flex', gap: '6px', alignItems: 'center' }}>
|
||||
<CustomSelect value={dayH} onChange={v => theme.setTimeDayStart(`${v}:${dayM}`)} options={hourOptions} />
|
||||
<span style={{ color: 'var(--text-muted)', fontWeight: 600 }}>:</span>
|
||||
<CustomSelect value={dayM} onChange={v => theme.setTimeDayStart(`${dayH}:${v}`)} options={minuteOptions} />
|
||||
<div style={{ marginTop: '1rem' }}>
|
||||
<div className="form-group" style={{ marginBottom: '1rem' }}>
|
||||
<label className="settings-label" style={{ marginBottom: 6 }}>{t('settings.themeSchedulerModeLabel')}</label>
|
||||
<div className="settings-segmented">
|
||||
<button
|
||||
type="button"
|
||||
className={`btn ${!isSystem ? 'btn-primary' : 'btn-ghost'}`}
|
||||
onClick={() => theme.setSchedulerMode('time')}
|
||||
>
|
||||
{t('settings.themeSchedulerModeTime')}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={`btn ${isSystem ? 'btn-primary' : 'btn-ghost'}`}
|
||||
onClick={() => theme.setSchedulerMode('system')}
|
||||
>
|
||||
{t('settings.themeSchedulerModeSystem')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="settings-label" style={{ marginBottom: 6 }}>{t('settings.themeSchedulerNightTheme')}</label>
|
||||
<CustomSelect value={theme.themeNight} onChange={theme.setThemeNight} options={themeOptions} />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="settings-label" style={{ marginBottom: 6 }}>{t('settings.themeSchedulerNightStart')}</label>
|
||||
<div style={{ display: 'flex', gap: '6px', alignItems: 'center' }}>
|
||||
<CustomSelect value={nightH} onChange={v => theme.setTimeNightStart(`${v}:${nightM}`)} options={hourOptions} />
|
||||
<span style={{ color: 'var(--text-muted)', fontWeight: 600 }}>:</span>
|
||||
<CustomSelect value={nightM} onChange={v => theme.setTimeNightStart(`${nightH}:${v}`)} options={minuteOptions} />
|
||||
{isSystem && (
|
||||
<div className="settings-hint settings-hint-info" style={{ marginBottom: '1rem' }}>
|
||||
{t('settings.themeSchedulerSystemRestartHint')}
|
||||
</div>
|
||||
)}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(160px, 1fr))', gap: '1rem' }}>
|
||||
<div className="form-group">
|
||||
<label className="settings-label" style={{ marginBottom: 6 }}>
|
||||
{isSystem ? t('settings.themeSchedulerLightTheme') : t('settings.themeSchedulerDayTheme')}
|
||||
</label>
|
||||
<CustomSelect value={theme.themeDay} onChange={theme.setThemeDay} options={themeOptions} />
|
||||
</div>
|
||||
{!isSystem && (
|
||||
<div className="form-group">
|
||||
<label className="settings-label" style={{ marginBottom: 6 }}>{t('settings.themeSchedulerDayStart')}</label>
|
||||
<div style={{ display: 'flex', gap: '6px', alignItems: 'center' }}>
|
||||
<CustomSelect value={dayH} onChange={v => theme.setTimeDayStart(`${v}:${dayM}`)} options={hourOptions} />
|
||||
<span style={{ color: 'var(--text-muted)', fontWeight: 600 }}>:</span>
|
||||
<CustomSelect value={dayM} onChange={v => theme.setTimeDayStart(`${dayH}:${v}`)} options={minuteOptions} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="form-group">
|
||||
<label className="settings-label" style={{ marginBottom: 6 }}>
|
||||
{isSystem ? t('settings.themeSchedulerDarkTheme') : t('settings.themeSchedulerNightTheme')}
|
||||
</label>
|
||||
<CustomSelect value={theme.themeNight} onChange={theme.setThemeNight} options={themeOptions} />
|
||||
</div>
|
||||
{!isSystem && (
|
||||
<div className="form-group">
|
||||
<label className="settings-label" style={{ marginBottom: 6 }}>{t('settings.themeSchedulerNightStart')}</label>
|
||||
<div style={{ display: 'flex', gap: '6px', alignItems: 'center' }}>
|
||||
<CustomSelect value={nightH} onChange={v => theme.setTimeNightStart(`${v}:${nightM}`)} options={hourOptions} />
|
||||
<span style={{ color: 'var(--text-muted)', fontWeight: 600 }}>:</span>
|
||||
<CustomSelect value={nightM} onChange={v => theme.setTimeNightStart(`${nightH}:${v}`)} options={minuteOptions} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user