2020-03-30 13:44:18 +02:00
import { createErrorModal , createInfoModal , createInputModal , createModal , Modal } from "tc-shared/ui/elements/Modal" ;
import { sliderfy } from "tc-shared/ui/elements/Slider" ;
import { settings , Settings } from "tc-shared/settings" ;
2020-09-12 15:49:20 +02:00
import * as sound from "tc-shared/sound/Sounds" ;
2020-03-30 13:44:18 +02:00
import { manager , set_master_volume , Sound } from "tc-shared/sound/Sounds" ;
2020-09-12 15:49:20 +02:00
import * as profiles from "tc-shared/profiles/ConnectionProfile" ;
2020-03-30 13:44:18 +02:00
import { ConnectionProfile } from "tc-shared/profiles/ConnectionProfile" ;
import { IdentitifyType } from "tc-shared/profiles/Identity" ;
import { TeaForumIdentity } from "tc-shared/profiles/identities/TeaForumIdentity" ;
import { TeaSpeakIdentity } from "tc-shared/profiles/identities/TeamSpeakIdentity" ;
import { NameIdentity } from "tc-shared/profiles/identities/NameIdentity" ;
import * as log from "tc-shared/log" ;
import { LogCategory } from "tc-shared/log" ;
2020-09-12 15:49:20 +02:00
import * as i18n from "tc-shared/i18n/localize" ;
2020-03-30 13:44:18 +02:00
import { RepositoryTranslation , TranslationRepository } from "tc-shared/i18n/localize" ;
2020-09-12 15:49:20 +02:00
import * as events from "tc-shared/events" ;
2020-03-30 13:44:18 +02:00
import { Registry } from "tc-shared/events" ;
import { spawnYesNo } from "tc-shared/ui/modal/ModalYesNo" ;
import * as i18nc from "tc-shared/i18n/country" ;
import { server_connections } from "tc-shared/ui/frames/connection_handlers" ;
import * as forum from "tc-shared/profiles/identities/teaspeak-forum" ;
import { formatMessage , set_icon_size } from "tc-shared/ui/frames/chat" ;
import { spawnTeamSpeakIdentityImport , spawnTeamSpeakIdentityImprove } from "tc-shared/ui/modal/ModalIdentity" ;
import { Device } from "tc-shared/audio/player" ;
import * as aplayer from "tc-backend/audio/player" ;
2020-04-10 20:57:50 +02:00
import { KeyMapSettings } from "tc-shared/ui/modal/settings/Keymap" ;
import * as React from "react" ;
import * as ReactDOM from "react-dom" ;
2020-07-23 19:31:31 +02:00
import { NotificationSettings } from "tc-shared/ui/modal/settings/Notifications" ;
2020-08-11 00:25:20 +02:00
import { initialize_audio_microphone_controller , MicrophoneSettingsEvents } from "tc-shared/ui/modal/settings/Microphone" ;
import { MicrophoneSettings } from "tc-shared/ui/modal/settings/MicrophoneRenderer" ;
2020-03-30 13:44:18 +02:00
2020-09-12 15:49:20 +02:00
export function spawnSettingsModal ( default_page? : string ) : Modal {
2020-03-30 13:44:18 +02:00
let modal : Modal ;
modal = createModal ( {
header : tr ( "Settings" ) ,
body : ( ) = > {
const tag = $ ( "#tmpl_settings" ) . renderTag ( ) . dividerfy ( ) ;
/* general "tab" mechanic */
const left = tag . find ( "> .left" ) ;
const right = tag . find ( "> .right" ) ;
{
left . find ( ".entry:not(.group)" ) . on ( 'click' , event = > {
const entry = $ ( event . target ) ;
right . find ( "> .container" ) . addClass ( "hidden" ) ;
left . find ( ".selected" ) . removeClass ( "selected" ) ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
const target = entry . attr ( "container" ) ;
2020-09-12 15:49:20 +02:00
if ( ! target ) return ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
right . find ( "> .container." + target ) . removeClass ( "hidden" ) ;
entry . addClass ( "selected" ) ;
} )
}
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
/* initialize all tabs */
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
/* enable one tab */
{
left . find ( ".entry[container" + ( default_page ? ( "='" + default_page + "'" ) : "" ) + "]" ) . first ( ) . trigger ( 'click' ) ;
}
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
return tag ;
} ,
footer : null
} ) ;
modal . htmlTag . find ( ".modal-body" ) . addClass ( "modal-settings" ) ;
settings_general_application ( modal . htmlTag . find ( ".right .container.general-application" ) , modal ) ;
settings_general_language ( modal . htmlTag . find ( ".right .container.general-language" ) , modal ) ;
settings_general_chat ( modal . htmlTag . find ( ".right .container.general-chat" ) , modal ) ;
2020-04-10 20:57:50 +02:00
settings_general_keymap ( modal . htmlTag . find ( ".right .container.general-keymap" ) , modal ) ;
2020-07-23 19:31:31 +02:00
settings_general_notifications ( modal . htmlTag . find ( ".right .container.general-notifications" ) , modal ) ;
2020-03-30 13:44:18 +02:00
settings_audio_microphone ( modal . htmlTag . find ( ".right .container.audio-microphone" ) , modal ) ;
settings_audio_speaker ( modal . htmlTag . find ( ".right .container.audio-speaker" ) , modal ) ;
settings_audio_sounds ( modal . htmlTag . find ( ".right .container.audio-sounds" ) , modal ) ;
const update_profiles = settings_identity_profiles ( modal . htmlTag . find ( ".right .container.identity-profiles" ) , modal ) ;
settings_identity_forum ( modal . htmlTag . find ( ".right .container.identity-forum" ) , modal , update_profiles as any ) ;
modal . close_listener . push ( ( ) = > {
2020-09-12 15:49:20 +02:00
if ( profiles . requires_save ( ) )
2020-03-30 13:44:18 +02:00
profiles . save ( ) ;
} ) ;
modal . open ( ) ;
return modal ;
}
function settings_general_application ( container : JQuery , modal : Modal ) {
/* hostbanner */
{
const option = container . find ( ".option-hostbanner-background" ) as JQuery < HTMLInputElement > ;
option . on ( 'change' , event = > {
settings . changeGlobal ( Settings . KEY_HOSTBANNER_BACKGROUND , option [ 0 ] . checked ) ;
2020-09-12 15:49:20 +02:00
for ( const sc of server_connections . all_connections ( ) )
2020-03-30 13:44:18 +02:00
sc . hostbanner . update ( ) ;
} ) . prop ( "checked" , settings . static_global ( Settings . KEY_HOSTBANNER_BACKGROUND ) ) ;
}
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
/* font size */
{
const current_size = parseInt ( getComputedStyle ( document . body ) . fontSize ) ; //settings.static_global(Settings.KEY_FONT_SIZE, 12);
const select = container . find ( ".option-font-size" ) ;
2020-09-12 15:49:20 +02:00
if ( select . find ( "option[value='" + current_size + "']" ) . length )
2020-03-30 13:44:18 +02:00
select . find ( "option[value='" + current_size + "']" ) . prop ( "selected" , true ) ;
else
select . find ( "option[value='-1']" ) . prop ( "selected" , true ) ;
select . on ( 'change' , event = > {
const value = parseInt ( select . val ( ) as string ) ;
settings . changeGlobal ( Settings . KEY_FONT_SIZE , value ) ;
console . log ( "Changed font size to %dpx" , value ) ;
$ ( document . body ) . css ( "font-size" , value + "px" ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
}
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
/* all permissions */
{
const option = container . find ( ".option-all-permissions" ) as JQuery < HTMLInputElement > ;
option . on ( 'change' , event = > {
settings . changeGlobal ( Settings . KEY_HOSTBANNER_BACKGROUND , option [ 0 ] . checked ) ;
} ) . prop ( "checked" , settings . global ( Settings . KEY_PERMISSIONS_SHOW_ALL ) ) ;
2019-01-28 20:36:11 +01:00
}
2020-03-30 13:44:18 +02:00
}
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
function settings_general_language ( container : JQuery , modal : Modal ) {
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
const container_entries = container . find ( ".container-list .entries" ) ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
const tag_loading = container . find ( ".cover-loading" ) ;
const template = $ ( "#settings-translations-list-entry" ) ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
const restart_hint = container . find ( ".restart-note" ) . hide ( ) ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
const display_repository_info = ( repository : TranslationRepository ) = > {
const info_modal = createModal ( {
header : tr ( "Repository info" ) ,
2019-01-28 20:36:11 +01:00
body : ( ) = > {
2020-03-30 13:44:18 +02:00
return $ ( "#settings-translations-list-entry-info" ) . renderTag ( {
type : "repository" ,
name : repository.name ,
url : repository.url ,
contact : repository.contact ,
translations : repository.translations || [ ] ,
} ) ;
} ,
footer : ( ) = > {
let footer = $ . spawn ( "div" ) ;
footer . addClass ( "modal-button-group" ) ;
footer . css ( "margin-top" , "5px" ) ;
footer . css ( "margin-bottom" , "5px" ) ;
footer . css ( "text-align" , "right" ) ;
let buttonOk = $ . spawn ( "button" ) ;
buttonOk . text ( tr ( "Close" ) ) ;
buttonOk . click ( ( ) = > info_modal . close ( ) ) ;
footer . append ( buttonOk ) ;
return footer ;
}
} ) ;
info_modal . open ( )
} ;
const display_translation_info = ( translation : RepositoryTranslation , repository : TranslationRepository ) = > {
const info_modal = createModal ( {
header : tr ( "Translation info" ) ,
body : ( ) = > {
const tag = $ ( "#settings-translations-list-entry-info" ) . renderTag ( {
type : "translation" ,
name : translation.name ,
url : translation.path ,
repository_name : repository.name ,
contributors : translation.contributors || [ ]
} ) ;
2019-11-24 13:41:42 +01:00
2020-03-30 13:44:18 +02:00
tag . find ( ".button-info" ) . on ( 'click' , ( ) = > display_repository_info ( repository ) ) ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
return tag ;
} ,
footer : ( ) = > {
let footer = $ . spawn ( "div" ) ;
footer . addClass ( "modal-button-group" ) ;
footer . css ( "margin-top" , "5px" ) ;
footer . css ( "margin-bottom" , "5px" ) ;
footer . css ( "text-align" , "right" ) ;
let buttonOk = $ . spawn ( "button" ) ;
buttonOk . text ( tr ( "Close" ) ) ;
buttonOk . click ( ( ) = > info_modal . close ( ) ) ;
footer . append ( buttonOk ) ;
return footer ;
}
} ) ;
info_modal . open ( )
} ;
const update_current_selected = ( ) = > {
2020-04-04 21:53:41 +02:00
const container_current = container . find ( ".selected-language" ) ;
2020-03-30 13:44:18 +02:00
container_current . empty ( ) . text ( tr ( "Loading" ) ) ;
let current_translation : RepositoryTranslation ;
i18n . iterate_repositories ( repository = > {
2020-09-12 15:49:20 +02:00
if ( current_translation ) return ;
for ( const entry of repository . translations )
if ( i18n . config . translation_config ( ) . current_translation_path == entry . path ) {
2020-03-30 13:44:18 +02:00
current_translation = entry ;
return ;
}
} ) . then ( ( ) = > {
container_current . empty ( ) ;
const language = current_translation ? current_translation . country_code : "gb" ;
$ . spawn ( "div" ) . addClass ( "country flag-" + language . toLowerCase ( ) ) . attr ( 'title' , i18nc . country_name ( language , tr ( "Unknown language" ) ) ) . appendTo ( container_current ) ;
$ . spawn ( "a" ) . text ( current_translation ? current_translation.name : tr ( "English (Default)" ) ) . appendTo ( container_current ) ;
} ) . catch ( error = > {
/* This shall never happen */
} ) ;
} ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
const initially_selected = i18n . config . translation_config ( ) . current_translation_url ;
const update_list = ( ) = > {
container_entries . empty ( ) ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
const currently_selected = i18n . config . translation_config ( ) . current_translation_url ;
//Default translation
{
const tag = template . renderTag ( {
type : "default" ,
selected : ! currently_selected || currently_selected == "default" ,
fallback_country_name : i18nc.country_name ( 'gb' ) ,
} ) ;
tag . on ( 'click' , ( ) = > {
i18n . select_translation ( undefined , undefined ) ;
container_entries . find ( ".selected" ) . removeClass ( "selected" ) ;
tag . addClass ( "selected" ) ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
update_current_selected ( ) ;
restart_hint . toggle ( initially_selected !== i18n . config . translation_config ( ) . current_translation_url ) ;
} ) ;
tag . appendTo ( container_entries ) ;
}
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
{
tag_loading . show ( ) ;
i18n . iterate_repositories ( repo = > {
let repo_tag = container_entries . find ( "[repository=\"" + repo . unique_id + "\"]" ) ;
if ( repo_tag . length == 0 ) {
repo_tag = template . renderTag ( {
2019-08-21 10:00:01 +02:00
type : "repository" ,
2020-03-30 13:44:18 +02:00
name : repo.name || repo . url ,
id : repo.unique_id
2019-01-28 20:36:11 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
repo_tag . find ( ".button-delete" ) . on ( 'click' , e = > {
e . preventDefault ( ) ;
spawnYesNo ( tr ( "Are you sure?" ) , tr ( "Do you really want to delete this repository?" ) , answer = > {
if ( answer ) {
i18n . delete_repository ( repo ) ;
update_list ( ) ;
}
} ) ;
} ) ;
repo_tag . find ( ".button-info" ) . on ( 'click' , e = > {
e . preventDefault ( ) ;
display_repository_info ( repo ) ;
} ) ;
container_entries . append ( repo_tag ) ;
2019-01-28 20:36:11 +01:00
}
2020-03-30 13:44:18 +02:00
2020-09-12 15:49:20 +02:00
for ( const translation of repo . translations ) {
2020-03-30 13:44:18 +02:00
const tag = template . renderTag ( {
2019-08-21 10:00:01 +02:00
type : "translation" ,
2020-03-30 13:44:18 +02:00
name : translation.name || translation . path ,
id : repo.unique_id ,
country_code : translation.country_code ,
2020-09-12 15:49:20 +02:00
selected : i18n.config.translation_config ( ) . current_translation_path == translation . path ,
2020-03-30 13:44:18 +02:00
fallback_country_name : i18nc.country_name ( 'gb' ) ,
country_name : i18nc.country_name ( ( translation . country_code || "XX" ) . toLowerCase ( ) ) ,
} ) ;
tag . find ( ".button-info" ) . on ( 'click' , e = > {
e . preventDefault ( ) ;
display_translation_info ( translation , repo ) ;
} ) ;
tag . on ( 'click' , e = > {
if ( e . isDefaultPrevented ( ) ) return ;
i18n . select_translation ( repo , translation ) ;
container_entries . find ( ".selected" ) . removeClass ( "selected" ) ;
tag . addClass ( "selected" ) ;
update_current_selected ( ) ;
restart_hint . toggle ( initially_selected !== i18n . config . translation_config ( ) . current_translation_url ) ;
2019-01-28 20:36:11 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
tag . insertAfter ( repo_tag ) ;
}
} ) . then ( ( ) = > tag_loading . hide ( ) ) . catch ( error = > {
console . error ( error ) ;
/* this should NEVER happen */
} )
}
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
} ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
/* button add repository */
{
container . find ( ".button-add-repository" ) . on ( 'click' , ( ) = > {
createInputModal ( tr ( "Enter repository URL" ) , tr ( "Enter repository URL:" ) , text = > {
try {
new URL ( text ) ;
return true ;
2020-09-12 15:49:20 +02:00
} catch ( error ) {
2020-03-30 13:44:18 +02:00
return false ;
2019-01-28 20:36:11 +01:00
}
2020-03-30 13:44:18 +02:00
} , url = > {
if ( ! url ) return ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
tag_loading . show ( ) ;
i18n . load_repository ( url as string ) . then ( repository = > {
i18n . register_repository ( repository ) ;
update_list ( ) ;
} ) . catch ( error = > {
tag_loading . hide ( ) ;
createErrorModal ( "Failed to load repository" , tr ( "Failed to query repository.<br>Ensure that this repository is valid and reachable.<br>Error: " ) + error ) . open ( ) ;
} )
} ) . open ( ) ;
} ) ;
}
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
container . find ( ".button-restart" ) . on ( 'click' , ( ) = > {
2020-09-12 15:49:20 +02:00
if ( __build . target === "web" ) {
2020-03-30 13:44:18 +02:00
location . reload ( ) ;
} else {
createErrorModal ( tr ( "Not implemented" ) , tr ( "Client restart isn't implemented.<br>Please do it manually!" ) ) . open ( ) ;
}
} ) ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
update_list ( ) ;
update_current_selected ( ) ;
}
2019-01-28 20:36:11 +01:00
2020-04-10 20:57:50 +02:00
function settings_general_keymap ( container : JQuery , modal : Modal ) {
2020-09-12 15:49:20 +02:00
const entry = < KeyMapSettings / > ;
2020-04-10 20:57:50 +02:00
ReactDOM . render ( entry , container [ 0 ] ) ;
2020-04-10 21:08:41 +02:00
modal . close_listener . push ( ( ) = > ReactDOM . unmountComponentAtNode ( container [ 0 ] ) ) ;
2020-04-10 20:57:50 +02:00
}
2020-07-23 19:31:31 +02:00
function settings_general_notifications ( container : JQuery , modal : Modal ) {
2020-09-12 15:49:20 +02:00
const entry = < NotificationSettings / > ;
2020-07-23 19:31:31 +02:00
ReactDOM . render ( entry , container [ 0 ] ) ;
modal . close_listener . push ( ( ) = > ReactDOM . unmountComponentAtNode ( container [ 0 ] ) ) ;
}
2020-03-30 13:44:18 +02:00
function settings_general_chat ( container : JQuery , modal : Modal ) {
/* timestamp format */
{
const option_fixed = container . find ( ".option-fixed-timestamps" ) as JQuery < HTMLInputElement > ;
const option_colloquial = container . find ( ".option-colloquial-timestamps" ) as JQuery < HTMLInputElement > ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
option_colloquial . on ( 'change' , event = > {
settings . changeGlobal ( Settings . KEY_CHAT_COLLOQUIAL_TIMESTAMPS , option_colloquial [ 0 ] . checked ) ;
} ) ;
2018-12-28 15:39:23 +01:00
2020-03-30 13:44:18 +02:00
option_fixed . on ( 'change' , event = > {
settings . changeGlobal ( Settings . KEY_CHAT_FIXED_TIMESTAMPS , option_fixed [ 0 ] . checked ) ;
option_colloquial
. prop ( "disabled" , option_fixed [ 0 ] . checked )
. parents ( "label" ) . toggleClass ( "disabled" , option_fixed [ 0 ] . checked ) ;
2020-09-12 15:49:20 +02:00
if ( option_fixed [ 0 ] . checked ) {
2020-03-30 13:44:18 +02:00
option_colloquial . prop ( "checked" , false ) ;
} else {
option_colloquial . prop ( "checked" , settings . static_global ( Settings . KEY_CHAT_COLLOQUIAL_TIMESTAMPS ) ) ;
2019-08-21 10:00:01 +02:00
}
2020-03-30 13:44:18 +02:00
} ) . prop ( "checked" , settings . static_global ( Settings . KEY_CHAT_FIXED_TIMESTAMPS ) ) . trigger ( 'change' ) ;
}
2018-12-28 15:39:23 +01:00
2020-03-30 13:44:18 +02:00
{
const option = container . find ( ".option-instant-channel-switch" ) as JQuery < HTMLInputElement > ;
option . on ( 'change' , event = > {
settings . changeGlobal ( Settings . KEY_SWITCH_INSTANT_CHAT , option [ 0 ] . checked ) ;
} ) . prop ( "checked" , settings . static_global ( Settings . KEY_SWITCH_INSTANT_CHAT ) ) ;
}
{
const option = container . find ( ".option-instant-client-switch" ) as JQuery < HTMLInputElement > ;
option . on ( 'change' , event = > {
settings . changeGlobal ( Settings . KEY_SWITCH_INSTANT_CLIENT , option [ 0 ] . checked ) ;
} ) . prop ( "checked" , settings . static_global ( Settings . KEY_SWITCH_INSTANT_CLIENT ) ) ;
}
{
const option = container . find ( ".option-colored-emojies" ) as JQuery < HTMLInputElement > ;
option . on ( 'change' , event = > {
settings . changeGlobal ( Settings . KEY_CHAT_COLORED_EMOJIES , option [ 0 ] . checked ) ;
} ) . prop ( "checked" , settings . static_global ( Settings . KEY_CHAT_COLORED_EMOJIES ) ) ;
}
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
{
const option = container . find ( ".option-support-markdown" ) as JQuery < HTMLInputElement > ;
option . on ( 'change' , event = > {
settings . changeGlobal ( Settings . KEY_CHAT_ENABLE_MARKDOWN , option [ 0 ] . checked ) ;
} ) . prop ( "checked" , settings . static_global ( Settings . KEY_CHAT_ENABLE_MARKDOWN ) ) ;
}
{
const option = container . find ( ".option-support-bbcode" ) as JQuery < HTMLInputElement > ;
option . on ( 'change' , event = > {
settings . changeGlobal ( Settings . KEY_CHAT_ENABLE_BBCODE , option [ 0 ] . checked ) ;
} ) . prop ( "checked" , settings . static_global ( Settings . KEY_CHAT_ENABLE_BBCODE ) ) ;
}
{
const option = container . find ( ".option-url-tagging" ) as JQuery < HTMLInputElement > ;
option . on ( 'change' , event = > {
settings . changeGlobal ( Settings . KEY_CHAT_TAG_URLS , option [ 0 ] . checked ) ;
} ) . prop ( "checked" , settings . static_global ( Settings . KEY_CHAT_TAG_URLS ) ) ;
}
/* Icon size */
{
const container_slider = container . find ( ".container-icon-size .container-slider" ) ;
const container_value = container . find ( ".container-icon-size .value" ) ;
sliderfy ( container_slider , {
unit : '%' ,
min_value : 25 ,
max_value : 300 ,
step : 5 ,
initial_value : settings.static_global ( Settings . KEY_ICON_SIZE ) ,
value_field : container_value
} ) ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
container_slider . on ( 'change' , event = > {
const value = parseInt ( container_slider . attr ( "value" ) as string ) ;
settings . changeGlobal ( Settings . KEY_ICON_SIZE , value ) ;
console . log ( "Changed icon size to %sem" , ( value / 100 ) . toFixed ( 2 ) ) ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
set_icon_size ( ( value / 100 ) . toFixed ( 2 ) + "em" ) ;
} ) ;
}
}
function settings_audio_microphone ( container : JQuery , modal : Modal ) {
2020-08-11 00:25:20 +02:00
const registry = new Registry < MicrophoneSettingsEvents > ( ) ;
initialize_audio_microphone_controller ( registry ) ;
2020-09-12 15:49:20 +02:00
const entry = < MicrophoneSettings events = { registry } / > ;
2020-08-11 00:25:20 +02:00
ReactDOM . render ( entry , container [ 0 ] ) ;
modal . close_listener . push ( ( ) = > {
ReactDOM . unmountComponentAtNode ( container [ 0 ] ) ;
registry . fire ( "notify_destroy" ) ;
} ) ;
2020-03-30 13:44:18 +02:00
return ;
}
function settings_identity_profiles ( container : JQuery , modal : Modal ) {
const registry = new Registry < events.modal.settings.profiles > ( ) ;
//registry.enable_debug("settings-identity");
modal_settings . initialize_identity_profiles_controller ( registry ) ;
modal_settings . initialize_identity_profiles_view ( container , registry , {
forum_setuppable : true
} ) ;
registry . on ( "setup-forum-connection" , event = > {
modal . htmlTag . find ( '.entry[container="identity-forum"]' ) . trigger ( 'click' ) ;
} ) ;
return ( ) = > registry . fire ( "reload-profile" ) ;
}
function settings_audio_speaker ( container : JQuery , modal : Modal ) {
/* devices */
{
const container_devices = container . find ( ".left .container-devices" ) ;
const contianer_error = container . find ( ".left .container-error" ) ;
const update_devices = ( ) = > {
container_devices . children ( ) . remove ( ) ;
const current_selected = aplayer . current_device ( ) ;
const generate_device = ( device : Device | undefined ) = > {
2020-09-12 15:49:20 +02:00
const selected = device === current_selected || ( typeof ( current_selected ) !== "undefined" && typeof ( device ) !== "undefined" && current_selected . device_id == device . device_id ) ;
2020-03-30 13:44:18 +02:00
const tag = $ . spawn ( "div" ) . addClass ( "device" ) . toggleClass ( "selected" , selected ) . append (
$ . spawn ( "div" ) . addClass ( "container-selected" ) . append (
$ . spawn ( "div" ) . addClass ( "icon_em client-apply" )
) ,
$ . spawn ( "div" ) . addClass ( "container-name" ) . append (
$ . spawn ( "div" ) . addClass ( "device-driver" ) . text (
device ? ( device . driver || "Unknown driver" ) : "No device"
) ,
$ . spawn ( "div" ) . addClass ( "device-name" ) . text (
device ? ( device . name || "Unknown name" ) : "No device"
)
)
) ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
tag . on ( 'click' , event = > {
2020-09-12 15:49:20 +02:00
if ( tag . hasClass ( "selected" ) )
2020-03-30 13:44:18 +02:00
return ;
2018-03-07 19:06:52 +01:00
2020-03-30 13:44:18 +02:00
const _old = container_devices . find ( ".selected" ) ;
_old . removeClass ( "selected" ) ;
tag . addClass ( "selected" ) ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
aplayer . set_device ( device ? device.device_id : null ) . then ( ( ) = > {
console . debug ( tr ( "Changed default speaker device" ) ) ;
} ) . catch ( ( error ) = > {
_old . addClass ( "selected" ) ;
tag . removeClass ( "selected" ) ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
console . error ( tr ( "Failed to change speaker to device %o: %o" ) , device , error ) ;
createErrorModal ( tr ( "Failed to change speaker" ) , formatMessage ( tr ( "Failed to change the speaker device to the target speaker{:br:}{}" ) , error ) ) . open ( ) ;
} ) ;
} ) ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
return tag ;
} ;
generate_device ( undefined ) . appendTo ( container_devices ) ;
aplayer . available_devices ( ) . then ( result = > {
contianer_error . text ( "" ) . hide ( ) ;
result . forEach ( e = > generate_device ( e ) . appendTo ( container_devices ) ) ;
} ) . catch ( error = > {
2020-09-12 15:49:20 +02:00
if ( typeof ( error ) === "string" )
2020-03-30 13:44:18 +02:00
contianer_error . text ( error ) . show ( ) ;
console . log ( tr ( "Failed to query available speaker devices: %o" ) , error ) ;
contianer_error . text ( tr ( "Errors occurred (View console)" ) ) . show ( ) ;
} ) ;
} ;
update_devices ( ) ;
const button_update = container . find ( ".button-update" ) ;
button_update . on ( 'click' , async event = > {
button_update . prop ( "disabled" , true ) ;
try {
update_devices ( ) ;
2020-09-12 15:49:20 +02:00
} catch ( error ) {
2020-03-30 13:44:18 +02:00
console . error ( tr ( "Failed to build new speaker device list: %o" ) , error ) ;
2019-01-28 20:36:11 +01:00
}
2020-03-30 13:44:18 +02:00
button_update . prop ( "disabled" , false ) ;
2019-08-21 10:00:01 +02:00
} ) ;
}
2020-03-30 13:44:18 +02:00
/* slider */
{
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
{
const container_master = container . find ( ".container-volume-master" ) ;
const slider = container_master . find ( ".container-slider" ) ;
sliderfy ( slider , {
min_value : 0 ,
max_value : 100 ,
step : 1 ,
initial_value : settings.static_global ( Settings . KEY_SOUND_MASTER , 100 ) ,
value_field : [ container_master . find ( ".container-value" ) ]
2019-01-28 20:36:11 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
slider . on ( 'change' , event = > {
const volume = parseInt ( slider . attr ( 'value' ) ) ;
2019-08-21 10:00:01 +02:00
2020-09-12 15:49:20 +02:00
if ( aplayer . set_master_volume )
2020-03-30 13:44:18 +02:00
aplayer . set_master_volume ( volume / 100 ) ;
settings . changeGlobal ( Settings . KEY_SOUND_MASTER , volume ) ;
} ) ;
2019-08-21 10:00:01 +02:00
}
2019-04-15 16:58:42 +02:00
2019-08-21 10:00:01 +02:00
{
2020-03-30 13:44:18 +02:00
const container_soundpack = container . find ( ".container-volume-soundpack" ) ;
const slider = container_soundpack . find ( ".container-slider" ) ;
sliderfy ( slider , {
min_value : 0 ,
max_value : 100 ,
step : 1 ,
initial_value : settings.static_global ( Settings . KEY_SOUND_MASTER_SOUNDS , 100 ) ,
value_field : [ container_soundpack . find ( ".container-value" ) ]
} ) ;
slider . on ( 'change' , event = > {
const volume = parseInt ( slider . attr ( 'value' ) ) ;
set_master_volume ( volume / 100 ) ;
settings . changeGlobal ( Settings . KEY_SOUND_MASTER_SOUNDS , volume ) ;
} ) ;
2019-08-21 10:00:01 +02:00
}
2020-03-30 13:44:18 +02:00
}
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
/* button test sound */
{
container . find ( ".button-test-sound" ) . on ( 'click' , event = > {
manager . play ( Sound . SOUND_TEST , {
default_volume : 1 ,
ignore_muted : true ,
ignore_overlap : true
} )
2019-12-21 15:01:18 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
}
}
function settings_audio_sounds ( contianer : JQuery , modal : Modal ) {
/* initialize sound list */
{
const container_sounds = contianer . find ( ".container-sounds" ) ;
2020-04-10 20:57:50 +02:00
let scrollbar ;
/ *
2020-04-03 00:15:47 +02:00
let scrollbar : SimpleBar ;
if ( "SimpleBar" in window )
scrollbar = new SimpleBar ( container_sounds [ 0 ] ) ;
2020-04-10 20:57:50 +02:00
* /
2020-03-30 13:44:18 +02:00
const generate_sound = ( _sound : Sound ) = > {
let tag_play_pause : JQuery , tag_play : JQuery , tag_pause : JQuery , tag_input_muted : JQuery ;
let tag = $ . spawn ( "div" ) . addClass ( "sound" ) . append (
tag_play_pause = $ . spawn ( "div" ) . addClass ( "container-button-play_pause" ) . append (
tag_play = $ . spawn ( "img" ) . attr ( "src" , "img/icon_sound_play.svg" ) ,
tag_pause = $ . spawn ( "img" ) . attr ( "src" , "img/icon_sound_pause.svg" )
) ,
$ . spawn ( "div" ) . addClass ( "container-name" ) . text ( _sound ) ,
$ . spawn ( "label" ) . addClass ( "container-button-toggle" ) . append (
$ . spawn ( "div" ) . addClass ( "switch" ) . append (
tag_input_muted = $ . spawn ( "input" ) . attr ( "type" , "checkbox" ) ,
$ . spawn ( "span" ) . addClass ( "slider" ) . append (
$ . spawn ( "div" ) . addClass ( "dot" )
)
)
)
) ;
tag_play_pause . on ( 'click' , event = > {
2020-09-12 15:49:20 +02:00
if ( tag_pause . is ( ":visible" ) )
2020-03-30 13:44:18 +02:00
return ;
tag_play . hide ( ) ;
tag_pause . show ( ) ;
2019-10-19 17:13:40 +02:00
2020-03-30 13:44:18 +02:00
const _done = flag = > {
tag_pause . hide ( ) ;
tag_play . show ( ) ;
} ;
const _timeout = setTimeout ( ( ) = > _done ( false ) , 10 * 1000 ) ; /* the sounds are not longer than 10 seconds */
2019-10-19 17:13:40 +02:00
2020-03-30 13:44:18 +02:00
sound . manager . play ( _sound , {
ignore_overlap : true ,
ignore_muted : true ,
default_volume : 1 ,
callback : flag = > {
clearTimeout ( _timeout ) ;
_done ( flag ) ;
}
} ) ;
2019-10-19 17:13:40 +02:00
} ) ;
2020-03-30 13:44:18 +02:00
tag_pause . hide ( ) ;
2018-03-07 19:06:52 +01:00
2020-03-30 13:44:18 +02:00
tag_input_muted . prop ( "checked" , sound . get_sound_volume ( _sound , 1 ) > 0 ) ;
tag_input_muted . on ( 'change' , event = > {
const volume = tag_input_muted . prop ( "checked" ) ? 1 : 0 ;
sound . set_sound_volume ( _sound , volume ) ;
console . log ( tr ( "Changed sound volume to %o for sound %o" ) , volume , _sound ) ;
} ) ;
2018-10-28 18:25:43 +01:00
2020-03-30 13:44:18 +02:00
return tag ;
} ;
2018-10-28 18:25:43 +01:00
2020-03-30 13:44:18 +02:00
//container-sounds
2020-09-12 15:49:20 +02:00
for ( const sound_key in Sound )
2020-04-03 00:15:47 +02:00
generate_sound ( Sound [ sound_key as any ] as any ) . appendTo ( scrollbar ? scrollbar . getContentElement ( ) : container_sounds ) ;
2020-03-30 13:44:18 +02:00
/* the filter */
const input_filter = contianer . find ( ".input-sounds-filter" ) ;
input_filter . on ( 'change keyup' , event = > {
const filter = input_filter . val ( ) as string ;
2018-10-28 18:25:43 +01:00
2020-03-30 13:44:18 +02:00
container_sounds . find ( ".sound" ) . each ( ( _ , _element ) = > {
const element = $ ( _element ) ;
element . toggle ( filter . length == 0 || element . text ( ) . toLowerCase ( ) . indexOf ( filter ) !== - 1 ) ;
} )
2020-03-27 16:15:15 +01:00
} ) ;
2019-08-21 10:00:01 +02:00
}
2020-03-30 13:44:18 +02:00
const overlap_tag = contianer . find ( ".option-overlap-same" ) ;
overlap_tag . on ( 'change' , event = > {
2020-04-10 20:57:50 +02:00
const activated = ( event . target as HTMLInputElement ) . checked ;
2020-03-30 13:44:18 +02:00
sound . set_overlap_activated ( activated ) ;
} ) . prop ( "checked" , sound . overlap_activated ( ) ) ;
2018-10-28 18:25:43 +01:00
2020-03-30 13:44:18 +02:00
const mute_tag = contianer . find ( ".option-mute-output" ) ;
mute_tag . on ( 'change' , event = > {
2020-04-10 20:57:50 +02:00
const activated = ( event . target as HTMLInputElement ) . checked ;
2020-03-30 13:44:18 +02:00
sound . set_ignore_output_muted ( ! activated ) ;
} ) . prop ( "checked" , ! sound . ignore_output_muted ( ) ) ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
modal . close_listener . push ( sound . save ) ;
}
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
export namespace modal_settings {
export interface ProfileViewSettings {
forum_setuppable : boolean
}
2020-09-12 15:49:20 +02:00
2020-03-30 13:44:18 +02:00
export function initialize_identity_profiles_controller ( event_registry : Registry < events.modal.settings.profiles > ) {
2020-09-12 15:49:20 +02:00
const send_error = ( event , profile , text ) = > event_registry . fire_async ( event , {
status : "error" ,
profile_id : profile ,
error : text
} ) ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "create-profile" , event = > {
const profile = profiles . create_new_profile ( event . name ) ;
profiles . mark_need_save ( ) ;
event_registry . fire_async ( "create-profile-result" , {
status : "success" ,
name : event.name ,
profile_id : profile.id
} ) ;
} ) ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "delete-profile" , event = > {
const profile = profiles . find_profile ( event . profile_id ) ;
2020-09-12 15:49:20 +02:00
if ( ! profile ) {
2020-03-30 13:44:18 +02:00
log . warn ( LogCategory . CLIENT , tr ( "Received profile event with unknown profile id (event: %s, id: %s)" ) , event . type , event . profile_id ) ;
send_error ( "delete-profile-result" , event . profile_id , tr ( "Unknown profile" ) ) ;
return ;
}
2019-02-17 16:08:10 +01:00
2020-03-30 13:44:18 +02:00
profiles . delete_profile ( profile ) ;
2020-09-12 15:49:20 +02:00
event_registry . fire_async ( "delete-profile-result" , { status : "success" , profile_id : event.profile_id } ) ;
2020-03-30 13:44:18 +02:00
} ) ;
const build_profile_info = ( profile : ConnectionProfile ) = > {
const forum_data = profile . selected_identity ( IdentitifyType . TEAFORO ) as TeaForumIdentity ;
const teamspeak_data = profile . selected_identity ( IdentitifyType . TEAMSPEAK ) as TeaSpeakIdentity ;
const nickname_data = profile . selected_identity ( IdentitifyType . NICKNAME ) as NameIdentity ;
return {
id : profile.id ,
name : profile.profile_name ,
nickname : profile.default_username ,
identity_type : profile.selected_identity_type as any ,
identity_forum : ! forum_data ? undefined : {
valid : forum_data.valid ( ) ,
fallback_name : forum_data.fallback_name ( )
} ,
identity_nickname : ! nickname_data ? undefined : {
name : nickname_data.name ( ) ,
fallback_name : nickname_data.fallback_name ( )
} ,
identity_teamspeak : ! teamspeak_data ? undefined : {
unique_id : teamspeak_data.uid ( ) ,
fallback_name : teamspeak_data.fallback_name ( )
}
}
} ;
event_registry . on ( "query-profile-list" , event = > {
2020-09-12 15:49:20 +02:00
event_registry . fire_async ( "query-profile-list-result" , {
status : "success" ,
profiles : profiles.profiles ( ) . map ( e = > build_profile_info ( e ) )
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2019-02-17 16:08:10 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-profile" , event = > {
const profile = profiles . find_profile ( event . profile_id ) ;
2020-09-12 15:49:20 +02:00
if ( ! profile ) {
2020-03-30 13:44:18 +02:00
log . warn ( LogCategory . CLIENT , tr ( "Received profile event with unknown profile id (event: %s, id: %s)" ) , event . type , event . profile_id ) ;
send_error ( "query-profile-result" , event . profile_id , tr ( "Unknown profile" ) ) ;
return ;
}
2018-10-28 18:25:43 +01:00
2020-09-12 15:49:20 +02:00
event_registry . fire_async ( "query-profile-result" , {
status : "success" ,
profile_id : event.profile_id ,
info : build_profile_info ( profile )
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2019-02-17 16:08:10 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set-default-profile" , event = > {
const profile = profiles . find_profile ( event . profile_id ) ;
2020-09-12 15:49:20 +02:00
if ( ! profile ) {
2020-03-30 13:44:18 +02:00
log . warn ( LogCategory . CLIENT , tr ( "Received profile event with unknown profile id (event: %s, id: %s)" ) , event . type , event . profile_id ) ;
send_error ( "set-default-profile-result" , event . profile_id , tr ( "Unknown profile" ) ) ;
return ;
}
2019-04-29 18:49:01 +02:00
2020-03-30 13:44:18 +02:00
const old = profiles . set_default_profile ( profile ) ;
2020-09-12 15:49:20 +02:00
event_registry . fire_async ( "set-default-profile-result" , {
status : "success" ,
old_profile_id : event.profile_id ,
new_profile_id : old.id
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2018-03-17 08:05:37 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set-profile-name" , event = > {
const profile = profiles . find_profile ( event . profile_id ) ;
2020-09-12 15:49:20 +02:00
if ( ! profile ) {
2020-03-30 13:44:18 +02:00
log . warn ( LogCategory . CLIENT , tr ( "Received profile event with unknown profile id (event: %s, id: %s)" ) , event . type , event . profile_id ) ;
send_error ( "set-profile-name-result" , event . profile_id , tr ( "Unknown profile" ) ) ;
return ;
}
2019-01-27 13:11:40 +01:00
2020-03-30 13:44:18 +02:00
profile . profile_name = event . name ;
profiles . mark_need_save ( ) ;
2020-09-12 15:49:20 +02:00
event_registry . fire_async ( "set-profile-name-result" , {
name : event.name ,
profile_id : event.profile_id ,
status : "success"
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2019-01-27 13:11:40 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set-default-name" , event = > {
const profile = profiles . find_profile ( event . profile_id ) ;
2020-09-12 15:49:20 +02:00
if ( ! profile ) {
2020-03-30 13:44:18 +02:00
log . warn ( LogCategory . CLIENT , tr ( "Received profile event with unknown profile id (event: %s, id: %s)" ) , event . type , event . profile_id ) ;
send_error ( "set-default-name-result" , event . profile_id , tr ( "Unknown profile" ) ) ;
return ;
}
2019-01-27 13:11:40 +01:00
2020-03-30 13:44:18 +02:00
profile . default_username = event . name ;
profiles . mark_need_save ( ) ;
2020-09-12 15:49:20 +02:00
event_registry . fire_async ( "set-default-name-result" , {
name : event.name ,
profile_id : event.profile_id ,
status : "success"
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set-identity-name-name" , event = > {
const profile = profiles . find_profile ( event . profile_id ) ;
2020-09-12 15:49:20 +02:00
if ( ! profile ) {
2020-03-30 13:44:18 +02:00
log . warn ( LogCategory . CLIENT , tr ( "Received profile event with unknown profile id (event: %s, id: %s)" ) , event . type , event . profile_id ) ;
send_error ( "set-identity-name-name-result" , event . profile_id , tr ( "Unknown profile" ) ) ;
return ;
2019-01-27 13:11:40 +01:00
}
2020-03-30 13:44:18 +02:00
let identity = profile . selected_identity ( IdentitifyType . NICKNAME ) as NameIdentity ;
2020-09-12 15:49:20 +02:00
if ( ! identity )
2020-03-30 13:44:18 +02:00
profile . set_identity ( IdentitifyType . NICKNAME , identity = new NameIdentity ( ) ) ;
identity . set_name ( event . name ) ;
profiles . mark_need_save ( ) ;
2020-09-12 15:49:20 +02:00
event_registry . fire_async ( "set-identity-name-name-result" , {
name : event.name ,
profile_id : event.profile_id ,
status : "success"
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
event_registry . on ( "query-profile-validity" , event = > {
const profile = profiles . find_profile ( event . profile_id ) ;
2020-09-12 15:49:20 +02:00
if ( ! profile ) {
2020-03-30 13:44:18 +02:00
log . warn ( LogCategory . CLIENT , tr ( "Received profile event with unknown profile id (event: %s, id: %s)" ) , event . type , event . profile_id ) ;
send_error ( "query-profile-validity-result" , event . profile_id , tr ( "Unknown profile" ) ) ;
return ;
2019-01-27 13:11:40 +01:00
}
2020-09-12 15:49:20 +02:00
event_registry . fire_async ( "query-profile-validity-result" , {
status : "success" ,
profile_id : event.profile_id ,
valid : profile.valid ( )
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2019-01-27 13:11:40 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-identity-teamspeak" , event = > {
const profile = profiles . find_profile ( event . profile_id ) ;
2020-09-12 15:49:20 +02:00
if ( ! profile ) {
2020-03-30 13:44:18 +02:00
log . warn ( LogCategory . CLIENT , tr ( "Received profile event with unknown profile id (event: %s, id: %s)" ) , event . type , event . profile_id ) ;
send_error ( "query-identity-teamspeak-result" , event . profile_id , tr ( "Unknown profile" ) ) ;
return ;
}
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
const ts = profile . selected_identity ( IdentitifyType . TEAMSPEAK ) as TeaSpeakIdentity ;
2020-09-12 15:49:20 +02:00
if ( ! ts ) {
event_registry . fire_async ( "query-identity-teamspeak-result" , {
status : "error" ,
profile_id : event.profile_id ,
error : tr ( "Missing identity" )
} ) ;
2020-03-30 13:44:18 +02:00
return ;
}
ts . level ( ) . then ( level = > {
2020-09-12 15:49:20 +02:00
event_registry . fire_async ( "query-identity-teamspeak-result" , {
status : "success" ,
level : level ,
profile_id : event.profile_id
} ) ;
2020-03-30 13:44:18 +02:00
} ) . catch ( error = > {
send_error ( "query-identity-teamspeak-result" , event . profile_id , tr ( "failed to calculate level" ) ) ;
} )
} ) ;
2019-01-27 13:11:40 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "select-identity-type" , event = > {
const profile = profiles . find_profile ( event . profile_id ) ;
2020-09-12 15:49:20 +02:00
if ( ! profile ) {
2020-03-30 13:44:18 +02:00
log . warn ( LogCategory . CLIENT , tr ( "Received profile event with unknown profile id (event: %s, id: %s)" ) , event . type , event . profile_id ) ;
return ;
}
2019-01-27 13:11:40 +01:00
2020-03-30 13:44:18 +02:00
profile . selected_identity_type = event . identity_type ;
profiles . mark_need_save ( ) ;
} ) ;
2019-08-21 10:00:01 +02:00
2020-09-12 15:49:20 +02:00
event_registry . on ( "generate-identity-teamspeak" , event = > {
2020-03-30 13:44:18 +02:00
const profile = profiles . find_profile ( event . profile_id ) ;
2020-09-12 15:49:20 +02:00
if ( ! profile ) {
2020-03-30 13:44:18 +02:00
log . warn ( LogCategory . CLIENT , tr ( "Received profile event with unknown profile id (event: %s, id: %s)" ) , event . type , event . profile_id ) ;
send_error ( "generate-identity-teamspeak-result" , event . profile_id , tr ( "Unknown profile" ) ) ;
return ;
}
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
TeaSpeakIdentity . generate_new ( ) . then ( identity = > {
profile . set_identity ( IdentitifyType . TEAMSPEAK , identity ) ;
profiles . mark_need_save ( ) ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
identity . level ( ) . then ( level = > {
event_registry . fire_async ( "generate-identity-teamspeak-result" , {
status : "success" ,
profile_id : event.profile_id ,
unique_id : identity.uid ( ) ,
level : level
} ) ;
} ) . catch ( error = > {
console . error ( tr ( "Failed to calculate level for a new identity. Error object: %o" ) , error ) ;
send_error ( "generate-identity-teamspeak-result" , event . profile_id , tr ( "failed to calculate level: " ) + error ) ;
2019-08-21 10:00:01 +02:00
} )
2020-03-30 13:44:18 +02:00
} ) . catch ( error = > {
console . error ( tr ( "Failed to generate a new identity. Error object: %o" ) , error ) ;
send_error ( "generate-identity-teamspeak-result" , event . profile_id , tr ( "failed to generate identity: " ) + error ) ;
2019-08-21 10:00:01 +02:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2019-01-27 13:11:40 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "import-identity-teamspeak" , event = > {
const profile = profiles . find_profile ( event . profile_id ) ;
2020-09-12 15:49:20 +02:00
if ( ! profile ) {
2020-03-30 13:44:18 +02:00
log . warn ( LogCategory . CLIENT , tr ( "Received profile event with unknown profile id (event: %s, id: %s)" ) , event . type , event . profile_id ) ;
return ;
}
2018-03-17 08:05:37 +01:00
2020-03-30 13:44:18 +02:00
spawnTeamSpeakIdentityImport ( identity = > {
profile . set_identity ( IdentitifyType . TEAMSPEAK , identity ) ;
profiles . mark_need_save ( ) ;
2018-05-05 14:58:30 +02:00
2020-03-30 13:44:18 +02:00
identity . level ( ) . catch ( error = > {
console . error ( tr ( "Failed to calculate level for a new imported identity. Error object: %o" ) , error ) ;
return Promise . resolve ( undefined ) ;
} ) . then ( level = > {
event_registry . fire_async ( "import-identity-teamspeak-result" , {
profile_id : event.profile_id ,
unique_id : identity.uid ( ) ,
level : level
} ) ;
} ) ;
} ) ;
} ) ;
2018-12-15 14:04:29 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "improve-identity-teamspeak-level" , event = > {
const profile = profiles . find_profile ( event . profile_id ) ;
2020-09-12 15:49:20 +02:00
if ( ! profile ) {
2020-03-30 13:44:18 +02:00
log . warn ( LogCategory . CLIENT , tr ( "Received profile event with unknown profile id (event: %s, id: %s)" ) , event . type , event . profile_id ) ;
return ;
}
const identity = profile . selected_identity ( IdentitifyType . TEAMSPEAK ) as TeaSpeakIdentity ;
if ( ! identity ) return ;
spawnTeamSpeakIdentityImprove ( identity , profile . profile_name ) . close_listener . push ( ( ) = > {
2020-03-27 16:15:15 +01:00
profiles . mark_need_save ( ) ;
2020-03-30 13:44:18 +02:00
identity . level ( ) . then ( level = > {
2020-09-12 15:49:20 +02:00
event_registry . fire_async ( "improve-identity-teamspeak-level-update" , {
profile_id : event.profile_id ,
new_level : level
} ) ;
2020-03-30 13:44:18 +02:00
} ) . catch ( error = > {
log . error ( LogCategory . CLIENT , tr ( "Failed to calculate identity level after improvement (%o)" ) , error ) ;
2019-08-21 10:00:01 +02:00
} ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2019-03-28 17:29:42 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "export-identity-teamspeak" , event = > {
const profile = profiles . find_profile ( event . profile_id ) ;
2020-09-12 15:49:20 +02:00
if ( ! profile ) {
2020-03-30 13:44:18 +02:00
log . warn ( LogCategory . CLIENT , tr ( "Received profile event with unknown profile id (event: %s, id: %s)" ) , event . type , event . profile_id ) ;
return ;
}
2019-03-07 15:30:53 +01:00
2020-03-30 13:44:18 +02:00
const identity = profile . selected_identity ( IdentitifyType . TEAMSPEAK ) as TeaSpeakIdentity ;
if ( ! identity ) return ;
identity . export_ts ( true ) . then ( data = > {
const element = $ . spawn ( "a" )
. text ( "donwload" )
. attr ( "href" , "data:test/plain;charset=utf-8," + encodeURIComponent ( data ) )
. attr ( "download" , name + ".ini" )
. css ( "display" , "none" )
. appendTo ( $ ( "body" ) ) ;
element [ 0 ] . click ( ) ;
element . remove ( ) ;
} ) . catch ( error = > {
console . error ( error ) ;
createErrorModal ( tr ( "Failed to export identity" ) , tr ( "Failed to export and save identity.<br>Error: " ) + error ) . open ( ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
}
2020-09-12 15:49:20 +02:00
2020-03-30 13:44:18 +02:00
export function initialize_identity_profiles_view ( container : JQuery , event_registry : Registry < events.modal.settings.profiles > , settings : ProfileViewSettings ) {
/* profile list */
{
const container_profiles = container . find ( ".container-profiles" ) ;
let selected_profile ;
const overlay_error = container_profiles . find ( ".overlay-error" ) ;
const overlay_timeout = container_profiles . find ( ".overlay-timeout" ) ;
const overlay_empty = container_profiles . find ( ".overlay-empty" ) ;
const build_profile = ( profile : events.modal.settings.ProfileInfo , selected : boolean ) = > {
let tag_avatar : JQuery , tag_default : JQuery ;
let tag = $ . spawn ( "div" ) . addClass ( "profile" ) . attr ( "profile-id" , profile . id ) . append (
tag_avatar = $ . spawn ( "div" ) . addClass ( "container-avatar" ) ,
$ . spawn ( "div" ) . addClass ( "container-info" ) . append (
$ . spawn ( "div" ) . addClass ( "container-type" ) . append (
$ . spawn ( "div" ) . addClass ( "identity-type" ) . text ( profile . identity_type || tr ( "Type unset" ) ) ,
tag_default = $ . spawn ( "div" ) . addClass ( "tag-default" ) . text ( tr ( "(Default)" ) ) ,
$ . spawn ( "div" ) . addClass ( "icon_em icon-status" ) . hide ( )
) ,
$ . spawn ( "div" ) . addClass ( "profile-name" ) . text ( profile . name || tr ( "Unnamed" ) )
)
) ;
tag_avatar . hide ( ) ; /* no avatars yet */
2019-03-07 15:30:53 +01:00
2020-09-12 15:49:20 +02:00
tag . on ( 'click' , event = > event_registry . fire ( "select-profile" , { profile_id : profile.id } ) ) ;
2020-03-30 13:44:18 +02:00
tag . toggleClass ( "selected" , selected ) ;
tag_default . toggle ( profile . id === "default" ) ;
2020-09-12 15:49:20 +02:00
event_registry . fire ( "query-profile-validity" , { profile_id : profile.id } ) ;
2020-03-30 13:44:18 +02:00
return tag ;
2019-08-21 10:00:01 +02:00
} ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "select-profile" , event = > {
container_profiles . find ( ".profile" ) . removeClass ( "selected" ) ;
container_profiles . find ( ".profile[profile-id='" + event . profile_id + "']" ) . addClass ( "selected" ) ;
selected_profile = event . profile_id ;
2020-03-27 16:15:15 +01:00
} ) ;
2019-03-07 15:30:53 +01:00
2018-12-28 15:39:23 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-profile-list" , event = > {
container_profiles . find ( ".profile" ) . remove ( ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-profile-list-result" , event = > {
container_profiles . find ( ".overlay" ) . hide ( ) ;
2020-09-12 15:49:20 +02:00
if ( event . status === "error" ) {
2020-03-30 13:44:18 +02:00
overlay_error . show ( ) . find ( ".error" ) . text ( event . error || tr ( "unknown error" ) ) ;
return ;
2020-09-12 15:49:20 +02:00
} else if ( event . status === "timeout" ) {
2020-03-30 13:44:18 +02:00
overlay_timeout . show ( ) ;
2020-03-27 16:15:15 +01:00
return ;
2019-08-21 10:00:01 +02:00
}
2020-09-12 15:49:20 +02:00
if ( ! event . profiles . length ) {
2020-03-30 13:44:18 +02:00
overlay_empty . show ( ) ;
2020-03-27 16:15:15 +01:00
return ;
}
2020-03-30 13:44:18 +02:00
container_profiles . find ( ".overlay" ) . hide ( ) ;
container_profiles . find ( ".profile" ) . remove ( ) ;
event . profiles . forEach ( e = > build_profile ( e , e . id == selected_profile ) . appendTo ( container_profiles ) ) ;
2019-08-21 10:00:01 +02:00
} ) ;
2018-12-28 15:39:23 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "delete-profile-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" ) return ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
//TODO: Animate removal?
container_profiles . find ( ".profile[profile-id='" + event . profile_id + "']" ) . remove ( ) ;
2019-08-21 10:00:01 +02:00
} ) ;
2018-12-28 15:39:23 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( 'create-profile-result' , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" ) return ;
2018-12-28 15:39:23 +01:00
2020-03-30 13:44:18 +02:00
event_registry . fire ( "query-profile-list" ) ;
2020-09-12 15:49:20 +02:00
event_registry . one ( "query-profile-list-result" , e = > event_registry . fire ( "select-profile" , { profile_id : event.profile_id } ) ) ;
2019-08-21 10:00:01 +02:00
} ) ;
2018-12-28 15:39:23 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set-profile-name-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" ) return ;
2019-01-19 13:42:18 +01:00
2020-03-30 13:44:18 +02:00
const profile = container_profiles . find ( ".profile[profile-id='" + event . profile_id + "']" ) ;
profile . find ( ".profile-name" ) . text ( event . name || tr ( "Unnamed" ) ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2018-12-28 15:39:23 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set-default-profile-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" ) return ;
2018-12-28 15:39:23 +01:00
2020-03-30 13:44:18 +02:00
const old_profile = container_profiles . find ( ".profile[profile-id='default']" ) ;
const new_profile = container_profiles . find ( ".profile[profile-id='" + event . old_profile_id + "']" ) ;
old_profile . attr ( "profile-id" , event . new_profile_id ) . find ( ".tag-default" ) . hide ( ) ;
new_profile . attr ( "profile-id" , "default" ) . find ( ".tag-default" ) . show ( ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2018-12-28 15:39:23 +01:00
2020-03-27 16:15:15 +01:00
event_registry . on ( "select-identity-type" , event = > {
2020-09-12 15:49:20 +02:00
if ( ! event . identity_type ) return ;
2018-12-28 15:39:23 +01:00
2020-03-30 13:44:18 +02:00
const profile = container_profiles . find ( ".profile[profile-id='" + event . profile_id + "']" ) ;
profile . find ( ".identity-type" ) . text ( event . identity_type . toUpperCase ( ) || tr ( "Type unset" ) ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2018-12-28 15:39:23 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-profile-validity-result" , event = > {
const profile = container_profiles . find ( ".profile[profile-id='" + event . profile_id + "']" ) ;
profile . find ( ".icon-status" )
. show ( )
. toggleClass ( "client-apply" , event . status === "success" && event . valid )
. toggleClass ( "client-delete" , event . status !== "success" || ! event . valid )
. attr ( "title" , event . status === "success" ? event . valid ? tr ( "Profile is valid" ) : tr ( "Provile is invalid" ) : event . error || tr ( "failed to query status" ) ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
/* status indicator updaters */
event_registry . on ( "select-identity-type" , event = > {
2020-09-12 15:49:20 +02:00
if ( ! event . profile_id ) return ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
/* we need a short delay so everything could apply*/
setTimeout ( ( ) = > {
2020-09-12 15:49:20 +02:00
event_registry . fire ( "query-profile-validity" , { profile_id : event.profile_id } ) ;
2020-03-30 13:44:18 +02:00
} , 100 ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
event_registry . on ( [ "set-default-name-result" , "set-profile-name-result" , "set-identity-name-name-result" , "generate-identity-teamspeak-result" ] , event = > {
2020-09-12 15:49:20 +02:00
if ( ! ( 'status' in event ) || ! ( 'profile_id' in event ) ) {
2020-03-30 13:44:18 +02:00
log . warn ( LogCategory . CLIENT , tr ( "Profile status watcher encountered an unuseal event!" ) ) ;
2020-03-27 16:15:15 +01:00
return ;
}
2020-09-12 15:49:20 +02:00
if ( ( event as any ) . status !== "success" ) return ;
event_registry . fire ( "query-profile-validity" , { profile_id : ( event as any ) . profile_id } ) ;
2020-03-30 13:44:18 +02:00
} )
}
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
/* list buttons */
{
/* reload */
{
const button = container . find ( ".button-reload-list" ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
button . on ( 'click' , event = > event_registry . fire ( "query-profile-list" ) ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-profile-list" , event = > button . prop ( "disabled" , true ) ) ;
event_registry . on ( "query-profile-list-result" , event = > button . prop ( "disabled" , false ) ) ;
}
2018-12-28 15:39:23 +01:00
2020-03-30 13:44:18 +02:00
/* set default */
2019-08-21 10:00:01 +02:00
{
2020-03-30 13:44:18 +02:00
const button = container . find ( ".button-set-default" ) ;
let current_profile ;
2019-08-21 10:00:01 +02:00
2020-09-12 15:49:20 +02:00
button . on ( 'click' , event = > event_registry . fire ( "set-default-profile" , { profile_id : current_profile } ) ) ;
2020-03-27 16:15:15 +01:00
event_registry . on ( "select-profile" , event = > {
2020-03-30 13:44:18 +02:00
current_profile = event . profile_id ;
button . prop ( "disabled" , ! event . profile_id || event . profile_id === "default" ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "set-default-profile-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status === "success" ) return ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
createErrorModal ( tr ( "Failed to set default profile" ) , tr ( "Failed to set default profile:" ) + "<br>" + ( event . status === "timeout" ? tr ( "request timeout" ) : ( event . error || tr ( "unknown error" ) ) ) ) . open ( ) ;
2019-01-19 13:42:18 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
button . prop ( "disabled" , true ) ;
}
2018-12-28 15:39:23 +01:00
2020-03-30 13:44:18 +02:00
/* delete button */
{
const button = container . find ( ".button-delete" ) ;
let current_profile ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
button . on ( 'click' , event = > {
2020-09-12 15:49:20 +02:00
if ( ! current_profile || current_profile === "default" ) return ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
spawnYesNo ( tr ( "Are you sure?" ) , tr ( "Do you really want to delete this profile?" ) , result = > {
if ( result )
2020-09-12 15:49:20 +02:00
event_registry . fire ( "delete-profile" , { profile_id : current_profile } ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "delete-profile-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status === "success" ) return ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
createErrorModal ( tr ( "Failed to delete profile" ) , tr ( "Failed to delete profile:" ) + "<br>" + ( event . status === "timeout" ? tr ( "request timeout" ) : ( event . error || tr ( "unknown error" ) ) ) ) . open ( ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "select-profile" , event = > {
current_profile = event . profile_id ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
button . prop ( "disabled" , ! event . profile_id || event . profile_id === "default" ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
}
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
/* create button */
{
const button = container . find ( ".button-create" ) ;
button . on ( 'click' , event = > {
createInputModal ( tr ( "Please enter a name" ) , tr ( "Please enter a name for the new profile:" ) , text = > text . length >= 3 && ! profiles . find_profile_by_name ( text ) , value = > {
if ( value )
2020-09-12 15:49:20 +02:00
event_registry . fire ( "create-profile" , { name : value as string } ) ;
2020-03-30 13:44:18 +02:00
} ) . open ( ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
event_registry . on ( 'create-profile' , event = > button . prop ( "disabled" , true ) ) ;
event_registry . on ( "create-profile-result" , event = > {
button . prop ( "disabled" , false ) ;
2020-09-12 15:49:20 +02:00
if ( event . status === "success" ) {
event_registry . fire ( "select-profile" , { profile_id : event.profile_id } ) ;
2020-03-27 16:15:15 +01:00
return ;
2018-12-28 15:39:23 +01:00
}
2020-03-30 13:44:18 +02:00
createErrorModal ( tr ( "Failed to create profile" ) , tr ( "Failed to create new profile:" ) + "<br>" + ( event . status === "timeout" ? tr ( "request timeout" ) : ( event . error || tr ( "unknown error" ) ) ) ) . open ( ) ;
2020-03-27 16:15:15 +01:00
} )
}
2020-03-30 13:44:18 +02:00
}
/* profile info */
{
let current_profile ;
const error_text = event = > event . status === "timeout" ? tr ( "request timeout" ) : ( event . error || tr ( "unknown error" ) ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
/* general info */
2020-03-27 16:15:15 +01:00
{
2020-03-30 13:44:18 +02:00
/* profile name */
2019-08-21 10:00:01 +02:00
{
2020-03-30 13:44:18 +02:00
const input = container . find ( ".profile-name" ) ;
let last_name ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
const update_name = ( ) = > input . prop ( "disabled" , false )
2020-09-12 15:49:20 +02:00
. val ( last_name )
. attr ( "placeholder" , tr ( "Profile name" ) )
. parent ( ) . removeClass ( "is-invalid" ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
const info_name = text = > input . prop ( "disabled" , true )
2020-09-12 15:49:20 +02:00
. val ( null )
. attr ( "placeholder" , text )
. parent ( ) . removeClass ( "is-invalid" ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-profile" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
info_name ( tr ( "loading" ) ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-profile-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
2020-03-27 16:15:15 +01:00
2020-09-12 15:49:20 +02:00
if ( event . status === "success" ) {
2020-03-30 13:44:18 +02:00
last_name = event . info . name ;
update_name ( ) ;
} else {
info_name ( error_text ( event ) ) ;
}
2020-03-27 16:15:15 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "set-profile-name" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
info_name ( tr ( "saving" ) ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "set-profile-name-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" ) {
2020-03-30 13:44:18 +02:00
createErrorModal ( tr ( "Failed to change profile name" ) , tr ( "Failed to create apply new name:" ) + "<br>" + error_text ( event ) ) . open ( ) ;
} else {
last_name = event . name ;
}
update_name ( ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
input . on ( 'keyup' , event = > {
const text = input . val ( ) as string ;
const profile = profiles . find_profile_by_name ( text ) ;
input . parent ( ) . toggleClass ( "is-invalid" , text . length < 3 || ( profile && profile . id != current_profile ) ) ;
} ) . on ( 'change' , event = > {
const text = input . val ( ) as string ;
const profile = profiles . find_profile_by_name ( text ) ;
2020-09-12 15:49:20 +02:00
if ( text . length < 3 || ( profile && profile . id != current_profile ) ) return ;
2020-03-27 16:15:15 +01:00
2020-09-12 15:49:20 +02:00
event_registry . fire ( "set-profile-name" , { profile_id : current_profile , name : text } ) ;
2020-03-27 16:15:15 +01:00
} ) ;
}
2020-03-30 13:44:18 +02:00
/* nickname name */
2020-03-27 16:15:15 +01:00
{
2020-03-30 13:44:18 +02:00
const input = container . find ( ".profile-default-name" ) ;
let last_name = null , fallback_names = { } , current_identity_type = "" ;
const update_name = ( ) = > input . prop ( "disabled" , false )
2020-09-12 15:49:20 +02:00
. val ( last_name )
. attr ( "placeholder" , fallback_names [ current_identity_type ] || tr ( "Another TeaSpeak user" ) )
. parent ( ) . removeClass ( "is-invalid" ) ;
2020-03-30 13:44:18 +02:00
const info_name = text = > input . prop ( "disabled" , true )
2020-09-12 15:49:20 +02:00
. val ( null )
. attr ( "placeholder" , text )
. parent ( ) . removeClass ( "is-invalid" ) ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-profile" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
2020-03-30 13:44:18 +02:00
input . prop ( "disabled" , true ) . val ( null ) . attr ( "placeholder" , tr ( "loading" ) ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-profile-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
if ( event . status === "success" ) {
2020-03-30 13:44:18 +02:00
current_identity_type = event . info . identity_type ;
fallback_names [ "nickname" ] = event . info . identity_nickname ? event.info.identity_nickname.fallback_name : undefined ;
fallback_names [ "teaforo" ] = event . info . identity_forum ? event.info.identity_forum.fallback_name : undefined ;
fallback_names [ "teamspeak" ] = event . info . identity_teamspeak ? event.info.identity_teamspeak.fallback_name : undefined ;
last_name = event . info . nickname ;
update_name ( ) ;
} else {
info_name ( error_text ( event ) ) ;
2020-03-27 16:15:15 +01:00
}
2020-03-30 13:44:18 +02:00
} ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "select-identity-type" , event = > {
if ( current_identity_type === event . identity_type ) return ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
current_identity_type = event . identity_type ;
update_name ( ) ;
} ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set-default-name" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
info_name ( tr ( "saving" ) ) ;
} ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set-default-name-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" ) {
2020-03-30 13:44:18 +02:00
createErrorModal ( tr ( "Failed to change nickname" ) , tr ( "Failed to create apply new nickname:" ) + "<br>" + error_text ( event ) ) . open ( ) ;
} else {
last_name = event . name ;
}
update_name ( ) ;
} ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
input . on ( 'keyup' , event = > {
const text = input . val ( ) as string ;
input . parent ( ) . toggleClass ( "is-invalid" , text . length != 0 && text . length < 3 ) ;
} ) . on ( 'change' , event = > {
const text = input . val ( ) as string ;
2020-09-12 15:49:20 +02:00
if ( text . length != 0 && text . length < 3 ) return ;
2020-03-27 16:15:15 +01:00
2020-09-12 15:49:20 +02:00
event_registry . fire ( "set-default-name" , { profile_id : current_profile , name : text } ) ;
2020-03-30 13:44:18 +02:00
} ) ;
}
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
/* identity type */
{
const select_identity_type = container . find ( ".profile-identity-type" ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
const show_message = ( text , is_invalid ) = > select_identity_type
2020-09-12 15:49:20 +02:00
. toggleClass ( "is-invalid" , is_invalid )
. prop ( "disabled" , true )
. find ( "option[value=error]" )
. text ( text )
. prop ( "selected" , true ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
const set_type = type = > select_identity_type
2020-09-12 15:49:20 +02:00
. toggleClass ( "is-invalid" , type === "unset" )
. prop ( "disabled" , false )
. find ( "option[value=" + type + "]" )
. prop ( "selected" , true ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-profile" , event = > show_message ( tr ( "loading" ) , false ) ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "select-identity-type" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
set_type ( event . identity_type || "unset" ) ;
} ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-profile-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
2020-03-27 16:15:15 +01:00
2020-09-12 15:49:20 +02:00
if ( event . status === "success" )
event_registry . fire ( "select-identity-type" , {
profile_id : event.profile_id ,
identity_type : event.info.identity_type
} ) ;
2020-03-30 13:44:18 +02:00
else
show_message ( error_text ( event ) , false ) ;
} ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
select_identity_type . on ( 'change' , event = > {
const type = ( select_identity_type . val ( ) as string ) . toLowerCase ( ) ;
2020-09-12 15:49:20 +02:00
if ( type === "error" || type == "unset" ) return ;
2020-03-27 16:15:15 +01:00
2020-09-12 15:49:20 +02:00
event_registry . fire ( "select-identity-type" , {
profile_id : current_profile ,
identity_type : type as any
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
}
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
/* avatar */
{
container . find ( ".button-change-avatar" ) . hide ( ) ;
}
}
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
/* special info TeamSpeak */
{
const container_settings = container . find ( ".container-teamspeak" ) ;
const container_valid = container_settings . find ( ".container-valid" ) ;
const container_invalid = container_settings . find ( ".container-invalid" ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
const input_current_level = container_settings . find ( ".current-level" ) ;
const input_unique_id = container_settings . find ( ".unique-id" ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
const button_new = container_settings . find ( ".button-new" ) ;
const button_improve = container_settings . find ( ".button-improve" ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
const button_import = container_settings . find ( ".button-import" ) ;
const button_export = container_settings . find ( ".button-export" ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
let is_profile_generated = false ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "select-identity-type" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
container_settings . toggle ( event . identity_type === "teamspeak" ) ;
} ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-profile" , event = > {
input_unique_id . val ( null ) . attr ( "placeholder" , tr ( "loading" ) ) ;
input_current_level . val ( null ) . attr ( "placeholder" , tr ( "loading" ) ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
button_new . prop ( "disabled" , true ) ;
button_improve . prop ( "disabled" , true ) ;
button_import . prop ( "disabled" , true ) ;
button_export . prop ( "disabled" , true ) ;
} ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
const update_identity = ( state : "not-created" | "created" , unique_id? : string , level? : number ) = > {
2020-09-12 15:49:20 +02:00
if ( state === "not-created" ) {
2020-03-30 13:44:18 +02:00
container_invalid . show ( ) ;
container_valid . hide ( ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
button_improve . prop ( "disabled" , true ) ;
button_export . prop ( "disabled" , true ) ;
} else {
container_invalid . hide ( ) ;
container_valid . show ( ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
input_unique_id . val ( unique_id ) . attr ( "placeholder" , null ) ;
2020-09-12 15:49:20 +02:00
if ( typeof level !== "number" )
event_registry . fire ( "query-identity-teamspeak" , { profile_id : current_profile } ) ;
2020-03-30 13:44:18 +02:00
else
input_current_level . val ( level ) . attr ( "placeholder" , null ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
button_improve . prop ( "disabled" , false ) ;
button_export . prop ( "disabled" , false ) ;
}
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
is_profile_generated = state === "created" ;
button_new . toggleClass ( "btn-blue" , ! is_profile_generated ) . toggleClass ( "btn-red" , is_profile_generated ) ;
button_import . toggleClass ( "btn-blue" , ! is_profile_generated ) . toggleClass ( "btn-red" , is_profile_generated ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
button_new . prop ( "disabled" , false ) ;
button_import . prop ( "disabled" , false ) ;
} ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-profile-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
2020-03-27 16:15:15 +01:00
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" ) {
2020-03-30 13:44:18 +02:00
input_unique_id . val ( null ) . attr ( "placeholder" , error_text ( event ) ) ;
return ;
}
2020-03-27 16:15:15 +01:00
2020-09-12 15:49:20 +02:00
if ( ! event . info . identity_teamspeak )
2020-03-30 13:44:18 +02:00
update_identity ( "not-created" ) ;
else
update_identity ( "created" , event . info . identity_teamspeak . unique_id ) ;
} ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-identity-teamspeak-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
2020-03-27 16:15:15 +01:00
2020-09-12 15:49:20 +02:00
if ( event . status === "success" ) {
2020-03-30 13:44:18 +02:00
input_current_level . val ( event . level ) . attr ( "placeholder" , null ) ;
} else {
input_current_level . val ( null ) . attr ( "placeholder" , error_text ( event ) ) ;
2020-03-27 16:15:15 +01:00
}
2020-03-30 13:44:18 +02:00
} ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
/* the new button */
2020-03-27 16:15:15 +01:00
{
2020-03-30 13:44:18 +02:00
button_new . on ( 'click' , event = > {
2020-09-12 15:49:20 +02:00
if ( is_profile_generated ) {
2020-03-30 13:44:18 +02:00
spawnYesNo ( tr ( "Are you sure" ) , tr ( "Do you really want to generate a new identity and override the old identity?" ) , result = > {
2020-09-12 15:49:20 +02:00
if ( result ) event_registry . fire ( "generate-identity-teamspeak" , { profile_id : current_profile } ) ;
2020-03-30 13:44:18 +02:00
} ) ;
} else {
2020-09-12 15:49:20 +02:00
event_registry . fire ( "generate-identity-teamspeak" , { profile_id : current_profile } ) ;
2020-03-30 13:44:18 +02:00
}
} ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "generate-identity-teamspeak-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
2020-03-27 16:15:15 +01:00
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" ) {
2020-03-30 13:44:18 +02:00
createErrorModal ( tr ( "Failed to generate a new identity" ) , tr ( "Failed to create a new identity:" ) + "<br>" + error_text ( event ) ) . open ( ) ;
return ;
}
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
update_identity ( "created" , event . unique_id , event . level ) ;
createInfoModal ( tr ( "Identity generated" ) , tr ( "A new identity had been successfully generated" ) ) . open ( ) ;
} ) ;
}
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
/* the import identity */
{
button_import . on ( 'click' , event = > {
2020-09-12 15:49:20 +02:00
if ( is_profile_generated ) {
2020-03-30 13:44:18 +02:00
spawnYesNo ( tr ( "Are you sure" ) , tr ( "Do you really want to import a new identity and override the old identity?" ) , result = > {
2020-09-12 15:49:20 +02:00
if ( result ) event_registry . fire ( "import-identity-teamspeak" , { profile_id : current_profile } ) ;
2020-03-30 13:44:18 +02:00
} ) ;
} else {
2020-09-12 15:49:20 +02:00
event_registry . fire ( "import-identity-teamspeak" , { profile_id : current_profile } ) ;
2020-03-30 13:44:18 +02:00
}
} ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "improve-identity-teamspeak-level-update" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
input_current_level . val ( event . new_level ) . attr ( "placeholder" , null ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "import-identity-teamspeak-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
2020-03-27 16:15:15 +01:00
2020-09-12 15:49:20 +02:00
event_registry . fire_async ( "query-profile" , { profile_id : event.profile_id } ) ; /* we do it like this so the default nickname changes as well */
2020-03-30 13:44:18 +02:00
createInfoModal ( tr ( "Identity imported" ) , tr ( "Your identity had been successfully imported generated" ) ) . open ( ) ;
2020-03-27 16:15:15 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
}
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
/* identity export */
{
button_export . on ( 'click' , event = > {
createInputModal ( tr ( "File name" ) , tr ( "Please enter the file name" ) , text = > ! ! text , name = > {
if ( name )
2020-09-12 15:49:20 +02:00
event_registry . fire ( "export-identity-teamspeak" , {
profile_id : current_profile ,
filename : name as string
} ) ;
2020-03-30 13:44:18 +02:00
} ) . open ( ) ;
} ) ;
}
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
/* the improve button */
2020-09-12 15:49:20 +02:00
button_improve . on ( 'click' , event = > event_registry . fire ( "improve-identity-teamspeak-level" , { profile_id : current_profile } ) ) ;
2020-03-30 13:44:18 +02:00
}
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
/* special info TeaSpeak - Forum */
{
const container_settings = container . find ( ".container-teaforo" ) ;
const container_valid = container_settings . find ( ".container-valid" ) ;
const container_invalid = container_settings . find ( ".container-invalid" ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
const button_setup = container_settings . find ( ".button-setup" ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "select-identity-type" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
container_settings . toggle ( event . identity_type === "teaforo" ) ;
} ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-profile" , event = > {
container_valid . toggle ( false ) ;
container_invalid . toggle ( false ) ;
} ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-profile-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
const valid = event . status === "success" && event . info . identity_forum && event . info . identity_forum . valid ;
container_valid . toggle ( ! ! valid ) ;
container_invalid . toggle ( ! valid ) ;
} ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
button_setup . on ( 'click' , event = > event_registry . fire_async ( "setup-forum-connection" ) ) ;
button_setup . toggle ( settings . forum_setuppable ) ;
}
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
/* special info nickname */
{
const container_settings = container . find ( ".container-nickname" ) ;
const input_nickname = container_settings . find ( ".nickname" ) ;
let last_name ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
const update_name = ( ) = > input_nickname . prop ( "disabled" , false )
. val ( last_name )
. attr ( "placeholder" , tr ( "Identity base name" ) )
. parent ( ) . removeClass ( "is-invalid" ) ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
const show_info = text = > input_nickname . prop ( "disabled" , true )
. val ( null )
. attr ( "placeholder" , text )
. parent ( ) . removeClass ( "is-invalid" ) ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "select-identity-type" , event = > event . profile_id === current_profile && container_settings . toggle ( event . identity_type === "nickname" ) ) ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-profile" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
show_info ( tr ( "loading" ) ) ;
} ) ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-profile-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
2019-01-28 20:36:11 +01:00
2020-09-12 15:49:20 +02:00
if ( event . status === "success" ) {
2020-03-30 13:44:18 +02:00
last_name = event . info . identity_nickname ? event.info.identity_nickname.name : null ;
update_name ( ) ;
} else {
show_info ( error_text ( event ) ) ;
2020-03-27 16:15:15 +01:00
}
2020-03-30 13:44:18 +02:00
} ) ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set-identity-name-name" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . profile_id !== current_profile ) return ;
2020-03-30 13:44:18 +02:00
show_info ( tr ( "saving" ) ) ;
} ) ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set-identity-name-name-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" ) {
2020-03-30 13:44:18 +02:00
createErrorModal ( tr ( "Failed to change name" ) , tr ( "Failed to create new name:" ) + "<br>" + error_text ( event ) ) . open ( ) ;
} else {
last_name = event . name ;
2020-03-27 16:15:15 +01:00
}
2020-03-30 13:44:18 +02:00
update_name ( ) ;
} ) ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
input_nickname . on ( 'keyup' , event = > {
const text = input_nickname . val ( ) as string ;
const profile = profiles . find_profile_by_name ( text ) ;
input_nickname . parent ( ) . toggleClass ( "is-invalid" , text . length < 3 || ( profile && profile . id != current_profile ) ) ;
} ) . on ( 'change' , event = > {
const text = input_nickname . val ( ) as string ;
const profile = profiles . find_profile_by_name ( text ) ;
2020-09-12 15:49:20 +02:00
if ( text . length < 3 || ( profile && profile . id != current_profile ) ) return ;
2019-01-28 20:36:11 +01:00
2020-09-12 15:49:20 +02:00
event_registry . fire ( "set-identity-name-name" , { profile_id : current_profile , name : text } ) ;
2020-03-30 13:44:18 +02:00
} ) ;
}
event_registry . on ( "select-profile" , e = > current_profile = e . profile_id ) ;
2019-08-21 10:00:01 +02:00
}
2019-11-24 13:41:42 +01:00
2020-03-30 13:44:18 +02:00
/* timeouts */
2019-11-24 13:41:42 +01:00
{
2020-03-30 13:44:18 +02:00
/* profile list */
{
let timeout ;
2020-09-12 15:49:20 +02:00
event_registry . on ( "query-profile-list" , event = > timeout = setTimeout ( ( ) = > event_registry . fire ( "query-profile-list-result" , { status : "timeout" } ) , 5000 ) ) ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "query-profile-list-result" , event = > {
clearTimeout ( timeout ) ;
timeout = undefined ;
} ) ;
}
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
/* profile create */
{
const timeouts = { } ;
event_registry . on ( "create-profile" , event = > {
clearTimeout ( timeouts [ event . name ] ) ;
timeouts [ event . name ] = setTimeout ( ( ) = > {
2020-09-12 15:49:20 +02:00
event_registry . fire ( "create-profile-result" , { name : event.name , status : "timeout" } ) ;
2020-03-30 13:44:18 +02:00
} , 5000 ) ;
} ) ;
2020-03-27 16:15:15 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "create-profile-result" , event = > {
clearTimeout ( timeouts [ event . name ] ) ;
delete timeouts [ event . name ] ;
} ) ;
}
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
/* profile set default create */
{
const timeouts = { } ;
event_registry . on ( "set-default-profile" , event = > {
clearTimeout ( timeouts [ event . profile_id ] ) ;
timeouts [ event . profile_id ] = setTimeout ( ( ) = > {
2020-09-12 15:49:20 +02:00
event_registry . fire ( "set-default-profile-result" , {
old_profile_id : event.profile_id ,
status : "timeout"
} ) ;
2020-03-30 13:44:18 +02:00
} , 5000 ) ;
} ) ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set-default-profile-result" , event = > {
clearTimeout ( timeouts [ event . old_profile_id ] ) ;
delete timeouts [ event . old_profile_id ] ;
} ) ;
}
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
const create_standard_timeout = ( event : keyof events . modal . settings . profiles , response_event : keyof events . modal . settings . profiles , key : string ) = > {
const timeouts = { } ;
event_registry . on ( event , event = > {
clearTimeout ( timeouts [ event [ key ] ] ) ;
timeouts [ event [ key ] ] = setTimeout ( ( ) = > {
2020-09-12 15:49:20 +02:00
const timeout_event = { status : "timeout" } ;
2020-03-30 13:44:18 +02:00
timeout_event [ key ] = event [ key ] ;
event_registry . fire ( response_event , timeout_event as any ) ;
} , 5000 ) ;
} ) ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
event_registry . on ( response_event , event = > {
clearTimeout ( timeouts [ event [ key ] ] ) ;
delete timeouts [ event [ key ] ] ;
} ) ;
} ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
create_standard_timeout ( "query-profile" , "query-profile-result" , "profile_id" ) ;
create_standard_timeout ( "query-identity-teamspeak" , "query-identity-teamspeak-result" , "profile_id" ) ;
create_standard_timeout ( "delete-profile" , "delete-profile-result" , "profile_id" ) ;
create_standard_timeout ( "set-profile-name" , "set-profile-name-result" , "profile_id" ) ;
create_standard_timeout ( "set-default-name" , "set-default-name-result" , "profile_id" ) ;
create_standard_timeout ( "query-profile-validity" , "query-profile-validity-result" , "profile_id" ) ;
create_standard_timeout ( "set-identity-name-name" , "set-identity-name-name-result" , "profile_id" ) ;
create_standard_timeout ( "generate-identity-teamspeak" , "generate-identity-teamspeak-result" , "profile_id" ) ;
}
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
/* some view semantics */
{
let selected_profile ;
event_registry . on ( "delete-profile-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" ) return ;
if ( event . profile_id !== selected_profile ) return ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
/* the selected profile has been deleted, so we need to select another one */
2020-09-12 15:49:20 +02:00
event_registry . fire ( "select-profile" , { profile_id : "default" } ) ;
2019-08-21 10:00:01 +02:00
} ) ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
/* reselect the default profile or the new default profile */
event_registry . on ( "set-default-profile-result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" ) return ;
if ( selected_profile === "default" )
event_registry . fire ( "select-profile" , { profile_id : event.new_profile_id } ) ;
else if ( selected_profile === event . old_profile_id )
event_registry . fire ( "select-profile" , { profile_id : "default" } ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "select-profile" , event = > {
selected_profile = event . profile_id ;
2020-09-12 15:49:20 +02:00
event_registry . fire ( "query-profile" , { profile_id : event.profile_id } ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "reload-profile" , event = > {
event_registry . fire ( "query-profile-list" ) ;
event_registry . fire ( "select-profile" , event . profile_id || selected_profile ) ;
2019-08-21 10:00:01 +02:00
} ) ;
2020-03-30 13:44:18 +02:00
}
2019-01-28 20:36:11 +01:00
2020-03-30 13:44:18 +02:00
event_registry . fire ( "query-profile-list" ) ;
2020-09-12 15:49:20 +02:00
event_registry . fire ( "select-profile" , { profile_id : "default" } ) ;
event_registry . fire ( "select-identity-type" , { profile_id : "default" , identity_type : undefined } ) ;
2020-03-30 13:44:18 +02:00
}
}
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
function settings_identity_forum ( container : JQuery , modal : Modal , update_profiles : ( ) = > any ) {
const containers_connected = container . find ( ".show-connected" ) ;
const containers_disconnected = container . find ( ".show-disconnected" ) ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
const update_state = ( ) = > {
const logged_in = forum . logged_in ( ) ;
containers_connected . toggle ( logged_in ) ;
containers_disconnected . toggle ( ! logged_in ) ;
2019-08-21 10:00:01 +02:00
2020-09-12 15:49:20 +02:00
if ( logged_in ) {
2020-03-30 13:44:18 +02:00
container . find ( ".forum-username" ) . text ( forum . data ( ) . name ( ) ) ;
container . find ( ".forum-premium" ) . text ( forum . data ( ) . is_premium ( ) ? tr ( "Yes" ) : tr ( "No" ) ) ;
}
} ;
/* login */
{
const button_login = container . find ( ".button-login" ) ;
const input_username = container . find ( ".input-username" ) ;
const input_password = container . find ( ".input-password" ) ;
const container_error = container . find ( ".container-login .container-error" ) ;
const container_captcha_g = container . find ( ".g-recaptcha" ) ;
let captcha : boolean | string = false ;
const update_button_state = ( ) = > {
let enabled = true ;
enabled = enabled && ! ! input_password . val ( ) ;
enabled = enabled && ! ! input_username . val ( ) ;
2020-09-12 15:49:20 +02:00
enabled = enabled && ( typeof ( captcha ) === "boolean" ? ! captcha : ! ! captcha ) ;
2020-03-30 13:44:18 +02:00
button_login . prop ( "disabled" , ! enabled ) ;
2019-08-21 10:00:01 +02:00
} ;
2020-03-30 13:44:18 +02:00
/* username */
input_username . on ( 'change keyup' , update_button_state ) ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
/* password */
input_password . on ( 'change keyup' , update_button_state ) ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
button_login . on ( 'click' , event = > {
input_username . prop ( "disabled" , true ) ;
input_password . prop ( "disabled" , true ) ;
button_login . prop ( "disabled" , true ) ;
container_error . removeClass ( "shown" ) ;
2019-08-21 10:00:01 +02:00
2020-09-12 15:49:20 +02:00
forum . login ( input_username . val ( ) as string , input_password . val ( ) as string , typeof ( captcha ) === "string" ? captcha : undefined ) . then ( state = > {
2020-03-30 13:44:18 +02:00
captcha = false ;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
console . debug ( tr ( "Forum login result: %o" ) , state ) ;
2020-09-12 15:49:20 +02:00
if ( state . status === "success" ) {
2020-03-30 13:44:18 +02:00
update_state ( ) ;
update_profiles ( ) ;
return ;
}
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
setTimeout ( ( ) = > {
2020-09-12 15:49:20 +02:00
if ( ! ! state . error_message ) /* clear password if we have an error */
2020-03-30 13:44:18 +02:00
input_password . val ( "" ) ;
input_password . focus ( ) ;
update_button_state ( ) ;
} , 0 ) ;
2020-09-12 15:49:20 +02:00
if ( state . status === "captcha" ) {
2020-03-30 13:44:18 +02:00
//TODO Works currently only with localhost!
button_login . hide ( ) ;
container_error . text ( state . error_message || tr ( "Captcha required" ) ) . addClass ( "shown" ) ;
captcha = "" ;
console . log ( tr ( "Showing captcha for site-key: %o" ) , state . captcha . data ) ;
forum . gcaptcha . spawn ( container_captcha_g , state . captcha . data , token = > {
captcha = token ;
console . debug ( tr ( "Got captcha token: %o" ) , token ) ;
container_captcha_g . hide ( ) ;
button_login . show ( ) ;
2019-08-21 10:00:01 +02:00
update_button_state ( ) ;
2020-03-30 13:44:18 +02:00
} ) . catch ( error = > {
console . error ( tr ( "Failed to initialize forum captcha: %o" ) , error ) ;
container_error . text ( "Failed to initialize GReCaptcha! No authentication possible." ) . addClass ( "shown" ) ;
container_captcha_g . hide ( ) ;
2019-08-21 10:00:01 +02:00
button_login . hide ( ) ;
2020-03-30 13:44:18 +02:00
} ) ;
container_captcha_g . show ( ) ;
} else {
container_error . text ( state . error_message || tr ( "Unknown error" ) ) . addClass ( "shown" ) ;
}
} ) . catch ( error = > {
console . error ( tr ( "Failed to login within the forum. Error: %o" ) , error ) ;
createErrorModal ( tr ( "Forum login failed." ) , tr ( "Forum login failed. Lookup the console for more information" ) ) . open ( ) ;
} ) . then ( ( ) = > {
input_username . prop ( "disabled" , false ) ;
input_password . prop ( "disabled" , false ) ;
update_button_state ( ) ;
2019-08-21 10:00:01 +02:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
update_button_state ( ) ;
}
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
/* logout */
{
container . find ( ".button-logout" ) . on ( 'click' , event = > {
forum . logout ( ) . catch ( error = > {
console . error ( tr ( "Failed to logout from forum: %o" ) , error ) ;
createErrorModal ( tr ( "Forum logout failed" ) , formatMessage ( tr ( "Failed to logout from forum account.{:br:}Error: {}" ) , error ) ) . open ( ) ;
} ) . then ( ( ) = > {
if ( modal . shown )
update_state ( ) ;
update_profiles ( ) ;
2019-08-21 10:00:01 +02:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2018-12-28 15:39:23 +01:00
}
2020-03-30 13:44:18 +02:00
update_state ( ) ;
2018-03-07 19:06:52 +01:00
}