mirror of
https://github.com/A-Star100/simpliplay-desktop.git
synced 2025-09-17 22:29:38 +00:00
Update main.js
This commit is contained in:
parent
087ac38abd
commit
42b7913620
@ -1,302 +1,36 @@
|
|||||||
const { app, BrowserWindow, Menu, MenuItem, shell, dialog, globalShortcut, ipcMain } = require('electron');
|
// main.js
|
||||||
const path = require('path');
|
const { app } = require('electron');
|
||||||
const fs = require('fs');
|
const { createWindow, setupWindowHandlers } = require('./src/windowManager');
|
||||||
const os = require('os');
|
const { setupMenu } = require('./src/menuManager');
|
||||||
const { pathToFileURL } = require("url");
|
const { setupShortcuts, unregisterShortcuts } = require('./src/shortcuts');
|
||||||
|
const { handleFileOpen } = require('./src/fileHandler');
|
||||||
// Main application window
|
const { APP_CONSTANTS } = require('./src/constants');
|
||||||
let mainWindow;
|
|
||||||
|
|
||||||
// State management
|
|
||||||
let didRegisterShortcuts = false;
|
|
||||||
const loadedAddons = new Map();
|
|
||||||
let gpuAccelStatus = "enabled";
|
|
||||||
const appVersion = "2.0.4.4";
|
|
||||||
|
|
||||||
// Security and Platform Configuration
|
|
||||||
const isDarwin = process.platform === 'darwin';
|
|
||||||
const isSingleInstance = app.requestSingleInstanceLock();
|
|
||||||
const snapshotsDir = path.join(os.homedir(), 'simpliplay-snapshots');
|
|
||||||
|
|
||||||
// Initialize IPC communication
|
|
||||||
ipcMain.handle('get-gpu-status', () => gpuAccelStatus);
|
|
||||||
|
|
||||||
|
// Handle GPU acceleration
|
||||||
if (process.argv.includes('--disable-gpu')) {
|
if (process.argv.includes('--disable-gpu')) {
|
||||||
app.disableHardwareAcceleration();
|
app.disableHardwareAcceleration();
|
||||||
gpuAccelStatus = "disabled";
|
APP_CONSTANTS.GPU_ACCEL = 'disabled';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDarwin && process.argv.includes('--use-gl')) {
|
// macOS-specific GL handling
|
||||||
|
if (process.platform === 'darwin' && process.argv.includes('--use-gl')) {
|
||||||
app.commandLine.appendSwitch('disable-features', 'Metal');
|
app.commandLine.appendSwitch('disable-features', 'Metal');
|
||||||
app.commandLine.appendSwitch('use-gl', 'desktop');
|
app.commandLine.appendSwitch('use-gl', 'desktop');
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Window Management
|
// App event handlers
|
||||||
|
app.whenReady().then(() => {
|
||||||
// Factory function to create a new browser window
|
createWindow();
|
||||||
const createMainWindow = () => {
|
|
||||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
|
||||||
mainWindow.focus();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mainWindow = new BrowserWindow({
|
|
||||||
width: 1920,
|
|
||||||
height: 1080,
|
|
||||||
webPreferences: {
|
|
||||||
preload: path.join(__dirname, "preload.js"),
|
|
||||||
contextIsolation: true,
|
|
||||||
enableRemoteModule: false,
|
|
||||||
nodeIntegration: false,
|
|
||||||
sandbox: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
mainWindow.loadFile("index.html");
|
|
||||||
|
|
||||||
mainWindow.on("focus", setupShortcuts);
|
|
||||||
mainWindow.on("blur", unregisterShortcuts);
|
|
||||||
mainWindow.on("closed", () => {
|
|
||||||
mainWindow = null;
|
|
||||||
unregisterShortcuts();
|
|
||||||
});
|
|
||||||
|
|
||||||
mainWindow.webContents.once("did-finish-load", () => {
|
|
||||||
if (gpuAccelStatus === "disabled") {
|
|
||||||
dialog.showMessageBox(mainWindow, {
|
|
||||||
type: 'warning',
|
|
||||||
title: 'Warning!',
|
|
||||||
message: "Disabling GPU acceleration greatly decreases performance and is not recommended.",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
setupMenu();
|
setupMenu();
|
||||||
setupContextMenu();
|
setupShortcuts();
|
||||||
};
|
handleFileOpen();
|
||||||
|
|
||||||
// --- File Handling
|
|
||||||
|
|
||||||
const handleOpenFile = (filePath) => {
|
|
||||||
const fileURL = pathToFileURL(filePath).href;
|
|
||||||
|
|
||||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
|
||||||
mainWindow.webContents.send("play-media", fileURL);
|
|
||||||
} else {
|
|
||||||
createMainWindow();
|
|
||||||
app.once('ready', () => {
|
|
||||||
mainWindow.webContents.once('did-finish-load', () => {
|
|
||||||
mainWindow.webContents.send("play-media", fileURL);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const isValidFileArg = (arg) => {
|
|
||||||
if (!arg || arg.startsWith('-') || arg.includes('electron')) return false;
|
|
||||||
const resolvedPath = path.resolve(arg);
|
|
||||||
if (!fs.existsSync(resolvedPath)) return false;
|
|
||||||
|
|
||||||
const badExtensions = ['.exe', '.bat', '.cmd', '.sh', '.msi', '.com', '.vbs', '.ps1', '.jar', '.scr'];
|
|
||||||
const ext = path.extname(resolvedPath).toLowerCase();
|
|
||||||
return !badExtensions.includes(ext);
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- Features and Utilities
|
|
||||||
|
|
||||||
const takeSnapshot = async () => {
|
|
||||||
if (!mainWindow) return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const image = await mainWindow.webContents.capturePage();
|
|
||||||
const png = image.toPNG();
|
|
||||||
|
|
||||||
fs.mkdirSync(snapshotsDir, { recursive: true });
|
|
||||||
const filePath = path.join(snapshotsDir, `snapshot-${Date.now()}.png`);
|
|
||||||
fs.writeFileSync(filePath, png);
|
|
||||||
|
|
||||||
const result = await dialog.showMessageBox(mainWindow, {
|
|
||||||
type: 'info',
|
|
||||||
title: 'Snapshot Saved',
|
|
||||||
message: `Snapshot saved to:\n${filePath}`,
|
|
||||||
buttons: ['OK', 'Open Folder'],
|
|
||||||
defaultId: 0,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result.response === 1) {
|
app.on('window-all-closed', () => {
|
||||||
shell.openPath(snapshotsDir);
|
if (process.platform !== 'darwin') {
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
dialog.showErrorBox("Snapshot Error", `Failed to capture snapshot: ${error.message}`);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- Menu and Shortcuts
|
|
||||||
|
|
||||||
const setupMenu = () => {
|
|
||||||
const isMac = process.platform === 'darwin';
|
|
||||||
const template = [
|
|
||||||
...(isMac ? [{
|
|
||||||
label: app.name,
|
|
||||||
submenu: [
|
|
||||||
{ role: 'about' },
|
|
||||||
{ type: 'separator' },
|
|
||||||
{ label: 'Check for Updates', accelerator: 'CmdOrCtrl+Shift+U', click: () => checkForUpdate(appVersion) },
|
|
||||||
{ type: 'separator' },
|
|
||||||
{ role: 'services' },
|
|
||||||
{ type: 'separator' },
|
|
||||||
{ role: 'hide' },
|
|
||||||
{ role: 'hideOthers' },
|
|
||||||
{ role: 'unhide' },
|
|
||||||
{ type: 'separator' },
|
|
||||||
{ role: 'quit' }
|
|
||||||
]
|
|
||||||
}] : []),
|
|
||||||
{
|
|
||||||
label: 'File',
|
|
||||||
submenu: [
|
|
||||||
{ label: 'Take a Snapshot', accelerator: 'CmdOrCtrl+Shift+S', click: takeSnapshot },
|
|
||||||
{ type: 'separator' },
|
|
||||||
isMac ? { role: 'close' } : { role: 'quit' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Add-ons',
|
|
||||||
submenu: [
|
|
||||||
{
|
|
||||||
label: 'Load Add-on...',
|
|
||||||
accelerator: 'CmdOrCtrl+Shift+A',
|
|
||||||
click: async () => {
|
|
||||||
const result = await dialog.showOpenDialog(mainWindow, {
|
|
||||||
title: 'Load Add-on',
|
|
||||||
filters: [{ name: 'JavaScript Files', extensions: ['js'] }], // Changed from .simpliplay to .js
|
|
||||||
properties: ['openFile'],
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!result.canceled && result.filePaths.length > 0) {
|
|
||||||
const filePath = result.filePaths[0];
|
|
||||||
const fileName = path.basename(filePath);
|
|
||||||
|
|
||||||
if (loadedAddons.has(filePath)) {
|
|
||||||
dialog.showErrorBox('Could not load addon', `An add-on named "${fileName}" has already been loaded.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const addonMenuItem = {
|
|
||||||
label: fileName,
|
|
||||||
type: 'checkbox',
|
|
||||||
checked: true,
|
|
||||||
click: (menuItem) => {
|
|
||||||
if (menuItem.checked) {
|
|
||||||
mainWindow.webContents.send('load-addon', pathToFileURL(filePath).href);
|
|
||||||
} else {
|
|
||||||
mainWindow.webContents.send('unload-addon', pathToFileURL(filePath).href);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Menu.getApplicationMenu().items.find(item => item.label === 'Add-ons').submenu.append(addonMenuItem);
|
|
||||||
loadedAddons.set(filePath, addonMenuItem);
|
|
||||||
mainWindow.webContents.send('load-addon', pathToFileURL(filePath).href);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ type: 'separator' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Help',
|
|
||||||
submenu: [
|
|
||||||
{ label: 'Source Code', click: () => shell.openExternal('https://github.com/A-Star100/simpliplay-desktop') },
|
|
||||||
{ label: 'Website', click: () => shell.openExternal('https://simpliplay.netlify.app') },
|
|
||||||
{ label: 'Help Center', click: () => shell.openExternal('https://simpliplay.netlify.app/help') },
|
|
||||||
{ type: 'separator' },
|
|
||||||
...(isMac ? [] : [{
|
|
||||||
label: 'Check for Updates',
|
|
||||||
accelerator: 'CmdOrCtrl+Shift+U',
|
|
||||||
click: () => checkForUpdate(appVersion)
|
|
||||||
}]),
|
|
||||||
]
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const menu = Menu.buildFromTemplate(template);
|
|
||||||
Menu.setApplicationMenu(menu);
|
|
||||||
};
|
|
||||||
|
|
||||||
const setupContextMenu = () => {
|
|
||||||
if (!mainWindow) return;
|
|
||||||
const contextMenu = Menu.buildFromTemplate([
|
|
||||||
{ label: 'Take a Snapshot', click: takeSnapshot },
|
|
||||||
{ type: 'separator' },
|
|
||||||
{ label: 'Inspect', click: () => mainWindow.webContents.openDevTools() }
|
|
||||||
]);
|
|
||||||
|
|
||||||
mainWindow.webContents.on('context-menu', (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
contextMenu.popup({ window: mainWindow });
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const setupShortcuts = () => {
|
|
||||||
if (didRegisterShortcuts) return;
|
|
||||||
globalShortcut.register('CommandOrControl+Q', () => {
|
|
||||||
dialog.showMessageBox(BrowserWindow.getFocusedWindow(), {
|
|
||||||
type: 'question',
|
|
||||||
buttons: ['Cancel', 'Quit'],
|
|
||||||
title: 'Quit?',
|
|
||||||
message: 'Are you sure you want to quit SimpliPlay?',
|
|
||||||
}).then(({ response }) => {
|
|
||||||
if (response === 1) app.quit();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
globalShortcut.register('CommandOrControl+Shift+S', takeSnapshot);
|
|
||||||
globalShortcut.register('CommandOrControl+S', takeSnapshot);
|
|
||||||
didRegisterShortcuts = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const unregisterShortcuts = () => {
|
|
||||||
globalShortcut.unregisterAll();
|
|
||||||
didRegisterShortcuts = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- Application Lifecycle
|
|
||||||
|
|
||||||
if (!isSingleInstance && !isDarwin) {
|
|
||||||
app.quit();
|
|
||||||
} else {
|
|
||||||
app.on('second-instance', (event, argv, workingDirectory) => {
|
|
||||||
if (mainWindow) {
|
|
||||||
if (mainWindow.isMinimized()) mainWindow.restore();
|
|
||||||
mainWindow.focus();
|
|
||||||
const fileArg = argv.find(isValidFileArg);
|
|
||||||
if (fileArg) handleOpenFile(fileArg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.on('open-file', (event, filePath) => {
|
|
||||||
event.preventDefault();
|
|
||||||
handleOpenFile(filePath);
|
|
||||||
});
|
|
||||||
|
|
||||||
app.on('ready', () => {
|
|
||||||
createMainWindow();
|
|
||||||
const fileArg = process.argv.slice(1).find(isValidFileArg);
|
|
||||||
if (fileArg) handleOpenFile(fileArg);
|
|
||||||
});
|
|
||||||
|
|
||||||
app.on('activate', () => {
|
|
||||||
if (BrowserWindow.getAllWindows().length === 0) {
|
|
||||||
createMainWindow();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.on("window-all-closed", () => {
|
|
||||||
if (!isDarwin) app.quit();
|
|
||||||
});
|
|
||||||
|
|
||||||
app.on("will-quit", () => {
|
|
||||||
unregisterShortcuts();
|
unregisterShortcuts();
|
||||||
});
|
app.quit();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.on('will-quit', unregisterShortcuts);
|
||||||
|
Loading…
Reference in New Issue
Block a user