Add first-run setup and theme synchronization

Introduce first-run setup flow and live chrome theme syncing.

- Add first_run_state.cpp/.h to read/write a first_run_state.json under user data and decide whether to show the setup UI.
- Wire first-run logic into NebulaController: track first_run_setup_active_, create initial setup tab, defer/bring up chrome browser accordingly, and add CompleteFirstRunSetup() to persist state and finish setup.
- Add SendThemeToChromeSurfaces() and handle "theme-update" and "complete-first-run" chrome commands; restrict setup completion to setup frame.
- Expose GetFirstRunStatePath() and GetSetupUrl() in UI path helpers and include the state file in the build list (CMakeLists.txt).
- Update chrome UI: new CSS variables and styles for tabs/url-bar; chrome.js can apply themes (applyTheme), persist/load theme, and listen for storage updates to apply theme changes live.
- Update customization.js, settings.js, and setup.js to normalize/persist themes, send theme updates to the native host (or fallback), and communicate completion via the native bridge when available; include customization.js in setup.html.

These changes allow the app to run an interactive first-run setup and keep the separate chrome UI in sync with user-selected themes.
This commit is contained in:
Andrew Zambazos
2026-05-20 20:14:43 +12:00
parent bbba5b2927
commit 302753cd3d
14 changed files with 416 additions and 59 deletions
+12 -4
View File
@@ -4,7 +4,7 @@
*/
class BrowserCustomizer {
constructor() {
constructor(options = {}) {
this.defaultTheme = {
name: 'Default',
colors: {
@@ -286,6 +286,10 @@ class BrowserCustomizer {
}
};
if (options.skipInit) {
return;
}
this.currentTheme = this.loadTheme();
this.activeThemeName = this.loadActiveThemeName();
this.init();
@@ -584,9 +588,13 @@ class BrowserCustomizer {
// This will be called to apply theme to home.html and other pages
this.saveTheme();
// Send theme update to host (for settings webview)
if (window.electronAPI && typeof window.electronAPI.sendToHost === 'function') {
window.electronAPI.sendToHost('theme-update', this.currentTheme);
const themePayload = JSON.stringify(this.currentTheme);
// Send theme update to host so the separate chrome browser can update live.
if (window.nebulaNative && typeof window.nebulaNative.postMessage === 'function') {
window.nebulaNative.postMessage('theme-update', themePayload);
} else if (window.electronAPI && typeof window.electronAPI.sendToHost === 'function') {
window.electronAPI.sendToHost('theme-update', themePayload);
}
// Fallback: send via postMessage (for iframe embedding)
try {