diff --git a/resources/electron/src/main/index.js b/resources/electron/src/main/index.js index 187e68b..6e0db3f 100644 --- a/resources/electron/src/main/index.js +++ b/resources/electron/src/main/index.js @@ -1,7 +1,7 @@ import NativePHP from '#plugin'; -import { app } from 'electron'; +import { app, BrowserWindow } from 'electron'; import path from 'path'; - +import { createSplash } from './splash.js'; // Inherit User's PATH in Process & ChildProcess import fixPath from 'fix-path'; fixPath(); @@ -14,7 +14,27 @@ const executable = process.platform === 'win32' ? 'php.exe' : 'php'; const phpBinary = path.join(buildPath, 'php', executable); const appPath = path.join(buildPath, 'app'); -/** - * Turn on the lights for the NativePHP app. - */ -NativePHP.bootstrap(app, defaultIcon, phpBinary, certificate, appPath); +let splashWindow; + +app.whenReady().then(() => { + try { + splashWindow = createSplash(appPath, import.meta.dirname); + } catch (error) { + console.error('Error creating splash screen:', error); + } + + NativePHP.bootstrap(app, defaultIcon, phpBinary, certificate, appPath); +}); + +app.on('browser-window-created', (event, window) => { + if (splashWindow && window !== splashWindow) { + window.webContents.on('did-navigate', (evt, url) => { + if (url.startsWith('http://127.0.0.1') || url.startsWith('http://localhost')) { + if (splashWindow) { + splashWindow.close(); + splashWindow = null; + } + } + }); + } +}); diff --git a/resources/electron/src/main/splash.js b/resources/electron/src/main/splash.js new file mode 100644 index 0000000..97558a6 --- /dev/null +++ b/resources/electron/src/main/splash.js @@ -0,0 +1,71 @@ +import path from 'path'; +import fs from 'fs'; +import { BrowserWindow, app } from 'electron'; + +function getLaravelBaseDir(appPath, importMetaDirname) { + if (app.isPackaged) { + return appPath; + } + + let currentPath = importMetaDirname; + for (let i = 0; i < 10; i++) { + if (fs.existsSync(path.join(currentPath, '.env'))) { + return currentPath; + } + const parentPath = path.join(currentPath, '..'); + if (parentPath === currentPath) break; + currentPath = parentPath; + } + return process.cwd(); +} + +export function getEnvConfig(baseDir, key, defaultValue = null) { + if (!baseDir) return defaultValue; + const envPath = path.join(baseDir, '.env'); + + try { + if (fs.existsSync(envPath)) { + const content = fs.readFileSync(envPath, 'utf8'); + const lines = content.split('\n'); + for (const line of lines) { + const trimmed = line.trim(); + if (!trimmed || trimmed.startsWith('#')) continue; + const [lineKey, ...valueParts] = trimmed.split('='); + if (lineKey.trim() === key) { + return valueParts.join('=').trim().replace(/^["']|["']$/g, ''); + } + } + } + } catch (e) { /* ignore */ } + return defaultValue; +} + +export function createSplash(appPath, importMetaDirname) { + const baseDir = getLaravelBaseDir(appPath, importMetaDirname); + + const enabled = getEnvConfig(baseDir, 'NATIVEPHP_SPLASH_ENABLED', 'false') === 'true'; + if (!enabled) return null; + + const width = parseInt(getEnvConfig(baseDir, 'NATIVEPHP_SPLASH_WIDTH', '400')); + const height = parseInt(getEnvConfig(baseDir, 'NATIVEPHP_SPLASH_HEIGHT', '300')); + const splashRelativePath = getEnvConfig(baseDir, 'NATIVEPHP_SPLASH_HTML', 'public/splash.html'); + + const splash = new BrowserWindow({ + width, + height, + frame: false, + transparent: true, + alwaysOnTop: true, + webPreferences: { nodeIntegration: false } + }); + + const finalHtmlPath = path.join(baseDir, splashRelativePath); + + if (fs.existsSync(finalHtmlPath)) { + splash.loadURL('file:///' + finalHtmlPath.replace(/\\/g, '/')); + } else { + console.error(`[NativePHP Splash] HTML Not Found. Path: ${finalHtmlPath}`); + } + + return splash; +}