Changed the loader
This commit is contained in:
parent
c97987828e
commit
15ab95c1f9
2 changed files with 475 additions and 350 deletions
|
@ -1,54 +1,193 @@
|
||||||
namespace app {
|
namespace loader {
|
||||||
export enum Type {
|
type Task = {
|
||||||
UNDEFINED,
|
name: string,
|
||||||
RELEASE,
|
priority: number, /* tasks with the same priority will be executed in sync */
|
||||||
DEBUG
|
function: () => Promise<void>
|
||||||
|
};
|
||||||
|
|
||||||
|
export enum Stage {
|
||||||
|
/*
|
||||||
|
loading loader required files (incl this)
|
||||||
|
*/
|
||||||
|
INITIALIZING,
|
||||||
|
/*
|
||||||
|
setting up the loading process
|
||||||
|
*/
|
||||||
|
SETUP,
|
||||||
|
/*
|
||||||
|
loading all javascript files
|
||||||
|
*/
|
||||||
|
JAVASCRIPT,
|
||||||
|
/*
|
||||||
|
loading all template files
|
||||||
|
*/
|
||||||
|
TEMPLATES,
|
||||||
|
/*
|
||||||
|
initializing static/global stuff
|
||||||
|
*/
|
||||||
|
JAVASCRIPT_INITIALIZING,
|
||||||
|
/*
|
||||||
|
finalizing load process
|
||||||
|
*/
|
||||||
|
FINALIZING,
|
||||||
|
/*
|
||||||
|
invoking main task
|
||||||
|
*/
|
||||||
|
LOADED
|
||||||
}
|
}
|
||||||
|
|
||||||
let moduleInitialized: boolean;
|
let current_stage: Stage = Stage.INITIALIZING;
|
||||||
let applicationLoaded: boolean;
|
const tasks: {[key:number]:Task[]} = {};
|
||||||
export let type: Type = Type.UNDEFINED;
|
|
||||||
export let loadedListener: (() => any)[];
|
|
||||||
export const appLoaded = Date.now();
|
|
||||||
|
|
||||||
export function initialized() : boolean {
|
export function register_task(stage: Stage, task: Task) {
|
||||||
return moduleInitialized && applicationLoaded;
|
const task_array = tasks[stage] || (tasks[stage] = []);
|
||||||
|
task_array.push(task);
|
||||||
|
task_array.sort((a, b) => a.priority < b.priority ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function callbackApp(errorMessage?: string) {
|
export async function execute() {
|
||||||
if(errorMessage) {
|
while(current_stage <= Stage.LOADED) {
|
||||||
console.error("Could not load application!");
|
let current_tasks: Task[] = [];
|
||||||
|
while((tasks[current_stage] || []).length > 0) {
|
||||||
|
if(current_tasks.length == 0 || current_tasks[0].priority == tasks[current_stage][0].priority) {
|
||||||
|
current_tasks.push(tasks[current_stage].pop());
|
||||||
|
} else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const errors: {
|
||||||
|
error: any,
|
||||||
|
task: Task
|
||||||
|
}[] = [];
|
||||||
|
|
||||||
|
const promises: Promise<void>[] = [];
|
||||||
|
for(const task of current_tasks) {
|
||||||
|
try {
|
||||||
|
promises.push(task.function().catch(error => {
|
||||||
|
errors.push({
|
||||||
|
task: task,
|
||||||
|
error: error
|
||||||
|
});
|
||||||
|
return Promise.resolve();
|
||||||
|
}));
|
||||||
|
} catch(error) {
|
||||||
|
errors.push({
|
||||||
|
task: task,
|
||||||
|
error: error
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all([...promises]);
|
||||||
|
|
||||||
|
if(errors.length > 0) {
|
||||||
|
console.error("Failed to execute loader. The following tasks failed (%d):", errors.length);
|
||||||
|
for(const error of errors)
|
||||||
|
console.error(" - %s: %o", error.task.name, error.error);
|
||||||
|
|
||||||
|
throw "failed to process step " + Stage[current_stage];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(current_tasks.length == 0) {
|
||||||
|
if(current_stage < Stage.LOADED)
|
||||||
|
console.debug("[loader] entering next state (%s)", Stage[current_stage + 1]);
|
||||||
|
current_stage += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.debug("[loader] finished loader.");
|
||||||
|
}
|
||||||
|
|
||||||
|
type Script = string | string[];
|
||||||
|
|
||||||
|
function script_name(path: string | string[]) {
|
||||||
|
if(Array.isArray(path)) {
|
||||||
|
let buffer = "";
|
||||||
|
let _or = " or ";
|
||||||
|
for(let entry of path)
|
||||||
|
buffer += _or + formatPath(entry);
|
||||||
|
return buffer.slice(_or.length);
|
||||||
|
} else return "<code>" + path + "</code>";
|
||||||
|
}
|
||||||
|
|
||||||
|
class SyntaxError {
|
||||||
|
source: any;
|
||||||
|
|
||||||
|
constructor(source: any) {
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function load_script(path: Script) : Promise<void> {
|
||||||
|
if(Array.isArray(path)) { //We have some fallback
|
||||||
|
return load_script(path[0]).catch(error => {
|
||||||
|
if(error instanceof SyntaxError)
|
||||||
|
return error.source;
|
||||||
|
|
||||||
|
if(path.length > 1)
|
||||||
|
return load_script(path.slice(1));
|
||||||
|
|
||||||
|
return error;
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
applicationLoaded = true;
|
return new Promise((resolve, reject) => {
|
||||||
testInitialisation();
|
const tag: HTMLScriptElement = document.createElement("script");
|
||||||
|
|
||||||
|
const error_handler = (event: ErrorEvent) => {
|
||||||
|
if(event.filename == tag.src) { //Our tag throw an uncaught error
|
||||||
|
//console.log("msg: %o, url: %o, line: %o, col: %o, error: %o", event.message, event.filename, event.lineno, event.colno, event.error);
|
||||||
|
window.removeEventListener('error', error_handler as any);
|
||||||
|
|
||||||
|
reject(new SyntaxError(event.error));
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.addEventListener('error', error_handler as any);
|
||||||
|
|
||||||
|
tag.type = "application/javascript";
|
||||||
|
tag.async = true;
|
||||||
|
tag.defer = true;
|
||||||
|
tag.onerror = error => {
|
||||||
|
window.removeEventListener('error', error_handler as any);
|
||||||
|
console.error("ERROR: %o", error);
|
||||||
|
tag.remove();
|
||||||
|
reject(error);
|
||||||
|
};
|
||||||
|
tag.onload = () => {
|
||||||
|
window.removeEventListener('error', error_handler as any);
|
||||||
|
console.debug("Script %o loaded", path);
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
document.getElementById("scripts").appendChild(tag);
|
||||||
|
tag.src = path;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initialize() {
|
export async function load_scripts(paths: Script[]) : Promise<void> {
|
||||||
moduleInitialized = false;
|
const promises: Promise<void>[] = [];
|
||||||
applicationLoaded = false;
|
const errors: {
|
||||||
loadedListener = [];
|
script: Script,
|
||||||
|
error: any
|
||||||
|
}[] = [];
|
||||||
|
|
||||||
Module['onRuntimeInitialized'] = function() {
|
for(const script of paths)
|
||||||
console.log("Runtime init!");
|
promises.push(load_script(script).catch(error => {
|
||||||
moduleInitialized = true;
|
errors.push({
|
||||||
testInitialisation();
|
script: script,
|
||||||
};
|
error: error
|
||||||
|
});
|
||||||
|
return Promise.resolve();
|
||||||
|
}));
|
||||||
|
|
||||||
Module['onAbort'] = message => {
|
await Promise.all([...promises]);
|
||||||
Module['onAbort'] = undefined;
|
|
||||||
displayCriticalError("Could not load webassembly files!<br>Message: <code>" + message + "</code>");
|
|
||||||
};
|
|
||||||
|
|
||||||
Module['locateFile'] = file => {
|
if(errors.length > 0) {
|
||||||
return "wasm/" + file;
|
console.error("Failed to load the following scripts:");
|
||||||
};
|
for(const script of errors)
|
||||||
|
console.log(" - %o: %o", script.script, script.error);
|
||||||
|
|
||||||
|
displayCriticalError("Failed to load script " + script_name(errors[0].script) + " <br>" + "View the browser console for more information!");
|
||||||
|
throw "failed to load script " + script_name(errors[0].script);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testInitialisation() {
|
|
||||||
if(moduleInitialized && applicationLoaded)
|
|
||||||
for(let l of loadedListener)
|
|
||||||
l();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +206,7 @@ const display_critical_load = message => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const loader_impl_display_critical_error = message => {
|
const loader_impl_display_critical_error = message => {
|
||||||
if(typeof(createErrorModal) !== 'undefined') {
|
if(typeof(createErrorModal) !== 'undefined' && typeof((<any>window).ModalFunctions) !== 'undefined') {
|
||||||
createErrorModal("A critical error occurred while loading the page!", message, {closeable: false}).open();
|
createErrorModal("A critical error occurred while loading the page!", message, {closeable: false}).open();
|
||||||
} else {
|
} else {
|
||||||
display_critical_load(message);
|
display_critical_load(message);
|
||||||
|
@ -89,86 +228,59 @@ function displayCriticalError(message: string) {
|
||||||
loader_impl_display_critical_error(message);
|
loader_impl_display_critical_error(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* all javascript loaders */
|
||||||
function load_scripts(paths: (string | string[])[]) : {path: string, promise: Promise<Boolean>}[] {
|
const loader_javascript = {
|
||||||
let result = [];
|
load_scripts: async () => {
|
||||||
for(let path of paths)
|
/*
|
||||||
result.push({path: path, promise: load_script(path)});
|
if(window.require !== undefined) {
|
||||||
return result;
|
console.log("Loading node specific things");
|
||||||
}
|
const remote = require('electron').remote;
|
||||||
|
module.paths.push(remote.app.getAppPath() + "/node_modules");
|
||||||
function load_script(path: string | string[]) : Promise<Boolean> {
|
module.paths.push(remote.app.getAppPath() + "/app");
|
||||||
if(Array.isArray(path)) { //Having fallbacks
|
module.paths.push(remote.getGlobal("browser-root") + "js/");
|
||||||
return new Promise<Boolean>((resolve, reject) => {
|
window.$ = require("assets/jquery.min.js");
|
||||||
load_script(path[0]).then(resolve).catch(error => {
|
require("native/loader_adapter.js");
|
||||||
if(path.length >= 2) {
|
|
||||||
load_script(path.slice(1)).then(resolve).catch(() => reject("could not load file " + formatPath(path)));
|
|
||||||
} else {
|
|
||||||
reject("could not load file");
|
|
||||||
}
|
}
|
||||||
});
|
*/
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const tag: HTMLScriptElement = document.createElement("script");
|
|
||||||
tag.type = "application/javascript";
|
|
||||||
tag.async = true;
|
|
||||||
tag.defer = true;
|
|
||||||
tag.onerror = error => {
|
|
||||||
console.log(error);
|
|
||||||
tag.remove();
|
|
||||||
reject(error);
|
|
||||||
};
|
|
||||||
tag.onload = () => {
|
|
||||||
console.debug("Script %o loaded", path);
|
|
||||||
resolve();
|
|
||||||
};
|
|
||||||
document.getElementById("scripts").appendChild(tag);
|
|
||||||
tag.src = path;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatPath(path: string | string[]) {
|
|
||||||
if(Array.isArray(path)) {
|
|
||||||
let buffer = "";
|
|
||||||
let _or = " or ";
|
|
||||||
for(let entry of path)
|
|
||||||
buffer += _or + formatPath(entry);
|
|
||||||
return buffer.slice(_or.length);
|
|
||||||
} else return "<code>" + path + "</code>";
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadRelease() {
|
|
||||||
app.type = app.Type.RELEASE;
|
|
||||||
console.log("Load for release!");
|
|
||||||
awaitLoad(load_scripts([
|
|
||||||
//Load general API's
|
|
||||||
["wasm/TeaWeb-Identity.js"],
|
|
||||||
["js/client.min.js", "js/client.js"]
|
|
||||||
])).then(() => {
|
|
||||||
console.log("Loaded successfully all scripts!");
|
|
||||||
app.callbackApp();
|
|
||||||
}).catch((error) => {
|
|
||||||
console.error("Could not load " + error.path);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Only possible for developers! **/
|
|
||||||
function loadDebug() {
|
|
||||||
app.type = app.Type.DEBUG;
|
|
||||||
console.log("Load for debug!");
|
|
||||||
|
|
||||||
let custom_scripts: (string | string[])[] = [];
|
|
||||||
|
|
||||||
if(!window.require) {
|
if(!window.require) {
|
||||||
console.log("Adding browser audio player");
|
await loader.load_script(["vendor/jquery/jquery.min.js"]);
|
||||||
custom_scripts.push(["js/audio/AudioPlayer.js"]);
|
}
|
||||||
custom_scripts.push(["js/audio/WebCodec.js"]);
|
await loader.load_script("vendor/jsrender/jsrender.min.js");
|
||||||
custom_scripts.push(["js/WebPPTListener.js"]);
|
await loader.load_scripts([
|
||||||
|
["vendor/bbcode/xbbcode.js"],
|
||||||
|
["vendor/moment/moment.js"],
|
||||||
|
["https://webrtc.github.io/adapter/adapter-latest.js"]
|
||||||
|
]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await loader.load_script("js/proto.js");
|
||||||
|
//we're loading for debug
|
||||||
|
|
||||||
|
loader.register_task(loader.Stage.JAVASCRIPT, {
|
||||||
|
name: "scripts debug",
|
||||||
|
priority: 20,
|
||||||
|
function: loader_javascript.load_scripts_debug
|
||||||
|
});
|
||||||
|
} catch(error) {
|
||||||
|
loader.register_task(loader.Stage.JAVASCRIPT, {
|
||||||
|
name: "scripts release",
|
||||||
|
priority: 20,
|
||||||
|
function: loadRelease /* fixme */
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
load_scripts_debug: async () => {
|
||||||
|
/* test if we're loading as TeaClient or WebClient */
|
||||||
|
if(!window.require) {
|
||||||
|
loader.register_task(loader.Stage.JAVASCRIPT, {
|
||||||
|
name: "javascript web",
|
||||||
|
priority: 10,
|
||||||
|
function: loader_javascript.load_scripts_debug_web
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
load_wait_scripts([
|
await loader.load_scripts([
|
||||||
["wasm/TeaWeb-Identity.js"],
|
["wasm/TeaWeb-Identity.js"],
|
||||||
|
|
||||||
//Load general API's
|
//Load general API's
|
||||||
|
@ -238,58 +350,91 @@ function loadDebug() {
|
||||||
"js/client.js",
|
"js/client.js",
|
||||||
"js/chat.js",
|
"js/chat.js",
|
||||||
|
|
||||||
"js/PPTListener.js",
|
"js/PPTListener.js"
|
||||||
...custom_scripts
|
]);
|
||||||
]).then(() => load_wait_scripts([
|
|
||||||
|
await loader.load_scripts([
|
||||||
"js/codec/CodecWrapperWorker.js",
|
"js/codec/CodecWrapperWorker.js",
|
||||||
"js/profiles/identities/NameIdentity.js", //Depends on Identity
|
"js/profiles/identities/NameIdentity.js", //Depends on Identity
|
||||||
"js/profiles/identities/TeaForumIdentity.js", //Depends on Identity
|
"js/profiles/identities/TeaForumIdentity.js", //Depends on Identity
|
||||||
"js/profiles/identities/TeamSpeakIdentity.js", //Depends on Identity
|
"js/profiles/identities/TeamSpeakIdentity.js", //Depends on Identity
|
||||||
])).then(() => load_wait_scripts([
|
]);
|
||||||
"js/main.js"
|
|
||||||
])).then(() => {
|
|
||||||
console.log("Loaded successfully all scripts!");
|
|
||||||
app.callbackApp();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function awaitLoad(promises: {path: string, promise: Promise<Boolean>}[]) : Promise<void> {
|
await loader.load_script("js/main.js");
|
||||||
return new Promise<void>((resolve, reject) => {
|
},
|
||||||
let awaiting = promises.length;
|
load_scripts_debug_web: async () => {
|
||||||
let success = true;
|
await loader.load_scripts([
|
||||||
|
["js/audio/AudioPlayer.js"],
|
||||||
|
["js/audio/WebCodec.js"],
|
||||||
|
["js/WebPPTListener.js"]
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
for(let entry of promises) {
|
loadRelease: async () => {
|
||||||
entry.promise.then(() => {
|
console.log("Load for release!");
|
||||||
awaiting--;
|
|
||||||
if(awaiting == 0) resolve();
|
await loader.load_scripts([
|
||||||
}).catch(error => {
|
//Load general API's
|
||||||
success = false;
|
["wasm/TeaWeb-Identity.js"],
|
||||||
if(error instanceof TypeError) {
|
["js/client.min.js", "js/client.js"]
|
||||||
console.error(error);
|
]);
|
||||||
let name = (error as any).fileName + "@" + (error as any).lineNumber + ":" + (error as any).columnNumber;
|
}
|
||||||
displayCriticalError("Failed to execute script <code>" + name + "</code>.<hr>If you believe that it isn't your mistake<br>then please contact an administrator!");
|
};
|
||||||
|
|
||||||
|
const loader_webassembly = {
|
||||||
|
test_webassembly: async () => {
|
||||||
|
if(typeof (WebAssembly) === "undefined" || typeof (WebAssembly.compile) === "undefined") {
|
||||||
|
console.log(navigator.browserSpecs);
|
||||||
|
if (navigator.browserSpecs.name == 'Safari') {
|
||||||
|
if (parseInt(navigator.browserSpecs.version) < 11) {
|
||||||
|
displayCriticalError("You require Safari 11 or higher to use the web client!<br>Safari " + navigator.browserSpecs.version + " does not support WebAssambly!");
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
console.error("Failed to load script " + entry.path);
|
|
||||||
}
|
}
|
||||||
displayCriticalError("Failed to load script " + formatPath(entry.path) + ".<hr>If you believe that it isn't your mistake<br>then please contact an administrator!");
|
}
|
||||||
|
else {
|
||||||
|
// Do something for all other browsers.
|
||||||
|
}
|
||||||
|
displayCriticalError("You require WebAssembly for TeaSpeak-Web!");
|
||||||
|
throw "Missing web assembly";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup_awaiter: async () => {
|
||||||
|
Module['_initialized'] = false;
|
||||||
|
Module['_initialized_callback'] = undefined;
|
||||||
|
|
||||||
|
Module['onRuntimeInitialized'] = () => {
|
||||||
|
Module['_initialized'] = true;
|
||||||
|
if(Module['_initialized_callback'])
|
||||||
|
Module['_initialized_callback']();
|
||||||
|
};
|
||||||
|
|
||||||
|
Module['onAbort'] = message => {
|
||||||
|
Module['onAbort'] = undefined;
|
||||||
|
Module['_initialized'] = false;
|
||||||
|
displayCriticalError("Could not load webassembly files!<br>Message: <code>" + message + "</code>");
|
||||||
|
};
|
||||||
|
|
||||||
|
Module['locateFile'] = file => "wasm/" + file;
|
||||||
|
},
|
||||||
|
awaiter: () => new Promise<void>((resolve, reject) => {
|
||||||
|
if(!Module['onAbort']) /* an error has been already encountered */
|
||||||
|
reject();
|
||||||
|
else if(!Module['_initialized'])
|
||||||
|
Module['_initialized_callback'] = resolve;
|
||||||
|
else
|
||||||
|
resolve();
|
||||||
})
|
})
|
||||||
}
|
};
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function load_wait_scripts(paths: (string | string[])[]) : Promise<void> {
|
|
||||||
return awaitLoad(load_scripts(paths));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function loadTemplates() {
|
async function load_templates() {
|
||||||
//Load the templates
|
try {
|
||||||
$.ajax("templates.html", {
|
const response = await $.ajax("templates.html", {
|
||||||
cache: false, //Change this when in release mode
|
cache: false, //Change this when in release mode
|
||||||
}).then((element, status) => {
|
});
|
||||||
|
|
||||||
let node = document.createElement("html");
|
let node = document.createElement("html");
|
||||||
node.innerHTML = element;
|
node.innerHTML = response;
|
||||||
let tags: HTMLCollection;
|
let tags: HTMLCollection;
|
||||||
if(node.getElementsByTagName("body").length > 0)
|
if(node.getElementsByTagName("body").length > 0)
|
||||||
tags = node.getElementsByTagName("body")[0].children;
|
tags = node.getElementsByTagName("body")[0].children;
|
||||||
|
@ -306,66 +451,17 @@ function loadTemplates() {
|
||||||
root.appendChild(tag);
|
root.appendChild(tag);
|
||||||
|
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
} catch(error) {
|
||||||
console.error("Could not load templates!");
|
console.dir(error);
|
||||||
console.log(error);
|
displayCriticalError("Failed to find template tag!");
|
||||||
displayCriticalError("Could not load HTML templates!");
|
throw "template error";
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Window {
|
interface Window {
|
||||||
$: JQuery;
|
$: JQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO release config!
|
|
||||||
function loadSide() {
|
|
||||||
if(window.require !== undefined) {
|
|
||||||
console.log("Loading node specific things");
|
|
||||||
const remote = require('electron').remote;
|
|
||||||
module.paths.push(remote.app.getAppPath() + "/node_modules");
|
|
||||||
module.paths.push(remote.app.getAppPath() + "/app");
|
|
||||||
module.paths.push(remote.getGlobal("browser-root") + "js/");
|
|
||||||
window.$ = require("assets/jquery.min.js");
|
|
||||||
require("native/loader_adapter.js");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(typeof (WebAssembly) === "undefined" || typeof (WebAssembly.compile) === "undefined") {
|
|
||||||
console.log(navigator.browserSpecs);
|
|
||||||
if (navigator.browserSpecs.name == 'Safari') {
|
|
||||||
if (parseInt(navigator.browserSpecs.version) < 11) {
|
|
||||||
displayCriticalError("You require Safari 11 or higher to use the web client!<br>Safari " + navigator.browserSpecs.version + " does not support WebAssambly!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Do something for all other browsers.
|
|
||||||
}
|
|
||||||
displayCriticalError("You require WebAssembly for TeaSpeak-Web!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//Load the general scripts and required scripts
|
|
||||||
(window.require !== undefined ?
|
|
||||||
Promise.resolve() :
|
|
||||||
load_wait_scripts([
|
|
||||||
"vendor/jquery/jquery.min.js"
|
|
||||||
])
|
|
||||||
).then(() => load_wait_scripts([
|
|
||||||
"vendor/jsrender/jsrender.min.js"
|
|
||||||
])).then(() => load_wait_scripts([
|
|
||||||
["vendor/bbcode/xbbcode.js"],
|
|
||||||
["vendor/moment/moment.js"],
|
|
||||||
["https://webrtc.github.io/adapter/adapter-latest.js"]
|
|
||||||
])).then(() => {
|
|
||||||
//Load the teaweb scripts
|
|
||||||
load_script("js/proto.js").then(loadDebug).catch(loadRelease);
|
|
||||||
//Load the teaweb templates
|
|
||||||
loadTemplates();
|
|
||||||
}).catch(error => {
|
|
||||||
displayCriticalError("Failed to load scripts.<br>Lookup the console for more details.");
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//FUN: loader_ignore_age=0&loader_default_duration=1500&loader_default_age=5000
|
//FUN: loader_ignore_age=0&loader_default_duration=1500&loader_default_age=5000
|
||||||
let _fadeout_warned = false;
|
let _fadeout_warned = false;
|
||||||
function fadeoutLoader(duration = undefined, minAge = undefined, ignoreAge = undefined) {
|
function fadeoutLoader(duration = undefined, minAge = undefined, ignoreAge = undefined) {
|
||||||
|
@ -393,11 +489,13 @@ function fadeoutLoader(duration = undefined, minAge = undefined, ignoreAge = und
|
||||||
else ignoreAge = false;
|
else ignoreAge = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
let age = Date.now() - app.appLoaded;
|
let age = Date.now() - app.appLoaded;
|
||||||
if(age < minAge && !ignoreAge) {
|
if(age < minAge && !ignoreAge) {
|
||||||
setTimeout(() => fadeoutLoader(duration, 0, true), minAge - age);
|
setTimeout(() => fadeoutLoader(duration, 0, true), minAge - age);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
$(".loader .bookshelf_wrapper").animate({top: 0, opacity: 0}, duration);
|
$(".loader .bookshelf_wrapper").animate({top: 0, opacity: 0}, duration);
|
||||||
$(".loader .half").animate({width: 0}, duration, () => {
|
$(".loader .half").animate({width: 0}, duration, () => {
|
||||||
|
@ -405,21 +503,9 @@ function fadeoutLoader(duration = undefined, minAge = undefined, ignoreAge = und
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* safari remove "fix" */
|
|
||||||
if(Element.prototype.remove === undefined)
|
|
||||||
Object.defineProperty(Element.prototype, "remove", {
|
|
||||||
enumerable: false,
|
|
||||||
configurable: false,
|
|
||||||
writable: false,
|
|
||||||
value: function(){
|
|
||||||
this.parentElement.removeChild(this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if(typeof Module === "undefined")
|
if(typeof Module === "undefined")
|
||||||
this["Module"] = {};
|
this["Module"] = {};
|
||||||
app.initialize();
|
|
||||||
app.loadedListener.push(fadeoutLoader);
|
|
||||||
|
|
||||||
navigator.browserSpecs = (function(){
|
navigator.browserSpecs = (function(){
|
||||||
let ua = navigator.userAgent, tem, M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
|
let ua = navigator.userAgent, tem, M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
|
||||||
|
@ -438,9 +524,67 @@ navigator.browserSpecs = (function(){
|
||||||
})();
|
})();
|
||||||
|
|
||||||
console.log(navigator.browserSpecs); //Object { name: "Firefox", version: "42" }
|
console.log(navigator.browserSpecs); //Object { name: "Firefox", version: "42" }
|
||||||
try {
|
|
||||||
loadSide();
|
/* register tasks */
|
||||||
} catch(error) {
|
loader.register_task(loader.Stage.INITIALIZING, {
|
||||||
displayCriticalError("Failed to invoke main loader function.");
|
name: "safari fix",
|
||||||
console.error(error);
|
function: async () => {
|
||||||
}
|
/* safari remove "fix" */
|
||||||
|
if(Element.prototype.remove === undefined)
|
||||||
|
Object.defineProperty(Element.prototype, "remove", {
|
||||||
|
enumerable: false,
|
||||||
|
configurable: false,
|
||||||
|
writable: false,
|
||||||
|
value: function(){
|
||||||
|
this.parentElement.removeChild(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
priority: 50
|
||||||
|
});
|
||||||
|
|
||||||
|
loader.register_task(loader.Stage.INITIALIZING, {
|
||||||
|
name: "webassembly tester",
|
||||||
|
function: loader_webassembly.test_webassembly,
|
||||||
|
priority: 20
|
||||||
|
});
|
||||||
|
|
||||||
|
loader.register_task(loader.Stage.INITIALIZING, {
|
||||||
|
name: "webassembly setup",
|
||||||
|
function: loader_webassembly.setup_awaiter,
|
||||||
|
priority: 10
|
||||||
|
});
|
||||||
|
|
||||||
|
loader.register_task(loader.Stage.JAVASCRIPT_INITIALIZING, {
|
||||||
|
name: "javascript webassembly",
|
||||||
|
function: loader_webassembly.awaiter,
|
||||||
|
priority: 10
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
loader.register_task(loader.Stage.JAVASCRIPT, {
|
||||||
|
name: "javascript",
|
||||||
|
function: loader_javascript.load_scripts,
|
||||||
|
priority: 10
|
||||||
|
});
|
||||||
|
|
||||||
|
loader.register_task(loader.Stage.TEMPLATES, {
|
||||||
|
name: "templates",
|
||||||
|
function: load_templates,
|
||||||
|
priority: 10
|
||||||
|
});
|
||||||
|
|
||||||
|
loader.register_task(loader.Stage.LOADED, {
|
||||||
|
name: "loaded handler",
|
||||||
|
function: async () => {
|
||||||
|
fadeoutLoader();
|
||||||
|
},
|
||||||
|
priority: 10
|
||||||
|
});
|
||||||
|
|
||||||
|
loader.execute().then(() => {
|
||||||
|
console.log("app successfully loaded!");
|
||||||
|
}).catch(error => {
|
||||||
|
displayCriticalError("failed to load app!<br>Please lookup the browser console for more details");
|
||||||
|
console.error("Failed to load app!\nError: %o", error);
|
||||||
|
});
|
|
@ -120,6 +120,7 @@ async function initialize() {
|
||||||
const main = $("#tmpl_main").renderTag();
|
const main = $("#tmpl_main").renderTag();
|
||||||
$("body").append(main);
|
$("body").append(main);
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
|
console.error(error);
|
||||||
display_load_error(tr("Failed to setup main page!"));
|
display_load_error(tr("Failed to setup main page!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -159,39 +160,14 @@ function main() {
|
||||||
//Modals.spawnSettingsModal();
|
//Modals.spawnSettingsModal();
|
||||||
//Modals.createChannelModal(undefined);
|
//Modals.createChannelModal(undefined);
|
||||||
|
|
||||||
/*
|
if(settings.static("connect_default") && settings.static("connect_address", "")) {
|
||||||
//FIXME
|
const profile_uuid = settings.static("connect_profile") as string;
|
||||||
if(settings.static("default_connect_url")) {
|
const profile = profiles.find_profile(profile_uuid) || profiles.default_profile();
|
||||||
switch (settings.static("default_connect_type")) {
|
const address = settings.static("connect_address", "");
|
||||||
case "teaforo":
|
const username = settings.static("connect_username", "Another TeaSpeak user");
|
||||||
if(forumIdentity && forumIdentity.valid())
|
|
||||||
globalClient.startConnection(settings.static("default_connect_url"), forumIdentity);
|
|
||||||
else
|
|
||||||
Modals.spawnConnectModal({
|
|
||||||
url: settings.static<string>("default_connect_url"),
|
|
||||||
enforce: true
|
|
||||||
}, { identity: IdentitifyType.TEAFORO, enforce: true});
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "teamspeak":
|
globalClient.startConnection(address, profile, username);
|
||||||
let connectIdentity = TSIdentityHelper.loadIdentity(settings.global("connect_identity_teamspeak_identity", ""));
|
|
||||||
if(!connectIdentity || !connectIdentity.valid())
|
|
||||||
Modals.spawnConnectModal({
|
|
||||||
url: settings.static<string>("default_connect_url"),
|
|
||||||
enforce: true
|
|
||||||
}, { identity: IdentitifyType.TEAMSPEAK, enforce: true});
|
|
||||||
else
|
|
||||||
globalClient.startConnection(settings.static("default_connect_url"), connectIdentity);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
Modals.spawnConnectModal({
|
|
||||||
url: settings.static<string>("default_connect_url"),
|
|
||||||
enforce: true
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
let tag = $("#tmpl_music_frame").renderTag({
|
let tag = $("#tmpl_music_frame").renderTag({
|
||||||
//thumbnail: "img/loading_image.svg"
|
//thumbnail: "img/loading_image.svg"
|
||||||
|
@ -220,7 +196,9 @@ function main() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
app.loadedListener.push(async () => {
|
loader.register_task(loader.Stage.LOADED, {
|
||||||
|
name: "async main invoke",
|
||||||
|
function: async () => {
|
||||||
try {
|
try {
|
||||||
await initialize();
|
await initialize();
|
||||||
main();
|
main();
|
||||||
|
@ -237,4 +215,7 @@ app.loadedListener.push(async () => {
|
||||||
ex = ex.name + ": " + ex.message;
|
ex = ex.name + ": " + ex.message;
|
||||||
displayCriticalError("Failed to invoke main function:<br>" + ex);
|
displayCriticalError("Failed to invoke main function:<br>" + ex);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
priority: 10
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue