Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,15 @@ const installExtensions = async () => {
const forceDownload = !!process.env.UPGRADE_EXTENSIONS
const extensions = ['REACT_DEVELOPER_TOOLS']

return installer
.default(
try {
return await installer.default(
extensions.map((name) => installer[name as keyof typeof Installer]),
forceDownload,
)
.catch((err: unknown) => logger.error(getErrorMessage(err)))
} catch (error) {
logger.warn(`Skipping development extension installation: ${getErrorMessage(error)}`)
return []
}
}

const createMainWindow = async () => {
Expand Down
52 changes: 39 additions & 13 deletions src/main/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,24 @@ interface DarwinMenuItemConstructorOptions extends MenuItemConstructorOptions {
export default class MenuBuilder {
private mainWindow: BrowserWindow
private projectService: ProjectService
private readonly handleDevelopmentContextMenu = (
_: Electron.Event,
props: Electron.ContextMenuParams,
): void => {
if (!this.hasLiveWindow()) return

const { x, y } = props

Menu.buildFromTemplate([
{
label: 'Inspect element',
click: () => {
if (!this.hasLiveWindow()) return
this.mainWindow.webContents.inspectElement(x, y)
},
},
]).popup({ window: this.mainWindow })
}

developOptions: MenuItemConstructorOptions[] = [
{ type: 'separator' },
Expand All @@ -32,7 +50,19 @@ export default class MenuBuilder {
this.projectService = new ProjectService(mainWindow)
}

private hasLiveWindow(): boolean {
return !this.mainWindow.isDestroyed()
}

private getFallbackMenu(): Menu {
return Menu.getApplicationMenu() ?? Menu.buildFromTemplate([])
}

async buildMenu(): Promise<Menu> {
if (!this.hasLiveWindow()) {
return this.getFallbackMenu()
}

if (process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true') {
this.setupDevelopmentEnvironment()
}
Expand Down Expand Up @@ -129,26 +159,22 @@ export default class MenuBuilder {
*/

setupDevelopmentEnvironment(): void {
this.mainWindow.webContents.on('context-menu', (_, props) => {
const { x, y } = props
if (!this.hasLiveWindow()) return

Menu.buildFromTemplate([
{
label: 'Inspect element',
click: () => {
this.mainWindow.webContents.inspectElement(x, y)
},
},
]).popup({ window: this.mainWindow })
})
this.mainWindow.webContents.removeListener('context-menu', this.handleDevelopmentContextMenu)
this.mainWindow.webContents.on('context-menu', this.handleDevelopmentContextMenu)
}

updateAppTheme() {
const newTheme = nativeTheme.shouldUseDarkColors ? 'light' : 'dark'
nativeTheme.themeSource = newTheme
store.set('theme', newTheme)
this.mainWindow.webContents.send('system:update-theme')
void this.buildMenu()
if (this.hasLiveWindow()) {
this.mainWindow.webContents.send('system:update-theme')
}
void this.buildMenu().catch((error) => {
console.error('Error rebuilding application menu:', error)
})
}

/**
Expand Down
6 changes: 5 additions & 1 deletion src/main/modules/ipc/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,11 @@ class MainProcessBridge implements MainIpcModule {
this.simulatorModule.stop()
this.mainWindow?.webContents.reload()
}
handleWindowRebuildMenu = () => void this.menuBuilder.buildMenu()
handleWindowRebuildMenu = () => {
void this.menuBuilder.buildMenu().catch((error) => {
console.error('Error rebuilding application menu:', error)
})
}

// Hardware handlers
handleHardwareGetAvailableCommunicationPorts = async () => this.hardwareModule.getAvailableSerialPorts()
Expand Down