TeaWeb/shared/js/main.tsx

691 lines
26 KiB
TypeScript
Raw Normal View History

import * as moment from "moment";
2020-03-30 11:44:18 +00:00
import * as loader from "tc-loader";
import {settings, Settings} from "tc-shared/settings";
import * as profiles from "tc-shared/profiles/ConnectionProfile";
import * as log from "tc-shared/log";
import {LogCategory} from "tc-shared/log";
import * as bipc from "./ipc/BrowserIPC";
2020-03-30 11:44:18 +00:00
import * as sound from "./sound/Sounds";
import * as i18n from "./i18n/localize";
import {tra} from "./i18n/localize";
2020-03-30 11:44:18 +00:00
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
import {createInfoModal} from "tc-shared/ui/elements/Modal";
import * as stats from "./stats";
import * as fidentity from "./profiles/identities/TeaForumIdentity";
import {default_recorder, RecorderProfile, set_default_recorder} from "tc-shared/voice/RecorderProfile";
import * as cmanager from "tc-shared/ui/frames/connection_handlers";
import {server_connections} from "tc-shared/ui/frames/connection_handlers";
2020-03-30 11:44:18 +00:00
import {spawnConnectModal} from "tc-shared/ui/modal/ModalConnect";
import * as top_menu from "./ui/frames/MenuBar";
import {spawnYesNo} from "tc-shared/ui/modal/ModalYesNo";
import {formatMessage} from "tc-shared/ui/frames/chat";
import {openModalNewcomer} from "tc-shared/ui/modal/ModalNewcomer";
import * as aplayer from "tc-backend/audio/player";
import * as ppt from "tc-backend/ppt";
2020-04-10 18:57:50 +00:00
import * as keycontrol from "./KeyControl";
2020-04-06 14:28:15 +00:00
import * as React from "react";
import * as ReactDOM from "react-dom";
import * as cbar from "./ui/frames/control-bar";
import * as global_ev_handler from "./events/ClientGlobalControlHandler";
2020-04-21 14:17:21 +00:00
import {global_client_actions} from "tc-shared/events/GlobalEvents";
import {FileTransferState, TransferProvider,} from "tc-shared/file/Transfer";
import {MenuEntryType, spawn_context_menu} from "tc-shared/ui/elements/ContextMenu";
import {copy_to_clipboard} from "tc-shared/utils/helpers";
import ContextMenuEvent = JQuery.ContextMenuEvent;
2020-08-09 12:30:17 +00:00
import "svg-sprites/client-icons";
2020-04-06 14:28:15 +00:00
2020-03-30 11:44:18 +00:00
/* required import for init */
import "../css/load-css"
2020-07-19 16:49:00 +00:00
import "./proto";
import "./ui/elements/ContextDivider";
import "./ui/elements/Tab";
import "./connection/CommandHandler";
import {ConnectRequestData} from "tc-shared/ipc/ConnectHandler";
2020-08-08 13:20:32 +00:00
import "./video-viewer/Controller";
2020-03-30 11:44:18 +00:00
declare global {
interface Window {
open_connected_question: () => Promise<boolean>;
}
}
function setup_close() {
2018-10-06 13:13:45 +00:00
window.onbeforeunload = event => {
if(profiles.requires_save())
profiles.save();
2018-10-06 13:13:45 +00:00
if(!settings.static(Settings.KEY_DISABLE_UNLOAD_DIALOG, false)) {
const active_connections = server_connections.all_connections().filter(e => e.connected);
2019-04-04 19:47:52 +00:00
if(active_connections.length == 0) return;
2018-10-06 13:13:45 +00:00
2020-07-19 16:49:00 +00:00
if(__build.target === "web") {
event.returnValue = "Are you really sure?<br>You're still connected!";
} else {
2019-08-21 08:00:01 +00:00
const do_exit = () => {
const dp = server_connections.all_connections().map(e => {
2019-08-21 08:00:01 +00:00
if(e.serverConnection.connected())
return e.serverConnection.disconnect(tr("client closed"));
return Promise.resolve();
}).map(e => e.catch(() => {
2019-08-21 08:00:01 +00:00
console.warn(tr("Failed to disconnect from server on client close: %o"), e);
}));
const exit = () => {
2020-03-30 11:44:18 +00:00
const {remote} = window.require('electron');
2019-08-21 08:00:01 +00:00
remote.getCurrentWindow().close();
};
Promise.all(dp).then(exit);
/* force exit after 2500ms */
setTimeout(exit, 2500);
};
if(window.open_connected_question) {
event.preventDefault();
event.returnValue = "question";
window.open_connected_question().then(result => {
if(result) {
2019-08-21 08:00:01 +00:00
/* prevent quitting because we try to disconnect */
window.onbeforeunload = e => e.preventDefault();
2019-08-21 08:00:01 +00:00
/* allow a force quit after 5 seconds */
setTimeout(() => window.onbeforeunload, 5000);
do_exit();
}
});
2019-08-21 08:00:01 +00:00
} else {
/* we're in debugging mode */
do_exit();
}
}
2018-10-06 13:13:45 +00:00
}
};
}
function setup_jsrender() : boolean {
if(!$.views) {
2019-08-30 21:06:39 +00:00
loader.critical_error("Missing jsrender viewer extension!");
return false;
2018-10-07 16:21:28 +00:00
}
$.views.settings.allowCode(true);
$.views.tags("rnd", (argument) => {
2018-06-24 11:38:53 +00:00
let min = parseInt(argument.substr(0, argument.indexOf('~')));
let max = parseInt(argument.substr(argument.indexOf('~') + 1));
return (Math.round(Math.random() * (min + max + 1) - min)).toString();
});
$.views.tags("fmt_date", (...args) => {
return moment(args[0]).format(args[1]);
});
$.views.tags("tr", (...args) => {
2020-03-31 13:19:53 +00:00
return /* @tr-ignore */ tr(args[0]);
});
$(".jsrender-template").each((idx, _entry) => {
if(!$.templates(_entry.id, _entry.innerHTML)) {
2019-08-30 21:06:39 +00:00
log.error(LogCategory.GENERAL, tr("Failed to setup cache for js renderer template %s!"), _entry.id);
} else
log.trace(LogCategory.GENERAL, tr("Successfully loaded jsrender template %s"), _entry.id);
});
return true;
}
async function initialize() {
try {
await i18n.initialize();
} catch(error) {
console.error(tr("Failed to initialized the translation system!\nError: %o"), error);
2019-08-30 21:06:39 +00:00
loader.critical_error("Failed to setup the translation system");
return;
}
2019-04-04 19:47:52 +00:00
bipc.setup();
}
async function initialize_app() {
try { //Initialize main template
2019-08-21 08:00:01 +00:00
const main = $("#tmpl_main").renderTag({
multi_session: !settings.static_global(Settings.KEY_DISABLE_MULTI_SESSION),
app_version: __build.version
2019-08-21 08:00:01 +00:00
}).dividerfy();
$("body").append(main);
} catch(error) {
2019-08-30 21:06:39 +00:00
log.error(LogCategory.GENERAL, error);
loader.critical_error(tr("Failed to setup main page!"));
return;
}
cmanager.initialize();
global_ev_handler.initialize(global_client_actions);
2020-04-06 14:28:15 +00:00
{
const bar = (
2020-04-06 14:29:40 +00:00
<cbar.ControlBar ref={cbar.react_reference()} multiSession={true} />
2020-04-06 14:28:15 +00:00
);
ReactDOM.render(bar, $(".container-control-bar")[0]);
}
/*
loader.register_task(loader.Stage.JAVASCRIPT_INITIALIZING, {
name: "settings init",
priority: 10,
function: async () => global_ev_handler.load_default_states(client_control_events)
});
*/
2019-04-04 19:47:52 +00:00
2020-03-30 11:44:18 +00:00
if(!aplayer.initialize())
2019-04-04 19:47:52 +00:00
console.warn(tr("Failed to initialize audio controller!"));
2020-03-30 11:44:18 +00:00
aplayer.on_ready(() => {
if(aplayer.set_master_volume)
aplayer.on_ready(() => aplayer.set_master_volume(settings.global(Settings.KEY_SOUND_MASTER) / 100));
else
2020-03-30 11:44:18 +00:00
log.warn(LogCategory.GENERAL, tr("Client does not support aplayer.set_master_volume()... May client is too old?"));
});
2019-04-04 19:47:52 +00:00
2020-03-30 11:44:18 +00:00
set_default_recorder(new RecorderProfile("default"));
default_recorder.initialize().catch(error => {
log.error(LogCategory.AUDIO, tr("Failed to initialize default recorder: %o"), error);
});
2019-04-04 19:47:52 +00:00
sound.initialize().then(() => {
2019-08-30 21:06:39 +00:00
log.info(LogCategory.AUDIO, tr("Sounds initialized"));
2019-04-04 19:47:52 +00:00
});
2019-08-21 08:00:01 +00:00
sound.set_master_volume(settings.global(Settings.KEY_SOUND_MASTER_SOUNDS) / 100);
2019-04-04 19:47:52 +00:00
await profiles.load();
2018-04-11 15:56:09 +00:00
try {
await ppt.initialize();
} catch(error) {
2019-08-30 21:06:39 +00:00
log.error(LogCategory.GENERAL, tr("Failed to initialize ppt!\nError: %o"), error);
loader.critical_error(tr("Failed to initialize ppt!"));
return;
}
Implemented the Material Design and fixed some bugs (#33) * cleaned up some files * Fundamental style update * Redesigned some style * fixed hostbanner popup * Removed old identity stuff * fixed close listener * Fixed changelog date * fixed release chat icons * fixed url * Fixed hostbanner * Uploaded missing images * Improved update handling * Improved script files * Fixed loading error and icon error * fixed Yes/No modal * Fixed loader issues with MS Edge * fixed modal style bug * Fixed control bar overflow for small devices * Improved error handling on identity creation * Logging generate error to terminal * fixed possible php error * fixed some possible loading errors when other files have'nt been already loaded. * removed debug message * Changed emsrcypten flags * Improved codec error handling * removed webassembly as required dependency * Improved and fixed channel tree issues * Improved the sliders * Removed unneeded files * fixed loader versions cache * second slight performance improved (dont animate elements anymore if they are not shown) * Fixed query visibility setting * not showing useless client infos for query clients * Added an auto reconnect system * Added a canceled message and increased reconnect interval * removed implemented todo * fixed repetitive channel names * Reworked the channel tree selected lines * Fixed channel tree names * Fixed name alignment * fixed the native client * added min width to the server select groups to avoid a disappearing effect on shrink * fixed bugged downloaded icons
2019-02-17 15:08:10 +00:00
setup_close();
}
/*
class TestProxy extends bipc.MethodProxy {
constructor(params: bipc.MethodProxyConnectParameters) {
super(bipc.get_handler(), params.channel_id && params.client_id ? params : undefined);
if(!this.is_slave()) {
this.register_method(this.add_slave);
}
if(!this.is_master()) {
this.register_method(this.say_hello);
this.register_method(this.add_master);
}
}
setup() {
super.setup();
}
protected on_connected() {
2019-08-30 21:06:39 +00:00
log.info(LogCategory.IPC, "Test proxy connected");
}
protected on_disconnected() {
2019-08-30 21:06:39 +00:00
log.info(LogCategory.IPC, "Test proxy disconnected");
}
private async say_hello() : Promise<void> {
2019-08-30 21:06:39 +00:00
log.info(LogCategory.IPC, "Hello World");
}
private async add_slave(a: number, b: number) : Promise<number> {
return a + b;
}
private async add_master(a: number, b: number) : Promise<number> {
return a * b;
}
}
interface Window {
proxy_instance: TestProxy & {url: () => string};
}
*/
export function handle_connect_request(properties: ConnectRequestData, connection: ConnectionHandler) {
const profile_uuid = properties.profile || (profiles.default_profile() || {id: 'default'}).id;
const profile = profiles.find_profile(profile_uuid) || profiles.default_profile();
const username = properties.username || profile.connect_username();
const password = properties.password ? properties.password.value : "";
const password_hashed = properties.password ? properties.password.hashed : false;
if(profile && profile.valid()) {
connection.startConnection(properties.address, profile, true, {
nickname: username,
password: password.length > 0 ? {
password: password,
hashed: password_hashed
} : undefined
});
server_connections.set_active_connection(connection);
} else {
2020-03-30 11:44:18 +00:00
spawnConnectModal({},{
url: properties.address,
enforce: true
}, {
profile: profile,
enforce: true
});
2019-09-18 23:25:57 +00:00
}
}
function main() {
/*
window.proxy_instance = new TestProxy({
client_id: settings.static_global<string>("proxy_client_id", undefined),
channel_id: settings.static_global<string>("proxy_channel_id", undefined)
}) as any;
if(window.proxy_instance.is_master()) {
window.proxy_instance.setup();
window.proxy_instance.url = () => {
const data = window.proxy_instance.generate_connect_parameters();
return "proxy_channel_id=" + data.channel_id + "&proxy_client_id=" + data.client_id;
};
}
*/
//http://localhost:63343/Web-Client/index.php?_ijt=omcpmt8b9hnjlfguh8ajgrgolr&default_connect_url=true&default_connect_type=teamspeak&default_connect_url=localhost%3A9987&disableUnloadDialog=1&loader_ignore_age=1
2019-04-04 19:47:52 +00:00
2019-08-21 08:00:01 +00:00
/* initialize font */
{
2019-09-12 21:59:35 +00:00
const font = settings.static_global(Settings.KEY_FONT_SIZE, 14); //parseInt(getComputedStyle(document.body).fontSize)
2019-08-21 08:00:01 +00:00
$(document.body).css("font-size", font + "px");
}
/* context menu prevent */
$(document).on('contextmenu', (event: ContextMenuEvent) => {
2019-08-21 08:00:01 +00:00
if(event.isDefaultPrevented())
return;
if(event.target instanceof HTMLInputElement) {
if((!!event.target.value || __build.target === "client") && !event.target.disabled && !event.target.readOnly && event.target.type !== "number") {
spawn_context_menu(event.pageX, event.pageY, {
type: MenuEntryType.ENTRY,
name: tr("Copy"),
callback: () => {
copy_to_clipboard(event.target.value);
},
icon_class: "client-copy",
visible: !!event.target.value
}, {
type: MenuEntryType.ENTRY,
name: tr("Paste"),
callback: () => {
const { clipboard } = __non_webpack_require__('electron');
event.target.value = clipboard.readText();
},
icon_class: "client-copy",
visible: __build.target === "client",
});
}
event.preventDefault();
return;
}
2019-08-21 08:00:01 +00:00
if(!settings.static_global(Settings.KEY_DISABLE_GLOBAL_CONTEXT_MENU))
event.preventDefault();
});
top_menu.initialize();
const initial_handler = server_connections.spawn_server_connection();
initial_handler.acquire_recorder(default_recorder, false);
cmanager.server_connections.set_active_connection(initial_handler);
2018-04-11 15:56:09 +00:00
/** Setup the XF forum identity **/
2020-03-30 11:44:18 +00:00
fidentity.update_forum();
2018-04-11 15:56:09 +00:00
let _resize_timeout;
2019-04-04 19:47:52 +00:00
$(window).on('resize', event => {
if(event.target !== window)
return;
2018-11-03 23:39:29 +00:00
if(_resize_timeout)
clearTimeout(_resize_timeout);
_resize_timeout = setTimeout(() => {
for(const connection of server_connections.all_connections())
2019-04-04 19:47:52 +00:00
connection.invoke_resized_on_activate = true;
const active_connection = server_connections.active_connection();
2019-04-04 19:47:52 +00:00
if(active_connection)
active_connection.resize_elements();
2019-04-29 17:35:16 +00:00
$(".window-resize-listener").trigger('resize');
2018-11-03 23:39:29 +00:00
}, 1000);
2018-10-06 13:13:45 +00:00
});
2020-04-10 18:57:50 +00:00
keycontrol.initialize();
2019-02-25 14:59:42 +00:00
stats.initialize({
verbose: true,
anonymize_ip_addresses: true,
volatile_collection_only: false
});
stats.register_user_count_listener(status => {
2019-08-30 21:06:39 +00:00
log.info(LogCategory.STATISTICS, tr("Received user count update: %o"), status);
2019-02-25 14:59:42 +00:00
});
2019-03-25 19:04:04 +00:00
server_connections.set_active_connection(server_connections.all_connections()[0]);
2019-09-18 23:25:57 +00:00
/*
2020-04-06 14:28:15 +00:00
(window as any).test_upload = (message?: string) => {
2019-04-04 19:47:52 +00:00
message = message || "Hello World";
const connection = server_connections.active_connection();
2019-04-04 19:47:52 +00:00
connection.fileManager.upload_file({
size: message.length,
2019-03-28 16:30:00 +00:00
overwrite: true,
2019-04-04 19:47:52 +00:00
channel: connection.getClient().currentChannel(),
2019-03-28 16:30:00 +00:00
name: '/HelloWorld.txt',
path: ''
}).then(key => {
const upload = new RequestFileUpload(key);
2019-04-04 19:47:52 +00:00
const buffer = new Uint8Array(message.length);
2019-03-28 16:30:00 +00:00
{
2019-04-04 19:47:52 +00:00
for(let index = 0; index < message.length; index++)
buffer[index] = message.charCodeAt(index);
2019-03-28 16:30:00 +00:00
}
upload.put_data(buffer).catch(error => {
console.error(error);
});
})
};
*/
(window as any).test_download = async () => {
const connection = server_connections.active_connection();
const download = connection.fileManager.initializeFileDownload({
targetSupplier: async () => await TransferProvider.provider().createDownloadTarget(),
name: "HomeStudent2019Retail.img",
path: "/",
channel: 4
});
console.log("Download stated");
await download.awaitFinished();
console.log("Download finished (%s)", FileTransferState[download.transferState()]);
//console.log(await (download.target as ResponseTransferTarget).getResponse().blob());
console.log("Have buffer");
};
(window as any).test_upload = async () => {
const connection = server_connections.active_connection();
const download = connection.fileManager.initializeFileUpload({
source: async () => await TransferProvider.provider().createTextSource("Hello my lovely world...."),
name: "test-upload.txt",
path: "/",
channel: 4
});
console.log("Download stated");
await download.awaitFinished();
console.log("Download finished (%s)", FileTransferState[download.transferState()]);
//console.log(await (download.target as ResponseTransferTarget).getResponse().blob());
console.log("Have buffer");
};
2019-04-04 19:47:52 +00:00
2019-09-18 23:25:57 +00:00
/* schedule it a bit later then the main because the main function is still within the loader */
2019-08-21 08:00:01 +00:00
setTimeout(() => {
const connection = server_connections.active_connection();
2019-08-21 08:00:01 +00:00
/*
Modals.createChannelModal(connection, undefined, undefined, connection.permissions, (cb, perms) => {
});
*/
2019-08-30 21:06:39 +00:00
// Modals.openServerInfo(connection.channelTree.server);
2019-08-21 08:00:01 +00:00
//Modals.createServerModal(connection.channelTree.server, properties => Promise.resolve());
2019-09-12 21:59:35 +00:00
//Modals.openClientInfo(connection.getClient());
//Modals.openServerInfoBandwidth(connection.channelTree.server);
2019-09-18 23:25:57 +00:00
//Modals.openBanList(connection);
/*
Modals.spawnBanClient(connection,[
{name: "WolverinDEV", unique_id: "XXXX"},
{name: "WolverinDEV", unique_id: "XXXX"},
{name: "WolverinDEV", unique_id: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"},
{name: "WolverinDEV", unique_id: "YYY"}
], () => {});
*/
2019-09-12 21:59:35 +00:00
}, 4000);
//spawnSettingsModal("general-keymap");
2019-08-21 08:00:01 +00:00
//Modals.spawnKeySelect(console.log);
2019-09-12 21:59:35 +00:00
//Modals.spawnBookmarkModal();
/*
{
const modal = createModal({
header: tr("Test Net Graph"),
body: () => {
const canvas = $.spawn("canvas")
.css("position", "absolute")
.css({
top: 0,
bottom: 0,
right: 0,
left: 0
});
return $.spawn("div")
.css("height", "5em")
.css("width", "30em")
.css("position", "relative")
.append(canvas);
},
footer: null
});
const graph = new net.graph.Graph(modal.htmlTag.find("canvas")[0] as any);
graph.initialize();
modal.close_listener.push(() => graph.terminate());
modal.open();
}
*/
2020-06-15 14:56:05 +00:00
//setTimeout(() => spawnPermissionEditorModal(server_connections.active_connection()), 3000);
//setTimeout(() => spawnGroupCreate(server_connections.active_connection(), "server"), 3000);
2020-03-27 15:15:15 +00:00
if(settings.static_global(Settings.KEY_USER_IS_NEW)) {
2020-03-30 11:44:18 +00:00
const modal = openModalNewcomer();
2020-03-27 15:15:15 +00:00
modal.close_listener.push(() => settings.changeGlobal(Settings.KEY_USER_IS_NEW, false));
}
//spawnVideoPopout(server_connections.active_connection(), "https://www.youtube.com/watch?v=9683D18fyvs");
2018-04-19 16:42:34 +00:00
}
2019-04-04 19:47:52 +00:00
const task_teaweb_starter: loader.Task = {
name: "voice app starter",
2018-12-30 00:38:13 +00:00
function: async () => {
try {
2019-04-04 19:47:52 +00:00
await initialize_app();
2018-12-30 00:38:13 +00:00
main();
2020-03-30 11:44:18 +00:00
if(!aplayer.initialized()) {
2018-12-30 00:38:13 +00:00
log.info(LogCategory.VOICE, tr("Initialize audio controller later!"));
2020-03-30 11:44:18 +00:00
if(!aplayer.initializeFromGesture) {
console.error(tr("Missing aplayer.initializeFromGesture"));
2018-12-30 00:38:13 +00:00
} else
$(document).one('click', () => aplayer.initializeFromGesture());
2018-12-30 00:38:13 +00:00
}
} catch (ex) {
console.error(ex.stack);
if(ex instanceof ReferenceError || ex instanceof TypeError)
ex = ex.name + ": " + ex.message;
2019-08-30 21:06:39 +00:00
loader.critical_error("Failed to invoke main function:<br>" + ex);
2018-09-25 15:39:38 +00:00
}
2018-12-30 00:38:13 +00:00
},
priority: 10
2019-04-04 19:47:52 +00:00
};
const task_connect_handler: loader.Task = {
name: "Connect handler",
function: async () => {
const address = settings.static(Settings.KEY_CONNECT_ADDRESS, "");
const chandler = bipc.getInstanceConnectHandler();
if(settings.static(Settings.KEY_FLAG_CONNECT_DEFAULT, false) && address) {
const connect_data = {
address: address,
profile: settings.static(Settings.KEY_CONNECT_PROFILE, ""),
username: settings.static(Settings.KEY_CONNECT_USERNAME, ""),
password: {
value: settings.static(Settings.KEY_CONNECT_PASSWORD, ""),
hashed: settings.static(Settings.KEY_FLAG_CONNECT_PASSWORD, false)
}
};
2020-06-15 14:56:05 +00:00
if(chandler && !settings.static(Settings.KEY_CONNECT_NO_SINGLE_INSTANCE)) {
try {
await chandler.post_connect_request(connect_data, () => new Promise<boolean>((resolve, reject) => {
spawnYesNo(tr("Another TeaWeb instance is already running"), tra("Another TeaWeb instance is already running.{:br:}Would you like to connect there?"), response => {
resolve(response);
}, {
closeable: false
}).open();
}));
log.info(LogCategory.CLIENT, tr("Executed connect successfully in another browser window. Closing this window"));
const message =
"You're connecting to {0} within the other TeaWeb instance.{:br:}" +
"You could now close this page.";
createInfoModal(
tr("Connecting successfully within other instance"),
2020-03-31 13:19:53 +00:00
formatMessage(/* @tr-ignore */ tr(message), connect_data.address),
{
closeable: false,
footer: undefined
}
).open();
return;
} catch(error) {
log.info(LogCategory.CLIENT, tr("Failed to execute connect within other TeaWeb instance. Using this one. Error: %o"), error);
}
}
loader.register_task(loader.Stage.LOADED, {
priority: 0,
function: async () => handle_connect_request(connect_data, server_connections.active_connection() || server_connections.spawn_server_connection()),
name: tr("default url connect")
});
}
if(chandler) {
/* no instance avail, so lets make us avail */
chandler.callback_available = data => {
return !settings.static_global(Settings.KEY_DISABLE_MULTI_SESSION);
};
chandler.callback_execute = data => {
handle_connect_request(data, server_connections.spawn_server_connection());
return true;
}
}
loader.register_task(loader.Stage.LOADED, task_teaweb_starter);
},
priority: 10
};
2019-04-04 19:47:52 +00:00
const task_certificate_callback: loader.Task = {
name: "certificate accept tester",
function: async () => {
/*
This is not needed any more. If we would use the certificate accept stuff, we would have an extra loader target.
I'm just keeping this, so later I've not to to any work, writing this, again.
2019-04-04 19:47:52 +00:00
const certificate_accept = settings.static_global(Settings.KEY_CERTIFICATE_CALLBACK, undefined);
if(certificate_accept) {
log.info(LogCategory.IPC, tr("Using this instance as certificate callback. ID: %s"), certificate_accept);
try {
try {
await bipc.getInstance().post_certificate_accpected(certificate_accept);
2019-04-04 19:47:52 +00:00
} catch(e) {} //FIXME remove!
log.info(LogCategory.IPC, tr("Other instance has acknowledged out work. Closing this window."));
const seconds_tag = $.spawn("a");
let seconds = 5;
let interval_id;
interval_id = setInterval(() => {
seconds--;
seconds_tag.text(seconds.toString());
if(seconds <= 0) {
clearTimeout(interval_id);
log.info(LogCategory.GENERAL, tr("Closing window"));
window.close();
return;
}
}, 1000);
createInfoModal(
tr("Certificate acccepted successfully"),
formatMessage(tr("You've successfully accepted the certificate.{:br:}This page will close in {0} seconds."), seconds_tag),
2019-04-04 19:47:52 +00:00
{
closeable: false,
footer: undefined
}
).open();
return;
} catch(error) {
log.warn(LogCategory.IPC, tr("Failed to successfully post certificate accept status: %o"), error);
}
} else {
log.info(LogCategory.IPC, tr("We're not used to accept certificated. Booting app."));
}
*/
loader.register_task(loader.Stage.LOADED, task_connect_handler);
2019-04-04 19:47:52 +00:00
},
priority: 10
};
loader.register_task(loader.Stage.JAVASCRIPT_INITIALIZING, {
name: "jrendere initialize",
function: async () => {
try {
if(!setup_jsrender())
throw "invalid load";
} catch (error) {
2019-08-30 21:06:39 +00:00
loader.critical_error(tr("Failed to setup jsrender"));
console.error(tr("Failed to load jsrender! %o"), error);
return;
}
},
priority: 100
});
loader.register_task(loader.Stage.JAVASCRIPT_INITIALIZING, {
2019-04-04 19:47:52 +00:00
name: "app starter",
function: async () => {
try {
await initialize();
if(__build.target == "web") {
2019-04-04 19:47:52 +00:00
loader.register_task(loader.Stage.LOADED, task_certificate_callback);
} else {
2019-04-04 19:47:52 +00:00
loader.register_task(loader.Stage.LOADED, task_teaweb_starter);
}
2019-04-04 19:47:52 +00:00
} catch (ex) {
if(ex instanceof Error || typeof(ex.stack) !== "undefined")
console.error((tr || (msg => msg))("Critical error stack trace: %o"), ex.stack);
2019-04-04 19:47:52 +00:00
if(ex instanceof ReferenceError || ex instanceof TypeError)
ex = ex.name + ": " + ex.message;
2019-08-30 21:06:39 +00:00
loader.critical_error("Failed to boot app function:<br>" + ex);
2019-04-04 19:47:52 +00:00
}
},
priority: 1000
2018-10-06 13:13:45 +00:00
});
2018-12-30 00:38:13 +00:00
2020-03-30 11:44:18 +00:00
loader.register_task(loader.Stage.LOADED, {
name: "error task",
function: async () => {
if(Settings.instance.static(Settings.KEY_LOAD_DUMMY_ERROR, false)) {
loader.critical_error("The tea is cold!", "Argh, this is evil! Cold tea dosn't taste good.");
throw "The tea is cold!";
}
},
priority: 20
2020-04-01 13:40:45 +00:00
});