diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js b/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js index 779baa42a..3ceda68d0 100644 --- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js +++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js @@ -2802,7 +2802,10 @@ export const hydrateCollectionWithUiStateSnapshot = (payload) => (dispatch, getS return new Promise((resolve, reject) => { const state = getState(); try { - if (!collectionSnapshotData) resolve(); + if (!collectionSnapshotData) { + resolve(); + return; + } const { pathname, selectedEnvironment } = collectionSnapshotData; const collection = findCollectionByPathname(state.collections.collections, pathname); const collectionCopy = cloneDeep(collection); diff --git a/packages/bruno-electron/src/app/collection-watcher.js b/packages/bruno-electron/src/app/collection-watcher.js index b2acdd942..f66dfb639 100644 --- a/packages/bruno-electron/src/app/collection-watcher.js +++ b/packages/bruno-electron/src/app/collection-watcher.js @@ -644,7 +644,7 @@ const onWatcherSetupComplete = (win, watchPath, collectionUid, watcher) => { const UiStateSnapshotStore = new UiStateSnapshot(); const collectionsSnapshotState = UiStateSnapshotStore.getCollections(); - const collectionSnapshotState = collectionsSnapshotState?.find((c) => c?.pathname == watchPath); + const collectionSnapshotState = collectionsSnapshotState?.find((c) => c?.pathname && path.normalize(c.pathname) === path.normalize(watchPath)); win.webContents.send('main:hydrate-app-with-ui-state-snapshot', collectionSnapshotState); }; diff --git a/packages/bruno-electron/src/app/onboarding.js b/packages/bruno-electron/src/app/onboarding.js index 7a20da1fb..c048a7550 100644 --- a/packages/bruno-electron/src/app/onboarding.js +++ b/packages/bruno-electron/src/app/onboarding.js @@ -69,8 +69,8 @@ async function importSampleCollection(collectionLocation, mainWindow) { * - Genuinely new users (no collections, no previous launch) → show welcome modal * - Existing users upgrading (have collections but no hasLaunchedBefore flag) → skip welcome modal * - * The 'main:onboarding-complete' event in finally unblocks the renderer:ready IPC handler, - * ensuring the renderer always gets the correct preference values. + * Called directly from the renderer:ready IPC handler in preferences.js to ensure + * preferences are set correctly before being sent to the renderer. */ async function onboardUser(mainWindow, lastOpenedCollections) { try { @@ -97,8 +97,7 @@ async function onboardUser(mainWindow, lastOpenedCollections) { const collectionInfo = await importSampleCollection(collectionLocation, mainWindow); // Store collection info to open after renderer is ready - // The main:collection-opened event is deferred because the renderer - // is still waiting for main:onboarding-complete at this point + // The main:collection-opened event is deferred until main:renderer-ready is emitted pendingSampleCollection = { mainWindow, ...collectionInfo }; } @@ -114,9 +113,6 @@ async function onboardUser(mainWindow, lastOpenedCollections) { console.error('Failed to handle onboarding:', error); // Still mark as launched to prevent retry on next startup await preferencesUtil.markAsLaunched(); - } finally { - // Always unblock the renderer:ready handler so the app can proceed - ipcMain.emit('main:onboarding-complete'); } } diff --git a/packages/bruno-electron/src/index.js b/packages/bruno-electron/src/index.js index ec33c3497..1c6495820 100644 --- a/packages/bruno-electron/src/index.js +++ b/packages/bruno-electron/src/index.js @@ -35,7 +35,6 @@ if (os.platform() === 'linux') { const menuTemplate = require('./app/menu-template'); const { openCollection } = require('./app/collections'); -const LastOpenedCollections = require('./store/last-opened-collections'); const registerNetworkIpc = require('./ipc/network'); const registerCollectionsIpc = require('./ipc/collection'); const registerFilesystemIpc = require('./ipc/filesystem'); @@ -57,12 +56,10 @@ const TerminalManager = require('./ipc/terminal'); const { safeParseJSON, safeStringifyJSON } = require('./utils/common'); const { getDomainsWithCookies } = require('./utils/cookies'); const { cookiesStore } = require('./store/cookies'); -const onboardUser = require('./app/onboarding'); const SystemMonitor = require('./app/system-monitor'); const { getIsRunningInRosetta } = require('./utils/arch'); const { handleAppProtocolUrl, getAppProtocolUrlFromArgv } = require('./utils/deeplink'); -const lastOpenedCollections = new LastOpenedCollections(); const systemMonitor = new SystemMonitor(); const terminalManager = new TerminalManager(); @@ -426,13 +423,8 @@ app.on('ready', async () => { }; } catch (err) { console.error('Error wrapping webContents.send:', err); - // Ensure onboarding gate is unblocked so renderer:ready doesn't hang - ipcMain.emit('main:onboarding-complete'); } - // Handle onboarding - await onboardUser(mainWindow, lastOpenedCollections); - // Send cookies list after renderer is ready try { cookiesStore.initializeCookies(); diff --git a/packages/bruno-electron/src/ipc/preferences.js b/packages/bruno-electron/src/ipc/preferences.js index 249908e95..6aea6aa0a 100644 --- a/packages/bruno-electron/src/ipc/preferences.js +++ b/packages/bruno-electron/src/ipc/preferences.js @@ -5,13 +5,16 @@ const { globalEnvironmentsStore } = require('../store/global-environments'); const { parsedFileCacheStore } = require('../store/parsed-file-cache-idb'); const { getCachedSystemProxy, fetchSystemProxy } = require('../store/system-proxy'); const { resolveDefaultLocation } = require('../utils/default-location'); +const onboardUser = require('../app/onboarding'); +const LastOpenedCollections = require('../store/last-opened-collections'); const registerPreferencesIpc = (mainWindow) => { + const lastOpenedCollections = new LastOpenedCollections(); + + const onboardingPromise = onboardUser(mainWindow, lastOpenedCollections); + ipcMain.handle('renderer:ready', async (event) => { - // Wait for onboarding to finish before reading preferences. - // Onboarding may set hasSeenWelcomeModal for new vs existing users, - // and we need the renderer to receive the correct values. - await new Promise((resolve) => ipcMain.once('main:onboarding-complete', resolve)); + await onboardingPromise; // load preferences const preferences = getPreferences();