Using a custom path to load the UI

This commit is contained in:
WolverinDEV 2021-03-22 19:11:05 +01:00
parent a2c6cba7f4
commit c158f2930f
5 changed files with 59 additions and 18 deletions

2
github

@ -1 +1 @@
Subproject commit 099ed8e240637a59be6f656ed299bbcac148b389
Subproject commit ca5350f32137268f13811961d84f4fd96639ae67

View File

@ -1,6 +1,6 @@
import * as electron from "electron";
import {app, Menu} from "electron";
import {app, Menu, protocol} from "electron";
import MessageBoxOptions = electron.MessageBoxOptions;
import {processArguments, parseProcessArguments, Arguments} from "../shared/process-arguments";
@ -11,6 +11,7 @@ import {initializeSingleInstance} from "./MultiInstanceHandler";
import "./AppInstance";
import {dereferenceApp, referenceApp} from "./AppInstance";
import {showUpdateWindow} from "./windows/client-updater/controller/ClientUpdate";
import {initializeCustomUiPackProtocol} from "./ui-loader/Loader";
async function handleAppReady() {
Menu.setApplicationMenu(null);
@ -173,6 +174,7 @@ function main() {
}
}
initializeCustomUiPackProtocol();
app.on('ready', handleAppReady);
}
export const execute = main;

View File

@ -9,21 +9,35 @@ import * as tar from "tar-stream";
import {Arguments, processArguments} from "../../shared/process-arguments";
import {parseVersion} from "../../shared/version";
import * as electron from "electron";
import MessageBoxOptions = Electron.MessageBoxOptions;
import {clientAppInfo, currentClientVersion} from "../app-updater";
import {CachedUIPack, UIPackInfo} from "./CacheFile";
import {localUiCache, saveLocalUiCache} from "./Cache";
import {shippedClientUi} from "./Shipped";
import {downloadUiPack, queryRemoteUiPacks} from "./Remote";
import * as url from "url";
import {showUpdateWindow} from "../windows/client-updater/controller/ClientUpdate";
import {protocol, session} from "electron";
import {kWindowPartitionMainApp} from "../windows/main-window/controller/MainWindow";
const kUiPackProtocol = "shared-ui";
export const remoteUiUrl = () => {
const default_path = is_debug ? "http://localhost/home/TeaSpeak/Web-Client/client-api/environment/" : "https://clientapi.teaspeak.de/";
return processArguments.has_value(...Arguments.SERVER_URL) ? processArguments.value(...Arguments.SERVER_URL) : default_path;
return processArguments.has_value(...Arguments.SERVER_URL) ? processArguments.value(...Arguments.SERVER_URL) : "https://clientapi.teaspeak.de/";
};
export function initializeCustomUiPackProtocol() {
protocol.registerSchemesAsPrivileged([{
scheme: kUiPackProtocol,
privileges: {
allowServiceWorkers: true,
supportFetchAPI: true,
bypassCSP: false,
corsEnabled: false,
secure: true,
standard: true
}
}]);
}
let temporaryDirectoryPromise: Promise<string>;
function generateTemporaryDirectory() : Promise<string> {
if(temporaryDirectoryPromise) {
@ -53,7 +67,7 @@ async function unpackLocalUiPack(version: CachedUIPack) : Promise<string> {
throw "failed to create temporary directory";
}
const gunzip = zlib.createGunzip();
const unzip = zlib.createUnzip();
const extract = tar.extract();
let fpipe: fs.ReadStream;
@ -90,7 +104,7 @@ async function unpackLocalUiPack(version: CachedUIPack) : Promise<string> {
});
const finishPromise = new Promise((resolve, reject) => {
gunzip.on('error', event => {
unzip.on('error', event => {
reject(event);
});
@ -100,7 +114,7 @@ async function unpackLocalUiPack(version: CachedUIPack) : Promise<string> {
reject(event);
});
fpipe.pipe(gunzip).pipe(extract);
fpipe.pipe(unzip).pipe(extract);
});
try {
@ -133,6 +147,32 @@ async function loadBundledUiPack(channel: string, callbackStatus: (message: stri
return url.pathToFileURL(path.join(result, "index.html")).toString();
}
function initializeFileSystemProtocol(directory: string) {
directory = path.normalize(directory);
const sessionProtocol = session.fromPartition(kWindowPartitionMainApp).protocol;
sessionProtocol.registerFileProtocol(kUiPackProtocol, (request, callback) => {
let targetPath;
const pathStartIndex = request.url.indexOf('/', kUiPackProtocol.length + 3);
if(pathStartIndex === -1) {
targetPath = path.join(directory, "index.html");
} else {
const endIndex = request.url.indexOf("?");
let requestedPath = endIndex === -1 ? request.url.substring(pathStartIndex) : request.url.substring(pathStartIndex, endIndex);
targetPath = path.normalize(path.join(directory, requestedPath));
}
if(!targetPath.startsWith(directory)) {
console.warn("Having UI-Pack path request which exceeds the target directory: %s", targetPath);
callback({ path: "__non__exiting" });
} else {
console.debug("Resolved %s to %s", request.url, targetPath);
callback({ path: targetPath });
}
});
}
async function loadCachedOrRemoteUiPack(channel: string, callbackStatus: (message: string, index: number) => any, ignoreNewVersionTimestamp: boolean) : Promise<string> {
callbackStatus("Fetching info", 0);
@ -237,7 +277,8 @@ async function loadCachedOrRemoteUiPack(channel: string, callbackStatus: (messag
callbackStatus("UI pack loaded", 1);
await doVersionInvalidate();
return url.pathToFileURL(path.join(target, "index.html")).toString();
initializeFileSystemProtocol(target);
return kUiPackProtocol + "://shared-ui/index.html";
} catch (error) {
invalidatedVersions.push(pack);
console.log("Failed to unpack UI pack: %o", error);

View File

@ -8,6 +8,7 @@ import * as path from "path";
let windowInstance: BrowserWindow;
export const kWindowPartitionMainApp = "persist:main-app";
export async function showMainWindow(entryPointUrl: string) {
if(windowInstance) {
throw "main window already initialized";
@ -29,7 +30,8 @@ export async function showMainWindow(entryPointUrl: string) {
webSecurity: false,
nodeIntegrationInWorker: true,
nodeIntegration: true,
preload: path.join(__dirname, "..", "renderer", "PreloadScript.js")
preload: path.join(__dirname, "..", "renderer", "PreloadScript.js"),
partition: kWindowPartitionMainApp
},
icon: path.join(__dirname, "..", "..", "..", "..", "resources", "logo.ico"),
});

View File

@ -1,16 +1,12 @@
{
"name": "TeaClient",
"version": "1.5.1-2",
"version": "1.5.2",
"description": "",
"main": "main.js",
"scripts": {
"crash_handler": "electron . crash-handler",
"test": "echo \"Error: no test specified\" && exit 1",
"start-d1": "electron . --disable-hardware-acceleration --debug -t --gdb -s -u=http://clientapi.teaspeak.dev/ --updater-ui-loader_type=0",
"start-n": "electron . -t --disable-hardware-acceleration --no-single-instance -u=https://clientapi.teaspeak.de/ -d",
"start-nd": "electron . -t --gdb --disable-hardware-acceleration --no-single-instance -u=http://clientapi.teaspeak.dev/ -d --updater-ui-loader_type=0",
"start-01": "electron . --updater-channel=test -u=http://dev.clientapi.teaspeak.de/ -d --updater-ui-loader_type=0 --updater-local-version=1.0.1",
"start-devel-download": "electron . --disable-hardware-acceleration --gdb --debug --updater-ui-loader_type=2 --updater-ui-ignore-version -t -u http://localhost:8081/",
"start-download-dev": "electron . --disable-hardware-acceleration --gdb --debug --updater-ui-loader_type=0 -t -u https://clientapi.teaspeak.dev/",
"start-s": "electron . --disable-hardware-acceleration --gdb --debug --updater-ui-loader_type=3 --updater-ui-ignore-version -t -u http://localhost:8080/",
"dtest": "electron . dtest",
"sass": "sass",