2020-09-12 15:49:20 +02:00
import { createErrorModal , createModal } from "../../ui/elements/Modal" ;
import { ConnectionHandler } from "../../ConnectionHandler" ;
import { MusicClientEntry } from "../../tree/Client" ;
2021-02-09 10:11:40 +01:00
import { Registry } from "../../events" ;
2020-09-12 15:49:20 +02:00
import { CommandResult } from "../../connection/ServerConnectionDeclaration" ;
2021-01-10 17:36:57 +01:00
import { LogCategory , logError , logWarn } from "../../log" ;
import { tr , tra } from "../../i18n/localize" ;
2020-09-12 15:49:20 +02:00
import * as tooltip from "../../ui/elements/Tooltip" ;
2021-04-27 13:30:33 +02:00
import * as i18nc from "../../i18n/CountryFlag" ;
2020-09-12 15:49:20 +02:00
import { find } from "../../permission/PermissionManager" ;
import * as htmltags from "../../ui/htmltags" ;
import { ErrorCode } from "../../connection/ErrorCode" ;
2020-03-30 13:44:18 +02:00
import ServerGroup = find . ServerGroup ;
2021-02-09 10:11:40 +01:00
type BotStatusType = "name" | "description" | "volume" | "country_code" | "channel_commander" | "priority_speaker" ;
type PlaylistStatusType = "replay_mode" | "finished" | "delete_played" | "max_size" | "notify_song_change" ;
interface music_manage {
show_container : { container : "settings" | "permissions" ; } ;
/* setting relevant */
query_bot_status : { } ,
bot_status : {
status : "success" | "error" ;
error_msg? : string ;
data ? : {
name : string ,
description : string ,
volume : number ,
country_code : string ,
default_country_code : string ,
channel_commander : boolean ,
priority_speaker : boolean ,
client_version : string ,
client_platform : string ,
uptime_mode : number ,
bot_type : number
}
} ,
set_bot_status : {
key : BotStatusType ,
value : any
} ,
set_bot_status_result : {
key : BotStatusType ,
status : "success" | "error" | "timeout" ,
error_msg? : string ,
value? : any
}
query_playlist_status : { } ,
playlist_status : {
status : "success" | "error" ,
error_msg? : string ,
data ? : {
replay_mode : number ,
finished : boolean ,
delete_played : boolean ,
max_size : number ,
notify_song_change : boolean
}
} ,
set_playlist_status : {
key : PlaylistStatusType ,
value : any
} ,
set_playlist_status_result : {
key : PlaylistStatusType ,
status : "success" | "error" | "timeout" ,
error_msg? : string ,
value? : any
}
/* permission relevant */
show_client_list : { } ,
hide_client_list : { } ,
filter_client_list : { filter : string | undefined } ,
"refresh_permissions" : { } ,
query_special_clients : { } ,
special_client_list : {
status : "success" | "error" | "error-permission" ,
error_msg? : string ,
clients ? : {
name : string ,
unique_id : string ,
database_id : number
} [ ]
} ,
search_client : { text : string } ,
search_client_result : {
status : "error" | "timeout" | "empty" | "success" ,
error_msg? : string ,
client ? : {
name : string ,
unique_id : string ,
database_id : number
}
} ,
/* sets a client to set the permission for */
special_client_set : {
client ? : {
name : string ,
unique_id : string ,
database_id : number
}
} ,
"query_general_permissions" : { } ,
"general_permissions" : {
status : "error" | "timeout" | "success" ,
error_msg? : string ,
permissions ? : { [ key : string ] : number }
} ,
"set_general_permission_result" : {
status : "error" | "success" ,
key : string ,
value? : number ,
error_msg? : string
} ,
"set_general_permission" : { /* try to change a permission for the server */
key : string ,
value : number
} ,
"query_client_permissions" : { client_database_id : number } ,
"client_permissions" : {
status : "error" | "timeout" | "success" ,
client_database_id : number ,
error_msg? : string ,
permissions ? : { [ key : string ] : number }
} ,
"set_client_permission_result" : {
status : "error" | "success" ,
client_database_id : number ,
key : string ,
value? : number ,
error_msg? : string
} ,
"set_client_permission" : { /* try to change a permission for the server */
client_database_id : number ,
key : string ,
value : number
} ,
"query_group_permissions" : { permission_name : string } ,
"group_permissions" : {
permission_name : string ;
status : "error" | "timeout" | "success"
groups ? : {
name : string ,
value : number ,
id : number
} [ ] ,
error_msg? : string
}
}
2020-03-30 13:44:18 +02:00
export function openMusicManage ( client : ConnectionHandler , bot : MusicClientEntry ) {
2021-02-09 10:11:40 +01:00
const ev_registry = new Registry < music_manage > ( ) ;
2020-07-20 19:08:13 +02:00
ev_registry . enableDebug ( "music-manage" ) ;
2020-03-30 13:44:18 +02:00
//dummy_controller(ev_registry);
permission_controller ( ev_registry , bot , client ) ;
let modal = createModal ( {
2020-11-29 14:42:02 +01:00
header : tr ( "Playlist Manage" ) ,
2020-09-12 15:49:20 +02:00
body : ( ) = > build_modal ( ev_registry ) ,
2020-03-30 13:44:18 +02:00
footer : null ,
min_width : "35em" ,
closeable : true
} ) ;
modal . htmlTag . find ( ".modal-body" ) . addClass ( "modal-music-manage" ) ;
/* "controller" */
{
2020-02-22 14:30:17 +01:00
}
2020-03-30 13:44:18 +02:00
modal . open ( ) ;
}
2020-02-22 14:30:17 +01:00
2021-02-09 10:11:40 +01:00
function permission_controller ( event_registry : Registry < music_manage > , bot : MusicClientEntry , client : ConnectionHandler ) {
2020-03-30 13:44:18 +02:00
const error_msg = error = > {
2020-09-12 15:49:20 +02:00
if ( error instanceof CommandResult ) {
if ( error . id === ErrorCode . SERVER_INSUFFICIENT_PERMISSIONS ) {
2020-03-30 13:44:18 +02:00
const permission = client . permissions . resolveInfo ( error . json [ "failed_permid" ] ) ;
return tr ( "failed on permission " ) + ( permission ? permission.name : tr ( "unknown" ) ) ;
}
return error . extra_message || error . message ;
2020-09-12 15:49:20 +02:00
} else if ( typeof error === "string" )
2020-03-30 13:44:18 +02:00
return error ;
else
return tr ( "command error" ) ;
} ;
{
event_registry . on ( "query_playlist_status" , event = > {
const playlist_id = bot . properties . client_playlist_id ;
2020-09-07 12:42:00 +02:00
client . serverConnection . command_helper . requestPlaylistInfo ( playlist_id ) . then ( result = > {
2020-03-30 13:44:18 +02:00
event_registry . fire ( "playlist_status" , {
status : "success" ,
data : {
replay_mode : result.playlist_replay_mode ,
finished : result.playlist_flag_finished ,
delete_played : result.playlist_flag_delete_played ,
notify_song_change : bot.properties.client_flag_notify_song_change ,
max_size : result.playlist_max_songs
2020-02-22 14:30:17 +01:00
}
} ) ;
2020-03-30 13:44:18 +02:00
} ) . catch ( error = > {
event_registry . fire ( "playlist_status" , {
status : "error" ,
error_msg : error_msg ( error )
} ) ;
2021-01-10 17:36:57 +01:00
logError ( LogCategory . CLIENT , tr ( "Failed to query playlist info for playlist %d: %o" ) , playlist_id , error ) ;
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_playlist_status" , event = > {
const playlist_id = bot . properties . client_playlist_id ;
const property_map = {
"replay_mode" : "playlist_replay_mode" ,
"finished" : "playlist_flag_finished" ,
"delete_played" : "playlist_flag_delete_played" ,
"max_size" : "playlist_max_songs"
} ;
Promise . resolve ( ) . then ( ( ) = > {
2020-09-12 15:49:20 +02:00
if ( event . key === "notify_song_change" ) {
2020-03-30 13:44:18 +02:00
return client . serverConnection . send_command ( "clientedit" , {
clid : bot.clientId ( ) ,
client_flag_notify_song_change : event.value
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} else {
2020-02-22 14:30:17 +01:00
const property = property_map [ event . key ] ;
2020-09-12 15:49:20 +02:00
if ( ! property ) return Promise . reject ( tr ( "unknown property" ) ) ;
2020-02-22 14:30:17 +01:00
const data = {
2020-03-30 13:44:18 +02:00
playlist_id : playlist_id
2020-02-22 14:30:17 +01:00
} ;
data [ property ] = event . value ;
2020-03-30 13:44:18 +02:00
return client . serverConnection . send_command ( "playlistedit" , data ) ;
}
} ) . then ( ( ) = > {
event_registry . fire ( "set_playlist_status_result" , {
status : "success" ,
key : event.key ,
value : event.value
} ) ;
} ) . catch ( error = > {
event_registry . fire ( "set_playlist_status_result" , {
status : "error" ,
key : event.key ,
error_msg : error_msg ( error )
} ) ;
2021-01-10 17:36:57 +01:00
logError ( LogCategory . CLIENT , tr ( "Failed to change playlist status %s for playlist %d: %o" ) , event . key , playlist_id , error ) ;
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_bot_status" , event = > {
setTimeout ( ( ) = > {
event_registry . fire ( "bot_status" , {
status : "success" ,
data : {
channel_commander : bot.properties.client_is_channel_commander ,
volume : bot.properties.player_volume ,
description : bot.properties.client_description ,
default_country_code : (
! bot . channelTree ? undefined :
! bot . channelTree . server ? undefined : bot . channelTree . server . properties . virtualserver_country_code ) || "DE" ,
country_code : bot.properties.client_country ,
name : bot.properties.client_nickname ,
priority_speaker : bot.properties.client_is_priority_speaker ,
bot_type : bot.properties.client_bot_type ,
client_platform : bot.properties.client_platform ,
client_version : bot.properties.client_version ,
uptime_mode : bot.properties.client_uptime_mode
}
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} , 0 ) ;
} ) ;
event_registry . on ( "set_bot_status" , event = > {
const property_map = {
"channel_commander" : "client_is_channel_commander" ,
"volume" : "player_volume" ,
"description" : "client_description" ,
"country_code" : "client_country" ,
"name" : "client_nickname" ,
"priority_speaker" : "client_is_priority_speaker" ,
"bot_type" : "client_bot_type" ,
"client_platform" : "client_platform" ,
"client_version" : "client_version" ,
"uptime_mode" : "client_uptime_mode"
} ;
Promise . resolve ( ) . then ( ( ) = > {
const property = property_map [ event . key ] ;
2020-09-12 15:49:20 +02:00
if ( ! property ) return Promise . reject ( tr ( "unknown property" ) ) ;
2020-03-30 13:44:18 +02:00
const data = {
clid : bot.clientId ( )
} ;
data [ property ] = event . value ;
return client . serverConnection . send_command ( "clientedit" , data ) ;
} ) . then ( ( ) = > {
event_registry . fire ( "set_bot_status_result" , {
status : "success" ,
key : event.key ,
value : event.value
} ) ;
} ) . catch ( error = > {
event_registry . fire ( "set_bot_status_result" , {
status : "error" ,
key : event.key ,
error_msg : error_msg ( error )
} ) ;
2021-01-10 17:36:57 +01:00
logError ( LogCategory . CLIENT , tr ( "Failed to change bot setting %s: %o" ) , event . key , error ) ;
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* permissions */
{
event_registry . on ( "query_general_permissions" , event = > {
const playlist_id = bot . properties . client_playlist_id ;
client . permissions . requestPlaylistPermissions ( playlist_id ) . then ( result = > {
const permissions = { } ;
2020-09-12 15:49:20 +02:00
for ( const permission of result )
if ( permission . hasValue ( ) )
2020-03-30 13:44:18 +02:00
permissions [ permission . type . name ] = permission . value ;
event_registry . fire ( "general_permissions" , {
status : "success" ,
permissions : permissions
} ) ;
} ) . catch ( error = > {
event_registry . fire ( "general_permissions" , {
status : "error" ,
error_msg : error_msg ( error )
} ) ;
2021-01-10 17:36:57 +01:00
logError ( LogCategory . CLIENT , tr ( "Failed to query playlist general permissions for playlist %d: %o" ) , playlist_id , error ) ;
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_general_permission" , event = > {
const playlist_id = bot . properties . client_playlist_id ;
client . serverConnection . send_command ( "playlistaddperm" , {
playlist_id : playlist_id ,
permsid : event.key ,
permvalue : event.value ,
permskip : false ,
permnegated : false
} ) . then ( ( ) = > {
event_registry . fire ( "set_general_permission_result" , {
key : event.key ,
status : "success" ,
value : event.value
} ) ;
} ) . catch ( error = > {
event_registry . fire ( "set_general_permission_result" , {
status : "error" ,
key : event.key ,
error_msg : error_msg ( error )
} ) ;
2021-01-10 17:36:57 +01:00
logError ( LogCategory . CLIENT , tr ( "Failed to set playlist general permissions for playlist %d and permission %d: %o" ) , playlist_id , event . key , error ) ;
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_client_permissions" , event = > {
const playlist_id = bot . properties . client_playlist_id ;
const client_id = event . client_database_id ;
client . permissions . requestPlaylistClientPermissions ( playlist_id , client_id ) . then ( result = > {
const permissions = { } ;
2020-09-12 15:49:20 +02:00
for ( const permission of result )
if ( permission . hasValue ( ) )
2020-03-30 13:44:18 +02:00
permissions [ permission . type . name ] = permission . value ;
event_registry . fire ( "client_permissions" , {
status : "success" ,
client_database_id : event.client_database_id ,
permissions : permissions
} ) ;
} ) . catch ( error = > {
event_registry . fire ( "client_permissions" , {
status : "error" ,
client_database_id : event.client_database_id ,
error_msg : error_msg ( error )
} ) ;
2021-01-10 17:36:57 +01:00
logError ( LogCategory . CLIENT , tr ( "Failed to query playlist client permissions for playlist %d and client %d: %o" ) , playlist_id , client_id , error ) ;
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_client_permission" , event = > {
const playlist_id = bot . properties . client_playlist_id ;
const client_id = event . client_database_id ;
client . serverConnection . send_command ( "playlistclientaddperm" , {
playlist_id : playlist_id ,
cldbid : client_id ,
permsid : event.key ,
permvalue : event.value ,
permskip : false ,
permnegated : false
} ) . then ( ( ) = > {
event_registry . fire ( "set_client_permission_result" , {
key : event.key ,
status : "success" ,
client_database_id : client_id ,
value : event.value
} ) ;
} ) . catch ( error = > {
event_registry . fire ( "set_client_permission_result" , {
status : "error" ,
key : event.key ,
client_database_id : client_id ,
error_msg : error_msg ( error )
} ) ;
2021-01-10 17:36:57 +01:00
logError ( LogCategory . CLIENT , tr ( "Failed to set playlist client permissions for playlist %d, permission %d and client id %d: %o" ) , playlist_id , event . key , client_id , error ) ;
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_special_clients" , event = > {
const playlist_id = bot . properties . client_playlist_id ;
client . serverConnection . command_helper . request_playlist_client_list ( playlist_id ) . then ( clients = > {
2020-09-07 12:42:00 +02:00
return client . serverConnection . command_helper . getInfoFromClientDatabaseId ( . . . clients ) ;
2020-03-30 13:44:18 +02:00
} ) . then ( clients = > {
event_registry . fire ( "special_client_list" , {
status : "success" ,
clients : clients.map ( e = > {
return {
2020-09-07 12:42:00 +02:00
name : e.clientNickname ,
unique_id : e.clientUniqueId ,
database_id : e.clientDatabaseId
2020-03-30 13:44:18 +02:00
}
} )
} ) ;
} ) . catch ( error = > {
event_registry . fire ( "special_client_list" , {
status : "error" ,
error_msg : error_msg ( error )
} ) ;
2021-01-10 17:36:57 +01:00
logError ( LogCategory . CLIENT , tr ( "Failed to query special client list for playlist %d: %o" ) , playlist_id , error ) ;
2020-03-30 13:44:18 +02:00
} )
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "search_client" , event = > {
2020-09-12 15:49:20 +02:00
if ( ! event . text ) return ;
2020-03-30 13:44:18 +02:00
const text = event . text ;
Promise . resolve ( ) . then ( ( ) = > {
let is_uuid = false ;
try {
is_uuid = atob ( text ) . length === 32 ;
2020-09-12 15:49:20 +02:00
} catch ( e ) {
}
if ( is_uuid ) {
2020-09-07 12:42:00 +02:00
return client . serverConnection . command_helper . getInfoFromUniqueId ( text ) ;
2020-09-12 15:49:20 +02:00
} else if ( text . match ( /^[0-9]{1,7}$/ ) && ! isNaN ( parseInt ( text ) ) ) {
2020-09-07 12:42:00 +02:00
return client . serverConnection . command_helper . getInfoFromClientDatabaseId ( parseInt ( text ) ) ;
2020-03-30 13:44:18 +02:00
} else {
//TODO: Database name lookup?
return Promise . reject ( "no results" ) ;
}
} ) . then ( result = > {
2020-09-12 15:49:20 +02:00
if ( result . length ) {
2020-03-30 13:44:18 +02:00
const client = result [ 0 ] ;
2020-02-22 14:30:17 +01:00
event_registry . fire ( "search_client_result" , {
2020-03-30 13:44:18 +02:00
status : "success" ,
client : {
2020-09-07 12:42:00 +02:00
name : client.clientNickname ,
unique_id : client.clientUniqueId ,
database_id : client.clientDatabaseId
2020-03-30 13:44:18 +02:00
}
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} else {
event_registry . fire ( "search_client_result" , {
status : "empty"
} ) ;
}
} ) . catch ( error = > {
event_registry . fire ( "search_client_result" , {
status : "error" ,
error_msg : error_msg ( error )
2020-02-22 14:30:17 +01:00
} ) ;
2021-01-10 17:36:57 +01:00
logError ( LogCategory . CLIENT , tr ( "Failed to lookup search text \"%s\": %o" ) , text , error ) ;
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_group_permissions" , event = > {
client . permissions . find_permission ( event . permission_name ) . then ( result = > {
let groups = [ ] ;
2020-09-12 15:49:20 +02:00
for ( const e of result ) {
if ( e . type !== "server_group" ) continue ;
2020-02-22 14:30:17 +01:00
2020-06-13 18:47:05 +02:00
const group = client . groups . findServerGroup ( ( e as ServerGroup ) . group_id ) ;
2020-09-12 15:49:20 +02:00
if ( ! group ) continue ;
2020-03-30 13:44:18 +02:00
groups . push ( {
name : group.name ,
value : e.value ,
id : group.id
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
}
event_registry . fire ( "group_permissions" , {
status : "success" ,
groups : groups ,
permission_name : event.permission_name
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) . catch ( error = > {
event_registry . fire ( "group_permissions" , {
status : "error" ,
error_msg : error_msg ( error ) ,
permission_name : event.permission_name
} ) ;
2021-01-10 17:36:57 +01:00
logError ( LogCategory . CLIENT , tr ( "Failed to execute permfind for permission %s: %o" ) , event . permission_name , error ) ;
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2020-02-22 14:30:17 +01:00
}
2020-03-30 13:44:18 +02:00
}
2021-02-09 10:11:40 +01:00
function dummy_controller ( event_registry : Registry < music_manage > ) {
2020-03-30 13:44:18 +02:00
/* settings */
{
event_registry . on ( "query_bot_status" , event = > {
setTimeout ( ( ) = > {
event_registry . fire ( "bot_status" , {
status : "success" ,
data : {
name : "Another TeaSpeak bot" ,
country_code : "DE" ,
default_country_code : "GB" ,
channel_commander : false ,
description : "Hello World" ,
priority_speaker : true ,
volume : 66 ,
uptime_mode : 0 ,
client_version : "Version" ,
client_platform : "Platform" ,
bot_type : 0
}
} )
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_playlist_status" , event = > {
setTimeout ( ( ) = > {
event_registry . fire ( "playlist_status" , {
status : "success" ,
data : {
max_size : 55 ,
notify_song_change : true ,
delete_played : false ,
finished : false ,
replay_mode : 2
}
} )
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* permissions */
{
event_registry . on ( "query_special_clients" , event = > {
setTimeout ( ( ) = > {
event_registry . fire ( "special_client_list" , {
status : "success" ,
clients : [ {
name : "WolverinDEV" ,
database_id : 1 ,
unique_id : "abd"
} , {
name : "WolverinDEV 2" ,
database_id : 2 ,
unique_id : "abd1"
} , {
name : "WolverinDEV 3" ,
database_id : 3 ,
unique_id : "abd1"
} ]
} ) ;
} , 0 ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_group_permissions" , event = > {
setTimeout ( ( ) = > {
event_registry . fire ( "group_permissions" , {
status : "success" ,
groups : [ {
value : 20 ,
name : "Server Admin p:20" ,
id : 0
} , {
value : 10 ,
name : "Server Mod p:10" ,
id : 0
} ] ,
permission_name : event.permission_name
} ) ;
} , 0 ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_general_permissions" , event = > {
setTimeout ( ( ) = > {
event_registry . fire ( "general_permissions" , {
status : "success" ,
permissions : {
i_playlist_song_needed_add_power : 77
}
} )
} , 0 ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_general_permission" , event = > {
setTimeout ( ( ) = > {
event_registry . fire ( "set_general_permission_result" , {
key : event.key ,
value : event.value ,
status : "success"
2020-02-22 14:30:17 +01:00
} ) ;
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_client_permissions" , event = > {
setTimeout ( ( ) = > {
event_registry . fire ( "client_permissions" , {
client_database_id : event.client_database_id ,
status : "success" ,
permissions : {
i_playlist_song_needed_add_power : 77
}
} )
} , 500 ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_client_permission" , event = > {
setTimeout ( ( ) = > {
event_registry . fire ( "set_client_permission_result" , {
key : event.key ,
client_database_id : event.client_database_id ,
status : "success" ,
value : event.value
} )
} , 500 ) ;
} ) ;
2020-02-22 14:30:17 +01:00
}
2020-03-30 13:44:18 +02:00
}
2020-02-22 14:30:17 +01:00
2021-02-09 10:11:40 +01:00
function build_modal ( event_registry : Registry < music_manage > ) : JQuery < HTMLElement > {
2020-03-30 13:44:18 +02:00
const tag = $ ( "#tmpl_music_manage" ) . renderTag ( ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const container_settings = tag . find ( ".body > .category-settings" ) ;
build_settings_container ( event_registry , container_settings ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const container_permissions = tag . find ( ".body > .category-permissions" ) ;
build_permission_container ( event_registry , container_permissions ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* general switch */
{
let shown_container : "settings" | "permissions" ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const header = tag . find ( ".header" ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const category_permissions = header . find ( ".category-permissions" ) ;
event_registry . on ( "show_container" , data = > {
category_permissions . toggleClass ( "selected" , data . container === "permissions" ) ;
container_permissions . toggleClass ( "hidden" , data . container !== "permissions" ) ;
} ) ;
category_permissions . on ( 'click' , event = > {
2020-09-12 15:49:20 +02:00
if ( shown_container === "permissions" ) return ;
event_registry . fire ( "show_container" , { container : "permissions" } ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const category_settings = header . find ( ".category-settings" ) ;
event_registry . on ( "show_container" , data = > {
category_settings . toggleClass ( "selected" , data . container === "settings" ) ;
container_settings . toggleClass ( "hidden" , data . container !== "settings" ) ;
} ) ;
category_settings . on ( 'click' , event = > {
2020-09-12 15:49:20 +02:00
if ( shown_container === "settings" ) return ;
event_registry . fire ( "show_container" , { container : "settings" } ) ;
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "show_container" , data = > shown_container = data . container ) ;
2020-02-22 14:30:17 +01:00
}
2020-03-30 13:44:18 +02:00
/* input length fix */
tag . find ( "input[maxlength]" ) . on ( "input" , event = > {
const input = event . target as HTMLInputElement ;
const max = parseInt ( input . getAttribute ( "maxlength" ) ) ;
const text = input . value ;
2020-09-12 15:49:20 +02:00
if ( ! isNaN ( max ) && text && text . length > max )
2020-03-30 13:44:18 +02:00
//input.value = text.substr(text.length - max);
input . value = text . substr ( 0 , max ) ;
} ) ;
/* initialize */
2020-09-12 15:49:20 +02:00
event_registry . fire ( "show_container" , { container : "settings" } ) ;
2020-03-30 13:44:18 +02:00
return tag . children ( ) ;
}
2021-02-09 10:11:40 +01:00
function build_settings_container ( event_registry : Registry < music_manage > , tag : JQuery < HTMLElement > ) {
2020-03-30 13:44:18 +02:00
const show_change_error = ( header , message ) = > {
createErrorModal ( tr ( "Failed to change value" ) , header + "<br>" + message ) . open ( ) ;
} ;
/* music bot settings */
{
const container = tag . find ( ".settings-bot" ) ;
/* bot name */
2020-02-22 14:30:17 +01:00
{
2020-03-30 13:44:18 +02:00
const input = container . find ( ".option-bot-name" ) ;
let last_value = undefined ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_bot_status" , event = > {
last_value = undefined ;
input
. prop ( "disabled" , true )
. val ( null )
. attr ( "placeholder" , tr ( "loading..." ) ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "bot_status" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status === "error" )
2020-02-22 14:30:17 +01:00
input
. prop ( "disabled" , true )
. val ( null )
2020-03-30 13:44:18 +02:00
. attr ( "placeholder" , event . error_msg || tr ( "error while loading" ) ) ;
else
2020-02-22 14:30:17 +01:00
input
. prop ( "disabled" , false )
. attr ( "placeholder" , null )
2020-03-30 13:44:18 +02:00
. val ( last_value = event . data . name ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_bot_status_result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . key !== "name" ) return ;
2020-02-22 14:30:17 +01:00
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" )
2020-03-30 13:44:18 +02:00
show_change_error ( tr ( "Failed to set bot name" ) , event . error_msg || tr ( "timeout" ) ) ;
else
last_value = event . value ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
input
. prop ( "disabled" , false )
. attr ( "placeholder" , null )
. val ( last_value ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
input . on ( "keyup" , event = > event . key === "Enter" && input . trigger ( "focusout" ) ) ;
input . on ( "focusout" , event = > {
const value = input . val ( ) as string ;
2020-09-12 15:49:20 +02:00
if ( value === last_value ) return ;
if ( ! value ) {
2020-03-30 13:44:18 +02:00
input . val ( last_value ) ;
return ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
input
. prop ( "disabled" , true )
. val ( null )
. attr ( "placeholder" , tr ( "applying..." ) ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . fire ( "set_bot_status" , {
key : "name" ,
value : value
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
}
/* country flag */
{
const input = container . find ( ".option-bot-country" ) ;
const flag = container . find ( ".container-country .country" ) ;
let last_value = undefined , fallback_country = undefined ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const update_country_code = input = > {
input = input || fallback_country || "ts" ;
flag . each ( ( _ , e ) = > {
2020-09-12 15:49:20 +02:00
for ( const [ index , klass ] of e . classList . entries ( ) )
if ( klass . startsWith ( "flag-" ) )
2020-03-30 13:44:18 +02:00
e . classList . remove ( klass ) ;
} ) ;
flag . addClass ( "flag-" + input . toLowerCase ( ) ) ;
2021-03-23 13:42:32 +01:00
flag . attr ( "title" , i18nc . getCountryName ( input , tr ( "Unknown country" ) ) ) ;
2020-03-30 13:44:18 +02:00
} ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_bot_status" , event = > {
last_value = undefined ;
input
. prop ( "disabled" , true )
. val ( null )
. attr ( "placeholder" , "..." ) ;
update_country_code ( "ts" ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "bot_status" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status === "error" )
2020-03-30 13:44:18 +02:00
input
. prop ( "disabled" , true )
. val ( null )
. attr ( "placeholder" , "err" ) ;
else {
2020-02-22 14:30:17 +01:00
input
. prop ( "disabled" , false )
. attr ( "placeholder" , null )
2020-03-30 13:44:18 +02:00
. val ( last_value = event . data . country_code ) ;
fallback_country = event . data . default_country_code ;
}
update_country_code ( last_value ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_bot_status_result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . key !== "country_code" ) return ;
2020-02-22 14:30:17 +01:00
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" )
2020-03-30 13:44:18 +02:00
show_change_error ( tr ( "Failed to set bots country" ) , event . error_msg || tr ( "timeout" ) ) ;
else
last_value = event . value ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
input
. prop ( "disabled" , false )
. attr ( "placeholder" , null )
. val ( last_value ) ;
update_country_code ( last_value ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
input . on ( "input" , ( ) = > {
update_country_code ( input . val ( ) ) ;
input . firstParent ( ".input-boxed" ) . removeClass ( "is-invalid" ) ;
} ) ;
input . on ( "keyup" , event = > event . key === "Enter" && input . trigger ( "focusout" ) ) ;
input . on ( "focusout" , event = > {
const value = input . val ( ) as string ;
2020-09-12 15:49:20 +02:00
if ( value === last_value ) return ;
if ( value && value . length != 2 ) {
2020-03-30 13:44:18 +02:00
input . firstParent ( ".input-boxed" ) . addClass ( "is-invalid" ) ;
return ;
}
input
. prop ( "disabled" , true )
. val ( null )
. attr ( "placeholder" , "..." ) ;
event_registry . fire ( "set_bot_status" , {
key : "country_code" ,
value : value
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* flag channel commander */
{
const input = container . find ( ".option-channel-commander" ) as JQuery < HTMLInputElement > ;
const label = input . parents ( "label" ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
let last_value = undefined ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_bot_status" , event = > {
last_value = undefined ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
label . addClass ( "disabled" ) ;
input
. prop ( "checked" , false )
. prop ( "disabled" , true ) ;
} ) ;
event_registry . on ( "bot_status" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status === "error" ) {
2020-02-22 14:30:17 +01:00
label . addClass ( "disabled" ) ;
input
. prop ( "checked" , false )
. prop ( "disabled" , true ) ;
2020-03-30 13:44:18 +02:00
} else {
label . removeClass ( "disabled" ) ;
input
. prop ( "checked" , last_value = event . data . channel_commander )
. prop ( "disabled" , false ) ;
}
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_bot_status_result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . key !== "channel_commander" ) return ;
2020-02-22 14:30:17 +01:00
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" )
2020-03-30 13:44:18 +02:00
show_change_error ( tr ( "Failed to change channel commander state" ) , event . error_msg || tr ( "timeout" ) ) ;
else
last_value = event . value ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
label . removeClass ( "disabled" ) ;
input
. prop ( "checked" , last_value )
. prop ( "disabled" , false ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
input . on ( "change" , event = > {
label . addClass ( "disabled" ) ;
input . prop ( "disabled" , true ) ;
event_registry . fire ( "set_bot_status" , {
key : "channel_commander" ,
value : input.prop ( "checked" )
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* flag priority speaker */
{
const input = container . find ( ".option-priority-speaker" ) as JQuery < HTMLInputElement > ;
const label = input . parents ( "label" ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
let last_value = undefined ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_bot_status" , event = > {
last_value = undefined ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
label . addClass ( "disabled" ) ;
input
. prop ( "checked" , false )
. prop ( "disabled" , true ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "bot_status" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status === "error" ) {
2020-02-22 14:30:17 +01:00
label . addClass ( "disabled" ) ;
input
. prop ( "checked" , false )
. prop ( "disabled" , true ) ;
2020-03-30 13:44:18 +02:00
} else {
2020-02-22 14:30:17 +01:00
label . removeClass ( "disabled" ) ;
input
2020-03-30 13:44:18 +02:00
. prop ( "checked" , last_value = event . data . priority_speaker )
2020-02-22 14:30:17 +01:00
. prop ( "disabled" , false ) ;
2020-03-30 13:44:18 +02:00
}
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_bot_status_result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . key !== "priority_speaker" ) return ;
2020-02-22 14:30:17 +01:00
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" )
2020-03-30 13:44:18 +02:00
show_change_error ( tr ( "Failed to change priority speaker state" ) , event . error_msg || tr ( "timeout" ) ) ;
else
last_value = event . value ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
label . removeClass ( "disabled" ) ;
input
. prop ( "checked" , last_value )
. prop ( "disabled" , false ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
input . on ( "change" , event = > {
label . addClass ( "disabled" ) ;
input . prop ( "disabled" , true ) ;
event_registry . fire ( "set_bot_status" , {
key : "priority_speaker" ,
value : input.prop ( "checked" )
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* status load timeout */
{
let timeout ;
event_registry . on ( "query_bot_status" , event = > {
timeout = setTimeout ( ( ) = > {
event_registry . fire ( "bot_status" , {
status : "error" ,
error_msg : tr ( "load timeout" )
} ) ;
} , 5000 ) ;
} ) ;
event_registry . on ( "bot_status" , event = > clearTimeout ( timeout ) ) ;
2020-02-22 14:30:17 +01:00
}
2020-03-30 13:44:18 +02:00
/* set status timeout */
2020-02-22 14:30:17 +01:00
{
2020-09-12 15:49:20 +02:00
let timeouts : { [ key : string ] : any } = { } ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_bot_status" , event = > {
clearTimeout ( timeouts [ event . key ] ) ;
timeouts [ event . key ] = setTimeout ( ( ) = > {
event_registry . fire ( "set_bot_status_result" , {
status : "timeout" ,
key : event.key ,
} ) ;
} , 5000 ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_bot_status_result" , event = > {
clearTimeout ( timeouts [ event . key ] ) ;
delete timeouts [ event . key ] ;
} ) ;
}
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* music bot settings */
{
const container = tag . find ( ".settings-playlist" ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* playlist replay mode */
{
const input = container . find ( ".option-replay-mode" ) as JQuery < HTMLSelectElement > ;
let last_value = undefined ;
const update_value = text = > {
2020-09-12 15:49:20 +02:00
if ( text ) {
2020-03-30 13:44:18 +02:00
input . prop ( "disabled" , true ) . addClass ( "disabled" ) ;
input . val ( "-1" ) ;
input . find ( "option[value=-1]" ) . text ( text ) ;
2020-09-12 15:49:20 +02:00
} else if ( last_value >= 0 && last_value <= 3 ) {
2020-03-30 13:44:18 +02:00
input
. prop ( "disabled" , false )
. removeClass ( "disabled" ) ;
input . val ( last_value ) ;
} else {
update_value ( tr ( "invalid value" ) ) ;
}
} ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_playlist_status" , event = > {
last_value = undefined ;
update_value ( tr ( "loading..." ) ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "playlist_status" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status === "error" ) {
2020-03-30 13:44:18 +02:00
update_value ( event . error_msg || tr ( "error while loading" ) ) ;
} else {
last_value = event . data . replay_mode ;
2020-02-22 14:30:17 +01:00
update_value ( undefined ) ;
2020-03-30 13:44:18 +02:00
}
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_playlist_status_result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . key !== "replay_mode" ) return ;
2020-02-22 14:30:17 +01:00
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" )
2020-03-30 13:44:18 +02:00
show_change_error ( tr ( "Failed to change replay mode" ) , event . error_msg || tr ( "timeout" ) ) ;
else
last_value = event . value ;
update_value ( undefined ) ;
} ) ;
input . on ( "keyup" , event = > event . key === "Enter" && input . trigger ( "focusout" ) ) ;
input . on ( "change" , event = > {
const value = parseInt ( input . val ( ) as string ) ;
2020-09-12 15:49:20 +02:00
if ( isNaN ( value ) ) return ;
2020-03-30 13:44:18 +02:00
update_value ( tr ( "applying..." ) ) ;
event_registry . fire ( "set_playlist_status" , {
key : "replay_mode" ,
value : value
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* playlist max size */
{
const input = container . find ( ".container-max-playlist-size input" ) ;
let last_value = undefined ;
event_registry . on ( "query_playlist_status" , event = > {
last_value = undefined ;
input
. prop ( "disabled" , true )
. val ( null )
. attr ( "placeholder" , tr ( "loading..." ) )
. firstParent ( ".input-boxed" ) . addClass ( "disabled" ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "playlist_status" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status === "error" )
2020-02-22 14:30:17 +01:00
input
. prop ( "disabled" , true )
. val ( null )
2020-03-30 13:44:18 +02:00
. attr ( "placeholder" , event . error_msg || tr ( "error while loading" ) )
2020-02-22 14:30:17 +01:00
. firstParent ( ".input-boxed" ) . addClass ( "disabled" ) ;
2020-03-30 13:44:18 +02:00
else
2020-02-22 14:30:17 +01:00
input
. prop ( "disabled" , false )
. attr ( "placeholder" , null )
2020-03-30 13:44:18 +02:00
. val ( ( last_value = event . data . max_size ) . toString ( ) )
2020-02-22 14:30:17 +01:00
. firstParent ( ".input-boxed" ) . removeClass ( "disabled" ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_playlist_status_result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . key !== "max_size" ) return ;
2020-02-22 14:30:17 +01:00
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" )
2020-03-30 13:44:18 +02:00
show_change_error ( tr ( "Failed to change max playlist size" ) , event . error_msg || tr ( "timeout" ) ) ;
else
last_value = event . value ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
input
. prop ( "disabled" , false )
. attr ( "placeholder" , null )
. val ( last_value )
. firstParent ( ".input-boxed" ) . removeClass ( "disabled" ) ;
} ) ;
input . on ( "input" , event = > input . parentsUntil ( ".input-boxed" ) . removeClass ( "is-invalid" ) ) ;
input . on ( "keyup" , event = > event . key === "Enter" && input . trigger ( "focusout" ) ) ;
input . on ( "focusout" , event = > {
const value = input . val ( ) as string ;
2020-09-12 15:49:20 +02:00
if ( value === last_value ) return ;
if ( value === "" ) {
2020-03-30 13:44:18 +02:00
input . val ( last_value ) ;
return ;
}
2020-09-12 15:49:20 +02:00
if ( isNaN ( parseInt ( value ) ) ) {
2020-03-30 13:44:18 +02:00
input . parentsUntil ( ".input-boxed" ) . addClass ( "is-invalid" ) ;
return ;
}
input
. prop ( "disabled" , true )
. val ( null )
. attr ( "placeholder" , tr ( "applying..." ) )
. firstParent ( ".input-boxed" ) . addClass ( "disabled" ) ;
event_registry . fire ( "set_playlist_status" , {
key : "max_size" ,
value : parseInt ( value )
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* flag delete played */
{
const input = container . find ( ".option-delete-played-songs" ) as JQuery < HTMLInputElement > ;
const label = input . parents ( "label" ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
let last_value = undefined ;
event_registry . on ( "query_playlist_status" , event = > {
last_value = undefined ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
label . addClass ( "disabled" ) ;
input
. prop ( "checked" , false )
. prop ( "disabled" , true ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "playlist_status" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status === "error" ) {
2020-02-22 14:30:17 +01:00
label . addClass ( "disabled" ) ;
input
. prop ( "checked" , false )
. prop ( "disabled" , true ) ;
2020-03-30 13:44:18 +02:00
} else {
label . removeClass ( "disabled" ) ;
input
. prop ( "checked" , last_value = event . data . delete_played )
. prop ( "disabled" , false ) ;
}
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_playlist_status_result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . key !== "delete_played" ) return ;
2020-02-22 14:30:17 +01:00
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" )
2020-03-30 13:44:18 +02:00
show_change_error ( tr ( "Failed to change delete state" ) , event . error_msg || tr ( "timeout" ) ) ;
else
last_value = event . value ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
label . removeClass ( "disabled" ) ;
input
. prop ( "checked" , last_value )
. prop ( "disabled" , false ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
input . on ( "change" , event = > {
label . addClass ( "disabled" ) ;
input . prop ( "disabled" , true ) ;
event_registry . fire ( "set_playlist_status" , {
key : "delete_played" ,
value : input.prop ( "checked" )
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* flag notify song change */
{
const input = container . find ( ".option-notify-songs-change" ) as JQuery < HTMLInputElement > ;
const label = input . parents ( "label" ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
let last_value = undefined ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_playlist_status" , event = > {
last_value = undefined ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
label . addClass ( "disabled" ) ;
input
. prop ( "checked" , false )
. prop ( "disabled" , true ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "playlist_status" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status === "error" ) {
2020-02-22 14:30:17 +01:00
label . addClass ( "disabled" ) ;
input
. prop ( "checked" , false )
. prop ( "disabled" , true ) ;
2020-03-30 13:44:18 +02:00
} else {
2020-02-22 14:30:17 +01:00
label . removeClass ( "disabled" ) ;
input
2020-03-30 13:44:18 +02:00
. prop ( "checked" , last_value = event . data . notify_song_change )
2020-02-22 14:30:17 +01:00
. prop ( "disabled" , false ) ;
2020-03-30 13:44:18 +02:00
}
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_playlist_status_result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . key !== "notify_song_change" ) return ;
2020-02-22 14:30:17 +01:00
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" )
2020-03-30 13:44:18 +02:00
show_change_error ( tr ( "Failed to change notify state" ) , event . error_msg || tr ( "timeout" ) ) ;
else
last_value = event . value ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
label . removeClass ( "disabled" ) ;
input
. prop ( "checked" , last_value )
. prop ( "disabled" , false ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
input . on ( "change" , event = > {
label . addClass ( "disabled" ) ;
input . prop ( "disabled" , true ) ;
event_registry . fire ( "set_playlist_status" , {
key : "notify_song_change" ,
value : input.prop ( "checked" )
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2020-02-22 14:30:17 +01:00
}
2020-03-30 13:44:18 +02:00
/* status load timeout */
2020-02-22 14:30:17 +01:00
{
let timeout ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_playlist_status" , event = > {
timeout = setTimeout ( ( ) = > {
event_registry . fire ( "playlist_status" , {
status : "error" ,
error_msg : tr ( "load timeout" )
} ) ;
} , 5000 ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "playlist_status" , event = > clearTimeout ( timeout ) ) ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* set status timeout */
{
2020-09-12 15:49:20 +02:00
let timeouts : { [ key : string ] : any } = { } ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_playlist_status" , event = > {
clearTimeout ( timeouts [ event . key ] ) ;
timeouts [ event . key ] = setTimeout ( ( ) = > {
event_registry . fire ( "set_playlist_status_result" , {
status : "timeout" ,
key : event.key ,
} ) ;
} , 5000 ) ;
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_playlist_status_result" , event = > {
clearTimeout ( timeouts [ event . key ] ) ;
delete timeouts [ event . key ] ;
2020-02-22 14:30:17 +01:00
} ) ;
}
2020-03-30 13:44:18 +02:00
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* reload button */
{
const button = tag . find ( ".button-reload" ) ;
let timeout ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( [ "query_bot_status" , "query_playlist_status" ] , event = > {
button . prop ( "disabled" , true ) ;
clearTimeout ( timeout ) ;
timeout = setTimeout ( ( ) = > {
button . prop ( "disabled" , false ) ;
} , 1000 ) ;
} ) ;
button . on ( "click" , event = > {
event_registry . fire ( "query_bot_status" ) ;
event_registry . fire ( "query_playlist_status" ) ;
} ) ;
}
tooltip . initialize ( tag ) ;
/* initialize on show */
{
let initialized = false ;
event_registry . on ( "show_container" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . container !== "settings" || initialized ) return ;
2020-03-30 13:44:18 +02:00
initialized = true ;
event_registry . fire ( "query_bot_status" ) ;
event_registry . fire ( "query_playlist_status" ) ;
} ) ;
}
}
2021-02-09 10:11:40 +01:00
function build_permission_container ( event_registry : Registry < music_manage > , tag : JQuery < HTMLElement > ) {
2020-03-30 13:44:18 +02:00
/* client search mechanism */
{
const container = tag . find ( ".table-head .column-client-specific .client-select" ) ;
let list_shown = false ;
/* search list show/hide */
2020-02-22 14:30:17 +01:00
{
2020-03-30 13:44:18 +02:00
const button_list_clients = container . find ( ".button-list-clients" ) ;
button_list_clients . on ( 'click' , event = >
event_registry . fire ( list_shown ? "hide_client_list" : "show_client_list" ) ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "show_client_list" , ( ) = > {
list_shown = true ;
button_list_clients . text ( tr ( "Hide clients" ) ) ;
} ) ;
event_registry . on ( "hide_client_list" , ( ) = > {
list_shown = false ;
button_list_clients . text ( tr ( "List clients" ) ) ;
2020-02-22 14:30:17 +01:00
} ) ;
}
2020-03-30 13:44:18 +02:00
/* the search box */
2020-02-22 14:30:17 +01:00
{
2020-03-30 13:44:18 +02:00
const input_search = container . find ( ".input-search" ) ;
const button_search = container . find ( ".button-search" ) ;
let search_timeout ;
let last_query ;
input_search . on ( 'keyup' , event = > {
const text = input_search . val ( ) as string ;
2020-09-12 15:49:20 +02:00
if ( text === last_query ) return ;
2020-03-30 13:44:18 +02:00
2020-09-12 15:49:20 +02:00
if ( text )
event_registry . fire ( "filter_client_list" , { filter : text } ) ;
2020-03-30 13:44:18 +02:00
else
2020-09-12 15:49:20 +02:00
event_registry . fire ( "filter_client_list" , { filter : undefined } ) ;
2020-03-30 13:44:18 +02:00
input_search . toggleClass ( "is-invalid" , ! list_shown && text === last_query ) ;
2020-09-12 15:49:20 +02:00
if ( ! list_shown ) {
2020-03-30 13:44:18 +02:00
button_search . prop ( "disabled" , ! text || ! ! search_timeout ) ;
} else {
last_query = text ;
}
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
input_search . on ( 'keydown' , event = > {
2020-09-12 15:49:20 +02:00
if ( event . key === "Enter" && ! list_shown && ! button_search . prop ( "disabled" ) )
2020-03-30 13:44:18 +02:00
button_search . trigger ( "click" ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "show_client_list" , ( ) = > {
button_search . prop ( "disabled" , true ) ;
input_search . attr ( "placeholder" , tr ( "Search client list" ) ) ;
} ) ;
event_registry . on ( "hide_client_list" , ( ) = > {
button_search . prop ( "disabled" , ! input_search . val ( ) || ! ! search_timeout ) ;
input_search . attr ( "placeholder" , tr ( "Client uid or database id" ) ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
button_search . on ( "click" , event = > {
button_search . prop ( "disabled" , true ) ;
input_search . blur ( ) ;
const text = input_search . val ( ) as string ;
last_query = text ;
event_registry . fire ( "search_client" , {
text : text
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
search_timeout = setTimeout ( ( ) = > event_registry . fire ( "search_client_result" , {
status : "timeout"
} ) , 5000 ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "search_client_result" , event = > {
clearTimeout ( search_timeout ) ;
search_timeout = 0 ;
button_search . prop ( "disabled" , ! input_search . val ( ) ) ;
2020-09-12 15:49:20 +02:00
if ( event . status === "timeout" ) {
2020-03-30 13:44:18 +02:00
createErrorModal ( tr ( "Client search failed" ) , tr ( "Failed to perform client search.<br>Search resulted in a timeout." ) ) . open ( ) ;
return ;
2020-09-12 15:49:20 +02:00
} else if ( event . status === "error" || event . status === "empty" ) {
2020-03-30 13:44:18 +02:00
//TODO: Display the error somehow?
input_search . addClass ( "is-invalid" ) ;
return ;
} else {
event_registry . fire ( "special_client_set" , {
client : event.client
} ) ;
}
} ) ;
}
/* the client list */
{
const container = tag . find ( ".overlay-client-list" ) ;
event_registry . on ( "show_client_list" , ( ) = > container . removeClass ( "hidden" ) ) ;
event_registry . on ( "hide_client_list" , ( ) = > container . addClass ( "hidden" ) ) ;
const button_refresh = container . find ( ".button-clientlist-refresh" ) ;
const container_entries = container . find ( ".container-client-list" ) ;
event_registry . on ( "special_client_list" , data = > {
button_refresh . prop ( "disabled" , false ) ;
container . find ( ".overlay" ) . addClass ( "hidden" ) ;
2020-09-12 15:49:20 +02:00
if ( data . status === "error-permission" ) {
2020-03-30 13:44:18 +02:00
const overlay = container . find ( ".overlay-query-error-permissions" ) ;
overlay . find ( "a" ) . text ( tr ( "Insufficient permissions" ) ) ;
overlay . removeClass ( "hidden" ) ;
2020-09-12 15:49:20 +02:00
} else if ( data . status === "success" ) {
2020-03-30 13:44:18 +02:00
container_entries . find ( ".client" ) . remove ( ) ; /* clear */
2020-09-12 15:49:20 +02:00
if ( ! data . clients . length ) {
2020-03-30 13:44:18 +02:00
const overlay = container . find ( ".overlay-empty-list" ) ;
overlay . removeClass ( "hidden" ) ;
2020-02-22 14:30:17 +01:00
} else {
2020-09-12 15:49:20 +02:00
for ( const client of data . clients ) {
2020-03-30 13:44:18 +02:00
const tag = $ . spawn ( "div" ) . addClass ( "client" ) . append (
htmltags . generate_client_object ( {
add_braces : false ,
client_id : 0 ,
client_database_id : client.database_id ,
client_name : client.name ,
client_unique_id : client.unique_id
} )
) ;
2020-09-12 15:49:20 +02:00
tag . on ( 'dblclick' , event = > event_registry . fire ( "special_client_set" , { client : client } ) ) ;
2020-03-30 13:44:18 +02:00
tag . attr ( "x-filter" , client . database_id + "_" + client . name + "_" + client . unique_id ) ;
container_entries . append ( tag ) ;
}
2020-02-22 14:30:17 +01:00
}
2020-03-30 13:44:18 +02:00
} else {
const overlay = container . find ( ".overlay-query-error" ) ;
overlay . find ( "a" ) . text ( data . error_msg ? data.error_msg : tr ( "query failed" ) ) ;
overlay . removeClass ( "hidden" ) ;
}
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* refresh button */
button_refresh . on ( 'click' , event = > {
button_refresh . prop ( "disabled" , true ) ;
event_registry . fire ( "query_special_clients" ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* special client list query timeout handler */
{
let query_timeout ;
event_registry . on ( "query_special_clients" , event = > {
query_timeout = setTimeout ( ( ) = > {
event_registry . fire ( "special_client_list" , {
status : "error" ,
error_msg : tr ( "Query timeout" )
} ) ;
} , 5000 ) ;
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "special_client_list" , event = > clearTimeout ( query_timeout ) ) ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* first time client list show */
{
let shown ;
event_registry . on ( 'show_client_list' , event = > {
2020-09-12 15:49:20 +02:00
if ( shown ) return ;
2020-03-30 13:44:18 +02:00
shown = true ;
event_registry . fire ( "query_special_clients" ) ;
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* the client list filter */
{
let filter ;
const overlay = container . find ( ".overlay-filter-no-result" ) ;
const update_filter = ( ) = > {
let shown = 0 , hidden = 0 ;
container_entries . find ( ".client" ) . each ( function ( ) {
const text = this . getAttribute ( "x-filter" ) ;
2020-09-12 15:49:20 +02:00
if ( ! filter || text . toLowerCase ( ) . indexOf ( filter ) != - 1 ) {
2020-03-30 13:44:18 +02:00
this . classList . remove ( "hidden" ) ;
shown ++ ;
} else {
this . classList . add ( "hidden" ) ;
hidden ++ ;
}
} ) ;
2020-09-12 15:49:20 +02:00
if ( shown == 0 && hidden == 0 ) return ;
2020-03-30 13:44:18 +02:00
overlay . toggleClass ( "hidden" , shown != 0 ) ;
} ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "special_client_list" , event = > update_filter ( ) ) ;
event_registry . on ( "filter_client_list" , event = > {
filter = ( event . filter || "" ) . toLowerCase ( ) ;
update_filter ( ) ;
2020-02-22 14:30:17 +01:00
} ) ;
}
2020-03-30 13:44:18 +02:00
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "special_client_set" , event = > {
container . toggleClass ( "hidden" , ! ! event . client ) ;
event_registry . fire ( "hide_client_list" ) ;
} ) ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* the client info */
{
const container = tag . find ( ".table-head .column-client-specific .client-info" ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
container . find ( ".button-client-deselect" ) . on ( "click" , event = > {
2020-09-12 15:49:20 +02:00
event_registry . fire ( "special_client_set" , { client : undefined } ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "special_client_set" , event = > {
container . toggleClass ( "hidden" , ! event . client ) ;
const client_container = container . find ( ".container-selected-client" ) ;
client_container . find ( ".htmltag-client" ) . remove ( ) ;
2020-09-12 15:49:20 +02:00
if ( event . client ) {
2020-03-30 13:44:18 +02:00
client_container . append ( htmltags . generate_client_object ( {
client_unique_id : event.client.unique_id ,
client_name : event.client.name ,
client_id : 0 ,
client_database_id : event.client.database_id ,
add_braces : false
} ) ) ;
}
} ) ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const power_needed_map = {
i_client_music_rename_power : "i_client_music_needed_rename_power" ,
i_client_music_modify_power : "i_client_music_needed_modify_power" ,
i_client_music_delete_power : "i_client_music_needed_delete_power" ,
i_playlist_view_power : "i_playlist_needed_view_power" ,
i_playlist_modify_power : "i_playlist_needed_modify_power" ,
i_playlist_permission_modify_power : "i_playlist_needed_permission_modify_power" ,
i_playlist_song_add_power : "i_playlist_song_needed_add_power" ,
i_playlist_song_move_power : "i_playlist_song_needed_move_power" ,
i_playlist_song_remove_power : "i_playlist_song_needed_remove_power" ,
b_virtualserver_playlist_permission_list : "b_virtualserver_playlist_permission_list"
} ;
const needed_power_map = Object . entries ( power_needed_map ) . reduce ( ( ret , entry ) = > {
const [ key , value ] = entry ;
ret [ value ] = key ;
return ret ;
} , { } ) ;
/* general permissions */
{
/* permission input functionality */
{
tag . find ( ".general-permission" ) . each ( ( _ , _e ) = > {
const elem = $ ( _e ) as JQuery < HTMLDivElement > ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const permission_name = elem . attr ( "x-permission" ) ;
2020-09-12 15:49:20 +02:00
if ( ! permission_name ) return ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const input = elem . find ( "input" ) ;
input . attr ( "maxlength" , 6 ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
let last_sync_value = undefined ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_general_permissions" , event = > {
input . prop ( "disabled" , true ) . val ( null ) ;
input . attr ( "placeholder" , tr ( "loading..." ) ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "general_permissions" , event = > {
input . prop ( "disabled" , true ) . val ( null ) ;
2020-09-12 15:49:20 +02:00
if ( event . status === "timeout" ) {
2020-03-30 13:44:18 +02:00
input . attr ( "placeholder" , tr ( "load timeout" ) ) ;
2020-09-12 15:49:20 +02:00
} else if ( event . status === "success" ) {
2020-03-30 13:44:18 +02:00
input . prop ( "disabled" , false ) ; //TODO: Check permissions?
input . attr ( "placeholder" , null ) ;
const value = event . permissions ? event . permissions [ permission_name ] || 0 : 0 ;
last_sync_value = value ;
input . val ( value ) ;
} else {
input . attr ( "placeholder" , event . error_msg || tr ( "load error" ) ) ;
}
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_general_permission_result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . key !== permission_name ) return ;
2020-03-30 13:44:18 +02:00
input . prop ( "disabled" , false ) ; //TODO: Check permissions?
input . attr ( "placeholder" , null ) ;
2020-09-12 15:49:20 +02:00
if ( event . status === "success" ) {
2020-03-30 13:44:18 +02:00
input . val ( event . value ) ;
last_sync_value = event . value ;
2020-09-12 15:49:20 +02:00
} else if ( event . status === "error" ) {
if ( typeof last_sync_value === "number" ) input . val ( last_sync_value ) ;
2021-04-24 13:59:49 +02:00
createErrorModal ( tr ( "Failed to change permission" ) , tra ( "Failed to change permission:\n{}" , event . error_msg ) ) . open ( ) ;
2020-03-30 13:44:18 +02:00
}
} ) ;
input . on ( "focusout" , event = > {
2020-09-12 15:49:20 +02:00
if ( input . prop ( "disabled" ) ) return ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const value = parseInt ( input . val ( ) as string ) ;
2020-09-12 15:49:20 +02:00
if ( value === last_sync_value ) return ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
input . prop ( "disabled" , true ) . val ( null ) ;
input . attr ( "placeholder" , tr ( "applying..." ) ) ;
event_registry . fire ( "set_general_permission" , {
key : permission_name ,
value : value || 0
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
input . on ( "keyup" , event = > event . key === "Enter" && input . blur ( ) ) ;
2020-02-22 14:30:17 +01:00
} ) ;
}
2020-03-30 13:44:18 +02:00
/* the tooltip functionality */
2020-02-22 14:30:17 +01:00
{
2020-03-30 13:44:18 +02:00
tag . find ( ".general-permission" ) . each ( ( _ , _e ) = > {
const elem = $ ( _e ) as JQuery < HTMLDivElement > ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const permission_name = elem . attr ( "x-permission" ) ;
2020-09-12 15:49:20 +02:00
if ( ! permission_name ) return ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const required_power = needed_power_map [ permission_name ] ;
2020-09-12 15:49:20 +02:00
if ( ! required_power ) return ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
let last_sync_value = undefined ;
let current_tag : JQuery ;
let loading = false ;
let query_result : {
status : "error" | "timeout" | "success"
groups ? : {
name : string ,
value : number ,
id : number
} [ ] ,
error_msg? : string
} ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "general_permissions" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status === "success" )
2020-03-30 13:44:18 +02:00
last_sync_value = event . permissions ? event . permissions [ permission_name ] || 0 : 0 ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_general_permission_result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . key !== permission_name ) return ;
2020-02-22 14:30:17 +01:00
2020-09-12 15:49:20 +02:00
if ( event . status === "success" )
2020-03-30 13:44:18 +02:00
last_sync_value = event . value ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "refresh_permissions" , event = > {
query_result = undefined ; /* require for the next time */
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const show_query_result = ( ) = > {
2020-09-12 15:49:20 +02:00
if ( ! current_tag ) return ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const container_groups = current_tag . find ( ".container-groups" ) ;
container_groups . children ( ) . remove ( ) ;
current_tag . find ( ".container-status" ) . addClass ( "hidden" ) ;
2020-02-22 14:30:17 +01:00
2020-09-12 15:49:20 +02:00
if ( loading ) {
2020-03-30 13:44:18 +02:00
current_tag . find ( ".status-loading" ) . removeClass ( "hidden" ) ;
2020-09-12 15:49:20 +02:00
} else if ( ! query_result || query_result . status === "error" ) {
2020-03-30 13:44:18 +02:00
current_tag
. find ( ".status-error" ) . removeClass ( "hidden" )
. text ( ( query_result ? query_result . error_msg : "" ) || tr ( "failed to query data" ) ) ;
2020-09-12 15:49:20 +02:00
} else if ( query_result . status === "timeout" ) {
2020-03-30 13:44:18 +02:00
current_tag
. find ( ".status-error" ) . removeClass ( "hidden" )
. text ( tr ( "timeout while loading" ) ) ;
} else {
let count = 0 ;
2020-09-12 15:49:20 +02:00
for ( const group of ( query_result . groups || [ ] ) ) {
if ( group . value !== - 1 && group . value < last_sync_value ) continue ;
2020-03-30 13:44:18 +02:00
count ++ ;
container_groups . append ( $ . spawn ( "div" ) . addClass ( "group" ) . text (
" - " + group . name + " (" + group . id + ")"
) ) ;
2020-02-22 14:30:17 +01:00
}
2020-09-12 15:49:20 +02:00
if ( count === 0 ) current_tag . find ( ".status-no-groups" ) . removeClass ( "hidden" ) ;
2020-03-30 13:44:18 +02:00
}
} ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
tooltip . initialize ( elem , {
on_show ( tag : JQuery < HTMLElement > ) {
current_tag = tag ;
2020-02-22 14:30:17 +01:00
2020-09-12 15:49:20 +02:00
if ( ! query_result && ! loading ) {
2020-03-30 13:44:18 +02:00
event_registry . fire ( "query_group_permissions" , {
permission_name : required_power
} ) ;
loading = true ;
}
show_query_result ( ) ;
} ,
on_hide ( tag : JQuery < HTMLElement > ) {
current_tag = undefined ;
}
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "group_permissions" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . permission_name !== required_power ) return ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
loading = false ;
query_result = event ;
show_query_result ( ) ;
} ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* refresh mechanism */
{
event_registry . on ( "refresh_permissions" , event = > event_registry . fire ( "query_general_permissions" ) ) ;
}
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* permission set timeout */
{
2020-09-12 15:49:20 +02:00
let permission_timers : { [ key : string ] : any } = { } ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_general_permission" , event = > {
2020-09-12 15:49:20 +02:00
if ( permission_timers [ event . key ] )
2020-03-30 13:44:18 +02:00
clearTimeout ( permission_timers [ event . key ] ) ;
permission_timers [ event . key ] = setTimeout ( ( ) = > {
event_registry . fire ( "set_general_permission_result" , {
key : event.key ,
status : "error" ,
error_msg : tr ( "controller timeout" )
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} , 5000 ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_general_permission_result" , event = > {
clearTimeout ( permission_timers [ event . key ] ) ;
delete permission_timers [ event . key ] ;
} ) ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* group query timeout */
{
2020-09-12 15:49:20 +02:00
let timers : { [ key : string ] : any } = { } ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_group_permissions" , event = > {
2020-09-12 15:49:20 +02:00
if ( timers [ event . permission_name ] )
2020-03-30 13:44:18 +02:00
clearTimeout ( timers [ event . permission_name ] ) ;
timers [ event . permission_name ] = setTimeout ( ( ) = > {
event_registry . fire ( "group_permissions" , {
permission_name : event.permission_name ,
status : "timeout"
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} , 5000 ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "group_permissions" , event = > {
clearTimeout ( timers [ event . permission_name ] ) ;
delete timers [ event . permission_name ] ;
} ) ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* query timeout */
{
let query_timeout ;
event_registry . on ( "query_general_permissions" , event = > {
clearTimeout ( query_timeout ) ;
query_timeout = setTimeout ( ( ) = > {
event_registry . fire ( "general_permissions" , {
status : "timeout"
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} , 5000 ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "general_permissions" , event = > clearTimeout ( query_timeout ) ) ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* refresh button */
{
const button = tag . find ( ".button-permission-refresh" ) ;
let refresh_timer ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
let loading_client_permissions = false ;
let loading_general_permissions = false ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const update_button = ( ) = >
button . prop ( "disabled" , refresh_timer || loading_client_permissions || loading_general_permissions ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_general_permissions" , event = > {
loading_general_permissions = true ;
update_button ( ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "general_permissions" , event = > {
loading_general_permissions = false ;
update_button ( ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_client_permissions" , event = > {
loading_client_permissions = true ;
update_button ( ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "client_permissions" , event = > {
loading_client_permissions = false ;
update_button ( ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
button . on ( 'click' , event = > {
event_registry . fire ( "refresh_permissions" ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* allow refreshes only every second */
refresh_timer = setTimeout ( ( ) = > {
refresh_timer = undefined ;
2020-02-22 14:30:17 +01:00
update_button ( ) ;
2020-03-30 13:44:18 +02:00
} , 1000 ) ;
} ) ;
2020-02-22 14:30:17 +01:00
}
2020-03-30 13:44:18 +02:00
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* client specific permissions */
{
const container = tag . find ( ".column-client-specific" ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
let client_database_id = 0 ;
2020-09-12 15:49:20 +02:00
let needed_permissions : { [ key : string ] : number } = { } ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* needed permissions updater */
{
event_registry . on ( "general_permissions" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . status !== "success" ) return ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
needed_permissions = event . permissions ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_general_permission_result" , event = > {
if ( event . status !== "success" ) return ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
needed_permissions [ event . key ] = event . value ;
} ) ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "special_client_set" , event = > {
client_database_id = event . client ? event.client.database_id : 0 ;
container . find ( ".client-permission" ) . toggleClass ( "hidden" , ! event . client ) ;
2020-02-22 14:30:17 +01:00
2020-09-12 15:49:20 +02:00
if ( client_database_id )
event_registry . fire ( "query_client_permissions" , { client_database_id : client_database_id } ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const enabled_class = "client-apply" ;
const disabled_class = "client-delete" ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
container . find ( ".client-permission" ) . each ( ( _ , _e ) = > {
const elem = $ ( _e ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const input = elem . find ( "input" ) ;
const status_indicator = elem . find ( ".icon_em" ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const permission_name = elem . attr ( "x-permission" ) as string ;
const permission_needed_name = power_needed_map [ permission_name ] ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
let last_sync_value = undefined ;
let hide_indicator = false ;
2020-02-22 14:30:17 +01:00
2020-09-12 15:49:20 +02:00
if ( typeof permission_needed_name !== "string" ) {
2021-01-10 17:36:57 +01:00
logWarn ( LogCategory . GENERAL , tr ( "Missing permission needed mapping for %s" ) , permission_name ) ;
2020-03-30 13:44:18 +02:00
return ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const update_indicator = ( ) = > {
const value = parseInt ( input . val ( ) as string ) ;
const needed = typeof needed_permissions [ permission_needed_name ] === "number" ? needed_permissions [ permission_needed_name ] : 0 ;
const flag = value == - 1 ? true : isNaN ( value ) || value == 0 ? false : value >= needed ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
status_indicator . toggle ( ! hide_indicator ) ;
status_indicator . toggleClass ( enabled_class , flag ) . toggleClass ( disabled_class , ! flag ) ;
} ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "special_client_set" , event = > {
last_sync_value = undefined ;
} ) ;
event_registry . on ( "general_permissions" , event = > update_indicator ( ) ) ;
event_registry . on ( "set_general_permission_result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . key !== permission_needed_name ) return ;
if ( event . status !== "success" ) return ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
update_indicator ( ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* loading the permission */
event_registry . on ( "query_client_permissions" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . client_database_id !== client_database_id ) return ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
last_sync_value = undefined ;
hide_indicator = true ;
input . prop ( "disabled" , true ) . val ( null ) ;
input . attr ( "placeholder" , tr ( "loading..." ) ) ;
update_indicator ( ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( 'client_permissions' , event = > {
2020-09-12 15:49:20 +02:00
if ( event . client_database_id !== client_database_id ) return ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
hide_indicator = false ;
input . prop ( "disabled" , true ) . val ( null ) ;
2020-09-12 15:49:20 +02:00
if ( event . status === "timeout" ) {
2020-03-30 13:44:18 +02:00
input . attr ( "placeholder" , tr ( "load timeout" ) ) ;
2020-09-12 15:49:20 +02:00
} else if ( event . status === "success" ) {
2020-03-30 13:44:18 +02:00
input . prop ( "disabled" , false ) ; //TODO: Check permissions?
input . attr ( "placeholder" , null ) ;
const value = event . permissions ? event . permissions [ permission_name ] || 0 : 0 ;
last_sync_value = value ;
input . val ( value ) ;
} else {
input . attr ( "placeholder" , event . error_msg || tr ( "load error" ) ) ;
}
update_indicator ( ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* permission editing */
input . attr ( "maxlength" , 6 ) ;
input . on ( "focusout" , event = > {
2020-09-12 15:49:20 +02:00
if ( ! client_database_id ) return ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
const value = parseInt ( input . val ( ) as string ) ;
2020-09-12 15:49:20 +02:00
if ( value === last_sync_value ) return ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
input . prop ( "disabled" , true ) . val ( null ) ;
input . attr ( "placeholder" , tr ( "applying..." ) ) ;
event_registry . fire ( "set_client_permission" , {
client_database_id : client_database_id ,
key : permission_name ,
value : value || 0
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
hide_indicator = true ;
update_indicator ( ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
input . on ( "change" , ( ) = > update_indicator ( ) ) ;
input . on ( "keyup" , event = > event . key === "Enter" && input . blur ( ) ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_client_permission_result" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . key !== permission_name ) return ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
input . prop ( "disabled" , false ) ; //TODO: Check permissions?
input . attr ( "placeholder" , null ) ;
2020-09-12 15:49:20 +02:00
if ( event . status === "success" ) {
2020-03-30 13:44:18 +02:00
input . val ( event . value ) ;
last_sync_value = event . value ;
2020-09-12 15:49:20 +02:00
} else if ( event . status === "error" ) {
if ( typeof last_sync_value === "number" ) input . val ( last_sync_value ) ;
2021-04-24 13:59:49 +02:00
createErrorModal ( tr ( "Failed to change permission" ) , tra ( "Failed to change permission:\n{}" , event . error_msg ) ) . open ( ) ;
2020-03-30 13:44:18 +02:00
}
hide_indicator = false ;
update_indicator ( ) ;
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* client permission query timeout */
{
2020-09-12 15:49:20 +02:00
let timeout : { [ key : number ] : any } = { } ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "query_client_permissions" , event = > {
2020-09-12 15:49:20 +02:00
if ( timeout [ event . client_database_id ] )
2020-02-22 14:30:17 +01:00
clearTimeout ( timeout [ event . client_database_id ] ) ;
2020-03-30 13:44:18 +02:00
timeout [ event . client_database_id ] = setTimeout ( ( ) = > {
event_registry . fire ( "client_permissions" , {
status : "timeout" ,
client_database_id : event.client_database_id
} ) ;
} , 5000 ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "client_permissions" , event = > {
clearTimeout ( timeout [ event . client_database_id ] ) ;
} ) ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* client permission set timeout */
{
2020-09-12 15:49:20 +02:00
let timeout : { [ key : string ] : any } = { } ;
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_client_permission" , event = > {
const key = event . client_database_id + "_" + event . key ;
2020-09-12 15:49:20 +02:00
if ( timeout [ key ] )
2020-03-30 13:44:18 +02:00
clearTimeout ( timeout [ key ] ) ;
timeout [ key ] = setTimeout ( ( ) = > {
event_registry . fire ( "set_client_permission_result" , {
key : event.key ,
status : "error" ,
client_database_id : event.client_database_id ,
error_msg : tr ( "timeout" )
} ) ;
} , 5000 ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
event_registry . on ( "set_client_permission_result" , event = > {
const key = event . client_database_id + "_" + event . key ;
2020-09-12 15:49:20 +02:00
if ( timeout [ key ] ) {
2020-03-30 13:44:18 +02:00
clearTimeout ( timeout [ key ] ) ;
delete timeout [ key ] ;
}
2020-02-22 14:30:17 +01:00
} ) ;
}
2020-03-30 13:44:18 +02:00
event_registry . on ( "refresh_permissions" , event = > {
2020-09-12 15:49:20 +02:00
if ( client_database_id )
event_registry . fire ( "query_client_permissions" , { client_database_id : client_database_id } ) ;
2020-02-22 14:30:17 +01:00
} ) ;
2020-03-30 13:44:18 +02:00
tooltip . initialize ( container ) ;
}
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* a title attribute for permission column */
tag . find ( ".table-body .column-permission a" ) . each ( function ( ) {
this . setAttribute ( "title" , this . textContent ) ;
} ) ;
2020-02-22 14:30:17 +01:00
2020-03-30 13:44:18 +02:00
/* initialize on show */
{
let initialized = false ;
event_registry . on ( "show_container" , event = > {
2020-09-12 15:49:20 +02:00
if ( event . container !== "permissions" || initialized ) return ;
2020-03-30 13:44:18 +02:00
initialized = true ;
2020-09-12 15:49:20 +02:00
event_registry . fire ( "special_client_set" , { client : undefined } ) ;
2020-03-30 13:44:18 +02:00
event_registry . fire ( "query_general_permissions" , { } ) ;
} ) ;
2020-02-22 14:30:17 +01:00
}
}