1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-01-11 18:24:43 +02:00

Desktop: Resolves #2665: Add support for system theme auto-switching

This commit is contained in:
Laurent Cozic 2020-05-21 00:47:38 +01:00
parent 3830f36c0b
commit 49451dba20
3 changed files with 93 additions and 16 deletions

View File

@ -59,6 +59,8 @@ class Application extends BaseApplication {
constructor() { constructor() {
super(); super();
this.lastMenuScreen_ = null; this.lastMenuScreen_ = null;
this.bridge_nativeThemeUpdated = this.bridge_nativeThemeUpdated.bind(this);
} }
hasGui() { hasGui() {
@ -311,11 +313,25 @@ class Application extends BaseApplication {
await Folder.expandTree(newState.folders, action.folderId); await Folder.expandTree(newState.folders, action.folderId);
} }
if (this.hasGui() && ((action.type == 'SETTING_UPDATE_ONE' && ['themeAutoDetect', 'theme', 'preferredLightTheme', 'preferredDarkTheme'].includes(action.key)) || action.type == 'SETTING_UPDATE_ALL')) {
this.handleThemeAutoDetect();
}
if (mustUpdateMenuItemStates) this.updateMenuItemStates(newState); if (mustUpdateMenuItemStates) this.updateMenuItemStates(newState);
return result; return result;
} }
handleThemeAutoDetect() {
if (!Setting.value('themeAutoDetect')) return;
if (bridge().shouldUseDarkColors()) {
Setting.setValue('theme', Setting.value('preferredDarkTheme'));
} else {
Setting.setValue('theme', Setting.value('preferredLightTheme'));
}
}
async refreshMenu() { async refreshMenu() {
const screen = this.lastMenuScreen_; const screen = this.lastMenuScreen_;
this.lastMenuScreen_ = null; this.lastMenuScreen_ = null;
@ -1263,6 +1279,10 @@ class Application extends BaseApplication {
menuItem.checked = state.devToolsVisible; menuItem.checked = state.devToolsVisible;
} }
bridge_nativeThemeUpdated() {
this.handleThemeAutoDetect();
}
updateTray() { updateTray() {
const app = bridge().electronApp(); const app = bridge().electronApp();
@ -1489,6 +1509,8 @@ class Application extends BaseApplication {
window.revisionService = RevisionService.instance(); window.revisionService = RevisionService.instance();
window.migrationService = MigrationService.instance(); window.migrationService = MigrationService.instance();
window.decryptionWorker = DecryptionWorker.instance(); window.decryptionWorker = DecryptionWorker.instance();
bridge().addEventListener('nativeThemeUpdated', this.bridge_nativeThemeUpdated);
} }
} }

View File

@ -1,6 +1,6 @@
const { _, setLocale } = require('lib/locale.js'); const { _, setLocale } = require('lib/locale.js');
const { dirname } = require('lib/path-utils.js'); const { dirname } = require('lib/path-utils.js');
const { BrowserWindow } = require('electron'); const { BrowserWindow, nativeTheme } = require('electron');
class Bridge { class Bridge {
@ -170,6 +170,18 @@ class Bridge {
return require('electron').screen; return require('electron').screen;
} }
shouldUseDarkColors() {
return nativeTheme.shouldUseDarkColors;
}
addEventListener(name, fn) {
if (name === 'nativeThemeUpdated') {
nativeTheme.on('updated', fn);
} else {
throw new Error(`Unsupported event: ${name}`);
}
}
} }
let bridge_ = null; let bridge_ = null;

View File

@ -37,6 +37,21 @@ class Setting extends BaseModel {
// if if private a setting might still be handled and modified by the app. For instance, the settings related to sorting notes are not // if if private a setting might still be handled and modified by the app. For instance, the settings related to sorting notes are not
// public for the mobile and desktop apps because they are handled separately in menus. // public for the mobile and desktop apps because they are handled separately in menus.
const themeOptions = () => {
const output = {};
output[Setting.THEME_LIGHT] = _('Light');
output[Setting.THEME_DARK] = _('Dark');
if (platform !== mobilePlatform) {
output[Setting.THEME_DRACULA] = _('Dracula');
output[Setting.THEME_SOLARIZED_LIGHT] = _('Solarised Light');
output[Setting.THEME_SOLARIZED_DARK] = _('Solarised Dark');
output[Setting.THEME_NORD] = _('Nord');
} else {
output[Setting.THEME_OLED_DARK] = _('OLED Dark');
}
return output;
};
this.metadata_ = { this.metadata_ = {
'clientId': { 'clientId': {
value: '', value: '',
@ -228,30 +243,58 @@ class Setting extends BaseModel {
return options; return options;
}, },
}, },
theme: { theme: {
value: Setting.THEME_LIGHT, value: Setting.THEME_LIGHT,
type: Setting.TYPE_INT, type: Setting.TYPE_INT,
public: true, public: true,
appTypes: ['mobile', 'desktop'], appTypes: ['mobile', 'desktop'],
show: (settings) => {
return !settings['themeAutoDetect'];
},
isEnum: true, isEnum: true,
label: () => _('Theme'), label: () => _('Theme'),
section: 'appearance', section: 'appearance',
options: () => { options: () => themeOptions(),
const output = {};
output[Setting.THEME_LIGHT] = _('Light');
output[Setting.THEME_DARK] = _('Dark');
if (platform !== mobilePlatform) {
output[Setting.THEME_DRACULA] = _('Dracula');
output[Setting.THEME_SOLARIZED_LIGHT] = _('Solarised Light');
output[Setting.THEME_SOLARIZED_DARK] = _('Solarised Dark');
output[Setting.THEME_NORD] = _('Nord');
output[Setting.THEME_ARITIM_DARK] = _('Aritim Dark');
} else {
output[Setting.THEME_OLED_DARK] = _('OLED Dark');
}
return output;
},
}, },
themeAutoDetect: {
value: false,
type: Setting.TYPE_BOOL,
section: 'appearance',
appTypes: ['desktop'],
public: true,
label: () => _('Automatically switch theme to match system theme'),
},
preferredLightTheme: {
value: Setting.THEME_LIGHT,
type: Setting.TYPE_INT,
public: true,
show: (settings) => {
return settings['themeAutoDetect'];
},
appTypes: ['desktop'],
isEnum: true,
label: () => _('Preferred light theme'),
section: 'appearance',
options: () => themeOptions(),
},
preferredDarkTheme: {
value: Setting.THEME_DARK,
type: Setting.TYPE_INT,
public: true,
show: (settings) => {
return settings['themeAutoDetect'];
},
appTypes: ['desktop'],
isEnum: true,
label: () => _('Preferred dark theme'),
section: 'appearance',
options: () => themeOptions(),
},
showNoteCounts: { value: true, type: Setting.TYPE_BOOL, public: true, advanced: true, appTypes: ['desktop'], label: () => _('Show note counts') }, showNoteCounts: { value: true, type: Setting.TYPE_BOOL, public: true, advanced: true, appTypes: ['desktop'], label: () => _('Show note counts') },
layoutButtonSequence: { layoutButtonSequence: {
value: Setting.LAYOUT_ALL, value: Setting.LAYOUT_ALL,