2023-03-30 07:58:59 +02:00
|
|
|
const path = require('path');
|
|
|
|
|
2023-05-10 17:54:22 +02:00
|
|
|
const {dialog, app, BrowserWindow, Tray, Menu } = require('electron');
|
2023-03-30 07:58:59 +02:00
|
|
|
const isDev = require('electron-is-dev');
|
2023-04-01 15:36:37 +02:00
|
|
|
const { autoUpdater } = require('electron-updater');
|
2023-05-10 17:54:22 +02:00
|
|
|
let win = null;
|
|
|
|
const instanceLock = app.requestSingleInstanceLock();
|
2023-06-20 08:23:24 +02:00
|
|
|
const isMacOS = process.platform === 'darwin';
|
2023-03-30 07:58:59 +02:00
|
|
|
|
|
|
|
if (require('electron-squirrel-startup')) app.quit();
|
|
|
|
|
2023-04-14 09:29:13 +02:00
|
|
|
const PORT = isDev ? '5173' : '51735';
|
2023-06-20 08:23:24 +02:00
|
|
|
const ICON = 'icon-rounded.png';
|
|
|
|
const ICON_TEMPLATE = 'iconTemplate.png';
|
2023-04-14 09:29:13 +02:00
|
|
|
|
2023-03-30 07:58:59 +02:00
|
|
|
function createWindow() {
|
2023-04-01 15:36:37 +02:00
|
|
|
autoUpdater.checkForUpdatesAndNotify();
|
2023-03-30 07:58:59 +02:00
|
|
|
|
2023-05-10 17:54:22 +02:00
|
|
|
win = new BrowserWindow({
|
2023-05-09 15:15:26 +02:00
|
|
|
autoHideMenuBar: true,
|
2023-03-30 07:58:59 +02:00
|
|
|
show: false,
|
2023-06-20 08:23:24 +02:00
|
|
|
icon: assetPath(ICON),
|
2023-03-30 07:58:59 +02:00
|
|
|
});
|
2023-04-08 16:31:56 +02:00
|
|
|
|
|
|
|
createTray(win);
|
|
|
|
|
2023-03-30 07:58:59 +02:00
|
|
|
win.maximize();
|
|
|
|
win.show();
|
|
|
|
|
2023-04-14 09:29:13 +02:00
|
|
|
isDev || createServer();
|
|
|
|
|
|
|
|
win.loadURL(`http://localhost:${PORT}`);
|
2023-03-30 07:58:59 +02:00
|
|
|
|
|
|
|
if (isDev) {
|
|
|
|
win.webContents.openDevTools({ mode: 'detach' });
|
|
|
|
}
|
2023-04-08 16:31:56 +02:00
|
|
|
|
|
|
|
return win;
|
2023-03-30 07:58:59 +02:00
|
|
|
}
|
|
|
|
|
2023-06-20 08:23:24 +02:00
|
|
|
const assetPath = (asset) => {
|
|
|
|
return path.join(
|
|
|
|
__dirname,
|
|
|
|
isDev ? `../public/${asset}` : `../dist/${asset}`
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2023-04-08 16:31:56 +02:00
|
|
|
const createTray = (window) => {
|
|
|
|
const tray = new Tray(
|
2023-06-20 08:23:24 +02:00
|
|
|
assetPath(!isMacOS ? ICON : ICON_TEMPLATE)
|
2023-04-08 16:31:56 +02:00
|
|
|
);
|
|
|
|
const contextMenu = Menu.buildFromTemplate([
|
2023-04-23 09:56:58 +02:00
|
|
|
{
|
|
|
|
label: 'Show',
|
|
|
|
click: () => {
|
|
|
|
win.maximize();
|
|
|
|
window.show();
|
|
|
|
},
|
|
|
|
},
|
2023-04-08 16:31:56 +02:00
|
|
|
{
|
|
|
|
label: 'Exit',
|
|
|
|
click: () => {
|
|
|
|
app.isQuiting = true;
|
|
|
|
app.quit();
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
|
2023-04-23 09:56:58 +02:00
|
|
|
tray.on('click', () => {
|
|
|
|
win.maximize();
|
|
|
|
window.show();
|
|
|
|
});
|
2023-08-13 15:31:29 +02:00
|
|
|
tray.setToolTip('BetterChat');
|
2023-04-08 16:31:56 +02:00
|
|
|
tray.setContextMenu(contextMenu);
|
|
|
|
|
|
|
|
return tray;
|
|
|
|
};
|
|
|
|
|
2023-03-30 07:58:59 +02:00
|
|
|
app.on('window-all-closed', () => {
|
2023-06-20 08:23:24 +02:00
|
|
|
if (!isMacOS) {
|
2023-03-30 07:58:59 +02:00
|
|
|
app.quit();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2023-05-10 17:54:22 +02:00
|
|
|
process.on('uncaughtException', (error) => {
|
|
|
|
// Perform any necessary cleanup tasks here
|
|
|
|
dialog.showErrorBox('An error occurred', error.stack);
|
|
|
|
|
|
|
|
// Exit the app
|
|
|
|
process.exit(1);
|
2023-03-30 07:58:59 +02:00
|
|
|
});
|
2023-04-14 09:29:13 +02:00
|
|
|
|
2023-05-10 17:54:22 +02:00
|
|
|
if (!instanceLock) {
|
|
|
|
app.quit()
|
|
|
|
} else {
|
|
|
|
app.on('second-instance', (event, commandLine, workingDirectory) => {
|
|
|
|
if (win) {
|
|
|
|
if (win.isMinimized()) win.restore()
|
|
|
|
win.focus()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
app.whenReady().then(() => {
|
|
|
|
win = createWindow()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-04-14 09:29:13 +02:00
|
|
|
const createServer = () => {
|
|
|
|
// Dependencies
|
|
|
|
const http = require('http');
|
|
|
|
const fs = require('fs');
|
|
|
|
const path = require('path');
|
|
|
|
|
|
|
|
// MIME types for different file extensions
|
|
|
|
const mimeTypes = {
|
|
|
|
'.html': 'text/html',
|
|
|
|
'.css': 'text/css',
|
|
|
|
'.js': 'text/javascript',
|
|
|
|
'.wasm': 'application/wasm',
|
|
|
|
'.jpg': 'image/jpeg',
|
|
|
|
'.jpeg': 'image/jpeg',
|
|
|
|
'.png': 'image/png',
|
|
|
|
'.gif': 'image/gif',
|
|
|
|
'.svg': 'image/svg+xml',
|
|
|
|
'.json': 'application/json',
|
|
|
|
};
|
|
|
|
|
|
|
|
// Create a http server
|
|
|
|
const server = http.createServer((request, response) => {
|
|
|
|
// Get the file path from the URL
|
|
|
|
let filePath =
|
2023-04-16 18:34:56 +02:00
|
|
|
request.url === '/'
|
|
|
|
? `${path.join(__dirname, '../dist/index.html')}`
|
|
|
|
: `${path.join(__dirname, `../dist/${request.url}`)}`;
|
2023-04-14 09:29:13 +02:00
|
|
|
|
|
|
|
// Get the file extension from the filePath
|
|
|
|
let extname = path.extname(filePath);
|
|
|
|
|
|
|
|
// Set the default MIME type to text/plain
|
|
|
|
let contentType = 'text/plain';
|
|
|
|
|
|
|
|
// Check if the file extension is in the MIME types object
|
|
|
|
if (extname in mimeTypes) {
|
|
|
|
contentType = mimeTypes[extname];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Read the file from the disk
|
|
|
|
fs.readFile(filePath, (error, content) => {
|
|
|
|
if (error) {
|
|
|
|
// If file read error occurs
|
|
|
|
if (error.code === 'ENOENT') {
|
|
|
|
// File not found error
|
|
|
|
response.writeHead(404);
|
|
|
|
response.end('File Not Found');
|
|
|
|
} else {
|
|
|
|
// Server error
|
|
|
|
response.writeHead(500);
|
|
|
|
response.end(`Server Error: ${error.code}`);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// File read successful
|
|
|
|
response.writeHead(200, { 'Content-Type': contentType });
|
|
|
|
response.end(content, 'utf-8');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
// Listen for request on port ${PORT}
|
|
|
|
server.listen(PORT, () => {
|
|
|
|
console.log(`Server listening on http://localhost:${PORT}/`);
|
|
|
|
});
|
|
|
|
};
|