2018-04-19 16:42:34 +00:00
namespace app {
export enum Type {
UNDEFINED ,
RELEASE ,
DEBUG
}
let module Initialized : boolean ;
let applicationLoaded : boolean ;
export let type : Type = Type . UNDEFINED ;
export let loadedListener : ( ( ) = > any ) [ ] ;
2018-04-19 17:46:47 +00:00
export const appLoaded = Date . now ( ) ;
2018-04-19 16:42:34 +00:00
export function initialized ( ) : boolean {
return module Initialized && applicationLoaded ;
}
export function callbackApp ( errorMessage? : string ) {
if ( errorMessage ) {
console . error ( "Could not load application!" ) ;
} else {
applicationLoaded = true ;
testInitialisation ( ) ;
}
}
export function initialize() {
module Initialized = false ;
applicationLoaded = false ;
loadedListener = [ ] ;
Module [ 'onRuntimeInitialized' ] = function ( ) {
console . log ( "Runtime init!" ) ;
module Initialized = true ;
testInitialisation ( ) ;
} ;
Module [ 'onAbort' ] = message = > {
Module [ 'onAbort' ] = undefined ;
displayCriticalError ( "Could not load webassembly files!<br>Message: <code>" + message + "</code>" , false ) ;
} ;
Module [ 'locateFile' ] = file = > {
console . log ( file + "|" + type ) ;
switch ( type ) {
case Type . RELEASE :
return "js/assembly/" + file ;
case Type . DEBUG :
return "asm/generated/" + file ;
}
} ;
}
function testInitialisation() {
if ( module Initialized && applicationLoaded )
for ( let l of loadedListener )
l ( ) ;
}
}
if ( typeof Module === "undefined" )
2018-04-19 13:59:00 +00:00
this [ "Module" ] = { } ;
2018-04-19 16:42:34 +00:00
app . initialize ( ) ;
2018-04-19 17:46:47 +00:00
app . loadedListener . push ( fadeoutLoader ) ;
2018-04-19 16:42:34 +00:00
2018-04-19 13:59:00 +00:00
2018-03-24 22:38:01 +00:00
function loadScripts ( paths : ( string | string [ ] ) [ ] ) : { path : string , promise : Promise < Boolean > } [ ] {
let result = [ ] ;
for ( let path of paths )
result . push ( { path : path , promise : loadScript ( path ) } ) ;
return result ;
}
function loadScript ( path : string | string [ ] ) : Promise < Boolean > {
if ( Array . isArray ( path ) ) { //Having fallbacks
return new Promise < Boolean > ( ( resolve , reject ) = > {
loadScript ( path [ 0 ] ) . then ( resolve ) . catch ( error = > {
if ( path . length >= 2 ) {
loadScript ( path . slice ( 1 ) ) . then ( resolve ) . catch ( ( ) = > reject ( "could not load file " + formatPath ( path ) ) ) ;
} else {
reject ( "could not load file (event fallback's)" ) ;
}
} ) ;
} ) ;
} else {
return new Promise < Boolean > ( ( resolve , reject ) = > {
const tag = document . createElement ( "script" ) ;
tag . type = "text\/javascript" ;
tag . onerror = error = > {
console . log ( error ) ;
tag . remove ( ) ;
reject ( error ) ;
} ;
tag . onload = ( ) = > 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() {
2018-04-19 16:42:34 +00:00
app . type = app . Type . RELEASE ;
2018-03-24 22:38:01 +00:00
console . log ( "Load for release!" ) ;
awaitLoad ( loadScripts ( [
//Load general API's
2018-04-19 16:42:34 +00:00
[ "js/assembly/TeaWeb-Identity.js" ] ,
2018-03-24 22:38:01 +00:00
[ "js/client.min.js" , "js/client.js" , "generated/js/client.min.js" , "generated/js/client.js" ]
] ) ) . then ( ( ) = > {
console . log ( "Loaded successfully all scripts!" ) ;
2018-04-19 16:42:34 +00:00
app . callbackApp ( ) ;
2018-03-24 22:38:01 +00:00
} ) . catch ( ( error ) = > {
console . error ( "Could not load " + error . path ) ;
} ) ;
}
/** Only possible for developers! **/
function loadDebug() {
2018-04-19 16:42:34 +00:00
app . type = app . Type . DEBUG ;
2018-03-24 22:38:01 +00:00
console . log ( "Load for debug!" ) ;
awaitLoad ( loadScripts ( [
2018-04-19 16:42:34 +00:00
[ "asm/generated/TeaWeb-Identity.js" ] ,
2018-03-24 22:38:01 +00:00
//Load general API's
2018-04-16 18:38:35 +00:00
"js/log.js" ,
2018-03-24 22:38:01 +00:00
"js/utils/modal.js" ,
"js/utils/tab.js" ,
2018-04-16 18:38:35 +00:00
"js/utils/helpers.js" ,
"js/crypto/sha.js" ,
"js/crypto/hex.js" ,
2018-03-24 22:38:01 +00:00
//Load UI
"js/ui/modal/ModalConnect.js" ,
"js/ui/modal/ModalSettings.js" ,
"js/ui/modal/ModalCreateChannel.js" ,
"js/ui/modal/ModalConnect.js" ,
2018-04-11 15:56:09 +00:00
"js/ui/modal/ModalChangeVolume.js" ,
2018-03-24 22:38:01 +00:00
"js/ui/channel.js" ,
"js/ui/client.js" ,
"js/ui/server.js" ,
"js/ui/view.js" ,
"js/ui/ControlBar.js" ,
//Load permissions
"js/permission/PermissionManager.js" ,
"js/permission/GroupManager.js" ,
//Load audio
"js/voice/VoiceHandler.js" ,
"js/voice/VoiceRecorder.js" ,
"js/voice/AudioResampler.js" ,
"js/voice/AudioController.js" ,
//Load codec
"js/codec/Codec.js" ,
2018-04-11 15:56:09 +00:00
"js/codec/BasicCodec.js" ,
"js/codec/CodecWrapper.js" ,
2018-03-24 22:38:01 +00:00
//Load general stuff
"js/settings.js" ,
"js/contextMenu.js" ,
"js/connection.js" ,
"js/FileManager.js" ,
"js/client.js" ,
"js/chat.js" ,
2018-04-11 15:56:09 +00:00
"js/InfoBar.js" ,
"js/Identity.js"
2018-03-24 22:38:01 +00:00
] ) ) . then ( ( ) = > {
awaitLoad ( loadScripts ( [ "js/main.js" ] ) ) . then ( ( ) = > {
console . log ( "Loaded successfully all scripts!" ) ;
2018-04-19 16:42:34 +00:00
app . callbackApp ( ) ;
2018-03-24 22:38:01 +00:00
} ) ;
} ) ;
}
function awaitLoad ( promises : { path : string , promise : Promise < Boolean > } [ ] ) : Promise < Boolean > {
return new Promise < Boolean > ( ( resolve , reject ) = > {
let awaiting = promises . length ;
for ( let entry of promises ) {
entry . promise . then ( ( ) = > {
awaiting -- ;
if ( awaiting == 0 ) resolve ( ) ;
} ) . catch ( error = > {
2018-04-11 15:56:09 +00:00
if ( error instanceof TypeError ) {
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 you're mistake<br>then please contact an administrator!" , false ) ;
return ;
} else {
console . error ( "Failed to load script " + entry . path ) ;
}
2018-03-24 22:38:01 +00:00
displayCriticalError ( "Failed to load script " + formatPath ( entry . path ) + ".<hr>If you believe that it isn't you're mistake<br>then please contact an administrator!" , false ) ;
} )
}
} ) ;
}
function displayCriticalError ( message : string , closeable : boolean = true ) {
if ( typeof ( createErrorModal ) !== 'undefined' ) {
createErrorModal ( "A critical error occurred while loading the page!" , message , { closeable : closeable } ) . open ( ) ;
} else {
let tag = document . getElementById ( "critical-load" ) ;
let detail = tag . getElementsByClassName ( "detail" ) [ 0 ] ;
detail . innerHTML = message ;
tag . style . display = "block" ;
}
2018-04-19 17:46:47 +00:00
fadeoutLoader ( ) ;
2018-03-24 22:38:01 +00:00
}
function loadTemplates() {
//Load the templates
$ . ajax ( "templates.html" , {
cache : false , //Change this when in release mode
} ) . then ( ( element , status ) = > {
let node = document . createElement ( "html" ) ;
node . innerHTML = element ;
let tags : HTMLCollection ;
if ( node . getElementsByTagName ( "body" ) . length > 0 )
tags = node . getElementsByTagName ( "body" ) [ 0 ] . children ;
else
tags = node . children ;
let root = document . getElementById ( "templates" ) ;
while ( tags . length > 0 )
root . appendChild ( tags . item ( 0 ) ) ;
} ) . catch ( error = > {
console . error ( "Could not load templates!" ) ;
console . log ( error ) ;
displayCriticalError ( "Could not load HTML templates!" , false ) ;
} ) ;
}
2018-04-18 18:12:10 +00:00
//TODO release config!
2018-03-24 22:38:01 +00:00
function loadSide() {
2018-04-19 17:46:47 +00:00
if ( typeof ( WebAssembly ) === "undefined" || typeof ( WebAssembly . compile ) === "undefined" ) {
displayCriticalError ( "You require WebAssembly for TeaSpeak-Web!" ) ;
return ;
}
2018-03-24 22:38:01 +00:00
//Load the general scripts and required scripts
awaitLoad ( loadScripts ( [
[ "vendor/jquery/jquery.min.js" , /*"https://code.jquery.com/jquery-latest.min.js"*/ ] ,
[ "https://webrtc.github.io/adapter/adapter-latest.js" ]
] ) ) . then ( ( ) = > awaitLoad ( loadScripts ( [
2018-04-11 15:56:09 +00:00
[ "https://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js" ]
2018-03-24 22:38:01 +00:00
] ) ) ) . then ( ( ) = > {
//Load the teaweb scripts
2018-04-19 16:42:34 +00:00
loadScript ( "js/proto.js" ) . then ( loadDebug ) . catch ( loadRelease ) ;
2018-03-24 22:38:01 +00:00
//Load the teaweb templates
loadTemplates ( ) ;
} ) ;
}
2018-04-19 17:46:47 +00:00
loadSide ( ) ;
//FUN: loader_ignore_age=0&loader_default_duration=1500&loader_default_age=5000
function fadeoutLoader ( duration = undefined , minAge = undefined , ignoreAge = undefined ) {
let settingsDefined = typeof ( StaticSettings ) !== "undefined" ;
if ( ! duration ) {
if ( settingsDefined )
duration = StaticSettings . instance . static ( "loader_default_duration" , 750 ) ;
else duration = 750 ;
}
if ( ! minAge ) {
if ( settingsDefined )
minAge = StaticSettings . instance . static ( "loader_default_age" , 1750 ) ;
else minAge = 750 ;
}
if ( ! ignoreAge ) {
if ( settingsDefined )
ignoreAge = StaticSettings . instance . static ( "loader_ignore_age" , false ) ;
else ignoreAge = false ;
}
let age = Date . now ( ) - app . appLoaded ;
if ( age < minAge && ! ignoreAge ) {
setTimeout ( ( ) = > fadeoutLoader ( duration , 0 , true ) , minAge - age ) ;
return ;
}
$ ( ".loader .bookshelf_wrapper" ) . animate ( { top : 0 , opacity : 0 } , duration ) ;
$ ( ".loader .half" ) . animate ( { width : 0 } , duration , ( ) = > {
$ ( ".loader" ) . detach ( ) ;
} ) ;
}