I am attempting to build a program using Electron, React.js, and Material UI. I can get the app to open, and the screen to show as intended. However, when I attempt to use ipcRender in a render component the entire screen goes blank. I can verify that this is the line of code that causes issues because simply commenting it out will bring everything back. I require this feature to make a custom app bar.
I have tried removing window.
from the require statement in the render function, but that stops react and throws an error. I have also tried setting nodeIntegration: true
however this makes no change.
This is the main file.
// Modules to control application life and create native browser window
const {app, BrowserWindow, Tray, nativeImage, ipcMain} = require('electron')
const path = require('path')
const Store = require('electron-store')
let tray, window
function createWindow () {
// Create the browser window.
window = new BrowserWindow({
width: 800,
height: 600,
show: true,
frame: true,
title: 'Nozdive Program',
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: false
}
})
window.on('closed', () => window = null)
// and load the index.html of the app.
window.loadURL('http://localhost:3000')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
}
const createTray = () => {
const icon = path.join(__dirname, 'assets/nozdive.png')
const nImage= nativeImage.createFromPath(icon)
tray = new Tray(nImage)
tray.on('click', (event) => toggleWindow())
}
const toggleWindow = () => {
window.isVisible() ? window.hide() : window.show()
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
ipcMain.on('minimize-event', () => window.minimize())
createTray()
createWindow()
app.on('activate', function () {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
const store = new Store()
Here is the render function.
import React, {useState} from 'react'
import { Box, Typography } from '@mui/material'
import MenuIcon from '@mui/icons-material/Menu';
import CloseIcon from '@mui/icons-material/Close';
import FullscreenIcon from '@mui/icons-material/Fullscreen';
import MinimizeIcon from '@mui/icons-material/Minimize';
// import FullscreenExitIcon from '@mui/icons-material/FullscreenExit';
import colors from '../config/colors';
const {ipcRenderer} = window.require('electron')
export default function TitleBar({toggleDrawer}) {
const [isActive, setIsActive] = useState()
const [isminimized, setIsminimized] = useState()
const [isFullScreen, setIsFullScreen] = useState(false)
const handleMinimize = () => {
toggleDrawer()
// ipcRenderer.invoke('minimize-event')
}
const toggleIsFullScreen = () => {
const state = isFullScreen
setIsFullScreen(!state)
}
const handleClose = () => {
toggleDrawer()
}
return (
<Box sx={styles.headerBox}>
<MenuIcon
sx={styles.headerFont}
onClick={toggleDrawer}
/>
<Box sx={styles.textbox}>
<Typography sx={styles.headerFont}>Nozdive's Program!</Typography>
</Box>
<Box sx={styles.windowControl}>
<MinimizeIcon
sx={styles.headerFont}
onClick={handleMinimize}
/>
<FullscreenIcon
sx={styles.headerFont}
onClick={toggleIsFullScreen}
/>
<CloseIcon
sx={styles.headerFont}
onClick={handleClose}
/>
</Box>
</Box>
)
}
const styles = {
headerBox: {
alignItems: 'center',
backgroundColor: colors.secondary,
display: 'flex',
height: 30,
width: '100vw',
},
headerFont: {
color: colors.tertiary,
fontSize: 30,
padding: 1,
},
textbox: {
display: 'flex',
width: '100vw',
alignItems: 'center',
justifyContent: 'center',
},
windowControl: {
display: 'flex',
justifyContent: 'center',
},
}
You should add the code below in preload.js
const { ipcRenderer } = require("electron");
process.once("loaded", () => {
window.ipcRenderer = ipcRenderer;
});