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('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)}`; }); }