2020-09-12 15:49:20 +02:00
import * as log from "./log" ;
2020-09-17 23:19:30 +02:00
import { LogCategory , logTrace } from "./log" ;
2020-03-30 13:44:18 +02:00
import * as loader from "tc-loader" ;
2020-07-20 19:08:13 +02:00
import { Stage } from "tc-loader" ;
2020-09-12 15:49:20 +02:00
import { Registry } from "./events" ;
2020-11-29 14:42:02 +01:00
import { tr } from "./i18n/localize" ;
2018-03-24 23:38:01 +01:00
2020-09-17 23:49:05 +02:00
export type ConfigValueTypes = boolean | number | string | object ;
export type ConfigValueTypeNames = "boolean" | "number" | "string" | "object" ;
2020-08-09 14:30:17 +02:00
2020-09-17 23:49:05 +02:00
export type ValueTypeMapping < T > = T extends boolean ? "boolean" :
2020-09-25 18:04:46 +02:00
T extends number ? "number" :
T extends string ? "string" :
T extends object ? "object" : never ;
2020-07-19 18:49:00 +02:00
export interface SettingsKey < ValueType extends ConfigValueTypes > {
2019-03-17 12:15:39 +01:00
key : string ;
2020-08-09 14:30:17 +02:00
valueType : ValueTypeMapping < ValueType > ;
2020-07-19 18:49:00 +02:00
defaultValue? : ValueType ;
fallbackKeys? : string | string [ ] ;
fallbackImports ? : { [ key : string ] : ( value : string ) = > ValueType } ;
2019-03-17 12:15:39 +01:00
description? : string ;
2019-08-21 10:00:01 +02:00
2020-07-19 18:49:00 +02:00
requireRestart? : boolean ;
}
export interface ValuedSettingsKey < ValueType extends ConfigValueTypes > extends SettingsKey < ValueType > {
defaultValue : ValueType ;
2019-03-17 12:15:39 +01:00
}
2020-07-19 18:49:00 +02:00
const kNoValuePresent = "--- no value present ---" ;
2020-03-30 13:44:18 +02:00
export class SettingsBase {
2019-04-04 21:47:52 +02:00
protected static readonly UPDATE_DIRECT : boolean = true ;
2018-02-27 17:20:49 +01:00
2020-07-19 18:49:00 +02:00
protected static decodeValueFromString < T extends ConfigValueTypes , DT > ( input : string | undefined , type : ConfigValueTypeNames , defaultValue : DT ) : T | DT {
if ( input === undefined || input === null )
return defaultValue ;
switch ( type ) {
case "string" :
return input as any ;
case "boolean" :
return ( input === "1" || input === "true" ) as any ;
2019-03-17 12:15:39 +01:00
2020-07-19 18:49:00 +02:00
case "number" :
return parseFloat ( input ) as any ;
2020-08-09 14:30:17 +02:00
case "object" :
try {
return JSON . parse ( input ) ;
} catch ( error ) {
return { } as any ;
}
2020-07-19 18:49:00 +02:00
default :
return defaultValue ;
}
2018-04-19 19:46:47 +02:00
}
2020-07-19 18:49:00 +02:00
protected static encodeValueToString < T extends ConfigValueTypes > ( input : T | undefined ) : string | undefined {
if ( input === undefined || input === null )
return undefined ;
switch ( typeof input ) {
case "string" :
return input ;
case "boolean" :
return input ? "1" : "0" ;
2018-02-27 17:20:49 +01:00
2020-07-19 18:49:00 +02:00
case "number" :
return input . toString ( ) ;
2020-08-09 14:30:17 +02:00
case "object" :
return JSON . stringify ( input ) ;
2020-07-19 18:49:00 +02:00
default :
return undefined ;
}
2018-04-19 19:46:47 +02:00
}
2018-02-27 17:20:49 +01:00
2020-07-19 18:49:00 +02:00
protected static resolveKey < ValueType extends ConfigValueTypes ,
DefaultType > ( key : SettingsKey < ValueType > ,
resolver : ( key : string ) = > string | undefined ,
defaultValueType : ConfigValueTypeNames ,
defaultValue : DefaultType ) : ValueType | DefaultType {
2019-03-17 12:15:39 +01:00
let value = resolver ( key . key ) ;
2020-07-19 18:49:00 +02:00
if ( value === undefined && key . fallbackKeys ) {
/* trying fallback values */
for ( const fallback of key . fallbackKeys ) {
2019-03-17 12:15:39 +01:00
value = resolver ( fallback ) ;
2020-07-19 18:49:00 +02:00
if ( value === undefined )
continue ;
if ( ! key . fallbackImports )
2019-03-17 12:15:39 +01:00
break ;
2020-07-19 18:49:00 +02:00
/* fallback key succeeded */
const fallbackValueImporter = key . fallbackImports [ fallback ] ;
if ( fallbackValueImporter )
return fallbackValueImporter ( value ) ;
break ;
2019-03-17 12:15:39 +01:00
}
}
2020-07-19 18:49:00 +02:00
return this . decodeValueFromString ( value , defaultValueType , defaultValue ) as any ;
2019-03-17 12:15:39 +01:00
}
2019-04-04 21:47:52 +02:00
}
2020-03-30 13:44:18 +02:00
export class StaticSettings extends SettingsBase {
2019-04-04 21:47:52 +02:00
private static _instance : StaticSettings ;
static get instance ( ) : StaticSettings {
if ( ! this . _instance )
this . _instance = new StaticSettings ( true ) ;
return this . _instance ;
}
2019-03-17 12:15:39 +01:00
2018-04-19 19:46:47 +02:00
protected _handle : StaticSettings ;
2020-07-19 22:02:31 +02:00
protected staticValues = { } ;
2018-04-16 20:38:35 +02:00
2018-04-19 19:46:47 +02:00
protected constructor ( _reserved = undefined ) {
2019-04-04 21:47:52 +02:00
super ( ) ;
2018-04-19 19:46:47 +02:00
if ( _reserved && ! StaticSettings . _instance ) {
this . initializeStatic ( ) ;
} else {
this . _handle = StaticSettings . instance ;
}
2018-04-16 20:38:35 +02:00
}
private initializeStatic() {
2019-04-04 21:47:52 +02:00
let search ;
if ( window . opener && window . opener !== window ) {
search = new URL ( window . location . href ) . search ;
} else {
search = location . search ;
}
search . substr ( 1 ) . split ( "&" ) . forEach ( part = > {
2018-04-16 20:38:35 +02:00
let item = part . split ( "=" ) ;
2020-07-19 22:02:31 +02:00
this . staticValues [ item [ 0 ] ] = decodeURIComponent ( item [ 1 ] ) ;
2018-04-16 20:38:35 +02:00
} ) ;
}
2020-07-19 18:49:00 +02:00
static < V extends ConfigValueTypes , DV > ( key : SettingsKey < V > , defaultValue : DV ) : V | DV ;
static < V extends ConfigValueTypes > ( key : ValuedSettingsKey < V > , defaultValue? : V ) : V ;
2018-02-27 17:20:49 +01:00
2020-07-19 18:49:00 +02:00
static < V extends ConfigValueTypes , DV > ( key : SettingsKey < V > , defaultValue : DV ) : V | DV {
2018-04-19 19:46:47 +02:00
if ( this . _handle ) {
2020-07-19 18:49:00 +02:00
return this . _handle . static < V , DV > ( key , defaultValue ) ;
2018-04-19 19:46:47 +02:00
}
2019-03-17 12:15:39 +01:00
2020-07-19 22:02:31 +02:00
return StaticSettings . resolveKey ( key , key = > this . staticValues [ key ] , key . valueType , arguments . length > 1 ? defaultValue : key.defaultValue ) ;
2018-04-19 19:46:47 +02:00
}
}
2020-07-19 17:12:41 +02:00
export interface SettingsEvents {
notify_setting_changed : {
setting : string ,
mode : "global" | "server" ,
oldValue : string ,
2020-09-07 12:42:00 +02:00
newValue : string ,
newCastedValue : any
2020-07-19 17:12:41 +02:00
}
}
2020-03-30 13:44:18 +02:00
export class Settings extends StaticSettings {
2020-07-19 18:49:00 +02:00
static readonly KEY_USER_IS_NEW : ValuedSettingsKey < boolean > = {
2020-03-27 16:15:15 +01:00
key : 'user_is_new_user' ,
2020-07-19 18:49:00 +02:00
valueType : "boolean" ,
defaultValue : true
} ;
static readonly KEY_LOG_LEVEL : SettingsKey < number > = {
key : 'log.level' ,
valueType : "number"
2020-03-27 16:15:15 +01:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_DISABLE_COSMETIC_SLOWDOWN : ValuedSettingsKey < boolean > = {
2019-06-26 14:06:20 +02:00
key : 'disable_cosmetic_slowdown' ,
2020-07-19 18:49:00 +02:00
description : 'Disable the cosmetic slowdows in some processes, like icon upload.' ,
valueType : "boolean" ,
defaultValue : false
2019-06-26 14:06:20 +02:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_DISABLE_CONTEXT_MENU : ValuedSettingsKey < boolean > = {
2019-03-17 12:15:39 +01:00
key : 'disableContextMenu' ,
2020-04-18 19:37:30 +02:00
description : 'Disable the context menu for the channel tree which allows to debug the DOM easier' ,
2020-07-19 18:49:00 +02:00
defaultValue : false ,
valueType : "boolean" ,
2019-03-17 12:15:39 +01:00
} ;
2019-08-21 10:00:01 +02:00
2020-07-19 18:49:00 +02:00
static readonly KEY_DISABLE_GLOBAL_CONTEXT_MENU : ValuedSettingsKey < boolean > = {
2019-08-21 10:00:01 +02:00
key : 'disableGlobalContextMenu' ,
2020-09-17 23:19:30 +02:00
description : 'Disable the general context menu' ,
defaultValue : true ,
2020-07-19 18:49:00 +02:00
valueType : "boolean" ,
2019-08-21 10:00:01 +02:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_DISABLE_UNLOAD_DIALOG : ValuedSettingsKey < boolean > = {
2019-03-17 12:15:39 +01:00
key : 'disableUnloadDialog' ,
2020-07-19 18:49:00 +02:00
description : 'Disables the unload popup on side closing' ,
valueType : "boolean" ,
defaultValue : false
2019-03-17 12:15:39 +01:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_DISABLE_VOICE : ValuedSettingsKey < boolean > = {
2019-03-17 12:15:39 +01:00
key : 'disableVoice' ,
2020-07-19 18:49:00 +02:00
description : 'Disables the voice bridge. If disabled, the audio and codec workers aren\'t required anymore' ,
valueType : "boolean" ,
defaultValue : false
2019-03-17 12:15:39 +01:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_DISABLE_MULTI_SESSION : ValuedSettingsKey < boolean > = {
2019-04-04 21:47:52 +02:00
key : 'disableMultiSession' ,
2020-07-19 18:49:00 +02:00
defaultValue : false ,
requireRestart : true ,
valueType : "boolean" ,
2019-04-04 21:47:52 +02:00
} ;
2019-03-17 12:15:39 +01:00
2020-07-19 18:49:00 +02:00
static readonly KEY_LOAD_DUMMY_ERROR : ValuedSettingsKey < boolean > = {
2019-03-25 20:04:04 +01:00
key : 'dummy_load_error' ,
2020-07-19 18:49:00 +02:00
description : 'Triggers a loading error at the end of the loading process.' ,
valueType : "boolean" ,
defaultValue : false
} ;
static readonly KEY_I18N_DEFAULT_REPOSITORY : ValuedSettingsKey < string > = {
key : 'i18n.default_repository' ,
valueType : "string" ,
defaultValue : "https://web.teaspeak.de/i18n/"
2019-03-25 20:04:04 +01:00
} ;
2020-04-09 15:10:14 +02:00
/* Default client states */
2020-07-19 18:49:00 +02:00
static readonly KEY_CLIENT_STATE_MICROPHONE_MUTED : ValuedSettingsKey < boolean > = {
2020-04-09 15:10:14 +02:00
key : 'client_state_microphone_muted' ,
2020-07-19 18:49:00 +02:00
defaultValue : false ,
fallbackKeys : [ "mute_input" ] ,
valueType : "boolean" ,
2019-03-17 12:15:39 +01:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_CLIENT_STATE_SPEAKER_MUTED : ValuedSettingsKey < boolean > = {
2020-04-09 15:10:14 +02:00
key : 'client_state_speaker_muted' ,
2020-07-19 18:49:00 +02:00
defaultValue : false ,
fallbackKeys : [ "mute_output" ] ,
valueType : "boolean" ,
2019-03-17 12:15:39 +01:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_CLIENT_STATE_QUERY_SHOWN : ValuedSettingsKey < boolean > = {
2020-04-09 15:10:14 +02:00
key : 'client_state_query_shown' ,
2020-07-19 18:49:00 +02:00
defaultValue : false ,
fallbackKeys : [ "show_server_queries" ] ,
valueType : "boolean" ,
2019-03-17 12:15:39 +01:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_CLIENT_STATE_SUBSCRIBE_ALL_CHANNELS : ValuedSettingsKey < boolean > = {
2020-04-09 15:10:14 +02:00
key : 'client_state_subscribe_all_channels' ,
2020-07-19 18:49:00 +02:00
defaultValue : true ,
fallbackKeys : [ "channel_subscribe_all" ] ,
valueType : "boolean" ,
2020-04-09 15:10:14 +02:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_CLIENT_STATE_AWAY : ValuedSettingsKey < boolean > = {
2020-04-09 15:10:14 +02:00
key : 'client_state_away' ,
2020-07-19 18:49:00 +02:00
defaultValue : false ,
valueType : "boolean" ,
2020-04-09 15:10:14 +02:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_CLIENT_AWAY_MESSAGE : ValuedSettingsKey < string > = {
2020-04-09 15:10:14 +02:00
key : 'client_away_message' ,
2020-07-19 18:49:00 +02:00
defaultValue : "" ,
valueType : "string"
2019-03-17 12:15:39 +01:00
} ;
/* Connect parameters */
2020-07-19 18:49:00 +02:00
static readonly KEY_FLAG_CONNECT_DEFAULT : ValuedSettingsKey < boolean > = {
key : 'connect_default' ,
valueType : "boolean" ,
defaultValue : false
2019-03-17 12:15:39 +01:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_CONNECT_ADDRESS : ValuedSettingsKey < string > = {
key : 'connect_address' ,
valueType : "string" ,
defaultValue : undefined
2019-03-17 12:15:39 +01:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_CONNECT_PROFILE : ValuedSettingsKey < string > = {
2019-12-21 16:46:56 +01:00
key : 'connect_profile' ,
2020-07-19 18:49:00 +02:00
defaultValue : 'default' ,
valueType : "string" ,
} ;
static readonly KEY_CONNECT_USERNAME : ValuedSettingsKey < string > = {
key : 'connect_username' ,
valueType : "string" ,
defaultValue : undefined
} ;
static readonly KEY_CONNECT_PASSWORD : ValuedSettingsKey < string > = {
key : 'connect_password' ,
valueType : "string" ,
defaultValue : undefined
} ;
static readonly KEY_FLAG_CONNECT_PASSWORD : ValuedSettingsKey < boolean > = {
key : 'connect_password_hashed' ,
valueType : "boolean" ,
defaultValue : false
} ;
static readonly KEY_CONNECT_HISTORY : ValuedSettingsKey < string > = {
key : 'connect_history' ,
valueType : "string" ,
defaultValue : ""
} ;
static readonly KEY_CONNECT_SHOW_HISTORY : ValuedSettingsKey < boolean > = {
key : 'connect_show_last_servers' ,
valueType : "boolean" ,
defaultValue : false
} ;
static readonly KEY_CONNECT_NO_SINGLE_INSTANCE : ValuedSettingsKey < boolean > = {
2020-06-15 16:56:05 +02:00
key : 'connect_no_single_instance' ,
2020-07-19 18:49:00 +02:00
defaultValue : false ,
valueType : "boolean" ,
2020-06-15 16:56:05 +02:00
} ;
2019-03-17 12:15:39 +01:00
2020-07-19 18:49:00 +02:00
static readonly KEY_CONNECT_NO_DNSPROXY : ValuedSettingsKey < boolean > = {
2019-11-24 01:16:07 +01:00
key : 'connect_no_dnsproxy' ,
2020-07-19 18:49:00 +02:00
defaultValue : false ,
valueType : "boolean" ,
2019-11-24 01:16:07 +01:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_CERTIFICATE_CALLBACK : ValuedSettingsKey < string > = {
key : 'certificate_callback' ,
valueType : "string" ,
defaultValue : undefined
2019-04-04 21:47:52 +02:00
} ;
2019-04-29 18:49:01 +02:00
/* sounds */
2020-07-19 18:49:00 +02:00
static readonly KEY_SOUND_MASTER : ValuedSettingsKey < number > = {
2019-08-21 10:00:01 +02:00
key : 'audio_master_volume' ,
2020-07-19 18:49:00 +02:00
defaultValue : 100 ,
valueType : "number" ,
2019-04-29 18:49:01 +02:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_SOUND_MASTER_SOUNDS : ValuedSettingsKey < number > = {
2019-08-21 10:00:01 +02:00
key : 'audio_master_volume_sounds' ,
2020-07-19 18:49:00 +02:00
defaultValue : 100 ,
valueType : "number" ,
} ;
static readonly KEY_SOUND_VOLUMES : SettingsKey < string > = {
key : 'sound_volume' ,
valueType : "string" ,
2019-08-21 10:00:01 +02:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_CHAT_FIXED_TIMESTAMPS : ValuedSettingsKey < boolean > = {
2019-08-21 10:00:01 +02:00
key : 'chat_fixed_timestamps' ,
2020-07-19 18:49:00 +02:00
defaultValue : false ,
description : 'Enables fixed timestamps for chat messages and disabled the updating once (2 seconds ago... etc)' ,
valueType : "boolean" ,
2019-08-21 10:00:01 +02:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_CHAT_COLLOQUIAL_TIMESTAMPS : ValuedSettingsKey < boolean > = {
2019-08-21 10:00:01 +02:00
key : 'chat_colloquial_timestamps' ,
2020-07-19 18:49:00 +02:00
defaultValue : true ,
description : 'Enabled colloquial timestamp formatting like "Yesterday at ..." or "Today at ..."' ,
valueType : "boolean" ,
2019-08-21 10:00:01 +02:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_CHAT_COLORED_EMOJIES : ValuedSettingsKey < boolean > = {
2019-08-21 10:00:01 +02:00
key : 'chat_colored_emojies' ,
2020-07-19 18:49:00 +02:00
defaultValue : true ,
description : 'Enables colored emojies powered by Twemoji' ,
valueType : "boolean" ,
2019-08-21 10:00:01 +02:00
} ;
2020-12-09 18:45:11 +01:00
static readonly KEY_CHAT_HIGHLIGHT_CODE : ValuedSettingsKey < boolean > = {
key : 'chat_highlight_code' ,
defaultValue : true ,
description : 'Enables code highlighting within the chat (Client restart required)' ,
valueType : "boolean" ,
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_CHAT_TAG_URLS : ValuedSettingsKey < boolean > = {
2019-08-21 10:00:01 +02:00
key : 'chat_tag_urls' ,
2020-07-19 18:49:00 +02:00
defaultValue : true ,
description : 'Automatically link urls with [url]' ,
valueType : "boolean" ,
2019-08-21 10:00:01 +02:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_CHAT_ENABLE_MARKDOWN : ValuedSettingsKey < boolean > = {
2019-08-21 10:00:01 +02:00
key : 'chat_enable_markdown' ,
2020-07-19 18:49:00 +02:00
defaultValue : true ,
description : 'Enabled markdown chat support.' ,
valueType : "boolean" ,
2019-08-21 10:00:01 +02:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_CHAT_ENABLE_BBCODE : ValuedSettingsKey < boolean > = {
2019-08-21 10:00:01 +02:00
key : 'chat_enable_bbcode' ,
2020-07-19 18:49:00 +02:00
defaultValue : false ,
description : 'Enabled bbcode support in chat.' ,
valueType : "boolean" ,
2019-08-21 10:00:01 +02:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_CHAT_IMAGE_WHITELIST_REGEX : ValuedSettingsKey < string > = {
2020-03-19 14:31:45 +01:00
key : 'chat_image_whitelist_regex' ,
2020-07-19 18:49:00 +02:00
defaultValue : JSON.stringify ( [ ] ) ,
valueType : "string" ,
2020-03-19 14:31:45 +01:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_SWITCH_INSTANT_CHAT : ValuedSettingsKey < boolean > = {
2019-08-21 10:00:01 +02:00
key : 'switch_instant_chat' ,
2020-07-19 18:49:00 +02:00
defaultValue : true ,
description : 'Directly switch to channel chat on channel select' ,
valueType : "boolean" ,
2019-08-21 10:00:01 +02:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_SWITCH_INSTANT_CLIENT : ValuedSettingsKey < boolean > = {
2019-08-21 10:00:01 +02:00
key : 'switch_instant_client' ,
2020-07-19 18:49:00 +02:00
defaultValue : true ,
description : 'Directly switch to client info on client select' ,
valueType : "boolean" ,
2019-08-21 10:00:01 +02:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_HOSTBANNER_BACKGROUND : ValuedSettingsKey < boolean > = {
2019-08-21 10:00:01 +02:00
key : 'hostbanner_background' ,
2020-07-19 18:49:00 +02:00
defaultValue : false ,
description : 'Enables a default background begind the hostbanner' ,
valueType : "boolean" ,
2019-08-21 10:00:01 +02:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_CHANNEL_EDIT_ADVANCED : ValuedSettingsKey < boolean > = {
2019-08-21 10:00:01 +02:00
key : 'channel_edit_advanced' ,
2020-07-19 18:49:00 +02:00
defaultValue : false ,
description : 'Edit channels in advanced mode with a lot more settings' ,
valueType : "boolean" ,
2019-08-21 10:00:01 +02:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_PERMISSIONS_SHOW_ALL : ValuedSettingsKey < boolean > = {
2019-11-24 13:41:42 +01:00
key : 'permissions_show_all' ,
2020-07-19 18:49:00 +02:00
defaultValue : false ,
description : 'Show all permissions even thou they dont make sense for the server/channel group' ,
valueType : "boolean" ,
2019-11-24 13:41:42 +01:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_TEAFORO_URL : ValuedSettingsKey < string > = {
2019-08-21 10:00:01 +02:00
key : "teaforo_url" ,
2020-07-19 18:49:00 +02:00
defaultValue : "https://forum.teaspeak.de/" ,
valueType : "string" ,
2019-08-21 10:00:01 +02:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_FONT_SIZE : ValuedSettingsKey < number > = {
key : "font_size" ,
valueType : "number" ,
2020-09-17 23:06:02 +02:00
defaultValue : 14 //parseInt(getComputedStyle(document.body).fontSize)
2019-04-29 18:49:01 +02:00
} ;
2019-10-19 17:13:40 +02:00
2020-07-19 18:49:00 +02:00
static readonly KEY_ICON_SIZE : ValuedSettingsKey < number > = {
2019-10-19 17:13:40 +02:00
key : "icon_size" ,
2020-07-19 18:49:00 +02:00
defaultValue : 100 ,
valueType : "number" ,
2019-10-19 17:13:40 +02:00
} ;
2019-04-29 18:49:01 +02:00
2020-07-19 18:49:00 +02:00
static readonly KEY_KEYCONTROL_DATA : ValuedSettingsKey < string > = {
2020-04-10 20:57:50 +02:00
key : "keycontrol_data" ,
2020-07-19 18:49:00 +02:00
defaultValue : "{}" ,
valueType : "string" ,
2020-04-10 20:57:50 +02:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_LAST_INVITE_LINK_TYPE : ValuedSettingsKey < string > = {
2019-10-13 21:33:07 +02:00
key : "last_invite_link_type" ,
2020-07-19 18:49:00 +02:00
defaultValue : "tea-web" ,
valueType : "string" ,
2019-10-13 21:33:07 +02:00
} ;
2020-07-19 18:49:00 +02:00
static readonly KEY_TRANSFERS_SHOW_FINISHED : ValuedSettingsKey < boolean > = {
2020-06-10 18:13:56 +02:00
key : 'transfers_show_finished' ,
2020-07-19 18:49:00 +02:00
defaultValue : true ,
description : "Show finished file transfers in the file transfer list" ,
valueType : "boolean" ,
2020-06-10 18:13:56 +02:00
} ;
2020-06-10 22:44:50 +02:00
static readonly KEY_TRANSFER_DOWNLOAD_FOLDER : SettingsKey < string > = {
key : "transfer_download_folder" ,
description : "The download folder for the file transfer downloads" ,
2020-07-19 18:49:00 +02:00
valueType : "string" ,
/* defaultValue: <users download directory> */
} ;
2020-07-20 19:08:13 +02:00
static readonly KEY_IPC_REMOTE_ADDRESS : SettingsKey < string > = {
key : "ipc-address" ,
valueType : "string"
} ;
2020-08-07 13:40:11 +02:00
static readonly KEY_W2G_SIDEBAR_COLLAPSED : ValuedSettingsKey < boolean > = {
key : 'w2g_sidebar_collapsed' ,
defaultValue : false ,
valueType : "boolean" ,
} ;
2020-09-07 12:42:00 +02:00
static readonly KEY_VOICE_ECHO_TEST_ENABLED : ValuedSettingsKey < boolean > = {
key : 'voice_echo_test_enabled' ,
defaultValue : true ,
valueType : "boolean" ,
} ;
2020-10-01 10:56:54 +02:00
static readonly KEY_RNNOISE_FILTER : ValuedSettingsKey < boolean > = {
key : 'rnnoise_filter' ,
defaultValue : true ,
description : 'Enable the rnnoise filter for supressing background noise' ,
valueType : "boolean" ,
} ;
2020-10-05 10:44:44 +02:00
static readonly KEY_LOADER_ANIMATION_ABORT : ValuedSettingsKey < boolean > = {
key : 'loader_animation_abort' ,
defaultValue : false ,
description : 'Abort the loader animation when the app has been finished loading' ,
valueType : "boolean" ,
} ;
2020-11-07 13:16:07 +01:00
static readonly KEY_STOP_VIDEO_ON_SWITCH : ValuedSettingsKey < boolean > = {
key : 'stop_video_on_channel_switch' ,
defaultValue : true ,
description : 'Stop video broadcasting on channel switch' ,
valueType : "boolean" ,
} ;
2020-12-10 13:32:35 +01:00
static readonly KEY_VIDEO_SHOW_ALL_CLIENTS : ValuedSettingsKey < boolean > = {
key : 'video_show_all_clients' ,
defaultValue : false ,
description : "Show all clients within the video frame, even if they're not broadcasting video" ,
valueType : "boolean" ,
} ;
static readonly KEY_VIDEO_FORCE_SHOW_OWN_VIDEO : ValuedSettingsKey < boolean > = {
key : 'video_force_show_own_video' ,
defaultValue : true ,
description : "Show own video preview even if you're not broadcasting any video" ,
valueType : "boolean" ,
} ;
static readonly KEY_VIDEO_AUTO_SUBSCRIBE_MODE : ValuedSettingsKey < number > = {
key : 'video_auto_subscribe_mode' ,
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" ,
} ;
2020-07-19 18:49:00 +02:00
static readonly FN_LOG_ENABLED : ( category : string ) = > SettingsKey < boolean > = category = > {
return {
key : "log." + category . toLowerCase ( ) + ".enabled" ,
valueType : "boolean" ,
}
} ;
static readonly FN_SEPARATOR_STATE : ( separator : string ) = > SettingsKey < string > = separator = > {
return {
key : "separator-settings-" + separator ,
valueType : "string" ,
fallbackKeys : [ "seperator-settings-" + separator ]
}
} ;
static readonly FN_LOG_LEVEL_ENABLED : ( category : string ) = > SettingsKey < boolean > = category = > {
return {
key : "log.level." + category . toLowerCase ( ) + ".enabled" ,
2020-08-09 14:30:17 +02:00
valueType : "boolean"
2020-07-19 18:49:00 +02:00
}
2020-06-10 22:44:50 +02:00
} ;
2019-10-13 21:33:07 +02:00
static readonly FN_INVITE_LINK_SETTING : ( name : string ) = > SettingsKey < string > = name = > {
return {
2020-07-19 18:49:00 +02:00
key : 'invite_link_setting_' + name ,
valueType : "string" ,
2019-10-13 21:33:07 +02:00
}
} ;
2019-08-31 18:31:01 +02:00
static readonly FN_SERVER_CHANNEL_SUBSCRIBE_MODE : ( channel_id : number ) = > SettingsKey < number > = channel = > {
2019-03-17 12:15:39 +01:00
return {
2020-07-19 18:49:00 +02:00
key : 'channel_subscribe_mode_' + channel ,
valueType : "number" ,
2019-03-17 12:15:39 +01:00
}
} ;
2020-07-19 18:49:00 +02:00
static readonly FN_SERVER_CHANNEL_COLLAPSED : ( channel_id : number ) = > ValuedSettingsKey < boolean > = channel = > {
2020-04-18 21:31:13 +02:00
return {
key : 'channel_collapsed_' + channel ,
2020-07-19 18:49:00 +02:00
defaultValue : false ,
valueType : "boolean" ,
2020-04-18 21:31:13 +02:00
}
} ;
2020-08-09 14:30:17 +02:00
static readonly FN_PROFILE_RECORD : ( name : string ) = > SettingsKey < object > = name = > {
2019-05-20 18:57:14 +02:00
return {
2020-07-19 18:49:00 +02:00
key : 'profile_record' + name ,
2020-08-09 14:30:17 +02:00
valueType : "object" ,
2019-05-20 18:57:14 +02:00
}
} ;
2020-07-12 16:31:57 +02:00
static readonly FN_CHANNEL_CHAT_READ : ( id : number ) = > SettingsKey < number > = id = > {
return {
2020-07-19 18:49:00 +02:00
key : 'channel_chat_read_' + id ,
valueType : "number" ,
}
} ;
static readonly FN_CLIENT_MUTED : ( clientUniqueId : string ) = > SettingsKey < boolean > = clientUniqueId = > {
return {
key : "client_" + clientUniqueId + "_muted" ,
valueType : "boolean" ,
fallbackKeys : [ "mute_client_" + clientUniqueId ]
}
} ;
static readonly FN_CLIENT_VOLUME : ( clientUniqueId : string ) = > SettingsKey < number > = clientUniqueId = > {
return {
key : "client_" + clientUniqueId + "_volume" ,
valueType : "number" ,
fallbackKeys : [ "volume_client_" + clientUniqueId ]
2020-07-12 16:31:57 +02:00
}
} ;
2020-07-22 00:55:28 +02:00
static readonly FN_EVENTS_NOTIFICATION_ENABLED : ( event : string ) = > SettingsKey < boolean > = event = > {
return {
2020-07-23 20:00:25 +02:00
key : "event_notification_" + event + "_enabled" ,
valueType : "boolean"
}
} ;
static readonly FN_EVENTS_LOG_ENABLED : ( event : string ) = > SettingsKey < boolean > = event = > {
return {
key : "event_log_" + event + "_enabled" ,
valueType : "boolean"
}
} ;
static readonly FN_EVENTS_FOCUS_ENABLED : ( event : string ) = > SettingsKey < boolean > = event = > {
return {
key : "event_focus_" + event + "_enabled" ,
2020-07-22 00:55:28 +02:00
valueType : "boolean"
}
} ;
2019-03-17 12:15:39 +01:00
static readonly KEYS = ( ( ) = > {
const result = [ ] ;
2020-07-19 18:49:00 +02:00
for ( const key of Object . keys ( Settings ) ) {
2019-03-17 12:15:39 +01:00
if ( ! key . toUpperCase ( ) . startsWith ( "KEY_" ) )
continue ;
result . push ( key ) ;
}
return result ;
} ) ( ) ;
2018-04-19 19:46:47 +02:00
2019-08-31 18:31:01 +02:00
static initialize() {
settings = new Settings ( ) ;
2020-04-09 15:10:14 +02:00
( window as any ) . settings = settings ;
( window as any ) . Settings = Settings ;
2019-08-31 18:31:01 +02:00
}
2020-07-19 17:12:41 +02:00
readonly events : Registry < SettingsEvents > ;
private readonly cacheGlobal = { } ;
private saveWorker : number ;
2018-04-19 19:46:47 +02:00
private updated : boolean = false ;
constructor ( ) {
super ( ) ;
2019-11-09 13:19:58 +01:00
2020-07-19 17:12:41 +02:00
this . events = new Registry < SettingsEvents > ( ) ;
2019-11-09 13:19:58 +01:00
const json = localStorage . getItem ( "settings.global" ) ;
try {
this . cacheGlobal = JSON . parse ( json ) ;
} catch ( error ) {
log . error ( LogCategory . GENERAL , tr ( "Failed to load global settings!\nJson: %s\nError: %o" ) , json , error ) ;
const show_popup = ( ) = > {
2020-07-19 22:02:31 +02: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 13:19:58 +01: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 19:46:47 +02:00
if ( ! this . cacheGlobal ) this . cacheGlobal = { } ;
this . saveWorker = setInterval ( ( ) = > {
if ( this . updated )
this . save ( ) ;
} , 5 * 1000 ) ;
2018-04-16 20:38:35 +02:00
}
2020-07-19 18:49:00 +02:00
static_global < V extends ConfigValueTypes > ( key : ValuedSettingsKey < V > , defaultValue? : V ) : V ;
static_global < V extends ConfigValueTypes , DV > ( key : SettingsKey < V > , defaultValue : DV ) : V | DV ;
static_global < V extends ConfigValueTypes , DV > ( key : SettingsKey < V > | ValuedSettingsKey < V > , defaultValue : DV ) : V | DV {
const staticValue = this . static ( key , kNoValuePresent ) ;
if ( staticValue !== kNoValuePresent )
return staticValue ;
2019-08-21 10:00:01 +02:00
2020-07-19 18:49:00 +02:00
if ( arguments . length > 1 )
return this . global ( key , defaultValue ) ;
return this . global ( key as ValuedSettingsKey < V > ) ;
2018-09-22 16:52:26 +02:00
}
2020-07-19 18:49:00 +02:00
global < V extends ConfigValueTypes , DV > ( key : SettingsKey < V > , defaultValue : DV ) : V | DV ;
global < V extends ConfigValueTypes > ( key : ValuedSettingsKey < V > , defaultValue? : V ) : V ;
global < V extends ConfigValueTypes , DV > ( key : SettingsKey < V > , defaultValue : DV ) : V | DV {
return StaticSettings . resolveKey ( key , key = > this . cacheGlobal [ key ] , key . valueType , arguments . length > 1 ? defaultValue : key.defaultValue ) ;
2018-02-27 17:20:49 +01:00
}
2020-07-19 18:49:00 +02:00
changeGlobal < T extends ConfigValueTypes > ( key : SettingsKey < T > , value? : T ) {
if ( this . cacheGlobal [ key . key ] === value )
return ;
2018-03-07 19:06:52 +01:00
2018-02-27 17:20:49 +01:00
this . updated = true ;
2020-07-19 17:12:41 +02:00
const oldValue = this . cacheGlobal [ key . key ] ;
2020-07-19 18:49:00 +02:00
this . cacheGlobal [ key . key ] = StaticSettings . encodeValueToString ( value ) ;
2020-07-19 17:12:41 +02:00
this . events . fire ( "notify_setting_changed" , {
mode : "global" ,
newValue : this.cacheGlobal [ key . key ] ,
oldValue : oldValue ,
2020-09-07 12:42:00 +02:00
setting : key.key ,
newCastedValue : value
2020-07-19 17:12:41 +02:00
} ) ;
2020-09-17 23:19:30 +02:00
logTrace ( LogCategory . GENERAL , tr ( "Changing global setting %s to %o" ) , key . key , value ) ;
2018-02-27 17:20:49 +01:00
if ( Settings . UPDATE_DIRECT )
this . save ( ) ;
}
2020-09-07 12:42:00 +02:00
globalChangeListener < T extends ConfigValueTypes > ( key : SettingsKey < T > , listener : ( newValue : T ) = > void ) : ( ) = > void {
return this . events . on ( "notify_setting_changed" , event = > {
if ( event . setting === key . key && event . mode === "global" ) {
listener ( event . newCastedValue ) ;
}
} )
}
2019-04-04 21:47:52 +02:00
save() {
this . updated = false ;
let global = JSON . stringify ( this . cacheGlobal ) ;
localStorage . setItem ( "settings.global" , global ) ;
2019-04-15 15:33:51 +02:00
if ( localStorage . save )
localStorage . save ( ) ;
2019-04-04 21:47:52 +02:00
}
}
2020-03-30 13:44:18 +02:00
export class ServerSettings extends SettingsBase {
2019-04-04 21:47:52 +02:00
private cacheServer = { } ;
2019-08-31 18:31:01 +02:00
private _server_unique_id : string ;
2020-07-19 17:12:41 +02:00
private _server_save_worker : number ;
2019-04-04 21:47:52 +02:00
private _server_settings_updated : boolean = false ;
2019-08-21 10:00:01 +02:00
private _destroyed = false ;
2019-04-04 21:47:52 +02:00
constructor ( ) {
super ( ) ;
this . _server_save_worker = setInterval ( ( ) = > {
if ( this . _server_settings_updated )
this . save ( ) ;
} , 5 * 1000 ) ;
}
2019-08-21 10:00:01 +02:00
destroy() {
this . _destroyed = true ;
2019-08-31 18:31:01 +02:00
this . _server_unique_id = undefined ;
2019-08-21 10:00:01 +02:00
this . cacheServer = undefined ;
clearInterval ( this . _server_save_worker ) ;
this . _server_save_worker = undefined ;
}
2020-07-19 18:49:00 +02:00
server < V extends ConfigValueTypes , DV extends V | undefined = undefined > ( key : SettingsKey < V > , defaultValue? : DV ) : V | DV {
if ( this . _destroyed )
throw "destroyed" ;
return StaticSettings . resolveKey ( key , key = > this . cacheServer [ key ] , key . valueType , arguments . length > 1 ? defaultValue : key.defaultValue ) ;
2019-04-04 21:47:52 +02:00
}
2020-07-19 18:49:00 +02:00
changeServer < T extends ConfigValueTypes > ( key : SettingsKey < T > , value? : T ) {
2019-08-21 10:00:01 +02:00
if ( this . _destroyed ) throw "destroyed" ;
2019-03-17 12:15:39 +01:00
2020-07-19 18:49:00 +02:00
if ( this . cacheServer [ key . key ] === value )
return ;
2018-03-07 19:06:52 +01:00
2019-04-04 21:47:52 +02:00
this . _server_settings_updated = true ;
2020-07-19 18:49:00 +02:00
this . cacheServer [ key . key ] = StaticSettings . encodeValueToString ( value ) ;
2018-02-27 17:20:49 +01:00
if ( Settings . UPDATE_DIRECT )
this . save ( ) ;
}
2019-08-31 18:31:01 +02:00
setServer ( server_unique_id : string ) {
2019-08-21 10:00:01 +02:00
if ( this . _destroyed ) throw "destroyed" ;
2019-08-31 18:31:01 +02:00
if ( this . _server_unique_id ) {
2018-04-16 20:38:35 +02:00
this . save ( ) ;
2018-03-07 19:06:52 +01:00
this . cacheServer = { } ;
2019-08-31 18:31:01 +02:00
this . _server_unique_id = undefined ;
2018-04-16 20:38:35 +02:00
}
2019-08-31 18:31:01 +02:00
this . _server_unique_id = server_unique_id ;
2018-04-16 20:38:35 +02:00
2019-08-31 18:31:01 +02:00
if ( this . _server_unique_id ) {
2019-11-09 13:19:58 +01:00
const json = localStorage . getItem ( "settings.server_" + server_unique_id ) ;
try {
this . cacheServer = JSON . parse ( json ) ;
} catch ( error ) {
log . error ( LogCategory . GENERAL , tr ( "Failed to load server settings for server %s!\nJson: %s\nError: %o" ) , server_unique_id , json , error ) ;
}
2018-04-16 20:38:35 +02:00
if ( ! this . cacheServer )
this . cacheServer = { } ;
2018-03-07 19:06:52 +01:00
}
2018-02-27 17:20:49 +01:00
}
save() {
2019-08-21 10:00:01 +02:00
if ( this . _destroyed ) throw "destroyed" ;
2019-04-04 21:47:52 +02:00
this . _server_settings_updated = false ;
2018-02-27 17:20:49 +01:00
2019-08-31 18:31:01 +02:00
if ( this . _server_unique_id ) {
2018-03-07 19:06:52 +01:00
let server = JSON . stringify ( this . cacheServer ) ;
2019-08-31 18:31:01 +02:00
localStorage . setItem ( "settings.server_" + this . _server_unique_id , server ) ;
2019-04-15 15:33:51 +02:00
if ( localStorage . save )
localStorage . save ( ) ;
2018-03-07 19:06:52 +01:00
}
2018-02-27 17:20:49 +01:00
}
2019-08-31 18:31:01 +02:00
}
2020-07-20 19:08:13 +02:00
export let settings : Settings = null ;
loader . register_task ( Stage . JAVASCRIPT_INITIALIZING , {
priority : 1000 ,
name : "Settings initialize" ,
function : async ( ) = > Settings . initialize ( )
} )