mirror of
https://github.com/aljazceru/goose.git
synced 2025-12-17 22:24:21 +01:00
UI v2 playground (#2569)
This commit is contained in:
153
ui-v2/electron/main.ts
Normal file
153
ui-v2/electron/main.ts
Normal file
@@ -0,0 +1,153 @@
|
||||
import * as fs from 'fs/promises';
|
||||
import * as path from 'path';
|
||||
|
||||
import { app, BrowserWindow, ipcMain, clipboard, dialog, session } from 'electron';
|
||||
import type {
|
||||
IpcMainInvokeEvent,
|
||||
OnHeadersReceivedListenerDetails,
|
||||
HeadersReceivedResponse,
|
||||
} from 'electron';
|
||||
|
||||
const isDevelopment = !app.isPackaged;
|
||||
const isHeadless = process.env.HEADLESS === 'true';
|
||||
|
||||
// Enable sandbox before app is ready
|
||||
app.enableSandbox();
|
||||
|
||||
if (isHeadless) {
|
||||
app.disableHardwareAcceleration();
|
||||
}
|
||||
|
||||
async function createWindow() {
|
||||
// Handle different preload paths for dev and prod
|
||||
const preloadPath = isDevelopment
|
||||
? path.join(app.getAppPath(), '.vite/build/preload/preload.js')
|
||||
: path.join(__dirname, 'preload.js');
|
||||
|
||||
// Create the browser window with headless options when needed
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 1200,
|
||||
height: 800,
|
||||
...(isHeadless
|
||||
? {
|
||||
show: false,
|
||||
webPreferences: {
|
||||
nodeIntegration: false,
|
||||
contextIsolation: true,
|
||||
webSecurity: true,
|
||||
preload: preloadPath,
|
||||
sandbox: true,
|
||||
offscreen: true,
|
||||
},
|
||||
}
|
||||
: {
|
||||
webPreferences: {
|
||||
nodeIntegration: false,
|
||||
contextIsolation: true,
|
||||
webSecurity: true,
|
||||
preload: preloadPath,
|
||||
sandbox: true,
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
// Set up CSP
|
||||
session.defaultSession.webRequest.onHeadersReceived(
|
||||
(
|
||||
details: OnHeadersReceivedListenerDetails,
|
||||
callback: (response: HeadersReceivedResponse) => void
|
||||
) => {
|
||||
callback({
|
||||
responseHeaders: {
|
||||
...details.responseHeaders,
|
||||
'Content-Security-Policy': [
|
||||
isDevelopment
|
||||
? `
|
||||
default-src 'self';
|
||||
script-src 'self' 'unsafe-inline';
|
||||
style-src 'self' 'unsafe-inline';
|
||||
connect-src 'self' ws://localhost:3001 http://localhost:3001;
|
||||
img-src 'self' data: https:;
|
||||
font-src 'self' data:;
|
||||
`
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim()
|
||||
: `
|
||||
default-src 'self';
|
||||
script-src 'self';
|
||||
style-src 'self' 'unsafe-inline';
|
||||
img-src 'self' data: https:;
|
||||
font-src 'self' data:;
|
||||
`
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim(),
|
||||
],
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Set up IPC handlers
|
||||
ipcMain.handle('clipboard-copy', async (_: IpcMainInvokeEvent, text: string) => {
|
||||
clipboard.writeText(text);
|
||||
});
|
||||
|
||||
ipcMain.handle('clipboard-read', async () => {
|
||||
return clipboard.readText();
|
||||
});
|
||||
|
||||
interface SaveFileParams {
|
||||
content: string;
|
||||
fileName: string;
|
||||
}
|
||||
|
||||
interface SaveFileResult {
|
||||
success: boolean;
|
||||
path?: string;
|
||||
}
|
||||
|
||||
ipcMain.handle(
|
||||
'save-file',
|
||||
async (
|
||||
_: IpcMainInvokeEvent,
|
||||
{ content, fileName }: SaveFileParams
|
||||
): Promise<SaveFileResult> => {
|
||||
const { filePath } = await dialog.showSaveDialog({
|
||||
defaultPath: fileName,
|
||||
});
|
||||
|
||||
if (filePath) {
|
||||
await fs.writeFile(filePath, content, 'utf8');
|
||||
return { success: true, path: filePath };
|
||||
}
|
||||
return { success: false };
|
||||
}
|
||||
);
|
||||
|
||||
// Load the app
|
||||
if (isDevelopment) {
|
||||
mainWindow.loadURL('http://localhost:3001/');
|
||||
if (!isHeadless) {
|
||||
mainWindow.webContents.openDevTools();
|
||||
}
|
||||
} else {
|
||||
// In production, load from the asar archive
|
||||
mainWindow.loadFile(path.join(__dirname, 'renderer/index.html'));
|
||||
}
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow().catch(console.error);
|
||||
|
||||
app.on('activate', function () {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow().catch(console.error);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user