2020-04-18 17:37:30 +00:00
|
|
|
import {ClientEvents, MusicClientEntry, SongInfo} from "tc-shared/ui/client";
|
2020-03-30 11:44:18 +00:00
|
|
|
import {guid} from "tc-shared/crypto/uid";
|
2020-04-05 20:33:09 +00:00
|
|
|
import * as React from "react";
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-04-06 14:29:40 +00:00
|
|
|
export interface Event<Events, T = keyof Events> {
|
2020-04-05 20:47:38 +00:00
|
|
|
readonly type: T;
|
|
|
|
as<T extends keyof Events>() : Events[T];
|
2020-03-30 11:44:18 +00:00
|
|
|
}
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-04-05 20:47:38 +00:00
|
|
|
interface SingletonEvents {
|
|
|
|
"singletone-instance": never;
|
2020-03-30 11:44:18 +00:00
|
|
|
}
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-04-05 20:47:38 +00:00
|
|
|
export class SingletonEvent implements Event<SingletonEvents, "singletone-instance"> {
|
2020-03-30 11:44:18 +00:00
|
|
|
static readonly instance = new SingletonEvent();
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
readonly type = "singletone-instance";
|
|
|
|
private constructor() { }
|
2020-04-05 20:47:38 +00:00
|
|
|
as<T extends keyof SingletonEvents>() : SingletonEvents[T] { return; }
|
2020-03-30 11:44:18 +00:00
|
|
|
}
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-04-05 20:33:09 +00:00
|
|
|
const event_annotation_key = guid();
|
2020-03-30 11:44:18 +00:00
|
|
|
export class Registry<Events> {
|
|
|
|
private readonly registry_uuid;
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
private handler: {[key: string]: ((event) => void)[]} = {};
|
|
|
|
private connections: {[key: string]:Registry<string>[]} = {};
|
2020-04-05 20:33:09 +00:00
|
|
|
private event_handler_objects: {
|
|
|
|
object: any,
|
|
|
|
handlers: {[key: string]: ((event) => void)[]}
|
|
|
|
}[] = [];
|
2020-03-30 11:44:18 +00:00
|
|
|
private debug_prefix = undefined;
|
2020-04-18 18:25:58 +00:00
|
|
|
private warn_unhandled_events = false;
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
constructor() {
|
|
|
|
this.registry_uuid = "evreg_data_" + guid();
|
|
|
|
}
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
enable_debug(prefix: string) { this.debug_prefix = prefix || "---"; }
|
|
|
|
disable_debug() { this.debug_prefix = undefined; }
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-04-06 14:29:40 +00:00
|
|
|
enable_warn_unhandled_events() { this.warn_unhandled_events = true; }
|
|
|
|
disable_warn_unhandled_events() { this.warn_unhandled_events = false; }
|
|
|
|
|
2020-04-05 20:47:38 +00:00
|
|
|
on<T extends keyof Events>(event: T, handler: (event?: Events[T] & Event<Events, T>) => void);
|
|
|
|
on(events: (keyof Events)[], handler: (event?: Event<Events, keyof Events>) => void);
|
2020-03-30 11:44:18 +00:00
|
|
|
on(events, handler) {
|
|
|
|
if(!Array.isArray(events))
|
|
|
|
events = [events];
|
|
|
|
|
|
|
|
handler[this.registry_uuid] = {
|
|
|
|
singleshot: false
|
|
|
|
};
|
|
|
|
for(const event of events) {
|
|
|
|
const handlers = this.handler[event] || (this.handler[event] = []);
|
|
|
|
handlers.push(handler);
|
2020-03-27 15:15:15 +00:00
|
|
|
}
|
2020-03-30 11:44:18 +00:00
|
|
|
}
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
/* one */
|
2020-04-05 20:47:38 +00:00
|
|
|
one<T extends keyof Events>(event: T, handler: (event?: Events[T] & Event<Events, T>) => void);
|
|
|
|
one(events: (keyof Events)[], handler: (event?: Event<Events, keyof Events>) => void);
|
2020-03-30 11:44:18 +00:00
|
|
|
one(events, handler) {
|
|
|
|
if(!Array.isArray(events))
|
|
|
|
events = [events];
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
for(const event of events) {
|
|
|
|
const handlers = this.handler[event] || (this.handler[event] = []);
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
handler[this.registry_uuid] = { singleshot: true };
|
|
|
|
handlers.push(handler);
|
2020-02-02 14:05:36 +00:00
|
|
|
}
|
2020-03-30 11:44:18 +00:00
|
|
|
}
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-04-18 17:37:30 +00:00
|
|
|
off<T extends keyof Events>(handler: (event?) => void);
|
|
|
|
off<T extends keyof Events>(event: T, handler: (event?: Events[T] & Event<Events, T>) => void);
|
2020-04-05 20:47:38 +00:00
|
|
|
off(event: (keyof Events)[], handler: (event?: Event<Events, keyof Events>) => void);
|
2020-03-30 11:44:18 +00:00
|
|
|
off(handler_or_events, handler?) {
|
|
|
|
if(typeof handler_or_events === "function") {
|
|
|
|
for(const key of Object.keys(this.handler))
|
|
|
|
this.handler[key].remove(handler_or_events);
|
|
|
|
} else {
|
|
|
|
if(!Array.isArray(handler_or_events))
|
|
|
|
handler_or_events = [handler_or_events];
|
|
|
|
|
|
|
|
for(const event of handler_or_events) {
|
|
|
|
const handlers = this.handler[event];
|
|
|
|
if(handlers) handlers.remove(handler);
|
2020-02-02 14:05:36 +00:00
|
|
|
}
|
|
|
|
}
|
2020-03-30 11:44:18 +00:00
|
|
|
}
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-04-06 14:29:40 +00:00
|
|
|
connect<EOther, T extends keyof Events & keyof EOther>(events: T | T[], target: Registry<EOther>) {
|
|
|
|
for(const event of Array.isArray(events) ? events : [events])
|
|
|
|
(this.connections[event as string] || (this.connections[event as string] = [])).push(target as any);
|
2020-03-30 11:44:18 +00:00
|
|
|
}
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-04-06 14:29:40 +00:00
|
|
|
disconnect<EOther, T extends keyof Events & keyof EOther>(events: T | T[], target: Registry<EOther>) {
|
|
|
|
for(const event of Array.isArray(events) ? events : [events])
|
|
|
|
(this.connections[event as string] || []).remove(target as any);
|
2020-03-30 11:44:18 +00:00
|
|
|
}
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
disconnect_all<EOther>(target: Registry<EOther>) {
|
|
|
|
for(const event of Object.keys(this.connections))
|
|
|
|
this.connections[event].remove(target as any);
|
|
|
|
}
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-04-18 17:37:30 +00:00
|
|
|
fire<T extends keyof Events>(event_type: T, data?: Events[T], overrideTypeKey?: boolean) {
|
2020-03-30 11:44:18 +00:00
|
|
|
if(this.debug_prefix) console.log("[%s] Trigger event: %s", this.debug_prefix, event_type);
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-04-18 17:37:30 +00:00
|
|
|
if(typeof data === "object" && 'type' in data && !overrideTypeKey) {
|
|
|
|
if((data as any).type !== event_type) {
|
|
|
|
debugger;
|
|
|
|
throw tr("The keyword 'type' is reserved for the event type and should not be passed as argument");
|
|
|
|
}
|
|
|
|
}
|
2020-03-30 11:44:18 +00:00
|
|
|
const event = Object.assign(typeof data === "undefined" ? SingletonEvent.instance : data, {
|
|
|
|
type: event_type,
|
|
|
|
as: function () { return this; }
|
|
|
|
});
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-04-18 17:37:30 +00:00
|
|
|
this.fire_event(event_type as string, event);
|
|
|
|
}
|
|
|
|
|
|
|
|
private fire_event(type: string, data: any) {
|
2020-04-06 14:29:40 +00:00
|
|
|
let invoke_count = 0;
|
2020-04-18 17:37:30 +00:00
|
|
|
for(const handler of (this.handler[type]?.slice(0) || [])) {
|
|
|
|
handler(data);
|
2020-04-06 14:29:40 +00:00
|
|
|
invoke_count++;
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
const reg_data = handler[this.registry_uuid];
|
|
|
|
if(typeof reg_data === "object" && reg_data.singleshot)
|
2020-04-18 17:37:30 +00:00
|
|
|
this.handler[type].remove(handler);
|
2020-02-02 14:05:36 +00:00
|
|
|
}
|
|
|
|
|
2020-04-18 17:37:30 +00:00
|
|
|
for(const evhandler of (this.connections[type]?.slice(0) || [])) {
|
|
|
|
evhandler.fire_event(type, data);
|
2020-04-06 14:29:40 +00:00
|
|
|
invoke_count++;
|
|
|
|
}
|
2020-04-18 18:25:58 +00:00
|
|
|
if(this.warn_unhandled_events && invoke_count === 0) {
|
2020-04-18 17:37:30 +00:00
|
|
|
console.warn(tr("Event handler (%s) triggered event %s which has no consumers."), this.debug_prefix, type);
|
2020-04-06 14:29:40 +00:00
|
|
|
}
|
2020-03-30 11:44:18 +00:00
|
|
|
}
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-04-18 17:37:30 +00:00
|
|
|
fire_async<T extends keyof Events>(event_type: T, data?: Events[T], callback?: () => void) {
|
|
|
|
setTimeout(() => {
|
|
|
|
this.fire(event_type, data);
|
|
|
|
if(typeof callback === "function")
|
|
|
|
callback();
|
|
|
|
});
|
2020-02-02 14:05:36 +00:00
|
|
|
}
|
2019-08-21 08:00:01 +00:00
|
|
|
|
2020-04-06 14:29:40 +00:00
|
|
|
destroy() {
|
2020-03-30 11:44:18 +00:00
|
|
|
this.handler = {};
|
2020-04-06 14:29:40 +00:00
|
|
|
this.connections = {};
|
|
|
|
this.event_handler_objects = [];
|
2020-03-30 11:44:18 +00:00
|
|
|
}
|
2020-04-05 20:33:09 +00:00
|
|
|
|
|
|
|
register_handler(handler: any) {
|
|
|
|
if(typeof handler !== "object")
|
|
|
|
throw "event handler must be an object";
|
|
|
|
const proto = Object.getPrototypeOf(handler);
|
|
|
|
if(typeof proto !== "object")
|
|
|
|
throw "event handler must have a prototype";
|
|
|
|
|
|
|
|
let registered_events = {};
|
|
|
|
for(const function_name of Object.getOwnPropertyNames(proto)) {
|
|
|
|
if(function_name === "constructor") continue;
|
2020-04-09 13:10:14 +00:00
|
|
|
if(typeof proto[function_name] !== "function") continue;
|
2020-04-05 20:33:09 +00:00
|
|
|
if(typeof proto[function_name][event_annotation_key] !== "object") continue;
|
|
|
|
|
|
|
|
const event_data = proto[function_name][event_annotation_key];
|
2020-04-06 14:29:40 +00:00
|
|
|
const ev_handler = event => proto[function_name].call(handler, event);
|
2020-04-05 20:33:09 +00:00
|
|
|
for(const event of event_data.events) {
|
|
|
|
registered_events[event] = registered_events[event] || [];
|
|
|
|
registered_events[event].push(ev_handler);
|
|
|
|
this.on(event, ev_handler);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(Object.keys(registered_events).length === 0)
|
|
|
|
throw "no events found in event handler";
|
|
|
|
|
|
|
|
this.event_handler_objects.push({
|
|
|
|
handlers: registered_events,
|
|
|
|
object: handler
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
unregister_handler(handler: any) {
|
|
|
|
const data = this.event_handler_objects.find(e => e.object === handler);
|
|
|
|
if(!data) throw "unknown event handler";
|
|
|
|
this.event_handler_objects.remove(data);
|
|
|
|
|
|
|
|
for(const key of Object.keys(data.handlers)) {
|
|
|
|
for(const evhandler of data.handlers[key])
|
|
|
|
this.off(evhandler);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function EventHandler<EventTypes>(events: (keyof EventTypes) | (keyof EventTypes)[]) {
|
|
|
|
return function (target: any,
|
|
|
|
propertyKey: string,
|
|
|
|
descriptor: PropertyDescriptor) {
|
|
|
|
if(typeof target[propertyKey] !== "function")
|
|
|
|
throw "Invalid event handler annotation. Expected to be on a function type.";
|
|
|
|
|
|
|
|
target[propertyKey][event_annotation_key] = {
|
|
|
|
events: Array.isArray(events) ? events : [events]
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-06 14:29:40 +00:00
|
|
|
export function ReactEventHandler<ObjectClass = React.Component<any, any>, EventTypes = any>(registry_callback: (object: ObjectClass) => Registry<EventTypes>) {
|
2020-04-05 20:33:09 +00:00
|
|
|
return function (constructor: Function) {
|
|
|
|
if(!React.Component.prototype.isPrototypeOf(constructor.prototype))
|
|
|
|
throw "Class/object isn't an instance of React.Component";
|
|
|
|
|
|
|
|
const didMount = constructor.prototype.componentDidMount;
|
|
|
|
constructor.prototype.componentDidMount = function() {
|
|
|
|
const registry = registry_callback(this);
|
|
|
|
if(!registry) throw "Event registry returned for an event object is invalid";
|
|
|
|
registry.register_handler(this);
|
|
|
|
|
|
|
|
if(typeof didMount === "function")
|
|
|
|
didMount.call(this, arguments);
|
|
|
|
};
|
|
|
|
|
|
|
|
const willUnmount = constructor.prototype.componentWillUnmount;
|
|
|
|
constructor.prototype.componentWillUnmount = function () {
|
|
|
|
const registry = registry_callback(this);
|
|
|
|
if(!registry) throw "Event registry returned for an event object is invalid";
|
2020-04-21 14:17:21 +00:00
|
|
|
try {
|
|
|
|
registry.unregister_handler(this);
|
|
|
|
} catch (error) {
|
|
|
|
console.warn("Failed to unregister event handler: %o", error);
|
|
|
|
}
|
2020-04-05 20:33:09 +00:00
|
|
|
|
|
|
|
if(typeof willUnmount === "function")
|
|
|
|
willUnmount.call(this, arguments);
|
|
|
|
};
|
|
|
|
}
|
2020-03-30 11:44:18 +00:00
|
|
|
}
|
2019-08-21 08:00:01 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
export namespace sidebar {
|
|
|
|
export interface music {
|
|
|
|
"open": {}, /* triggers when frame should be shown */
|
|
|
|
"close": {}, /* triggers when frame will be closed */
|
|
|
|
|
|
|
|
"bot_change": {
|
|
|
|
old: MusicClientEntry | undefined,
|
|
|
|
new: MusicClientEntry | undefined
|
|
|
|
},
|
|
|
|
"bot_property_update": {
|
|
|
|
properties: string[]
|
|
|
|
},
|
|
|
|
|
|
|
|
"action_play": {},
|
|
|
|
"action_pause": {},
|
|
|
|
"action_song_set": { song_id: number },
|
|
|
|
"action_forward": {},
|
|
|
|
"action_rewind": {},
|
|
|
|
"action_forward_ms": {
|
|
|
|
units: number;
|
|
|
|
},
|
|
|
|
"action_rewind_ms": {
|
|
|
|
units: number;
|
|
|
|
},
|
|
|
|
"action_song_add": {},
|
|
|
|
"action_song_delete": { song_id: number },
|
|
|
|
"action_playlist_reload": {},
|
|
|
|
|
|
|
|
"playtime_move_begin": {},
|
|
|
|
"playtime_move_end": {
|
|
|
|
canceled: boolean,
|
|
|
|
target_time?: number
|
|
|
|
},
|
|
|
|
|
|
|
|
"reorder_begin": { song_id: number; entry: JQuery },
|
|
|
|
"reorder_end": { song_id: number; canceled: boolean; entry: JQuery; previous_entry?: number },
|
|
|
|
|
2020-04-18 17:37:30 +00:00
|
|
|
"player_time_update": ClientEvents["music_status_update"],
|
|
|
|
"player_song_change": ClientEvents["music_song_change"],
|
2020-03-30 11:44:18 +00:00
|
|
|
|
2020-04-18 17:37:30 +00:00
|
|
|
"playlist_song_add": ClientEvents["playlist_song_add"] & { insert_effect?: boolean },
|
|
|
|
"playlist_song_remove": ClientEvents["playlist_song_remove"],
|
|
|
|
"playlist_song_reorder": ClientEvents["playlist_song_reorder"],
|
|
|
|
"playlist_song_loaded": ClientEvents["playlist_song_loaded"] & { html_entry?: JQuery },
|
2020-03-30 11:44:18 +00:00
|
|
|
}
|
|
|
|
}
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
export namespace modal {
|
|
|
|
export type BotStatusType = "name" | "description" | "volume" | "country_code" | "channel_commander" | "priority_speaker";
|
|
|
|
export type PlaylistStatusType = "replay_mode" | "finished" | "delete_played" | "max_size" | "notify_song_change";
|
|
|
|
export 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,
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
country_code: string,
|
|
|
|
default_country_code: string,
|
|
|
|
|
|
|
|
channel_commander: boolean,
|
|
|
|
priority_speaker: boolean,
|
|
|
|
|
|
|
|
client_version: string,
|
|
|
|
client_platform: string,
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
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
|
2020-02-02 14:05:36 +00:00
|
|
|
}
|
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
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
|
|
|
|
}
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
/* permission relevant */
|
|
|
|
show_client_list: {},
|
|
|
|
hide_client_list: {},
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
filter_client_list: { filter: string | undefined },
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"refresh_permissions": {},
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
},
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
/* 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-02-02 14:05:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
export interface newcomer {
|
|
|
|
"show_step": {
|
|
|
|
"step": "welcome" | "microphone" | "identity" | "finish"
|
|
|
|
},
|
|
|
|
"exit_guide": {
|
|
|
|
ask_yesno: boolean
|
|
|
|
},
|
2020-02-22 13:30:17 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"modal-shown": {},
|
2020-02-22 13:30:17 +00:00
|
|
|
|
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"step-status": {
|
|
|
|
next_button: boolean,
|
|
|
|
previous_button: boolean
|
|
|
|
}
|
|
|
|
}
|
2020-02-22 13:30:17 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
export namespace settings {
|
|
|
|
export type ProfileInfo = {
|
|
|
|
id: string,
|
|
|
|
name: string,
|
|
|
|
nickname: string,
|
|
|
|
identity_type: "teaforo" | "teamspeak" | "nickname",
|
2020-02-22 13:30:17 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
identity_forum?: {
|
|
|
|
valid: boolean,
|
|
|
|
fallback_name: string
|
2020-02-22 13:30:17 +00:00
|
|
|
},
|
2020-03-30 11:44:18 +00:00
|
|
|
identity_nickname?: {
|
|
|
|
name: string,
|
|
|
|
fallback_name: string
|
2020-02-22 13:30:17 +00:00
|
|
|
},
|
2020-03-30 11:44:18 +00:00
|
|
|
identity_teamspeak?: {
|
|
|
|
unique_id: string,
|
|
|
|
fallback_name: string
|
2020-02-22 13:30:17 +00:00
|
|
|
}
|
2020-03-30 11:44:18 +00:00
|
|
|
}
|
2020-02-22 13:30:17 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
export interface profiles {
|
|
|
|
"reload-profile": { profile_id?: string },
|
|
|
|
"select-profile": { profile_id: string },
|
2020-02-22 13:30:17 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"query-profile-list": { },
|
|
|
|
"query-profile-list-result": {
|
|
|
|
status: "error" | "success" | "timeout",
|
2020-02-22 13:30:17 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
error?: string;
|
|
|
|
profiles?: ProfileInfo[]
|
|
|
|
}
|
2020-02-22 13:30:17 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"query-profile": { profile_id: string },
|
|
|
|
"query-profile-result": {
|
|
|
|
status: "error" | "success" | "timeout",
|
|
|
|
profile_id: string,
|
2020-02-22 13:30:17 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
error?: string;
|
|
|
|
info?: ProfileInfo
|
2020-02-22 13:30:17 +00:00
|
|
|
},
|
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"select-identity-type": {
|
|
|
|
profile_id: string,
|
|
|
|
identity_type: "teamspeak" | "teaforo" | "nickname" | "unset"
|
2020-02-22 13:30:17 +00:00
|
|
|
},
|
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"query-profile-validity": { profile_id: string },
|
|
|
|
"query-profile-validity-result": {
|
|
|
|
profile_id: string,
|
|
|
|
status: "error" | "success" | "timeout",
|
2020-02-22 13:30:17 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
error?: string,
|
|
|
|
valid?: boolean
|
2020-02-22 13:30:17 +00:00
|
|
|
}
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"create-profile": { name: string },
|
|
|
|
"create-profile-result": {
|
|
|
|
status: "error" | "success" | "timeout",
|
|
|
|
name: string;
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
profile_id?: string;
|
|
|
|
error?: string;
|
|
|
|
},
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"delete-profile": { profile_id: string },
|
|
|
|
"delete-profile-result": {
|
|
|
|
status: "error" | "success" | "timeout",
|
|
|
|
profile_id: string,
|
|
|
|
error?: string
|
2020-03-27 15:15:15 +00:00
|
|
|
}
|
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"set-default-profile": { profile_id: string },
|
|
|
|
"set-default-profile-result": {
|
|
|
|
status: "error" | "success" | "timeout",
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
/* the profile which now has the id "default" */
|
|
|
|
old_profile_id: string,
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
/* the "default" profile which now has a new id */
|
|
|
|
new_profile_id?: string
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
error?: string;
|
|
|
|
}
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
/* profile name events */
|
|
|
|
"set-profile-name": {
|
|
|
|
profile_id: string,
|
|
|
|
name: string
|
|
|
|
},
|
|
|
|
"set-profile-name-result": {
|
|
|
|
status: "error" | "success" | "timeout",
|
|
|
|
profile_id: string,
|
|
|
|
name?: string
|
|
|
|
},
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
/* profile nickname events */
|
|
|
|
"set-default-name": {
|
|
|
|
profile_id: string,
|
|
|
|
name: string | null
|
|
|
|
},
|
|
|
|
"set-default-name-result": {
|
|
|
|
status: "error" | "success" | "timeout",
|
|
|
|
profile_id: string,
|
|
|
|
name?: string | null
|
|
|
|
},
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"query-identity-teamspeak": { profile_id: string },
|
|
|
|
"query-identity-teamspeak-result": {
|
|
|
|
status: "error" | "success" | "timeout",
|
|
|
|
profile_id: string,
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
error?: string,
|
|
|
|
level?: number
|
|
|
|
}
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"set-identity-name-name": { profile_id: string, name: string },
|
|
|
|
"set-identity-name-name-result": {
|
|
|
|
status: "error" | "success" | "timeout",
|
|
|
|
profile_id: string,
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
error?: string,
|
|
|
|
name?: string
|
|
|
|
},
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"generate-identity-teamspeak": { profile_id: string },
|
|
|
|
"generate-identity-teamspeak-result": {
|
|
|
|
profile_id: string,
|
|
|
|
status: "error" | "success" | "timeout",
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
error?: string,
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
level?: number
|
|
|
|
unique_id?: string
|
|
|
|
},
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"improve-identity-teamspeak-level": { profile_id: string },
|
|
|
|
"improve-identity-teamspeak-level-update": {
|
|
|
|
profile_id: string,
|
|
|
|
new_level: number
|
|
|
|
},
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"import-identity-teamspeak": { profile_id: string },
|
|
|
|
"import-identity-teamspeak-result": {
|
|
|
|
profile_id: string,
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
level?: number
|
|
|
|
unique_id?: string
|
|
|
|
}
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"export-identity-teamspeak": {
|
|
|
|
profile_id: string,
|
|
|
|
filename: string
|
|
|
|
},
|
2020-03-27 15:15:15 +00:00
|
|
|
|
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"setup-forum-connection": {}
|
|
|
|
}
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
export type MicrophoneSettings = "volume" | "vad-type" | "ppt-key" | "ppt-release-delay" | "ppt-release-delay-active" | "threshold-threshold";
|
|
|
|
export interface microphone {
|
|
|
|
"query-devices": { refresh_list: boolean },
|
|
|
|
"query-device-result": {
|
|
|
|
status: "success" | "error" | "timeout",
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
error?: string,
|
|
|
|
devices?: {
|
|
|
|
id: string,
|
|
|
|
name: string,
|
|
|
|
driver: string
|
|
|
|
}[]
|
|
|
|
active_device?: string;
|
|
|
|
},
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"query-settings": {},
|
|
|
|
"query-settings-result": {
|
|
|
|
status: "success" | "error" | "timeout",
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
error?: string,
|
|
|
|
info?: {
|
|
|
|
volume: number,
|
|
|
|
vad_type: string,
|
|
|
|
|
|
|
|
vad_ppt: {
|
|
|
|
key: any, /* ppt.KeyDescriptor */
|
|
|
|
release_delay: number,
|
|
|
|
release_delay_active: boolean
|
|
|
|
},
|
|
|
|
vad_threshold: {
|
|
|
|
threshold: number
|
|
|
|
}
|
2020-03-27 15:15:15 +00:00
|
|
|
}
|
2020-03-30 11:44:18 +00:00
|
|
|
},
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"set-device": { device_id: string },
|
|
|
|
"set-device-result": {
|
|
|
|
device_id: string,
|
|
|
|
status: "success" | "error" | "timeout",
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
error?: string
|
|
|
|
},
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"set-setting": {
|
|
|
|
setting: MicrophoneSettings;
|
|
|
|
value: any;
|
|
|
|
},
|
|
|
|
"set-setting-result": {
|
|
|
|
setting: MicrophoneSettings,
|
|
|
|
status: "success" | "error" | "timeout",
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
error?: string,
|
|
|
|
value?: any
|
|
|
|
},
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
"update-device-level": {
|
|
|
|
devices: {
|
2020-03-27 15:15:15 +00:00
|
|
|
device_id: string,
|
2020-03-30 11:44:18 +00:00
|
|
|
status: "success" | "error",
|
2020-03-27 15:15:15 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
level?: number,
|
2020-03-27 15:15:15 +00:00
|
|
|
error?: string
|
2020-03-30 11:44:18 +00:00
|
|
|
}[]
|
|
|
|
},
|
|
|
|
|
|
|
|
"audio-initialized": {},
|
|
|
|
"deinitialize": {}
|
2020-03-27 15:15:15 +00:00
|
|
|
}
|
2020-02-22 13:30:17 +00:00
|
|
|
}
|
2020-02-02 14:05:36 +00:00
|
|
|
}
|
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
//Some test code
|
2020-04-18 17:37:30 +00:00
|
|
|
/*
|
|
|
|
const eclient = new Registry<ClientEvents>();
|
2020-04-05 20:47:38 +00:00
|
|
|
const emusic = new Registry<sidebar.music>();
|
2020-02-02 14:05:36 +00:00
|
|
|
|
2020-04-05 20:47:38 +00:00
|
|
|
eclient.on("property_update", event => { event.as<"playlist_song_loaded">(); });
|
2020-02-02 14:05:36 +00:00
|
|
|
eclient.connect("playlist_song_loaded", emusic);
|
2020-04-18 17:37:30 +00:00
|
|
|
eclient.connect("playlist_song_loaded", emusic);
|
|
|
|
*/
|