/// 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"); };