From 8392e33f5b6c0ac79f0307acd7f065bf0bdbd5c0 Mon Sep 17 00:00:00 2001 From: Amit Haridas Date: Mon, 14 Sep 2026 19:49:07 +0530 Subject: [PATCH] =?UTF-8?q?refactor(main):=20drive=20View=20=E2=86=92=20Th?= =?UTF-8?q?eme=20submenu=20from=20ThemeRegistry?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wires the three registry-layer modules into src/main.js: - Require ThemeRegistry + buildThemeMenu + the bootstrap side-effect module at the top of the file so the registry is populated before the menu is built. - Replace the 109-line hardcoded View → Theme submenu block with a buildThemeMenu({ setTheme, getCurrentThemeId }) call — themes are now driven entirely from ThemeRegistry.list() / categories(). - Harden setTheme() to validate the incoming id against the registry and fall back to 'atomonelight' if the stored id no longer exists (e.g. after a downgrade or theme rename), with a console.warn so the fallback is observable. Pure wiring — no new behaviour, no unrelated edits. All 79 test suites / 931 tests remain green; lint and prettier checks clean. Amit Haridas --- src/main.js | 124 +++++++--------------------------------------------- 1 file changed, 15 insertions(+), 109 deletions(-) diff --git a/src/main.js b/src/main.js index d76a2f8..f99ae60 100644 --- a/src/main.js +++ b/src/main.js @@ -18,6 +18,9 @@ const ExportCss = require('./main/ExportCss'); const ExportPresets = require('./main/ExportPresets'); const EpubFontEmbedder = require('./main/EpubFontEmbedder'); const DocxFontEmbedder = require('./main/DocxFontEmbedder'); +const ThemeRegistry = require('./main/ThemeRegistry'); +const { buildThemeMenu } = require('./main/themeMenuBuilder'); +require('./main/ThemeRegistry.bootstrap'); // Add MiKTeX to PATH for LaTeX support if (process.platform === 'win32') { @@ -1135,113 +1138,10 @@ function createMenu() { }, { label: 'Theme', - submenu: [ - // Light Themes (grouped first) - { - label: 'Atom One Light (Default)', - click: () => setTheme('atomonelight'), - }, - { - label: 'GitHub Light', - click: () => setTheme('github'), - }, - { - label: 'Light', - click: () => setTheme('light'), - }, - { - label: 'Solarized Light', - click: () => setTheme('solarized'), - }, - { - label: 'Gruvbox Light', - click: () => setTheme('gruvbox-light'), - }, - { - label: 'Ayu Light', - click: () => setTheme('ayu-light'), - }, - { - label: 'Sepia', - click: () => setTheme('sepia'), - }, - { - label: 'Paper', - click: () => setTheme('paper'), - }, - { - label: 'Rose Pine Dawn', - click: () => setTheme('rosepine-dawn'), - }, - { - label: 'Concrete Light', - click: () => setTheme('concrete-light'), - }, - { - type: 'separator', - }, - // Dark Themes - { - label: 'Dark', - click: () => setTheme('dark'), - }, - { - label: 'One Dark', - click: () => setTheme('onedark'), - }, - { - label: 'Dracula', - click: () => setTheme('dracula'), - }, - { - label: 'Nord', - click: () => setTheme('nord'), - }, - { - label: 'Monokai', - click: () => setTheme('monokai'), - }, - { - label: 'Material', - click: () => setTheme('material'), - }, - { - label: 'Gruvbox Dark', - click: () => setTheme('gruvbox-dark'), - }, - { - label: 'Tokyo Night', - click: () => setTheme('tokyonight'), - }, - { - label: 'Palenight', - click: () => setTheme('palenight'), - }, - { - label: 'Ayu Dark', - click: () => setTheme('ayu-dark'), - }, - { - label: 'Ayu Mirage', - click: () => setTheme('ayu-mirage'), - }, - { - label: 'Oceanic Next', - click: () => setTheme('oceanic-next'), - }, - { - label: 'Cobalt2', - click: () => setTheme('cobalt2'), - }, - { - label: 'Concrete Dark', - click: () => setTheme('concrete-dark'), - }, - { - label: 'Concrete Warm', - click: () => setTheme('concrete-warm'), - }, - ], + submenu: buildThemeMenu({ + setTheme: (id) => setTheme(id), + getCurrentThemeId: () => store.get('theme', 'atomonelight'), + }), }, { type: 'separator', @@ -3950,8 +3850,14 @@ async function importWithMarkItDown() { } function setTheme(theme) { - store.set('theme', theme); - mainWindow.webContents.send('theme-changed', theme); + // Stored id may not exist anymore (e.g. after downgrade or if a theme id + // was renamed). Fall back to the default so the UI never goes blank. + const safeId = ThemeRegistry.get(theme) ? theme : 'atomonelight'; + if (safeId !== theme) { + console.warn(`[theme] unknown theme id "${theme}", falling back to ${safeId}`); + } + store.set('theme', safeId); + mainWindow.webContents.send('theme-changed', safeId); } // IPC handlers