46 lines
2.2 KiB
TypeScript
46 lines
2.2 KiB
TypeScript
import { invoke, isTauri } from '@tauri-apps/api/core';
|
|
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
|
|
type Theme = 'system' | 'dark' | 'light';
|
|
export function installTheme() {
|
|
const media = window.matchMedia('(prefers-color-scheme: dark)');
|
|
const select = document.getElementById('theme-select') as HTMLSelectElement;
|
|
let preference: Theme = 'system';
|
|
let changed = false;
|
|
let saves = Promise.resolve();
|
|
for (const mode of ['dark', 'light'] as const) {
|
|
monaco.editor.defineTheme(`cex-${mode}`, {
|
|
base: mode === 'dark' ? 'vs-dark' : 'vs', inherit: true, rules: [],
|
|
colors: mode === 'dark' ? {
|
|
'editor.background': '#171c23', 'editor.foreground': '#dce3eb',
|
|
'editorLineNumber.foreground': '#738195', 'editorLineNumber.activeForeground': '#a4dccb',
|
|
'editor.lineHighlightBackground': '#202832', 'editor.selectionBackground': '#31564e',
|
|
'editorCursor.foreground': '#83d8bd',
|
|
} : {
|
|
'editor.background': '#ffffff', 'editor.foreground': '#243347',
|
|
'editorLineNumber.foreground': '#788496', 'editorLineNumber.activeForeground': '#176e59',
|
|
'editor.lineHighlightBackground': '#f2f6f8', 'editor.selectionBackground': '#c9e6dc',
|
|
'editorCursor.foreground': '#176e59',
|
|
},
|
|
});
|
|
}
|
|
function apply() {
|
|
const mode = preference === 'system' ? (media.matches ? 'dark' : 'light') : preference;
|
|
document.documentElement.dataset.theme = mode;
|
|
select.value = preference;
|
|
monaco.editor.setTheme(`cex-${mode}`);
|
|
}
|
|
select.onchange = () => {
|
|
changed = true; preference = select.value as Theme; apply();
|
|
const theme = preference;
|
|
if (isTauri()) saves = saves.then(() => invoke('save_theme', { theme })).then(() => {
|
|
select.title = 'Color theme';
|
|
}).catch(error => { select.title = `Theme applied, but could not save preference: ${String(error)}`; });
|
|
};
|
|
media.addEventListener('change', () => { if (preference === 'system') apply(); });
|
|
apply();
|
|
if (isTauri()) void invoke<Theme>('load_theme').then(value => {
|
|
if (!changed && ['system', 'dark', 'light'].includes(value)) { preference = value; apply(); }
|
|
}).catch(error => { select.title = `Using system theme. Could not load preference: ${String(error)}`; });
|
|
}
|