From 42b7913620a5cf544a17208eaa7f8779be5d5b32 Mon Sep 17 00:00:00 2001 From: Anirudh Sevugan Date: Sun, 17 Aug 2025 18:01:10 -0500 Subject: [PATCH] Update main.js --- simpliplay/main.js | 314 ++++----------------------------------------- 1 file changed, 24 insertions(+), 290 deletions(-) diff --git a/simpliplay/main.js b/simpliplay/main.js index be5392f..c368f51 100644 --- a/simpliplay/main.js +++ b/simpliplay/main.js @@ -1,302 +1,36 @@ -const { app, BrowserWindow, Menu, MenuItem, shell, dialog, globalShortcut, ipcMain } = require('electron'); -const path = require('path'); -const fs = require('fs'); -const os = require('os'); -const { pathToFileURL } = require("url"); - -// Main application window -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); +// main.js +const { app } = require('electron'); +const { createWindow, setupWindowHandlers } = require('./src/windowManager'); +const { setupMenu } = require('./src/menuManager'); +const { setupShortcuts, unregisterShortcuts } = require('./src/shortcuts'); +const { handleFileOpen } = require('./src/fileHandler'); +const { APP_CONSTANTS } = require('./src/constants'); +// Handle GPU acceleration if (process.argv.includes('--disable-gpu')) { 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('use-gl', 'desktop'); } -// --- Window Management - -// Factory function to create a new browser window -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.", - }); - } - }); - +// App event handlers +app.whenReady().then(() => { + createWindow(); 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) { - shell.openPath(snapshotsDir); - } - } 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", () => { +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { unregisterShortcuts(); - }); -} + app.quit(); + } +}); + +app.on('will-quit', unregisterShortcuts);