mirror of
https://github.com/Pandipipas/scoreko-electron-dev.git
synced 2026-06-06 05:32:06 +00:00
Add loading window functionality with HTML and update application controller
This commit is contained in:
@@ -13,6 +13,7 @@ export type ApplicationWindow = {
|
|||||||
isDestroyed: () => boolean;
|
isDestroyed: () => boolean;
|
||||||
isMinimized: () => boolean;
|
isMinimized: () => boolean;
|
||||||
loadURL: (url: string) => Promise<unknown>;
|
loadURL: (url: string) => Promise<unknown>;
|
||||||
|
loadFile: (filePath: string) => Promise<unknown>;
|
||||||
restore: () => void;
|
restore: () => void;
|
||||||
show: () => void;
|
show: () => void;
|
||||||
};
|
};
|
||||||
@@ -119,6 +120,13 @@ export function createApplicationController({
|
|||||||
deps.setAppUserModelId(appConfig.userModelId);
|
deps.setAppUserModelId(appConfig.userModelId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mainWindow = deps.createMainWindow();
|
||||||
|
loadingWindow = deps.createLoadingWindow();
|
||||||
|
|
||||||
|
await loadingWindow.loadFile(paths.staticLoadingHtmlPath);
|
||||||
|
loadingWindow.show();
|
||||||
|
await sleep(50);
|
||||||
|
|
||||||
state = "preparing";
|
state = "preparing";
|
||||||
const preparedRuntime = deps.prepareRuntime({
|
const preparedRuntime = deps.prepareRuntime({
|
||||||
sourceRuntimePath: paths.sourceNodecgRuntimePath,
|
sourceRuntimePath: paths.sourceNodecgRuntimePath,
|
||||||
@@ -131,11 +139,6 @@ export function createApplicationController({
|
|||||||
|
|
||||||
nodecgManager = deps.createNodecgProcessManager(preparedRuntime.runtimePath);
|
nodecgManager = deps.createNodecgProcessManager(preparedRuntime.runtimePath);
|
||||||
|
|
||||||
mainWindow = deps.createMainWindow();
|
|
||||||
loadingWindow = deps.createLoadingWindow();
|
|
||||||
|
|
||||||
loadingWindow.show();
|
|
||||||
|
|
||||||
state = "starting";
|
state = "starting";
|
||||||
await startNodecg();
|
await startNodecg();
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ export type ApplicationPaths = {
|
|||||||
nodecgBaseUrl: string;
|
nodecgBaseUrl: string;
|
||||||
mainDashboardUrl: string;
|
mainDashboardUrl: string;
|
||||||
loadingDashboardUrl: string;
|
loadingDashboardUrl: string;
|
||||||
|
staticLoadingHtmlPath: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getRootPath(isDev: boolean, compiledMainDir: string, resourcesPath: string): string {
|
export function getRootPath(isDev: boolean, compiledMainDir: string, resourcesPath: string): string {
|
||||||
@@ -78,5 +79,6 @@ export function getApplicationPaths({
|
|||||||
nodecgBaseUrl: getNodecgBaseUrl(appConfig.nodecgPort),
|
nodecgBaseUrl: getNodecgBaseUrl(appConfig.nodecgPort),
|
||||||
mainDashboardUrl: getDashboardUrl(appConfig.nodecgPort, appConfig.bundleName, appConfig.mainDashboardRoute),
|
mainDashboardUrl: getDashboardUrl(appConfig.nodecgPort, appConfig.bundleName, appConfig.mainDashboardRoute),
|
||||||
loadingDashboardUrl: getDashboardUrl(appConfig.nodecgPort, appConfig.bundleName, appConfig.loadingDashboardRoute),
|
loadingDashboardUrl: getDashboardUrl(appConfig.nodecgPort, appConfig.bundleName, appConfig.loadingDashboardRoute),
|
||||||
|
staticLoadingHtmlPath: path.join(rootPath, "static", "loading.html"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ class MockWindow implements ApplicationWindow {
|
|||||||
this.events.push(`${this.name}:load:${url}`);
|
this.events.push(`${this.name}:load:${url}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async loadFile(filePath: string): Promise<void> {
|
||||||
|
this.events.push(`${this.name}:loadFile:${filePath}`);
|
||||||
|
}
|
||||||
|
|
||||||
restore(): void {
|
restore(): void {
|
||||||
this.events.push(`${this.name}:restore`);
|
this.events.push(`${this.name}:restore`);
|
||||||
this.minimized = false;
|
this.minimized = false;
|
||||||
@@ -87,6 +91,7 @@ test("ApplicationController preserves startup ordering and schedules updates aft
|
|||||||
nodecgBaseUrl: "http://127.0.0.1:9090",
|
nodecgBaseUrl: "http://127.0.0.1:9090",
|
||||||
mainDashboardUrl: "http://localhost:9090/bundles/scoreko-dev/dashboard/main.html?standalone=true",
|
mainDashboardUrl: "http://localhost:9090/bundles/scoreko-dev/dashboard/main.html?standalone=true",
|
||||||
loadingDashboardUrl: "http://localhost:9090/bundles/scoreko-dev/dashboard/loading/main.html?standalone=true",
|
loadingDashboardUrl: "http://localhost:9090/bundles/scoreko-dev/dashboard/loading/main.html?standalone=true",
|
||||||
|
staticLoadingHtmlPath: "/app/static/loading.html",
|
||||||
};
|
};
|
||||||
|
|
||||||
const controller = createApplicationController({
|
const controller = createApplicationController({
|
||||||
@@ -129,11 +134,13 @@ test("ApplicationController preserves startup ordering and schedules updates aft
|
|||||||
assert.equal(controller.getState(), "ready");
|
assert.equal(controller.getState(), "ready");
|
||||||
assert.deepEqual(events, [
|
assert.deepEqual(events, [
|
||||||
"set-app-user-model-id",
|
"set-app-user-model-id",
|
||||||
"prepare-runtime",
|
|
||||||
"create-manager",
|
|
||||||
"create-main",
|
"create-main",
|
||||||
"create-loading",
|
"create-loading",
|
||||||
|
`loading:loadFile:${paths.staticLoadingHtmlPath}`,
|
||||||
"loading:show",
|
"loading:show",
|
||||||
|
"sleep:50",
|
||||||
|
"prepare-runtime",
|
||||||
|
"create-manager",
|
||||||
"start-nodecg",
|
"start-nodecg",
|
||||||
"wait-nodecg",
|
"wait-nodecg",
|
||||||
`loading:load:${paths.loadingDashboardUrl}`,
|
`loading:load:${paths.loadingDashboardUrl}`,
|
||||||
@@ -158,6 +165,7 @@ test("ApplicationController directly launches packaged app after runtime install
|
|||||||
nodecgBaseUrl: "http://127.0.0.1:9090",
|
nodecgBaseUrl: "http://127.0.0.1:9090",
|
||||||
mainDashboardUrl: "http://localhost:9090/main",
|
mainDashboardUrl: "http://localhost:9090/main",
|
||||||
loadingDashboardUrl: "http://localhost:9090/loading",
|
loadingDashboardUrl: "http://localhost:9090/loading",
|
||||||
|
staticLoadingHtmlPath: "/app/static/loading.html",
|
||||||
},
|
},
|
||||||
deps: {
|
deps: {
|
||||||
createLoadingWindow: () => {
|
createLoadingWindow: () => {
|
||||||
@@ -189,10 +197,12 @@ test("ApplicationController directly launches packaged app after runtime install
|
|||||||
|
|
||||||
assert.equal(controller.getState(), "ready");
|
assert.equal(controller.getState(), "ready");
|
||||||
assert.deepEqual(events, [
|
assert.deepEqual(events, [
|
||||||
"create-manager",
|
|
||||||
"create-main",
|
"create-main",
|
||||||
"create-loading",
|
"create-loading",
|
||||||
|
"loading:loadFile:/app/static/loading.html",
|
||||||
"loading:show",
|
"loading:show",
|
||||||
|
"sleep:50",
|
||||||
|
"create-manager",
|
||||||
"start-nodecg",
|
"start-nodecg",
|
||||||
"wait-nodecg",
|
"wait-nodecg",
|
||||||
"loading:load:http://localhost:9090/loading",
|
"loading:load:http://localhost:9090/loading",
|
||||||
@@ -217,6 +227,7 @@ test("ApplicationController activation before readiness routes through launch",
|
|||||||
nodecgBaseUrl: "http://127.0.0.1:9090",
|
nodecgBaseUrl: "http://127.0.0.1:9090",
|
||||||
mainDashboardUrl: "http://localhost:9090/main",
|
mainDashboardUrl: "http://localhost:9090/main",
|
||||||
loadingDashboardUrl: "http://localhost:9090/loading",
|
loadingDashboardUrl: "http://localhost:9090/loading",
|
||||||
|
staticLoadingHtmlPath: "/app/static/loading.html",
|
||||||
},
|
},
|
||||||
deps: {
|
deps: {
|
||||||
createLoadingWindow: () => new MockWindow("loading", events),
|
createLoadingWindow: () => new MockWindow("loading", events),
|
||||||
@@ -257,6 +268,7 @@ test("ApplicationController shutdown is idempotent", async () => {
|
|||||||
nodecgBaseUrl: "http://127.0.0.1:9090",
|
nodecgBaseUrl: "http://127.0.0.1:9090",
|
||||||
mainDashboardUrl: "http://localhost:9090/main",
|
mainDashboardUrl: "http://localhost:9090/main",
|
||||||
loadingDashboardUrl: "http://localhost:9090/loading",
|
loadingDashboardUrl: "http://localhost:9090/loading",
|
||||||
|
staticLoadingHtmlPath: "/app/static/loading.html",
|
||||||
},
|
},
|
||||||
deps: {
|
deps: {
|
||||||
createLoadingWindow: () => new MockWindow("loading", events),
|
createLoadingWindow: () => new MockWindow("loading", events),
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Scoreko</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #0f0f0f;
|
||||||
|
color: #ffffff;
|
||||||
|
font-family: system-ui, -apple-system, sans-serif;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.spinner {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border: 4px solid rgba(255, 255, 255, 0.1);
|
||||||
|
border-left-color: #ffffff;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
@keyframes spin {
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="spinner"></div>
|
||||||
|
<p>Preparando Scoreko...</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user