///
import {Arguments, process_args, parse_arguments} from "../shared/process-arguments";
import {remote} from "electron";
import * as crash_handler from "../crash_handler";
import * as electron from "electron";
import * as path from "path";
import * as os from "os";
/* first of all setup crash handler */
{
const is_electron_run = process.argv[0].endsWith("electron") || process.argv[0].endsWith("electron.exe");
crash_handler.initialize_handler("renderer", is_electron_run);
}
interface Window {
$: any;
jQuery: any;
jsrender: any;
impl_display_critical_error: any;
displayCriticalError: any;
teaclient_initialize: any;
open_connected_question: () => Promise;
}
declare const window: Window;
export const require_native: NodeRequireFunction = id => require(id);
export const initialize = async () => {
/* we use out own jquery resource */
loader.register_task(loader.Stage.JAVASCRIPT, {
name: "teaclient jquery",
function: jquery_initialize,
priority: 80
});
loader.register_task(loader.Stage.JAVASCRIPT, {
name: "teaclient general",
function: load_basic_modules,
priority: 10
});
loader.register_task(loader.Stage.JAVASCRIPT_INITIALIZING, {
name: "teaclient javascript init",
function: load_modules,
priority: 50
});
loader.register_task(loader.Stage.INITIALIZING, {
name: "teaclient initialize modules",
function: module_loader_setup,
priority: 60
});
loader.register_task(loader.Stage.INITIALIZING, {
name: "teaclient initialize persistent storage",
function: async () => {
const storage = require("./PersistentLocalStorage");
await storage.initialize();
},
priority: 90
});
loader.register_task(loader.Stage.INITIALIZING, {
name: "teaclient initialize logging",
function: initialize_logging,
priority: 80
});
loader.register_task(loader.Stage.INITIALIZING, {
name: "teaclient initialize error",
function: initialize_error_handler,
priority: 100
});
loader.register_task(loader.Stage.INITIALIZING, {
name: "teaclient initialize arguments",
function: async () => {
parse_arguments();
if(process_args.has_value(Arguments.DUMMY_CRASH_RENDERER))
crash_handler.handler.crash();
if(!process_args.has_flag(Arguments.DEBUG)) {
window.open_connected_question = () => {
return new Promise(resolve => {
remote.dialog.showMessageBox(remote.getCurrentWindow(), {
type: 'question',
buttons: ['Yes', 'No'],
title: 'Confirm',
message: 'Are you really sure?\nYou\'re still connected!'
}, choice => {
resolve(choice === 0);
});
});
};
}
},
priority: 110
});
loader.register_task(loader.Stage.INITIALIZING, {
name: 'gdb-waiter',
function: async () => {
if(process_args.has_flag(Arguments.DEV_TOOLS_GDB)) {
console.log("Process ID: %d", process.pid);
await new Promise(resolve => {
console.log("Waiting for continue!");
const listener = () => {
console.log("Continue");
document.removeEventListener('click', listener);
resolve();
};
document.addEventListener('click', listener);
});
}
},
priority: 100
});
};
const jquery_initialize = async () => {
window.$ = require("jquery");
window.jQuery = window.$;
Object.assign(window.$, window.jsrender = require('jsrender'));
};
const initialize_logging = async () => {
const logger = require("./logger");
logger.setup();
};
const initialize_error_handler = async () => {
const _impl = message => {
if(!process_args.has_flag(Arguments.DEBUG)) {
console.error("Displaying critical error: %o", message);
message = message.replace(/
/i, "\n");
const win = remote.getCurrentWindow();
remote.dialog.showMessageBox({
type: "error",
buttons: ["exit"],
title: "A critical error happened!",
message: message
});
win.close();
} else {
console.error("Received critical error: %o", message);
console.error("Ignoring error due to the debug mode");
}
};
if(window.impl_display_critical_error)
window.impl_display_critical_error = _impl;
else
window.displayCriticalError = _impl;
};
const module_loader_setup = async () => {
const native_paths = (() => {
const app_path = (remote || electron).app.getAppPath();
const result = [];
result.push(app_path + "/native/build/" + os.platform() + "_" + os.arch() + "/");
if(app_path.endsWith(".asar"))
result.push(path.join(path.dirname(app_path), "natives"));
return result;
})();
window["require_setup"] = _mod => {
if(!_mod || !_mod.paths) return;
console.dir(_mod);
_mod.paths.push(...native_paths);
const org_req = _mod.__proto__.require;
if(!_mod.proxied) {
_mod.require = function a(m) {
let stack = new Error().stack;
if(stack.startsWith("Error"))
stack = stack.substr(6);
//console.log("require \"%s\"\nStack:\n%s", m, stack);
return org_req.apply(_mod, [m]);
};
_mod.proxied = true;
}
};
};
const load_basic_modules = async () => {
console.dir(require("./audio/AudioPlayer")); /* setup audio */
console.dir(require("./audio/AudioRecorder")); /* setup audio */
require("./logger");
};
const load_modules = async () => {
window["require_setup"](this);
console.log(module.paths);
console.log("Loading native extensions...");
try {
try {
require("./ppt");
} catch(error) {
console.error("Failed to load ppt");
console.dir(error);
throw error;
}
try {
require("./version");
} catch(error) {
console.error("Failed to load version extension");
console.dir(error);
throw error;
}
try {
require("./connection/ServerConnection");
} catch(error) {
console.error("Failed to load server connection extension");
console.dir(error);
throw error;
}
try {
require("./connection/FileTransfer");
} catch(error) {
console.error("Failed to load file transfer extension");
console.dir(error);
throw error;
}
try {
require("./dns/dns_resolver");
} catch(error) {
console.error("Failed to load dns extension");
console.dir(error);
throw error;
}
try {
require("./context-menu");
} catch(error) {
console.error("Failed to load context menu extension");
console.dir(error);
throw error;
}
} catch(error){
console.log(error);
window.displayCriticalError("Failed to load native extensions: " + error);
throw error;
}
console.log("Loaded native extensions");
};