TeaSpeak-Client/modules/core/ui-loader/graphical.ts
2020-10-01 10:56:22 +02:00

164 lines
4.9 KiB
TypeScript

import * as electron from "electron";
import * as path from "path";
import {screen} from "electron";
import {Arguments, processArguments} from "../../shared/process-arguments";
import * as loader from "./loader";
import * as updater from "../app-updater";
import * as url from "url";
import {loadWindowBounds, startTrackWindowBounds} from "../../shared/window";
export namespace ui {
let gui: electron.BrowserWindow;
let promise: Promise<String>;
let resolve: any;
let reject: any;
export function running() : boolean {
return promise !== undefined;
}
export function cancel() : boolean {
if(resolve)
resolve();
cleanup();
return true;
}
export function cleanup() {
if(gui) {
promise = undefined;
resolve = undefined;
gui.destroy();
gui = undefined;
reject = error => {
if(error)
console.error("Received error from loader after it had been closed... Error: %o", error);
};
}
}
async function load_files() {
const channel = await updater.selected_channel();
try {
const entry_point = await loader.load_files(channel, (status, index) => {
if(gui) {
gui.webContents.send('progress-update', status, index);
}
});
const resolved = () => {
resolve(entry_point);
promise = undefined;
resolve = undefined;
reject = error => {
if(error)
console.error("Received error from loader after it had been closed... Error: %o", error);
};
};
if(!processArguments.has_flag(...Arguments.DISABLE_ANIMATION))
setTimeout(resolved, 250);
else
setImmediate(resolved);
} catch (error) {
throw error;
}
}
export function show_await_update() {
if(gui)
gui.webContents.send('await-update');
}
function spawn_gui() {
if(gui) {
gui.focus();
return;
}
console.log("Open UI loader window.");
let dev_tools = false;
const WINDOW_WIDTH = 340 + (dev_tools ? 1000 : 0);
const WINDOW_HEIGHT = 400 + (process.platform == "win32" ? 40 : 0);
gui = new electron.BrowserWindow({
width: WINDOW_WIDTH,
height: WINDOW_HEIGHT,
frame: dev_tools,
resizable: dev_tools,
show: false,
autoHideMenuBar: true,
webPreferences: {
webSecurity: false,
nodeIntegrationInWorker: false,
nodeIntegration: true
}
});
gui.setMenu(null);
gui.loadURL(url.pathToFileURL(path.join(path.dirname(module.filename), "ui", "loading_screen.html")).toString())
gui.on('closed', () => {
if(resolve) {
resolve();
}
gui = undefined;
cleanup();
});
gui.on('ready-to-show', () => {
gui.show();
try {
let bounds = screen.getPrimaryDisplay()?.bounds;
let x, y;
if(bounds) {
x = (bounds.x | 0) + ((bounds.width | 0) - WINDOW_WIDTH) / 2;
y = (bounds.y | 0) + ((bounds.height | 0) - WINDOW_HEIGHT) / 2;
} else {
x = 0;
y = 0;
}
console.log("Setting UI position to %ox%o", x, y);
if(typeof x === "number" && typeof y === "number")
gui.setPosition(x, y);
} catch (error) {
console.warn("Failed to apply UI position: %o", error);
}
loadWindowBounds('ui-load-window', gui, undefined, { applySize: false }).then(() => {
startTrackWindowBounds('ui-load-window', gui);
const call_loader = () => load_files().catch(reject);
if(!processArguments.has_flag(...Arguments.DISABLE_ANIMATION))
setTimeout(call_loader, 1000);
else
setImmediate(call_loader);
if(dev_tools)
gui.webContents.openDevTools();
});
});
}
export async function execute_loader() : Promise<String> {
return promise = new Promise((_resolve, _reject) => {
resolve = _resolve;
reject = _reject || (error => {
console.error("Failed to load UI files! Error: %o", error)
});
spawn_gui();
});
}
export function preloading_page(entry_point: string) : string {
global["browser-root"] = entry_point; /* setup entry point */
return path.join(path.dirname(module.filename), "ui", "preload_page.html");
}
}