Feat: Implement splash screen with progress indicators during startup

This commit is contained in:
MasterAcnolo
2026-04-11 22:36:42 +02:00
parent ca8b107f61
commit 8be47b9821
4 changed files with 144 additions and 0 deletions

37
app/splashManager.js Normal file
View File

@@ -0,0 +1,37 @@
const { BrowserWindow } = require("electron");
const path = require("path");
let splashWindow = null;
function createSplashWindow() {
splashWindow = new BrowserWindow({
width: 400,
height: 300,
frame: false,
transparent: true,
alwaysOnTop: true,
resizable: false,
skipTaskbar: true,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
},
});
splashWindow.loadFile(path.join(__dirname, "../public/splash.html"));
}
function closeSplashWindow() {
if (splashWindow) {
splashWindow.close();
splashWindow = null;
}
}
function setSplashProgress(step) {
if (splashWindow) {
splashWindow.webContents.executeJavaScript(`window.setProgress(${step})`);
}
}
module.exports = { createSplashWindow, closeSplashWindow, setSplashProgress };

View File

@@ -20,6 +20,7 @@ async function createMainWindow() {
minHeight: 800, minHeight: 800,
frame: !configFeatures.customTopBar, frame: !configFeatures.customTopBar,
devTools: !app.isPackaged, devTools: !app.isPackaged,
show: false,
webPreferences: { webPreferences: {
nodeIntegration: false, nodeIntegration: false,
contextIsolation: true, contextIsolation: true,

12
main.js
View File

@@ -9,6 +9,7 @@ process.on("unhandledRejection", (reason) => {
}); });
const { app } = require("electron"); const { app } = require("electron");
const { createSplashWindow, closeSplashWindow, setSplashProgress } = require("./app/splashManager");
const path = require("path"); const path = require("path");
const { logger, logSessionStart, logSessionEnd } = require("./server/logger"); const { logger, logSessionStart, logSessionEnd } = require("./server/logger");
@@ -40,24 +41,35 @@ if (!config.localMode) {
app.whenReady().then(async () => { app.whenReady().then(async () => {
logSessionStart(); logSessionStart();
createSplashWindow();
if (!config.localMode && !checkNativeDependencies()) return; if (!config.localMode && !checkNativeDependencies()) return;
const { userYtDlp } = require("./server/helpers/path.helpers"); const { userYtDlp } = require("./server/helpers/path.helpers");
updateYtDlp(userYtDlp); updateYtDlp(userYtDlp);
try { try {
setSplashProgress(0); // Checking dependencies
await require("./server/server").startServer(); await require("./server/server").startServer();
setSplashProgress(1); // Starting server
registerIpcHandlers(getMainWindow); registerIpcHandlers(getMainWindow);
const themeFolderPath = config.localMode const themeFolderPath = config.localMode
? path.join(__dirname, "theme") ? path.join(__dirname, "theme")
: path.join(process.resourcesPath, "theme"); : path.join(process.resourcesPath, "theme");
setSplashProgress(2); // Loading themes
await initThemes(themeFolderPath); await initThemes(themeFolderPath);
setSplashProgress(3); // Almost ready
await createMainWindow(); await createMainWindow();
await new Promise(resolve => setTimeout(resolve, 2000));
closeSplashWindow();
getMainWindow().show();
if (configFeatures.discordRPC) startRPC(); if (configFeatures.discordRPC) startRPC();
if (configFeatures.autoUpdate) AutoUpdater(getMainWindow()); if (configFeatures.autoUpdate) AutoUpdater(getMainWindow());

94
public/splash.html Normal file
View File

@@ -0,0 +1,94 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body {
width: 100%;
height: 100%;
background: transparent;
overflow: hidden;
}
.splash-container {
width: 100%;
height: 100%;
background: #D9D9D9;
border-radius: 12px;
overflow: hidden;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 28px;
font-family: "Segoe UI", sans-serif;
}
.progress-wrapper {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
}
.progress-track {
width: 180px;
height: 3px;
background: #d0d0d0;
border-radius: 99px;
overflow: hidden;
}
.progress-bar {
height: 100%;
width: 0%;
background: #1a1a1a;
border-radius: 99px;
transition: width 0.3s ease;
}
.status {
font-size: 14px;
color: #6d6d6d;
letter-spacing: 0.5px;
}
</style>
</head>
<body>
<div class="splash-container">
<img src="../build/banner.png" alt="Freedom Loader" style="width: 90%;">
<div class="progress-wrapper">
<div class="progress-track">
<div class="progress-bar" id="progress-bar"></div>
</div>
<span class="status" id="status">Starting...</span>
</div>
</div>
<script>
const steps = [
"Checking dependencies...",
"Starting server...",
"Loading themes...",
"Almost ready...",
];
let current = 0;
const bar = document.getElementById("progress-bar");
const status = document.getElementById("status");
function advance(label, percent) {
bar.style.width = percent + "%";
status.textContent = label;
}
window.setProgress = (step) => {
if (step >= steps.length) {
advance("", 100);
return;
}
const percent = Math.round(((step + 1) / steps.length) * 100);
advance(steps[step], percent);
};
window.setProgress(0);
</script>
</body>
</html>