2020-09-12 13:49:20 +00:00
import * as log from "./log" ;
2021-01-10 16:36:57 +00:00
import { LogCategory , logError , logTrace } from "./log" ;
2020-03-30 11:44:18 +00:00
import * as loader from "tc-loader" ;
2020-07-20 17:08:13 +00:00
import { Stage } from "tc-loader" ;
2020-09-12 13:49:20 +00:00
import { Registry } from "./events" ;
2020-11-29 13:42:02 +00:00
import { tr } from "./i18n/localize" ;
2018-03-24 22:38:01 +00:00
2021-01-10 15:13:15 +00:00
export type RegistryValueType = boolean | number | string | object ;
export type RegistryValueTypeNames = "boolean" | "number" | "string" | "object" ;
2020-08-09 12:30:17 +00:00
2021-01-10 15:13:15 +00:00
export type RegistryValueTypeMapping < T > = T extends boolean ? "boolean" :
T extends number ? "number" :
T extends string ? "string" :
T extends object ? "object" :
never ;
2020-07-19 16:49:00 +00:00
2021-01-10 15:13:15 +00:00
export interface RegistryKey < ValueType extends RegistryValueType > {
2019-03-17 11:15:39 +00:00
key : string ;
2021-01-10 15:13:15 +00:00
valueType : RegistryValueTypeMapping < ValueType > ;
2020-07-19 16:49:00 +00:00
fallbackKeys? : string | string [ ] ;
fallbackImports ? : { [ key : string ] : ( value : string ) = > ValueType } ;
2019-03-17 11:15:39 +00:00
description? : string ;
2019-08-21 08:00:01 +00:00
2020-07-19 16:49:00 +00:00
requireRestart? : boolean ;
}
2021-01-10 15:13:15 +00:00
export interface ValuedRegistryKey < ValueType extends RegistryValueType > extends RegistryKey < ValueType > {
2020-07-19 16:49:00 +00:00
defaultValue : ValueType ;
2019-03-17 11:15:39 +00:00
}
2021-01-10 15:13:15 +00:00
const UPDATE_DIRECT : boolean = true ;
2018-02-27 16:20:49 +00:00
2021-01-10 15:13:15 +00:00
function decodeValueFromString < T extends RegistryValueType > ( input : string , type : RegistryValueTypeMapping < T > ) : T {
switch ( type ) {
case "string" :
return input as any ;
2020-07-19 16:49:00 +00:00
2021-01-10 15:13:15 +00:00
case "boolean" :
return ( input === "1" || input === "true" ) as any ;
2020-07-19 16:49:00 +00:00
2021-01-10 15:13:15 +00:00
case "number" :
return parseFloat ( input ) as any ;
2019-03-17 11:15:39 +00:00
2021-01-10 15:13:15 +00:00
case "object" :
try {
return JSON . parse ( input ) ;
} catch ( error ) {
return { } as any ;
}
2020-08-09 12:30:17 +00:00
2021-01-10 15:13:15 +00:00
default :
throw "value not decodable" ;
2018-04-19 17:46:47 +00:00
}
2021-01-10 15:13:15 +00:00
}
2020-07-19 16:49:00 +00:00
2021-01-10 15:13:15 +00:00
function encodeValueToString < T extends RegistryValueType > ( input : T ) : string {
switch ( typeof input ) {
case "string" :
return input ;
2020-07-19 16:49:00 +00:00
2021-01-10 15:13:15 +00:00
case "boolean" :
return input ? "1" : "0" ;
2018-02-27 16:20:49 +00:00
2021-01-10 15:13:15 +00:00
case "number" :
return input . toString ( ) ;
2020-07-19 16:49:00 +00:00
2021-01-10 15:13:15 +00:00
case "object" :
return JSON . stringify ( input ) ;
2020-08-09 12:30:17 +00:00
2021-01-10 15:13:15 +00:00
default :
throw "value has invalid type" ;
2018-04-19 17:46:47 +00:00
}
2021-01-10 15:13:15 +00:00
}
2018-02-27 16:20:49 +00:00
2021-01-10 15:13:15 +00:00
function resolveKey < ValueType extends RegistryValueType , DefaultType > (
key : RegistryKey < ValueType > ,
2021-02-19 22:05:48 +00:00
resolver : ( key : string ) = > string | undefined | null ,
2021-01-10 15:13:15 +00:00
defaultValue : DefaultType
) : ValueType | DefaultType {
let value = resolver ( key . key ) ;
2021-02-19 22:05:48 +00:00
2021-01-10 15:13:15 +00:00
if ( typeof value === "string" ) {
2021-01-10 16:36:57 +00:00
return decodeValueFromString ( value , key . valueType ) ;
2019-03-17 11:15:39 +00:00
}
2019-04-04 19:47:52 +00:00
2021-01-10 15:13:15 +00:00
/* trying fallback values */
2021-01-10 16:36:57 +00:00
for ( const fallback of key . fallbackKeys || [ ] ) {
2021-01-10 15:13:15 +00:00
value = resolver ( fallback ) ;
if ( typeof value !== "string" ) {
continue ;
}
2019-03-17 11:15:39 +00:00
2021-02-14 16:22:53 +00:00
if ( key . fallbackImports ) {
const fallbackValueImporter = key . fallbackImports [ fallback ] ;
if ( fallbackValueImporter ) {
return fallbackValueImporter ( value ) ;
}
2018-04-19 17:46:47 +00:00
}
2021-01-10 15:13:15 +00:00
2021-02-14 16:22:53 +00:00
return decodeValueFromString ( value , key . valueType ) ;
2018-04-16 18:38:35 +00:00
}
2021-01-10 15:13:15 +00:00
return defaultValue ;
}
2021-02-19 22:05:48 +00:00
export class UrlParameterParser {
private readonly url : URL ;
constructor ( url : URL ) {
this . url = url ;
}
private getParameter ( key : string ) : string | undefined {
const value = this . url . searchParams . get ( key ) ;
if ( value === null ) {
return undefined ;
}
return decodeURIComponent ( value ) ;
}
2021-01-10 15:13:15 +00:00
2021-02-19 22:05:48 +00:00
getValue < V extends RegistryValueType , DV > ( key : RegistryKey < V > , defaultValue : DV ) : V | DV ;
getValue < V extends RegistryValueType > ( key : ValuedRegistryKey < V > , defaultValue? : V ) : V ;
getValue < V extends RegistryValueType , DV > ( key : RegistryKey < V > | ValuedRegistryKey < V > , defaultValue : DV ) : V | DV {
if ( arguments . length > 1 ) {
return resolveKey ( key , key = > this . getParameter ( key ) , defaultValue ) ;
} else if ( "defaultValue" in key ) {
return resolveKey ( key , key = > this . getParameter ( key ) , key . defaultValue ) ;
2019-04-04 19:47:52 +00:00
} else {
2021-02-19 22:05:48 +00:00
throw tr ( "missing value" ) ;
2019-04-04 19:47:52 +00:00
}
2021-02-19 22:05:48 +00:00
}
}
2019-04-04 19:47:52 +00:00
2021-02-19 22:05:48 +00:00
export class UrlParameterBuilder {
private parameters = { } ;
setValue < V extends RegistryValueType > ( key : RegistryKey < V > , value : V ) {
if ( value === undefined ) {
delete this . parameters [ key . key ] ;
} else {
this . parameters [ key . key ] = encodeURIComponent ( encodeValueToString ( value ) ) ;
}
2018-04-16 18:38:35 +00:00
}
2021-02-19 22:05:48 +00:00
build ( ) : string {
return Object . keys ( this . parameters ) . map ( key = > ` ${ key } = ${ this . parameters [ key ] } ` ) . join ( "&" ) ;
}
}
/ * *
* Switched appended to the application via the URL .
* TODO : Passing native client switches
* /
export namespace AppParameters {
export const Instance = new UrlParameterParser ( new URL ( window . location . href ) ) ;
2021-01-10 15:13:15 +00:00
export function getValue < V extends RegistryValueType , DV > ( key : RegistryKey < V > , defaultValue : DV ) : V | DV ;
export function getValue < V extends RegistryValueType > ( key : ValuedRegistryKey < V > , defaultValue? : V ) : V ;
export function getValue < V extends RegistryValueType , DV > ( key : RegistryKey < V > | ValuedRegistryKey < V > , defaultValue : DV ) : V | DV {
if ( arguments . length > 1 ) {
2021-02-19 22:05:48 +00:00
return Instance . getValue ( key , defaultValue ) ;
2021-01-10 15:13:15 +00:00
} else if ( "defaultValue" in key ) {
2021-02-19 22:05:48 +00:00
return Instance . getValue ( key ) ;
2021-01-10 15:13:15 +00:00
} else {
throw tr ( "missing value" ) ;
}
}
}
2021-02-19 22:05:48 +00:00
2021-01-16 12:36:06 +00:00
( window as any ) . AppParameters = AppParameters ;
2018-02-27 16:20:49 +00:00
2021-01-10 15:13:15 +00:00
export namespace AppParameters {
export const KEY_CONNECT_ADDRESS : RegistryKey < string > = {
key : "ca" ,
fallbackKeys : [ "connect_address" ] ,
valueType : "string" ,
description : "A target address to automatically connect to."
} ;
2021-02-20 15:57:52 +00:00
export const KEY_CONNECT_INVITE_REFERENCE : RegistryKey < string > = {
key : "cir" ,
fallbackKeys : [ "connect-invite-reference" ] ,
valueType : "string" ,
description : "The invite link used to generate the connect parameters"
} ;
2021-01-10 15:13:15 +00:00
export const KEY_CONNECT_NO_SINGLE_INSTANCE : ValuedRegistryKey < boolean > = {
key : "cnsi" ,
fallbackKeys : [ "connect_no_single_instance" ] ,
defaultValue : false ,
valueType : "boolean" ,
} ;
export const KEY_CONNECT_TYPE : ValuedRegistryKey < number > = {
key : "ct" ,
fallbackKeys : [ "connect_type" ] ,
valueType : "number" ,
defaultValue : 0 ,
description : "Connection establish type for automatic connect attempts.\n0 = Connect directly\n1 = Open connect modal"
} ;
export const KEY_CONNECT_NICKNAME : RegistryKey < string > = {
key : "cn" ,
2021-02-19 22:05:48 +00:00
fallbackKeys : [ "connect_username" , "nickname" ] ,
2021-01-10 15:13:15 +00:00
valueType : "string"
} ;
export const KEY_CONNECT_TOKEN : RegistryKey < string > = {
key : "ctk" ,
2021-02-19 22:05:48 +00:00
fallbackKeys : [ "connect_token" , "connect-token" , "token" ] ,
2021-01-10 15:13:15 +00:00
valueType : "string" ,
description : "Token which will be used by default if the connection attempt succeeded."
} ;
export const KEY_CONNECT_PROFILE : RegistryKey < string > = {
key : "cp" ,
fallbackKeys : [ "connect_profile" ] ,
valueType : "string" ,
description : "The profile which should be used upon connect attempt."
} ;
export const KEY_CONNECT_SERVER_PASSWORD : RegistryKey < string > = {
key : "csp" ,
2021-02-19 22:05:48 +00:00
fallbackKeys : [ "connect_server_password" , "server-password" ] ,
2021-01-10 15:13:15 +00:00
valueType : "string" ,
2021-02-19 22:05:48 +00:00
description : "The password for the auto connect attempt."
} ;
export const KEY_CONNECT_PASSWORDS_HASHED : ValuedRegistryKey < boolean > = {
key : "cph" ,
fallbackKeys : [ "connect_passwords_hashed" , "passwords-hashed" ] ,
valueType : "boolean" ,
description : "Indicate whatever all passwords are hashed or not" ,
defaultValue : false
2021-01-10 15:13:15 +00:00
} ;
export const KEY_CONNECT_CHANNEL : RegistryKey < string > = {
key : "cc" ,
fallbackKeys : [ "connect_channel" ] ,
valueType : "string" ,
description : "The target channel for the connect attempt."
} ;
export const KEY_CONNECT_CHANNEL_PASSWORD : RegistryKey < string > = {
key : "ccp" ,
2021-02-19 22:05:48 +00:00
fallbackKeys : [ "connect_channel_password" , "channel-password" ] ,
2021-01-10 15:13:15 +00:00
valueType : "string" ,
description : "The target channel password (hashed) for the connect attempt."
} ;
2021-02-20 16:46:17 +00:00
export const KEY_IPC_APP_ADDRESS : RegistryKey < string > = {
2021-01-10 15:13:15 +00:00
key : "ipc-address" ,
valueType : "string" ,
2021-02-20 15:57:52 +00:00
description : "Address of the apps IPC channel"
2021-01-10 15:13:15 +00:00
} ;
2021-02-20 16:46:17 +00:00
export const KEY_IPC_CORE_PEER_ADDRESS : RegistryKey < string > = {
key : "ipc-core-peer" ,
2021-01-16 12:36:06 +00:00
valueType : "string" ,
2021-02-20 16:46:17 +00:00
description : "Peer address of the apps core" ,
} ;
export const KEY_MODAL_IDENTITY_CODE : RegistryKey < string > = {
key : "modal-identify" ,
valueType : "string" ,
description : "An authentication code used to register the new process as the modal"
2021-01-16 12:36:06 +00:00
} ;
2021-01-10 15:13:15 +00:00
export const KEY_MODAL_TARGET : RegistryKey < string > = {
key : "modal-target" ,
valueType : "string" ,
description : "Target modal unique id which should be loaded"
} ;
export const KEY_LOAD_DUMMY_ERROR : ValuedRegistryKey < boolean > = {
key : "dummy_load_error" ,
description : "Triggers a loading error at the end of the loading process." ,
valueType : "boolean" ,
defaultValue : false
} ;
}
export class StaticSettings {
private static _instance : StaticSettings ;
static get instance ( ) : StaticSettings {
if ( ! this . _instance ) {
this . _instance = new StaticSettings ( true ) ;
2018-04-19 17:46:47 +00:00
}
2019-03-17 11:15:39 +00:00
2021-01-10 15:13:15 +00:00
return this . _instance ;
}
protected staticValues = { } ;
protected constructor ( _reserved = undefined ) { }
static < V extends RegistryValueType , DV > ( key : RegistryKey < V > , defaultValue : DV ) : V | DV ;
static < V extends RegistryValueType > ( key : ValuedRegistryKey < V > , defaultValue? : V ) : V ;
static < V extends RegistryValueType , DV > ( key : RegistryKey < V > | ValuedRegistryKey < V > , defaultValue : DV ) : V | DV {
if ( arguments . length > 1 ) {
return AppParameters . getValue ( key , defaultValue ) ;
} else {
return AppParameters . getValue ( key as ValuedRegistryKey < V > ) ;
}
2018-04-19 17:46:47 +00:00
}
}
2020-07-19 15:12:41 +00:00
export interface SettingsEvents {
notify_setting_changed : {
setting : string ,
mode : "global" | "server" ,
oldValue : string ,
2020-09-07 10:42:00 +00:00
newValue : string ,
newCastedValue : any
2020-07-19 15:12:41 +00:00
}
}
2021-01-10 15:13:15 +00:00
export class Settings {
static readonly KEY_USER_IS_NEW : ValuedRegistryKey < boolean > = {
key : "user_is_new_user" ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
defaultValue : true
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_LOG_LEVEL : RegistryKey < number > = {
key : "log.level" ,
2020-07-19 16:49:00 +00:00
valueType : "number"
2020-03-27 15:15:15 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_DISABLE_COSMETIC_SLOWDOWN : ValuedRegistryKey < boolean > = {
key : "disable_cosmetic_slowdown" ,
description : "Disable the cosmetic slowdows in some processes, like icon upload." ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
defaultValue : false
2019-06-26 12:06:20 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_DISABLE_CONTEXT_MENU : ValuedRegistryKey < boolean > = {
key : "disableContextMenu" ,
description : "Disable the context menu for the channel tree which allows to debug the DOM easier" ,
2020-07-19 16:49:00 +00:00
defaultValue : false ,
valueType : "boolean" ,
2019-03-17 11:15:39 +00:00
} ;
2019-08-21 08:00:01 +00:00
2021-01-10 15:13:15 +00:00
static readonly KEY_DISABLE_GLOBAL_CONTEXT_MENU : ValuedRegistryKey < boolean > = {
key : "disableGlobalContextMenu" ,
description : "Disable the general context menu" ,
2020-09-17 21:19:30 +00:00
defaultValue : true ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
2019-08-21 08:00:01 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_DISABLE_UNLOAD_DIALOG : ValuedRegistryKey < boolean > = {
key : "disableUnloadDialog" ,
description : "Disables the unload popup on side closing" ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
defaultValue : false
2019-03-17 11:15:39 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_DISABLE_VOICE : ValuedRegistryKey < boolean > = {
key : "disableVoice" ,
description : "Disables the voice bridge. If disabled, the audio and codec workers aren\'t required anymore" ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
defaultValue : false
2019-03-17 11:15:39 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_DISABLE_MULTI_SESSION : ValuedRegistryKey < boolean > = {
key : "disableMultiSession" ,
2020-07-19 16:49:00 +00:00
defaultValue : false ,
requireRestart : true ,
valueType : "boolean" ,
2019-04-04 19:47:52 +00:00
} ;
2019-03-17 11:15:39 +00:00
2021-01-10 15:13:15 +00:00
static readonly KEY_I18N_DEFAULT_REPOSITORY : ValuedRegistryKey < string > = {
key : "i18n.default_repository" ,
2020-07-19 16:49:00 +00:00
valueType : "string" ,
defaultValue : "https://web.teaspeak.de/i18n/"
2019-03-25 19:04:04 +00:00
} ;
2020-04-09 13:10:14 +00:00
/* Default client states */
2021-01-10 15:13:15 +00:00
static readonly KEY_CLIENT_STATE_MICROPHONE_MUTED : ValuedRegistryKey < boolean > = {
key : "client_state_microphone_muted" ,
2020-07-19 16:49:00 +00:00
defaultValue : false ,
fallbackKeys : [ "mute_input" ] ,
valueType : "boolean" ,
2019-03-17 11:15:39 +00:00
} ;
2020-07-19 16:49:00 +00:00
2021-01-10 15:13:15 +00:00
static readonly KEY_CLIENT_STATE_SPEAKER_MUTED : ValuedRegistryKey < boolean > = {
key : "client_state_speaker_muted" ,
2020-07-19 16:49:00 +00:00
defaultValue : false ,
fallbackKeys : [ "mute_output" ] ,
valueType : "boolean" ,
2019-03-17 11:15:39 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CLIENT_STATE_QUERY_SHOWN : ValuedRegistryKey < boolean > = {
key : "client_state_query_shown" ,
2020-07-19 16:49:00 +00:00
defaultValue : false ,
fallbackKeys : [ "show_server_queries" ] ,
valueType : "boolean" ,
2019-03-17 11:15:39 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CLIENT_STATE_SUBSCRIBE_ALL_CHANNELS : ValuedRegistryKey < boolean > = {
key : "client_state_subscribe_all_channels" ,
2020-07-19 16:49:00 +00:00
defaultValue : true ,
fallbackKeys : [ "channel_subscribe_all" ] ,
valueType : "boolean" ,
2020-04-09 13:10:14 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CLIENT_STATE_AWAY : ValuedRegistryKey < boolean > = {
key : "client_state_away" ,
2020-07-19 16:49:00 +00:00
defaultValue : false ,
valueType : "boolean" ,
2020-04-09 13:10:14 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CLIENT_AWAY_MESSAGE : ValuedRegistryKey < string > = {
key : "client_away_message" ,
2020-07-19 16:49:00 +00:00
defaultValue : "" ,
valueType : "string"
2019-03-17 11:15:39 +00:00
} ;
/* Connect parameters */
2021-01-10 15:13:15 +00:00
static readonly KEY_FLAG_CONNECT_DEFAULT : ValuedRegistryKey < boolean > = {
key : "connect_default" ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
defaultValue : false
2019-03-17 11:15:39 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CONNECT_ADDRESS : ValuedRegistryKey < string > = {
key : "connect_address" ,
2020-07-19 16:49:00 +00:00
valueType : "string" ,
defaultValue : undefined
2019-03-17 11:15:39 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CONNECT_PROFILE : ValuedRegistryKey < string > = {
key : "connect_profile" ,
defaultValue : "default" ,
2020-07-19 16:49:00 +00:00
valueType : "string" ,
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CONNECT_USERNAME : ValuedRegistryKey < string > = {
key : "connect_username" ,
2020-07-19 16:49:00 +00:00
valueType : "string" ,
defaultValue : undefined
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CONNECT_PASSWORD : ValuedRegistryKey < string > = {
key : "connect_password" ,
2020-07-19 16:49:00 +00:00
valueType : "string" ,
defaultValue : undefined
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_FLAG_CONNECT_PASSWORD : ValuedRegistryKey < boolean > = {
key : "connect_password_hashed" ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
defaultValue : false
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CONNECT_HISTORY : ValuedRegistryKey < string > = {
key : "connect_history" ,
2020-07-19 16:49:00 +00:00
valueType : "string" ,
defaultValue : ""
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CONNECT_SHOW_HISTORY : ValuedRegistryKey < boolean > = {
key : "connect_show_last_servers" ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
defaultValue : false
} ;
2019-03-17 11:15:39 +00:00
2021-01-10 15:13:15 +00:00
static readonly KEY_CONNECT_NO_DNSPROXY : ValuedRegistryKey < boolean > = {
key : "connect_no_dnsproxy" ,
2020-07-19 16:49:00 +00:00
defaultValue : false ,
valueType : "boolean" ,
2019-11-24 00:16:07 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CERTIFICATE_CALLBACK : ValuedRegistryKey < string > = {
key : "certificate_callback" ,
2020-07-19 16:49:00 +00:00
valueType : "string" ,
defaultValue : undefined
2019-04-04 19:47:52 +00:00
} ;
2019-04-29 16:49:01 +00:00
/* sounds */
2021-01-10 15:13:15 +00:00
static readonly KEY_SOUND_MASTER : ValuedRegistryKey < number > = {
key : "audio_master_volume" ,
2020-07-19 16:49:00 +00:00
defaultValue : 100 ,
valueType : "number" ,
2019-04-29 16:49:01 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_SOUND_MASTER_SOUNDS : ValuedRegistryKey < number > = {
key : "audio_master_volume_sounds" ,
2020-07-19 16:49:00 +00:00
defaultValue : 100 ,
valueType : "number" ,
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_SOUND_VOLUMES : RegistryKey < string > = {
key : "sound_volume" ,
2020-07-19 16:49:00 +00:00
valueType : "string" ,
2019-08-21 08:00:01 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CHAT_FIXED_TIMESTAMPS : ValuedRegistryKey < boolean > = {
key : "chat_fixed_timestamps" ,
2020-07-19 16:49:00 +00:00
defaultValue : false ,
2021-01-10 15:13:15 +00:00
description : "Enables fixed timestamps for chat messages and disabled the updating once (2 seconds ago... etc)" ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
2019-08-21 08:00:01 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CHAT_COLLOQUIAL_TIMESTAMPS : ValuedRegistryKey < boolean > = {
key : "chat_colloquial_timestamps" ,
2020-07-19 16:49:00 +00:00
defaultValue : true ,
2021-01-10 15:13:15 +00:00
description : "Enabled colloquial timestamp formatting like \"Yesterday at ...\" or \"Today at ...\"" ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
2019-08-21 08:00:01 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CHAT_COLORED_EMOJIES : ValuedRegistryKey < boolean > = {
key : "chat_colored_emojies" ,
2020-07-19 16:49:00 +00:00
defaultValue : true ,
2021-01-10 15:13:15 +00:00
description : "Enables colored emojies powered by Twemoji" ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
2019-08-21 08:00:01 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CHAT_HIGHLIGHT_CODE : ValuedRegistryKey < boolean > = {
key : "chat_highlight_code" ,
2020-12-09 17:45:11 +00:00
defaultValue : true ,
2021-01-10 15:13:15 +00:00
description : "Enables code highlighting within the chat (Client restart required)" ,
2020-12-09 17:45:11 +00:00
valueType : "boolean" ,
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CHAT_TAG_URLS : ValuedRegistryKey < boolean > = {
key : "chat_tag_urls" ,
2020-07-19 16:49:00 +00:00
defaultValue : true ,
2021-01-10 15:13:15 +00:00
description : "Automatically link urls with [url]" ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
2019-08-21 08:00:01 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CHAT_ENABLE_MARKDOWN : ValuedRegistryKey < boolean > = {
key : "chat_enable_markdown" ,
2020-07-19 16:49:00 +00:00
defaultValue : true ,
2021-01-10 15:13:15 +00:00
description : "Enabled markdown chat support." ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
2019-08-21 08:00:01 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CHAT_ENABLE_BBCODE : ValuedRegistryKey < boolean > = {
key : "chat_enable_bbcode" ,
2020-07-19 16:49:00 +00:00
defaultValue : false ,
2021-01-10 15:13:15 +00:00
description : "Enabled bbcode support in chat." ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
2019-08-21 08:00:01 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CHAT_IMAGE_WHITELIST_REGEX : ValuedRegistryKey < string > = {
key : "chat_image_whitelist_regex" ,
2020-07-19 16:49:00 +00:00
defaultValue : JSON.stringify ( [ ] ) ,
valueType : "string" ,
2020-03-19 13:31:45 +00:00
} ;
2021-02-15 18:03:22 +00:00
static readonly KEY_CHAT_LAST_USED_EMOJI : ValuedRegistryKey < string > = {
key : "chat_last_used_emoji" ,
defaultValue : ":joy:" ,
valueType : "string" ,
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_SWITCH_INSTANT_CHAT : ValuedRegistryKey < boolean > = {
key : "switch_instant_chat" ,
2020-07-19 16:49:00 +00:00
defaultValue : true ,
2021-01-10 15:13:15 +00:00
description : "Directly switch to channel chat on channel select" ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
2019-08-21 08:00:01 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_SWITCH_INSTANT_CLIENT : ValuedRegistryKey < boolean > = {
key : "switch_instant_client" ,
2020-07-19 16:49:00 +00:00
defaultValue : true ,
2021-01-10 15:13:15 +00:00
description : "Directly switch to client info on client select" ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
2019-08-21 08:00:01 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_HOSTBANNER_BACKGROUND : ValuedRegistryKey < boolean > = {
key : "hostbanner_background" ,
2020-07-19 16:49:00 +00:00
defaultValue : false ,
2021-01-10 15:13:15 +00:00
description : "Enables a default background begind the hostbanner" ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
2019-08-21 08:00:01 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_CHANNEL_EDIT_ADVANCED : ValuedRegistryKey < boolean > = {
key : "channel_edit_advanced" ,
2020-07-19 16:49:00 +00:00
defaultValue : false ,
2021-01-10 15:13:15 +00:00
description : "Edit channels in advanced mode with a lot more settings" ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
2019-08-21 08:00:01 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_PERMISSIONS_SHOW_ALL : ValuedRegistryKey < boolean > = {
key : "permissions_show_all" ,
2020-07-19 16:49:00 +00:00
defaultValue : false ,
2021-01-10 15:13:15 +00:00
description : "Show all permissions even thou they dont make sense for the server/channel group" ,
2020-07-19 16:49:00 +00:00
valueType : "boolean" ,
2019-11-24 12:41:42 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_TEAFORO_URL : ValuedRegistryKey < string > = {
2019-08-21 08:00:01 +00:00
key : "teaforo_url" ,
2020-07-19 16:49:00 +00:00
defaultValue : "https://forum.teaspeak.de/" ,
valueType : "string" ,
2019-08-21 08:00:01 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_FONT_SIZE : ValuedRegistryKey < number > = {
2020-07-19 16:49:00 +00:00
key : "font_size" ,
valueType : "number" ,
2020-09-17 21:06:02 +00:00
defaultValue : 14 //parseInt(getComputedStyle(document.body).fontSize)
2019-04-29 16:49:01 +00:00
} ;
2019-10-19 15:13:40 +00:00
2021-01-10 15:13:15 +00:00
static readonly KEY_ICON_SIZE : ValuedRegistryKey < number > = {
2019-10-19 15:13:40 +00:00
key : "icon_size" ,
2020-07-19 16:49:00 +00:00
defaultValue : 100 ,
valueType : "number" ,
2019-10-19 15:13:40 +00:00
} ;
2019-04-29 16:49:01 +00:00
2021-01-10 15:13:15 +00:00
static readonly KEY_KEYCONTROL_DATA : ValuedRegistryKey < string > = {
2020-04-10 18:57:50 +00:00
key : "keycontrol_data" ,
2020-07-19 16:49:00 +00:00
defaultValue : "{}" ,
valueType : "string" ,
2020-04-10 18:57:50 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_LAST_INVITE_LINK_TYPE : ValuedRegistryKey < string > = {
2019-10-13 19:33:07 +00:00
key : "last_invite_link_type" ,
2020-07-19 16:49:00 +00:00
defaultValue : "tea-web" ,
valueType : "string" ,
2019-10-13 19:33:07 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_TRANSFERS_SHOW_FINISHED : ValuedRegistryKey < boolean > = {
key : "transfers_show_finished" ,
2020-07-19 16:49:00 +00:00
defaultValue : true ,
description : "Show finished file transfers in the file transfer list" ,
valueType : "boolean" ,
2020-06-10 16:13:56 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_TRANSFER_DOWNLOAD_FOLDER : RegistryKey < string > = {
2020-06-10 20:44:50 +00:00
key : "transfer_download_folder" ,
description : "The download folder for the file transfer downloads" ,
2020-07-19 16:49:00 +00:00
valueType : "string" ,
/* defaultValue: <users download directory> */
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_IPC_REMOTE_ADDRESS : RegistryKey < string > = {
2020-07-20 17:08:13 +00:00
key : "ipc-address" ,
valueType : "string"
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_W2G_SIDEBAR_COLLAPSED : ValuedRegistryKey < boolean > = {
key : "w2g_sidebar_collapsed" ,
2020-08-07 11:40:11 +00:00
defaultValue : false ,
valueType : "boolean" ,
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_VOICE_ECHO_TEST_ENABLED : ValuedRegistryKey < boolean > = {
key : "voice_echo_test_enabled" ,
2020-09-07 10:42:00 +00:00
defaultValue : true ,
valueType : "boolean" ,
} ;
2021-02-15 14:53:01 +00:00
static readonly KEY_RTC_EXTRA_VIDEO_CHANNELS : ValuedRegistryKey < number > = {
key : "rtc_extra_video_channels" ,
defaultValue : 0 ,
requireRestart : true ,
valueType : "number" ,
description : "Extra video channels within the initial WebRTC sdp offer.\n" +
"Note: By default the screen/camera share channels are already present"
} ;
static readonly KEY_RTC_EXTRA_AUDIO_CHANNELS : ValuedRegistryKey < number > = {
key : "rtc_extra_audio_channels" ,
defaultValue : 6 ,
requireRestart : true ,
valueType : "number" ,
description : "Extra audio channels within the initial WebRTC sdp offer.\n" +
"Note:\n" +
"1. By default the voice/whisper channels are already present.\n" +
"2. This setting does not work for Firefox."
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_RNNOISE_FILTER : ValuedRegistryKey < boolean > = {
key : "rnnoise_filter" ,
2020-10-01 08:56:54 +00:00
defaultValue : true ,
2021-02-15 14:53:01 +00:00
description : "Enable the rnnoise filter for suppressing background noise" ,
2020-10-01 08:56:54 +00:00
valueType : "boolean" ,
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_LOADER_ANIMATION_ABORT : ValuedRegistryKey < boolean > = {
key : "loader_animation_abort" ,
2020-10-05 08:44:44 +00:00
defaultValue : false ,
2021-01-10 15:13:15 +00:00
description : "Abort the loader animation when the app has been finished loading" ,
2020-10-05 08:44:44 +00:00
valueType : "boolean" ,
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_STOP_VIDEO_ON_SWITCH : ValuedRegistryKey < boolean > = {
key : "stop_video_on_channel_switch" ,
2020-11-07 12:16:07 +00:00
defaultValue : true ,
2021-01-10 15:13:15 +00:00
description : "Stop video broadcasting on channel switch" ,
2020-11-07 12:16:07 +00:00
valueType : "boolean" ,
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_VIDEO_SHOW_ALL_CLIENTS : ValuedRegistryKey < boolean > = {
key : "video_show_all_clients" ,
2020-12-10 12:32:35 +00:00
defaultValue : false ,
description : "Show all clients within the video frame, even if they're not broadcasting video" ,
valueType : "boolean" ,
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_VIDEO_FORCE_SHOW_OWN_VIDEO : ValuedRegistryKey < boolean > = {
key : "video_force_show_own_video" ,
2020-12-10 12:32:35 +00:00
defaultValue : true ,
description : "Show own video preview even if you're not broadcasting any video" ,
valueType : "boolean" ,
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_VIDEO_AUTO_SUBSCRIBE_MODE : ValuedRegistryKey < number > = {
key : "video_auto_subscribe_mode" ,
2020-12-10 12:32:35 +00:00
defaultValue : 1 ,
description : "Auto subscribe to incoming videos.\n0 := Do not auto subscribe.\n1 := Auto subscribe to the first video.\n2 := Subscribe to all incoming videos." ,
valueType : "number" ,
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_VIDEO_DEFAULT_MAX_WIDTH : ValuedRegistryKey < number > = {
key : "video_default_max_width" ,
2020-12-16 21:06:46 +00:00
defaultValue : 1280 ,
description : "The default maximal width of the video being crated." ,
valueType : "number" ,
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_VIDEO_DEFAULT_MAX_HEIGHT : ValuedRegistryKey < number > = {
key : "video_default_max_height" ,
2020-12-16 21:06:46 +00:00
defaultValue : 720 ,
description : "The default maximal height of the video being crated." ,
valueType : "number" ,
} ;
2021-01-15 23:03:01 +00:00
static readonly KEY_VIDEO_DEFAULT_MAX_BANDWIDTH : ValuedRegistryKey < number > = {
key : "video_default_max_bandwidth" ,
defaultValue : 1_600_000 ,
description : "The default video bandwidth to use in bits/seconds.\nA too high value might not be allowed by all server permissions." ,
valueType : "number" ,
} ;
static readonly KEY_VIDEO_DEFAULT_KEYFRAME_INTERVAL : ValuedRegistryKey < number > = {
key : "video_default_keyframe_interval" ,
defaultValue : 0 ,
description : "The default interval to forcibly request a keyframe from ourself in seconds. A value of zero means no such interval." ,
valueType : "number" ,
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_VIDEO_DYNAMIC_QUALITY : ValuedRegistryKey < boolean > = {
key : "video_dynamic_quality" ,
2021-01-04 20:28:47 +00:00
defaultValue : true ,
description : "Dynamically decrease video quality in order to archive a higher framerate." ,
valueType : "boolean" ,
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_VIDEO_DYNAMIC_FRAME_RATE : ValuedRegistryKey < boolean > = {
key : "video_dynamic_frame_rate" ,
2021-01-04 20:28:47 +00:00
defaultValue : true ,
description : "Dynamically decrease video framerate to allow higher video resolutions." ,
valueType : "boolean" ,
} ;
2021-01-10 15:13:15 +00:00
static readonly KEY_VIDEO_QUICK_SETUP : ValuedRegistryKey < boolean > = {
key : "video_quick_setup" ,
2021-01-06 17:48:50 +00:00
defaultValue : true ,
description : "Automatically select the default video device and start broadcasting without the video configure dialog." ,
valueType : "boolean" ,
} ;
2021-02-19 22:05:48 +00:00
static readonly KEY_INVITE_SHORT_URL : ValuedRegistryKey < boolean > = {
key : "invite_short_url" ,
defaultValue : true ,
description : "Enable/disable the short url for the invite menu" ,
valueType : "boolean" ,
} ;
static readonly KEY_INVITE_ADVANCED_ENABLED : ValuedRegistryKey < boolean > = {
key : "invite_advanced_enabled" ,
defaultValue : false ,
description : "Enable/disable the advanced menu for the invite menu" ,
valueType : "boolean" ,
} ;
2021-01-10 15:13:15 +00:00
static readonly FN_LOG_ENABLED : ( category : string ) = > RegistryKey < boolean > = category = > {
2020-07-19 16:49:00 +00:00
return {
key : "log." + category . toLowerCase ( ) + ".enabled" ,
valueType : "boolean" ,
}
} ;
2021-01-10 15:13:15 +00:00
static readonly FN_SEPARATOR_STATE : ( separator : string ) = > RegistryKey < string > = separator = > {
2020-07-19 16:49:00 +00:00
return {
key : "separator-settings-" + separator ,
valueType : "string" ,
fallbackKeys : [ "seperator-settings-" + separator ]
}
} ;
2021-01-10 15:13:15 +00:00
static readonly FN_LOG_LEVEL_ENABLED : ( category : string ) = > RegistryKey < boolean > = category = > {
2020-07-19 16:49:00 +00:00
return {
key : "log.level." + category . toLowerCase ( ) + ".enabled" ,
2020-08-09 12:30:17 +00:00
valueType : "boolean"
2020-07-19 16:49:00 +00:00
}
2020-06-10 20:44:50 +00:00
} ;
2021-01-10 15:13:15 +00:00
static readonly FN_INVITE_LINK_SETTING : ( name : string ) = > RegistryKey < string > = name = > {
2019-10-13 19:33:07 +00:00
return {
2021-01-10 15:13:15 +00:00
key : "invite_link_setting_" + name ,
2020-07-19 16:49:00 +00:00
valueType : "string" ,
2019-10-13 19:33:07 +00:00
}
} ;
2021-01-10 15:13:15 +00:00
static readonly FN_SERVER_CHANNEL_SUBSCRIBE_MODE : ( channel_id : number ) = > RegistryKey < number > = channel = > {
2019-03-17 11:15:39 +00:00
return {
2021-01-10 15:13:15 +00:00
key : "channel_subscribe_mode_" + channel ,
2020-07-19 16:49:00 +00:00
valueType : "number" ,
2019-03-17 11:15:39 +00:00
}
} ;
2021-01-10 15:13:15 +00:00
static readonly FN_SERVER_CHANNEL_COLLAPSED : ( channel_id : number ) = > ValuedRegistryKey < boolean > = channel = > {
2020-04-18 19:31:13 +00:00
return {
2021-01-10 15:13:15 +00:00
key : "channel_collapsed_" + channel ,
2020-07-19 16:49:00 +00:00
defaultValue : false ,
valueType : "boolean" ,
2020-04-18 19:31:13 +00:00
}
} ;
2021-01-10 15:13:15 +00:00
static readonly FN_PROFILE_RECORD : ( name : string ) = > RegistryKey < object > = name = > {
2019-05-20 16:57:14 +00:00
return {
2021-01-10 15:13:15 +00:00
key : "profile_record" + name ,
2020-08-09 12:30:17 +00:00
valueType : "object" ,
2019-05-20 16:57:14 +00:00
}
} ;
2021-01-10 15:13:15 +00:00
static readonly FN_CHANNEL_CHAT_READ : ( id : number ) = > RegistryKey < number > = id = > {
2020-07-12 14:31:57 +00:00
return {
2021-01-10 15:13:15 +00:00
key : "channel_chat_read_" + id ,
2020-07-19 16:49:00 +00:00
valueType : "number" ,
}
} ;
2021-01-10 15:13:15 +00:00
static readonly FN_CLIENT_MUTED : ( clientUniqueId : string ) = > RegistryKey < boolean > = clientUniqueId = > {
2020-07-19 16:49:00 +00:00
return {
key : "client_" + clientUniqueId + "_muted" ,
valueType : "boolean" ,
fallbackKeys : [ "mute_client_" + clientUniqueId ]
}
} ;
2021-01-10 15:13:15 +00:00
static readonly FN_CLIENT_VOLUME : ( clientUniqueId : string ) = > RegistryKey < number > = clientUniqueId = > {
2020-07-19 16:49:00 +00:00
return {
key : "client_" + clientUniqueId + "_volume" ,
valueType : "number" ,
fallbackKeys : [ "volume_client_" + clientUniqueId ]
2020-07-12 14:31:57 +00:00
}
} ;
2021-01-10 15:13:15 +00:00
static readonly FN_EVENTS_NOTIFICATION_ENABLED : ( event : string ) = > RegistryKey < boolean > = event = > {
2020-07-21 22:55:28 +00:00
return {
2020-07-23 18:00:25 +00:00
key : "event_notification_" + event + "_enabled" ,
valueType : "boolean"
}
} ;
2021-01-10 15:13:15 +00:00
static readonly FN_EVENTS_LOG_ENABLED : ( event : string ) = > RegistryKey < boolean > = event = > {
2020-07-23 18:00:25 +00:00
return {
key : "event_log_" + event + "_enabled" ,
valueType : "boolean"
}
} ;
2021-01-10 15:13:15 +00:00
static readonly FN_EVENTS_FOCUS_ENABLED : ( event : string ) = > RegistryKey < boolean > = event = > {
2020-07-23 18:00:25 +00:00
return {
key : "event_focus_" + event + "_enabled" ,
2020-07-21 22:55:28 +00:00
valueType : "boolean"
}
} ;
2019-03-17 11:15:39 +00:00
static readonly KEYS = ( ( ) = > {
const result = [ ] ;
2020-07-19 16:49:00 +00:00
for ( const key of Object . keys ( Settings ) ) {
2021-01-10 15:13:15 +00:00
if ( ! key . toUpperCase ( ) . startsWith ( "KEY_" ) ) {
2019-03-17 11:15:39 +00:00
continue ;
2021-01-10 15:13:15 +00:00
}
2019-03-17 11:15:39 +00:00
result . push ( key ) ;
}
return result ;
} ) ( ) ;
2018-04-19 17:46:47 +00:00
2019-08-31 16:31:01 +00:00
static initialize() {
settings = new Settings ( ) ;
2020-04-09 13:10:14 +00:00
( window as any ) . settings = settings ;
( window as any ) . Settings = Settings ;
2019-08-31 16:31:01 +00:00
}
2021-01-10 15:13:15 +00:00
2020-07-19 15:12:41 +00:00
readonly events : Registry < SettingsEvents > ;
2021-01-10 15:13:15 +00:00
2020-07-19 15:12:41 +00:00
private readonly cacheGlobal = { } ;
private saveWorker : number ;
2018-04-19 17:46:47 +00:00
private updated : boolean = false ;
constructor ( ) {
2020-07-19 15:12:41 +00:00
this . events = new Registry < SettingsEvents > ( ) ;
2019-11-09 12:19:58 +00:00
const json = localStorage . getItem ( "settings.global" ) ;
try {
this . cacheGlobal = JSON . parse ( json ) ;
} catch ( error ) {
2021-01-10 16:36:57 +00:00
logError ( LogCategory . GENERAL , tr ( "Failed to load global settings!\nJson: %s\nError: %o" ) , json , error ) ;
2019-11-09 12:19:58 +00:00
const show_popup = ( ) = > {
2020-07-19 20:02:31 +00:00
//FIXME: Readd this
//createErrorModal(tr("Failed to load global settings"), tr("Failed to load global client settings!\nLookup console for more information.")).open();
2019-11-09 12:19:58 +00:00
} ;
if ( ! loader . finished ( ) )
loader . register_task ( loader . Stage . LOADED , {
priority : 0 ,
name : "Settings error" ,
function : async ( ) = > show_popup ( )
} ) ;
else
show_popup ( ) ;
}
2018-04-19 17:46:47 +00:00
if ( ! this . cacheGlobal ) this . cacheGlobal = { } ;
this . saveWorker = setInterval ( ( ) = > {
if ( this . updated )
this . save ( ) ;
} , 5 * 1000 ) ;
2018-04-16 18:38:35 +00:00
}
2021-01-10 15:13:15 +00:00
getValue < V extends RegistryValueType , DV > ( key : RegistryKey < V > , defaultValue : DV ) : V | DV ;
getValue < V extends RegistryValueType > ( key : ValuedRegistryKey < V > , defaultValue? : V ) : V ;
getValue < V extends RegistryValueType , DV > ( key : RegistryKey < V > | ValuedRegistryKey < V > , defaultValue : DV ) : V | DV {
if ( arguments . length > 1 ) {
return resolveKey ( key , key = > this . cacheGlobal [ key ] , defaultValue ) ;
} else if ( "defaultValue" in key ) {
return resolveKey ( key , key = > this . cacheGlobal [ key ] , key . defaultValue ) ;
} else {
2021-01-10 16:36:57 +00:00
debugger ;
2021-01-10 15:13:15 +00:00
throw tr ( "missing default value" ) ;
}
2018-09-22 14:52:26 +00:00
}
2021-01-10 15:13:15 +00:00
setValue < T extends RegistryValueType > ( key : RegistryKey < T > , value? : T ) {
if ( value === null ) {
value = undefined ;
}
2018-02-27 16:20:49 +00:00
2021-01-10 15:13:15 +00:00
if ( this . cacheGlobal [ key . key ] === value ) {
2020-07-19 16:49:00 +00:00
return ;
2021-01-10 15:13:15 +00:00
}
2018-03-07 18:06:52 +00:00
2020-07-19 15:12:41 +00:00
const oldValue = this . cacheGlobal [ key . key ] ;
2021-01-10 15:13:15 +00:00
if ( value === undefined ) {
delete this . cacheGlobal [ key . key ] ;
} else {
this . cacheGlobal [ key . key ] = encodeValueToString ( value ) ;
}
this . updated = true ;
2020-07-19 15:12:41 +00:00
this . events . fire ( "notify_setting_changed" , {
mode : "global" ,
newValue : this.cacheGlobal [ key . key ] ,
oldValue : oldValue ,
2020-09-07 10:42:00 +00:00
setting : key.key ,
newCastedValue : value
2020-07-19 15:12:41 +00:00
} ) ;
2020-09-17 21:19:30 +00:00
logTrace ( LogCategory . GENERAL , tr ( "Changing global setting %s to %o" ) , key . key , value ) ;
2021-01-10 15:13:15 +00:00
if ( UPDATE_DIRECT ) {
2018-02-27 16:20:49 +00:00
this . save ( ) ;
2021-01-10 15:13:15 +00:00
}
2018-02-27 16:20:49 +00:00
}
2021-01-10 15:13:15 +00:00
globalChangeListener < T extends RegistryValueType > ( key : RegistryKey < T > , listener : ( newValue : T ) = > void ) : ( ) = > void {
2020-09-07 10:42:00 +00:00
return this . events . on ( "notify_setting_changed" , event = > {
if ( event . setting === key . key && event . mode === "global" ) {
listener ( event . newCastedValue ) ;
}
} )
}
2019-04-04 19:47:52 +00:00
save() {
this . updated = false ;
let global = JSON . stringify ( this . cacheGlobal ) ;
localStorage . setItem ( "settings.global" , global ) ;
2019-04-15 13:33:51 +00:00
if ( localStorage . save )
localStorage . save ( ) ;
2019-04-04 19:47:52 +00:00
}
}
2021-01-10 15:13:15 +00:00
export class ServerSettings {
2019-04-04 19:47:52 +00:00
private cacheServer = { } ;
2021-01-10 15:13:15 +00:00
private serverUniqueId : string ;
private serverSaveWorker : number ;
private serverSettingsUpdated : boolean = false ;
2019-08-21 08:00:01 +00:00
private _destroyed = false ;
2019-04-04 19:47:52 +00:00
constructor ( ) {
2021-01-10 15:13:15 +00:00
this . serverSaveWorker = setInterval ( ( ) = > {
if ( this . serverSettingsUpdated ) {
2019-04-04 19:47:52 +00:00
this . save ( ) ;
2021-01-10 15:13:15 +00:00
}
2019-04-04 19:47:52 +00:00
} , 5 * 1000 ) ;
}
2019-08-21 08:00:01 +00:00
destroy() {
this . _destroyed = true ;
2021-01-10 15:13:15 +00:00
this . serverUniqueId = undefined ;
2019-08-21 08:00:01 +00:00
this . cacheServer = undefined ;
2021-01-10 15:13:15 +00:00
clearInterval ( this . serverSaveWorker ) ;
this . serverSaveWorker = undefined ;
2019-08-21 08:00:01 +00:00
}
2021-01-10 16:36:57 +00:00
getValue < V extends RegistryValueType , DV > ( key : RegistryKey < V > , defaultValue : DV ) : V | DV ;
getValue < V extends RegistryValueType > ( key : ValuedRegistryKey < V > , defaultValue? : V ) : V ;
getValue ( key , defaultValue ) {
2021-01-10 15:13:15 +00:00
if ( this . _destroyed ) {
2020-07-19 16:49:00 +00:00
throw "destroyed" ;
2021-01-10 15:13:15 +00:00
}
2020-07-19 16:49:00 +00:00
2021-01-10 15:13:15 +00:00
if ( arguments . length > 1 ) {
return resolveKey ( key , key = > this . cacheServer [ key ] , defaultValue ) ;
} else if ( "defaultValue" in key ) {
return resolveKey ( key , key = > this . cacheServer [ key ] , key . defaultValue ) ;
} else {
2021-01-10 16:36:57 +00:00
debugger ;
2021-01-10 15:13:15 +00:00
throw tr ( "missing default value" ) ;
}
2019-04-04 19:47:52 +00:00
}
2021-01-10 15:13:15 +00:00
setValue < T extends RegistryValueType > ( key : RegistryKey < T > , value? : T ) {
if ( this . _destroyed ) {
throw "destroyed" ;
}
2019-03-17 11:15:39 +00:00
2021-01-10 15:13:15 +00:00
if ( this . cacheServer [ key . key ] === value ) {
2020-07-19 16:49:00 +00:00
return ;
2021-01-10 15:13:15 +00:00
}
2018-03-07 18:06:52 +00:00
2021-01-10 15:13:15 +00:00
this . serverSettingsUpdated = true ;
if ( value === undefined || value === null ) {
delete this . cacheServer [ key . key ] ;
} else {
this . cacheServer [ key . key ] = encodeValueToString ( value ) ;
}
2018-02-27 16:20:49 +00:00
2021-01-10 15:13:15 +00:00
if ( UPDATE_DIRECT ) {
2018-02-27 16:20:49 +00:00
this . save ( ) ;
2021-01-10 15:13:15 +00:00
}
2018-02-27 16:20:49 +00:00
}
2019-08-31 16:31:01 +00:00
setServer ( server_unique_id : string ) {
2019-08-21 08:00:01 +00:00
if ( this . _destroyed ) throw "destroyed" ;
2021-01-10 15:13:15 +00:00
if ( this . serverUniqueId ) {
2018-04-16 18:38:35 +00:00
this . save ( ) ;
2018-03-07 18:06:52 +00:00
this . cacheServer = { } ;
2021-01-10 15:13:15 +00:00
this . serverUniqueId = undefined ;
2018-04-16 18:38:35 +00:00
}
2021-01-10 15:13:15 +00:00
this . serverUniqueId = server_unique_id ;
2018-04-16 18:38:35 +00:00
2021-01-10 15:13:15 +00:00
if ( this . serverUniqueId ) {
2019-11-09 12:19:58 +00:00
const json = localStorage . getItem ( "settings.server_" + server_unique_id ) ;
try {
this . cacheServer = JSON . parse ( json ) ;
} catch ( error ) {
2021-01-10 16:36:57 +00:00
logError ( LogCategory . GENERAL , tr ( "Failed to load server settings for server %s!\nJson: %s\nError: %o" ) , server_unique_id , json , error ) ;
2019-11-09 12:19:58 +00:00
}
2018-04-16 18:38:35 +00:00
if ( ! this . cacheServer )
this . cacheServer = { } ;
2018-03-07 18:06:52 +00:00
}
2018-02-27 16:20:49 +00:00
}
save() {
2021-01-10 15:13:15 +00:00
if ( this . _destroyed ) {
throw "destroyed" ;
}
this . serverSettingsUpdated = false ;
2018-02-27 16:20:49 +00:00
2021-01-10 15:13:15 +00:00
if ( this . serverUniqueId ) {
2018-03-07 18:06:52 +00:00
let server = JSON . stringify ( this . cacheServer ) ;
2021-01-10 15:13:15 +00:00
localStorage . setItem ( "settings.server_" + this . serverUniqueId , server ) ;
if ( localStorage . save ) {
2019-04-15 13:33:51 +00:00
localStorage . save ( ) ;
2021-01-10 15:13:15 +00:00
}
2018-03-07 18:06:52 +00:00
}
2018-02-27 16:20:49 +00:00
}
2019-08-31 16:31:01 +00:00
}
2020-07-20 17:08:13 +00:00
export let settings : Settings = null ;
loader . register_task ( Stage . JAVASCRIPT_INITIALIZING , {
priority : 1000 ,
name : "Settings initialize" ,
function : async ( ) = > Settings . initialize ( )
} )