Also applied the new selected info structure for ServerEntity and ChannelEntity
parent
6bb0179958
commit
31d8b7a56c
|
@ -0,0 +1,10 @@
|
|||
.select_info_table { }
|
||||
.select_info_table tr { }
|
||||
.select_info_table tr td {
|
||||
}
|
||||
|
||||
.select_info_table tr td:nth-child(1) {
|
||||
font-weight: bold;
|
||||
padding-right: 5px;
|
||||
min-width: 20%;
|
||||
}
|
|
@ -103,11 +103,6 @@
|
|||
flex-direction: column;
|
||||
}
|
||||
|
||||
.info_key {
|
||||
font-weight: bold;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
/* The Modal (background) */
|
||||
.modal {
|
||||
display: none; /* Hidden by default */
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
<link rel="stylesheet" href="css/modals.css" type="text/css">
|
||||
<link rel="stylesheet" href="css/loader.css" type="text/css">
|
||||
<link rel="stylesheet" href="css/music/info_plate.css" type="text/css">
|
||||
<link rel="stylesheet" href="css/frame/SelectInfo.css" type="text/css">
|
||||
|
||||
<!-- https://localhost:9987/?forward_url=http%3A%2F%2Flocalhost%3A63344%2FWeb-Client%2Findex.php%3F_ijt%3D82b1uhmnh0a5l1n35nnjps5eid%26loader_ignore_age%3D1%26connect_default_host%3Dlocalhost%26default_connect_type%3Dforum%26default_connect_url%3Dtrue%26default_connect_type%3Dteamspeak%26default_connect_url%3Dlocalhost%253A9987 -->
|
||||
<!-- PHP generated properies -->
|
||||
|
|
|
@ -227,7 +227,7 @@ class FileManager {
|
|||
transfer.remotePort = json["port"];
|
||||
transfer.remoteHost = (json["ip"] ? json["ip"] : "").replace(/,/g, "");
|
||||
if(!transfer.remoteHost || transfer.remoteHost == '0.0.0.0' || transfer.remoteHost == '127.168.0.0')
|
||||
transfer.remoteHost = this.handle.serverConnection._remoteHost;
|
||||
transfer.remoteHost = this.handle.serverConnection._remote_address.host;
|
||||
|
||||
(transfer["_promiseCallback"] as (val: DownloadFileTransfer) => void)(transfer);
|
||||
this.pendingDownloadTransfers.remove(transfer);
|
||||
|
|
|
@ -91,8 +91,8 @@ class TSClient {
|
|||
port = 9987;
|
||||
}
|
||||
console.log("Start connection to " + host + ":" + port);
|
||||
this.channelTree.initialiseHead(addr);
|
||||
this.serverConnection.startConnection(host, port, new HandshakeHandler(identity, name));
|
||||
this.channelTree.initialiseHead(addr, {host, port});
|
||||
this.serverConnection.startConnection({host, port}, new HandshakeHandler(identity, name));
|
||||
}
|
||||
|
||||
|
||||
|
@ -145,9 +145,9 @@ class TSClient {
|
|||
callback += "&default_connect_type=teamspeak";
|
||||
break;
|
||||
}
|
||||
callback += "&default_connect_url=" + encodeURIComponent(this.serverConnection._remoteHost + ":" + this.serverConnection._remotePort);
|
||||
callback += "&default_connect_url=" + encodeURIComponent(this.serverConnection._remote_address.host + ":" + this.serverConnection._remote_address.port);
|
||||
|
||||
return "https://" + this.serverConnection._remoteHost + ":" + this.serverConnection._remotePort + "/?forward_url=" + encodeURIComponent(callback);
|
||||
return "https://" + this.serverConnection._remote_address.host + ":" + this.serverConnection._remote_address.port + "/?forward_url=" + encodeURIComponent(callback);
|
||||
}
|
||||
|
||||
handleDisconnect(type: DisconnectReason, data: any = {}) {
|
||||
|
|
|
@ -31,8 +31,7 @@ class ReturnListener<T> {
|
|||
|
||||
class ServerConnection {
|
||||
_client: TSClient;
|
||||
_remoteHost: string;
|
||||
_remotePort: number;
|
||||
_remote_address: ServerAddress;
|
||||
_socket: WebSocket;
|
||||
_connectionState: ConnectionState = ConnectionState.UNCONNECTED;
|
||||
_handshakeHandler: HandshakeHandler;
|
||||
|
@ -62,19 +61,18 @@ class ServerConnection {
|
|||
return (this._retCodeIdx++).toString();
|
||||
}
|
||||
|
||||
startConnection(host : string, port : number, handshake: HandshakeHandler, timeout: number = 1000) {
|
||||
startConnection(address : ServerAddress, handshake: HandshakeHandler, timeout: number = 1000) {
|
||||
if(this._connectTimeoutHandler) {
|
||||
clearTimeout(this._connectTimeoutHandler);
|
||||
this._connectTimeoutHandler = null;
|
||||
this.disconnect();
|
||||
}
|
||||
this.updateConnectionState(ConnectionState.CONNECTING);
|
||||
this._remoteHost = host;
|
||||
this._remotePort = port;
|
||||
this._remote_address = address;
|
||||
this._handshakeHandler = handshake;
|
||||
this._handshakeHandler.setConnection(this);
|
||||
this._connected = false;
|
||||
chat.serverChat().appendMessage("Connecting to " + host + ":" + port);
|
||||
chat.serverChat().appendMessage("Connecting to " + address.host + ":" + address.port);
|
||||
|
||||
const self = this;
|
||||
try {
|
||||
|
@ -83,7 +81,7 @@ class ServerConnection {
|
|||
this._client.handleDisconnect(DisconnectReason.CONNECT_FAILURE);
|
||||
}, timeout);
|
||||
let sockCpy;
|
||||
this._socket = (sockCpy = new WebSocket('wss:' + this._remoteHost + ":" + this._remotePort));
|
||||
this._socket = (sockCpy = new WebSocket('wss:' + address.host + ":" + address.port));
|
||||
clearTimeout(this._connectTimeoutHandler);
|
||||
this._connectTimeoutHandler = null;
|
||||
if(this._socket != sockCpy) return; //Connect timeouted
|
||||
|
@ -375,11 +373,19 @@ class ConnectionCommandHandler {
|
|||
this.connection._client.clientId = parseInt(json["aclid"]);
|
||||
this.connection._client.getClient().updateVariables({key: "client_nickname", value: json["acn"]});
|
||||
|
||||
let updates: {
|
||||
key: string,
|
||||
value: string
|
||||
}[] = [];
|
||||
for(let key in json) {
|
||||
if(key === "aclid") continue;
|
||||
if(key === "acn") continue;
|
||||
this.connection._client.channelTree.server.updateProperty(key, json[key]);
|
||||
|
||||
updates.push({key: key, value: json[key]});
|
||||
}
|
||||
this.connection._client.channelTree.server.updateVariables(...updates);
|
||||
|
||||
|
||||
chat.serverChat().name = this.connection._client.channelTree.server.properties["virtualserver_name"];
|
||||
chat.serverChat().appendMessage("Connected as {0}", true, this.connection._client.getClient().createChatTag(true));
|
||||
globalClient.onConnected();
|
||||
|
@ -712,27 +718,39 @@ class ConnectionCommandHandler {
|
|||
handleNotifyServerEdited(json) {
|
||||
json = json[0];
|
||||
|
||||
let updates: {
|
||||
key: string,
|
||||
value: string
|
||||
}[] = [];
|
||||
for(let key in json) {
|
||||
if(key === "invokerid") continue;
|
||||
if(key === "invokername") continue;
|
||||
if(key === "invokeruid") continue;
|
||||
if(key === "reasonid") continue;
|
||||
|
||||
this.connection._client.channelTree.server.updateProperty(key, json[key]);
|
||||
updates.push({key: key, value: json[key]});
|
||||
}
|
||||
this.connection._client.channelTree.server.updateVariables(...updates);
|
||||
if(this.connection._client.selectInfo.currentSelected == this.connection._client.channelTree.server)
|
||||
this.connection._client.selectInfo.update();
|
||||
}
|
||||
|
||||
handleNotifyServerUpdated(json) {
|
||||
json = json[0];
|
||||
|
||||
let updates: {
|
||||
key: string,
|
||||
value: string
|
||||
}[] = [];
|
||||
for(let key in json) {
|
||||
if(key === "invokerid") continue;
|
||||
if(key === "invokername") continue;
|
||||
if(key === "invokeruid") continue;
|
||||
if(key === "reasonid") continue;
|
||||
|
||||
this.connection._client.channelTree.server.updateProperty(key, json[key]);
|
||||
updates.push({key: key, value: json[key]});
|
||||
}
|
||||
this.connection._client.channelTree.server.updateVariables(...updates);
|
||||
let info = this.connection._client.selectInfo;
|
||||
if(info.currentSelected instanceof ServerEntry)
|
||||
info.update();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
enum LogCategory {
|
||||
CHANNEL,
|
||||
CLIENT,
|
||||
SERVER,
|
||||
PERMISSIONS,
|
||||
GENERAL,
|
||||
NETWORKING
|
||||
|
@ -18,6 +19,7 @@ namespace log {
|
|||
let category_mapping = new Map<number, string>([
|
||||
[LogCategory.CHANNEL, "Channel "],
|
||||
[LogCategory.CLIENT, "Client "],
|
||||
[LogCategory.SERVER, "Server "],
|
||||
[LogCategory.PERMISSIONS, "Permission "],
|
||||
[LogCategory.GENERAL, "General "],
|
||||
[LogCategory.NETWORKING, "Network "]
|
||||
|
|
10
js/proto.ts
10
js/proto.ts
|
@ -7,10 +7,13 @@ interface Array<T> {
|
|||
|
||||
interface JQuery {
|
||||
tmpl(values?: any) : JQuery;
|
||||
render(values?: any) : string;
|
||||
renderTag(values?: any) : JQuery;
|
||||
}
|
||||
|
||||
interface JQueryStatic<TElement extends Node = HTMLElement> {
|
||||
spawn<K extends keyof HTMLElementTagNameMap>(tagName: K): JQuery<HTMLElementTagNameMap[K]>;
|
||||
views: any;
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,12 +54,11 @@ if(typeof ($) !== "undefined") {
|
|||
return $(document.createElement(tagName));
|
||||
}
|
||||
}
|
||||
if(!$.prototype.tmpl) {
|
||||
$.prototype.tmpl = function (values?: any) : JQuery {
|
||||
return this.render(values);
|
||||
if(!$.prototype.renderTag) {
|
||||
$.prototype.renderTag = function (values?: any) : JQuery {
|
||||
return $(this.render(values));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!String.prototype.format) {
|
||||
|
|
|
@ -5,21 +5,21 @@ abstract class InfoManagerBase {
|
|||
private intervals: number[] = [];
|
||||
|
||||
protected resetTimers() {
|
||||
for(let interval of this.intervals)
|
||||
clearInterval(interval);
|
||||
for(let timer of this.timers)
|
||||
clearTimeout(timer);
|
||||
}
|
||||
|
||||
protected resetIntervals() {
|
||||
for(let timer of this.timers)
|
||||
clearTimeout(timer);
|
||||
for(let interval of this.intervals)
|
||||
clearInterval(interval);
|
||||
}
|
||||
|
||||
protected registerTimer(timer: NodeJS.Timer) {
|
||||
this.timers.push(timer);
|
||||
}
|
||||
|
||||
protected registerInterval(interval: number) {
|
||||
this.intervals.push(interval);
|
||||
protected registerInterval<T extends number | NodeJS.Timer>(interval: T) {
|
||||
this.intervals.push(interval as number);
|
||||
}
|
||||
|
||||
abstract available<V>(object: V) : boolean;
|
||||
|
@ -41,9 +41,6 @@ class InfoBar {
|
|||
private current_selected?: ServerEntry | ChannelEntry | ClientEntry;
|
||||
private _htmlTag: JQuery<HTMLElement>;
|
||||
|
||||
private timers: NodeJS.Timer[] = [];
|
||||
private intervals: number[] = [];
|
||||
|
||||
private current_manager: InfoManagerBase = undefined;
|
||||
private managers: InfoManagerBase[] = [];
|
||||
|
||||
|
@ -52,31 +49,30 @@ class InfoBar {
|
|||
this._htmlTag = htmlTag;
|
||||
|
||||
this.managers.push(new ClientInfoManager());
|
||||
}
|
||||
this.managers.push(new ChannelInfoManager());
|
||||
this.managers.push(new ServerInfoManager());
|
||||
|
||||
//TODO music client
|
||||
/*
|
||||
this._htmlTag.append("Im a music bot!");
|
||||
let frame = $("#tmpl_music_frame" + (this.current_selected.properties.music_track_id == 0 ? "_empty" : "")).tmpl({
|
||||
thumbnail: "img/loading_image.svg"
|
||||
}).css("align-self", "center");
|
||||
|
||||
private createInfoTable(infos: any) : JQuery<HTMLElement> {
|
||||
let table = $.spawn("table");
|
||||
if(this.current_selected.properties.music_track_id == 0) {
|
||||
|
||||
for(let key in infos) {
|
||||
console.log("Display info " + key);
|
||||
let entry = $.spawn("tr");
|
||||
entry.append($.spawn("td").addClass("info_key").html(key + ":"));
|
||||
let value = $.spawn("td");
|
||||
console.log(infos[key]);
|
||||
console.log( MessageHelper.formatElement(infos[key]));
|
||||
MessageHelper.formatElement(infos[key]).forEach(e => e.appendTo(value));
|
||||
entry.append(value);
|
||||
table.append(entry);
|
||||
}
|
||||
} else {
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
this._htmlTag.append(frame);
|
||||
*/
|
||||
}
|
||||
|
||||
setCurrentSelected<T extends ServerEntry | ChannelEntry | ClientEntry | undefined>(entry: T) {
|
||||
if(this.current_selected == entry) return;
|
||||
if(this.current_manager) {
|
||||
this.current_manager.finalizeFrame.call(this.current_manager, this.current_selected, this._htmlTag);
|
||||
(this.current_manager as InfoManager<undefined>).finalizeFrame.call(this.current_manager, this.current_selected, this._htmlTag);
|
||||
this.current_manager = null;
|
||||
this.current_selected = null;
|
||||
}
|
||||
|
@ -90,10 +86,9 @@ class InfoBar {
|
|||
}
|
||||
}
|
||||
|
||||
console.log("Got info manager: %o", this.current_manager);
|
||||
if(this.current_manager) {
|
||||
this.current_manager.createFrame.call(this.current_manager, this.current_selected, this._htmlTag);
|
||||
} else this.buildBar(); //FIXME Remove that this is just for now (because not all types are implemented)
|
||||
console.log("Using info manager: %o", this.current_manager);
|
||||
if(this.current_manager)
|
||||
(this.current_manager as InfoManager<undefined>).createFrame.call(this.current_manager, this.current_selected, this._htmlTag);
|
||||
}
|
||||
|
||||
get currentSelected() {
|
||||
|
@ -102,204 +97,7 @@ class InfoBar {
|
|||
|
||||
update(){
|
||||
if(this.current_manager && this.current_selected)
|
||||
this.current_manager.updateFrame.call(this.current_manager, this.current_selected, this._htmlTag);
|
||||
}
|
||||
|
||||
private updateServerTimings() {
|
||||
this._htmlTag.find(".uptime").text(formatDate((this.current_selected as ServerEntry).calculateUptime()));
|
||||
}
|
||||
|
||||
private updateClientTimings() {
|
||||
this._htmlTag.find(".online").text(formatDate((this.current_selected as ClientEntry).calculateOnlineTime()));
|
||||
}
|
||||
|
||||
private buildBar() {
|
||||
this._htmlTag.empty();
|
||||
if(!this.current_selected) return;
|
||||
|
||||
|
||||
if(this.current_selected instanceof ServerEntry) {
|
||||
if(this.current_selected.shouldUpdateProperties()) this.current_selected.updateProperties();
|
||||
|
||||
let version = this.current_selected.properties.virtualserver_version;
|
||||
if(version.startsWith("TeaSpeak ")) version = version.substr("TeaSpeak ".length);
|
||||
|
||||
this._htmlTag.append(this.createInfoTable({
|
||||
"Name": this.current_selected.properties.virtualserver_name,
|
||||
"Address": "unknown",
|
||||
"Type": "TeaSpeak",
|
||||
"Version": version + " on " + this.current_selected.properties.virtualserver_platform,
|
||||
"Uptime": "<a class='uptime'>" + formatDate(this.current_selected.calculateUptime()) + "</a>",
|
||||
"Current Channels": this.current_selected.properties.virtualserver_channelsonline,
|
||||
"Current Clients": this.current_selected.properties.virtualserver_clientsonline,
|
||||
"Current Queries": this.current_selected.properties.virtualserver_queryclientsonline
|
||||
}));
|
||||
|
||||
this._htmlTag.append($.spawn("div").css("height", "100%"));
|
||||
let requestUpdate = $.spawn("button");
|
||||
requestUpdate.css("min-height", "16px");
|
||||
requestUpdate.css("bottom", 0);
|
||||
requestUpdate.text("update info");
|
||||
if(this.current_selected.shouldUpdateProperties())
|
||||
requestUpdate.css("color", "green");
|
||||
else {
|
||||
requestUpdate.attr("disabled", "true");
|
||||
requestUpdate.css("color", "red");
|
||||
}
|
||||
this._htmlTag.append(requestUpdate);
|
||||
|
||||
const _server : ServerEntry = this.current_selected;
|
||||
const _this = this;
|
||||
requestUpdate.click(function () {
|
||||
_server.updateProperties();
|
||||
_this.buildBar();
|
||||
});
|
||||
this.timers.push(setTimeout(function () {
|
||||
requestUpdate.css("color", "green");
|
||||
requestUpdate.removeAttr("disabled");
|
||||
}, _server.nextInfoRequest - new Date().getTime()));
|
||||
this.intervals.push(setInterval(this.updateServerTimings.bind(this),1000));
|
||||
} else if(this.current_selected instanceof ChannelEntry) {
|
||||
let props = this.current_selected.properties;
|
||||
this._htmlTag.append(this.createInfoTable({
|
||||
"Name": this.current_selected.createChatTag(),
|
||||
"Topic": this.current_selected.properties.channel_topic,
|
||||
"Codec": this.current_selected.properties.channel_codec,
|
||||
"Codec Quality": this.current_selected.properties.channel_codec_quality,
|
||||
"Type": ChannelType.normalize(this.current_selected.channelType()),
|
||||
"Current clients": this.current_selected.channelTree.clientsByChannel(this.current_selected).length + " / " + (props.channel_maxclients == -1 ? "Unlimited" : props.channel_maxclients),
|
||||
"Subscription Status": "unknown",
|
||||
"Voice Data Encryption": "unknown"
|
||||
}));
|
||||
} else if(this.current_selected instanceof MusicClientEntry) {
|
||||
this._htmlTag.append("Im a music bot!");
|
||||
let frame = $("#tmpl_music_frame" + (this.current_selected.properties.music_track_id == 0 ? "_empty" : "")).tmpl({
|
||||
thumbnail: "img/loading_image.svg"
|
||||
}).css("align-self", "center");
|
||||
|
||||
if(this.current_selected.properties.music_track_id == 0) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
this._htmlTag.append(frame);
|
||||
//TODO
|
||||
} else if(this.current_selected instanceof ClientEntry) {
|
||||
this.current_selected.updateClientVariables();
|
||||
let version: string = this.current_selected.properties.client_version;
|
||||
if(!version) version = "";
|
||||
let infos = {
|
||||
"Name": this.current_selected.createChatTag(),
|
||||
"Description": this.current_selected.properties.client_description,
|
||||
"Version": MessageHelper.formatMessage("{0} on {1}", $.spawn("a").attr("title", version).text(version.split(" ")[0]), this.current_selected.properties.client_platform),
|
||||
"Online since": $.spawn("a").addClass("online").text(formatDate(this.current_selected.calculateOnlineTime())),
|
||||
"Volume": this.current_selected.audioController.volume * 100 + " %"
|
||||
};
|
||||
if(this.current_selected.properties.client_teaforum_id > 0) {
|
||||
infos["TeaSpeak Account"] = $.spawn("a")
|
||||
.attr("href", "//forum.teaspeak.de/index.php?members/" + this.current_selected.properties.client_teaforum_id)
|
||||
.attr("target", "_blank")
|
||||
.text(this.current_selected.properties.client_teaforum_id);
|
||||
}
|
||||
this._htmlTag.append(this.createInfoTable(infos));
|
||||
|
||||
{
|
||||
let serverGroups = $.spawn("div");
|
||||
serverGroups
|
||||
.css("display", "flex")
|
||||
.css("flex-direction", "column");
|
||||
|
||||
let header = $.spawn("div");
|
||||
header
|
||||
.css("display", "flex")
|
||||
.css("margin-top", "5px")
|
||||
.css("align-items", "center");
|
||||
$.spawn("div").addClass("icon client-permission_server_groups").appendTo(header);
|
||||
$.spawn("div").text("Server groups:").css("margin-left", "3px").css("font-weight", "bold").appendTo(header);
|
||||
header.appendTo(serverGroups);
|
||||
|
||||
for(let groupId of this.current_selected.assignedServerGroupIds()) {
|
||||
let group = this.handle.groups.serverGroup(groupId);
|
||||
if(!group) continue;
|
||||
|
||||
let groupTag = $.spawn("div");
|
||||
groupTag
|
||||
.css("display", "flex")
|
||||
.css("margin-top", "1px")
|
||||
.css("margin-left", "10px")
|
||||
.css("align-items", "center");
|
||||
this.handle.fileManager.icons.generateTag(group.properties.iconid).appendTo(groupTag);
|
||||
$.spawn("div").text(group.name).css("margin-left", "3px").appendTo(groupTag);
|
||||
groupTag.appendTo(serverGroups);
|
||||
}
|
||||
|
||||
this._htmlTag.append(serverGroups);
|
||||
}
|
||||
|
||||
{
|
||||
let channelGroup = $.spawn("div");
|
||||
channelGroup
|
||||
.css("display", "flex")
|
||||
.css("flex-direction", "column")
|
||||
.css("margin-bottom", "20px");
|
||||
|
||||
let header = $.spawn("div");
|
||||
header
|
||||
.css("display", "flex")
|
||||
.css("margin-top", "10px")
|
||||
.css("align-items", "center");
|
||||
$.spawn("div").addClass("icon client-permission_channel").appendTo(header);
|
||||
$.spawn("div").text("Channel group:").css("margin-left", "3px").css("font-weight", "bold").appendTo(header);
|
||||
header.appendTo(channelGroup);
|
||||
|
||||
let group = this.handle.groups.channelGroup(this.current_selected.assignedChannelGroup());
|
||||
if(group) {
|
||||
let groupTag = $.spawn("div");
|
||||
groupTag
|
||||
.css("display", "flex")
|
||||
.css("margin-top", "1px")
|
||||
.css("margin-left", "10px")
|
||||
.css("align-items", "center");
|
||||
this.handle.fileManager.icons.generateTag(group.properties.iconid).appendTo(groupTag);
|
||||
$.spawn("div").text(group.name)
|
||||
.css("margin-left", "3px").appendTo(groupTag);
|
||||
groupTag.appendTo(channelGroup);
|
||||
|
||||
}
|
||||
this._htmlTag.append(channelGroup);
|
||||
}
|
||||
|
||||
{
|
||||
if(this.current_selected.properties.client_flag_avatar.length > 0)
|
||||
this.handle.fileManager.avatars.generateTag(this.current_selected)
|
||||
.css("max-height", "90%")
|
||||
.css("max-width", "100%").appendTo(this._htmlTag);
|
||||
}
|
||||
|
||||
{
|
||||
let spawnTag = (type: string, description: string) : JQuery => {
|
||||
return $.spawn("div").css("display", "inline-flex")
|
||||
.append($.spawn("div").addClass("icon_x32 client-" + type).css("margin-right", "5px"))
|
||||
.append($.spawn("a").text(description).css("align-self", "center"));
|
||||
};
|
||||
|
||||
if(!this.current_selected.properties.client_output_hardware)
|
||||
spawnTag("hardware_output_muted", "Speakers/Headphones disabled").appendTo(this._htmlTag);
|
||||
|
||||
|
||||
if(!this.current_selected.properties.client_input_hardware)
|
||||
spawnTag("hardware_input_muted", "Microphone disabled").appendTo(this._htmlTag);
|
||||
|
||||
if(this.current_selected.properties.client_output_muted)
|
||||
spawnTag("output_muted", "Speakers/Headphones Muted").appendTo(this._htmlTag);
|
||||
|
||||
if(this.current_selected.properties.client_input_muted)
|
||||
spawnTag("input_muted", "Microphone Muted").appendTo(this._htmlTag);
|
||||
}
|
||||
|
||||
this.intervals.push(setInterval(this.updateClientTimings.bind(this),1000));
|
||||
}
|
||||
(this.current_manager as InfoManager<undefined>).updateFrame.call(this.current_manager, this.current_selected, this._htmlTag);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -314,13 +112,10 @@ class ClientInfoManager extends InfoManager<ClientEntry> {
|
|||
}
|
||||
|
||||
updateFrame(client: ClientEntry, html_tag: JQuery<HTMLElement>) {
|
||||
this.resetIntervals();
|
||||
html_tag.empty();
|
||||
|
||||
let properties: any = {};
|
||||
|
||||
let version: string = client.properties.client_version;
|
||||
if(!version) version = "";
|
||||
|
||||
properties["client_name"] = client.createChatTag()[0];
|
||||
properties["client_onlinetime"] = formatDate(client.calculateOnlineTime());
|
||||
properties["sound_volume"] = client.audioController.volume * 100;
|
||||
|
@ -355,9 +150,100 @@ class ClientInfoManager extends InfoManager<ClientEntry> {
|
|||
.text(client.properties.client_teaforum_id);
|
||||
}
|
||||
|
||||
let rendered = $($("#tmpl_selected_client").render([properties]));
|
||||
let rendered = $("#tmpl_selected_client").renderTag([properties]);
|
||||
rendered.find("node").each((index, element) => { $(element).replaceWith(properties[$(element).attr("key")]); });
|
||||
html_tag.append(rendered);
|
||||
console.log(properties);
|
||||
|
||||
this.registerInterval(setInterval(() => {
|
||||
html_tag.find(".update_onlinetime").text(formatDate(client.calculateOnlineTime()));
|
||||
}, 1000));
|
||||
}
|
||||
}
|
||||
|
||||
class ServerInfoManager extends InfoManager<ServerEntry> {
|
||||
createFrame(server: ServerEntry, html_tag: JQuery<HTMLElement>) {
|
||||
if(server.shouldUpdateProperties()) server.updateProperties();
|
||||
this.updateFrame(server, html_tag);
|
||||
}
|
||||
|
||||
updateFrame(server: ServerEntry, html_tag: JQuery<HTMLElement>) {
|
||||
this.resetIntervals();
|
||||
html_tag.empty();
|
||||
let properties: any = {};
|
||||
|
||||
properties["server_name"] = $.spawn("a").text(server.properties.virtualserver_name);
|
||||
properties["server_onlinetime"] = formatDate(server.calculateUptime());
|
||||
properties["server_address"] = server.remote_address.host + ":" + server.remote_address.port;
|
||||
|
||||
for(let key in server.properties)
|
||||
properties["property_" + key] = server.properties[key];
|
||||
|
||||
let rendered = $("#tmpl_selected_server").renderTag([properties]);
|
||||
rendered.find("node").each((index, element) => { $(element).replaceWith(properties[$(element).attr("key")]); });
|
||||
html_tag.append(rendered);
|
||||
|
||||
this.registerInterval(setInterval(() => {
|
||||
html_tag.find(".update_onlinetime").text(formatDate(server.calculateUptime()));
|
||||
}, 1000));
|
||||
|
||||
|
||||
//TODO update button
|
||||
/*
|
||||
let requestUpdate = $.spawn("button");
|
||||
requestUpdate.css("min-height", "16px");
|
||||
requestUpdate.css("bottom", 0);
|
||||
requestUpdate.text("update info");
|
||||
if(this.current_selected.shouldUpdateProperties())
|
||||
requestUpdate.css("color", "green");
|
||||
else {
|
||||
requestUpdate.attr("disabled", "true");
|
||||
requestUpdate.css("color", "red");
|
||||
}
|
||||
this._htmlTag.append(requestUpdate);
|
||||
|
||||
const _server : ServerEntry = this.current_selected;
|
||||
const _this = this;
|
||||
requestUpdate.click(function () {
|
||||
_server.updateProperties();
|
||||
_this.buildBar();
|
||||
});
|
||||
this.timers.push(setTimeout(function () {
|
||||
requestUpdate.css("color", "green");
|
||||
requestUpdate.removeAttr("disabled");
|
||||
}, _server.nextInfoRequest - new Date().getTime()));
|
||||
*/
|
||||
}
|
||||
|
||||
available<V>(object: V): boolean {
|
||||
return typeof object == "object" && object instanceof ServerEntry;
|
||||
}
|
||||
}
|
||||
|
||||
class ChannelInfoManager extends InfoManager<ChannelEntry> {
|
||||
createFrame(channel: ChannelEntry, html_tag: JQuery<HTMLElement>) {
|
||||
this.updateFrame(channel, html_tag);
|
||||
}
|
||||
|
||||
updateFrame(channel: ChannelEntry, html_tag: JQuery<HTMLElement>) {
|
||||
this.resetIntervals();
|
||||
html_tag.empty();
|
||||
let properties: any = {};
|
||||
|
||||
properties["channel_name"] = channel.createChatTag();
|
||||
properties["channel_type"] = ChannelType.normalize(channel.channelType());
|
||||
properties["channel_clients"] = channel.channelTree.clientsByChannel(channel).length;
|
||||
properties["channel_subscribed"] = true; //TODO
|
||||
|
||||
for(let key in channel.properties)
|
||||
properties["property_" + key] = channel.properties[key];
|
||||
|
||||
let rendered = $("#tmpl_selected_channel").renderTag([properties]);
|
||||
rendered.find("node").each((index, element) => { $(element).replaceWith(properties[$(element).attr("key")]); });
|
||||
html_tag.append(rendered);
|
||||
}
|
||||
|
||||
available<V>(object: V): boolean {
|
||||
return typeof object == "object" && object instanceof ChannelEntry;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,27 +1,37 @@
|
|||
/// <reference path="channel.ts" />
|
||||
|
||||
class ServerEntry {
|
||||
channelTree: ChannelTree;
|
||||
properties: any = {
|
||||
virtualserver_name: "",
|
||||
virtualserver_icon_id: 0,
|
||||
virtualserver_version: "unknown",
|
||||
virtualserver_platform: "unknown",
|
||||
virtualserver_unique_identifier: "",
|
||||
class ServerProperties {
|
||||
virtualserver_name: string = "";
|
||||
virtualserver_icon_id: number = 0;
|
||||
virtualserver_version: string = "unknown";
|
||||
virtualserver_platform: string = "unknown";
|
||||
virtualserver_unique_identifier: string = "";
|
||||
|
||||
virtualserver_clientsonline: 0,
|
||||
virtualserver_queryclientsonline: 0,
|
||||
virtualserver_channelsonline: 0,
|
||||
virtualserver_uptime: 0,
|
||||
virtualserver_maxclients: 0
|
||||
};
|
||||
virtualserver_clientsonline: number = 0;
|
||||
virtualserver_queryclientsonline: number = 0;
|
||||
virtualserver_channelsonline: number = 0;
|
||||
virtualserver_uptime: number = 0;
|
||||
virtualserver_maxclients: number = 0
|
||||
}
|
||||
|
||||
interface ServerAddress {
|
||||
host: string;
|
||||
port: number;
|
||||
}
|
||||
|
||||
class ServerEntry {
|
||||
remote_address: ServerAddress;
|
||||
channelTree: ChannelTree;
|
||||
properties: ServerProperties;
|
||||
|
||||
lastInfoRequest: number = 0;
|
||||
nextInfoRequest: number = 0;
|
||||
private _htmlTag: JQuery<HTMLElement>;
|
||||
|
||||
constructor(tree, name) {
|
||||
constructor(tree, name, address: ServerAddress) {
|
||||
this.properties = new ServerProperties();
|
||||
this.channelTree = tree;
|
||||
this.remote_address = address;
|
||||
this.properties.virtualserver_name = name;
|
||||
}
|
||||
|
||||
|
@ -70,15 +80,26 @@ class ServerEntry {
|
|||
);
|
||||
}
|
||||
|
||||
updateProperty(key, value) : void {
|
||||
console.log("Updating property " + key + " => '" + value + "' for the server");
|
||||
this.properties[key] = value;
|
||||
if(key == "virtualserver_name") {
|
||||
this.htmlTag.find(".name").text(value);
|
||||
} else if(key == "virtualserver_icon_id") {
|
||||
if(this.channelTree.client.fileManager && this.channelTree.client.fileManager.icons)
|
||||
this.htmlTag.find(".icon_property").replaceWith(this.channelTree.client.fileManager.icons.generateTag(this.properties.virtualserver_icon_id).addClass("icon_property"));
|
||||
updateVariables(...variables: {key: string, value: string}[]) {
|
||||
let group = log.group(log.LogType.DEBUG, LogCategory.SERVER, "Update properties (%i)", variables.length);
|
||||
|
||||
for(let variable of variables) {
|
||||
if(typeof(this.properties[variable.key]) === "boolean")
|
||||
this.properties[variable.key] = variable.value == "true" || variable.value == "1";
|
||||
else if(typeof (this.properties[variable.key]) === "number")
|
||||
this.properties[variable.key] = parseInt(variable.value);
|
||||
else
|
||||
this.properties[variable.key] = variable.value;
|
||||
group.log("Updating server " + this.properties.virtualserver_name + ". Key " + variable.key + " Value: '" + variable.value + "' (" + typeof (this.properties[variable.key]) + ")");
|
||||
if(variable.key == "virtualserver_name") {
|
||||
this.htmlTag.find(".name").text(variable.value);
|
||||
} else if(variable.key == "virtualserver_icon_id") {
|
||||
if(this.channelTree.client.fileManager && this.channelTree.client.fileManager.icons)
|
||||
this.htmlTag.find(".icon_property").replaceWith(this.channelTree.client.fileManager.icons.generateTag(this.properties.virtualserver_icon_id).addClass("icon_property"));
|
||||
}
|
||||
}
|
||||
|
||||
group.end();
|
||||
}
|
||||
|
||||
updateProperties() {
|
||||
|
@ -92,7 +113,7 @@ class ServerEntry {
|
|||
}
|
||||
|
||||
calculateUptime() : number {
|
||||
if(this.properties.virtualserver_uptime == 0 || this.lastInfoRequest == 0) return Number.parseInt(this.properties.virtualserver_uptime);
|
||||
return Number.parseInt(this.properties.virtualserver_uptime) + (new Date().getTime() - this.lastInfoRequest) / 1000;
|
||||
if(this.properties.virtualserver_uptime == 0 || this.lastInfoRequest == 0) return this.properties.virtualserver_uptime;
|
||||
return this.properties.virtualserver_uptime + (new Date().getTime() - this.lastInfoRequest) / 1000;
|
||||
}
|
||||
}
|
|
@ -48,8 +48,8 @@ class ChannelTree {
|
|||
);
|
||||
}
|
||||
|
||||
initialiseHead(serverName: string) {
|
||||
this.server = new ServerEntry(this, serverName);
|
||||
initialiseHead(serverName: string, address: ServerAddress) {
|
||||
this.server = new ServerEntry(this, serverName, address);
|
||||
this.server.htmlTag.appendTo(this.htmlTree);
|
||||
this.server.initializeListener();
|
||||
}
|
||||
|
|
175
templates.html
175
templates.html
|
@ -303,35 +303,55 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<!--
|
||||
let spawnTag = (type: string, description: string) : JQuery => {
|
||||
return $.spawn("div").css("display", "inline-flex")
|
||||
.append($.spawn("div").addClass("icon_x32 client-" + type).css("margin-right", "5px"))
|
||||
.append($.spawn("a").text(description).css("align-self", "center"));
|
||||
};
|
||||
|
||||
if(!this.current_selected.properties.client_output_hardware)
|
||||
spawnTag("hardware_output_muted", "Speakers/Headphones disabled").appendTo(this._htmlTag);
|
||||
|
||||
|
||||
if(!this.current_selected.properties.client_input_hardware)
|
||||
spawnTag("hardware_input_muted", "Microphone disabled").appendTo(this._htmlTag);
|
||||
|
||||
if(this.current_selected.properties.client_output_muted)
|
||||
spawnTag("output_muted", "Speakers/Headphones Muted").appendTo(this._htmlTag);
|
||||
|
||||
if(this.current_selected.properties.client_input_muted)
|
||||
spawnTag("input_muted", "Microphone Muted").appendTo(this._htmlTag);
|
||||
-->
|
||||
<script id="tmpl_selected_client" type="text/x-jsrender">
|
||||
<table>
|
||||
<table class="select_info_table">
|
||||
<tr>
|
||||
<td>Name:</td>
|
||||
<td class="info_key"><node key="client_name"/></td>
|
||||
<td><node key="client_name"/></td>
|
||||
</tr>
|
||||
{{if property_client_description.length > 0}}
|
||||
<tr>
|
||||
<td>Description:</td>
|
||||
<td class="info_key">{{>property_client_description}}</td>
|
||||
<td>{{>property_client_description}}</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
<tr>
|
||||
<td>Version:</td>
|
||||
<td class="info_key"><a title="{{:property_client_version}}">{{*: data.property_client_version.split(" ")[0]; }}</a> on {{:property_client_platform}}</td>
|
||||
<td><a title="{{>property_client_version}}">{{*: data.property_client_version.split(" ")[0]; }}</a> on {{>property_client_platform}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Online since:</td>
|
||||
<td class="info_key update_onlinetime">{{:client_onlinetime}}</td>
|
||||
<td class="update_onlinetime">{{:client_onlinetime}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Volume:</td>
|
||||
<td class="info_key">{{:sound_volume}}%</td>
|
||||
<td>{{:sound_volume}}%</td>
|
||||
</tr>
|
||||
|
||||
{{if client_teaforum_id > 0}}
|
||||
<tr>
|
||||
<td>TeaSpeak Account:</td>
|
||||
<td class="info_key"><a href="//forum.teaspeak.de/index.php?members/{{:property_client_teaforum_id}}" target="_blank">{{:property_client_teaforum_name}}</a></td>
|
||||
<td><a href="//forum.teaspeak.de/index.php?members/{{:property_client_teaforum_id}}" target="_blank">{{>property_client_teaforum_name}}</a></td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
</table>
|
||||
|
@ -362,6 +382,147 @@
|
|||
<div style="margin-left: 3px">{{*: data["group_" + data.group_channel + "_name"]}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Costume tags/icons -->
|
||||
<!-- Speakers/Headphones disabled -->
|
||||
{{if !property_client_output_hardware}}
|
||||
<div style="display: inline-flex">
|
||||
<div class="icon_x32 client-hardware_output_muted" style="margin-right: 5px"></div>
|
||||
<a style="align-self: center">Speakers/Headphones disabled</a>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<!-- Microphone disabled -->
|
||||
{{if !property_client_input_hardware}}
|
||||
<div style="display: inline-flex">
|
||||
<div class="icon_x32 client-hardware_input_muted" style="margin-right: 5px"></div>
|
||||
<a style="align-self: center">Microphone disabled</a>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<!-- Speakers/Headphones Muted -->
|
||||
{{if property_client_output_muted}}
|
||||
<div style="display: inline-flex">
|
||||
<div class="icon_x32 client-output_muted" style="margin-right: 5px"></div>
|
||||
<a style="align-self: center">Speakers/Headphones Muted</a>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<!-- Microphone Muted -->
|
||||
{{if property_client_input_muted}}
|
||||
<div style="display: inline-flex">
|
||||
<div class="icon_x32 client-input_muted" style="margin-right: 5px"></div>
|
||||
<a style="align-self: center">Microphone Muted</a>
|
||||
</div>
|
||||
{{/if}}
|
||||
</script>
|
||||
|
||||
<!--
|
||||
let version = this.current_selected.properties.virtualserver_version;
|
||||
if(version.startsWith("TeaSpeak ")) version = version.substr("TeaSpeak ".length);
|
||||
|
||||
this._htmlTag.append(this.createInfoTable({
|
||||
"Name": this.current_selected.properties.virtualserver_name,
|
||||
"Address": "unknown",
|
||||
"Type": "TeaSpeak",
|
||||
"Version": version + " on " + this.current_selected.properties.virtualserver_platform,
|
||||
"Uptime": "<a class='uptime'>" + formatDate(this.current_selected.calculateUptime()) + "</a>",
|
||||
"Current Channels": this.current_selected.properties.virtualserver_channelsonline,
|
||||
"Current Clients": this.current_selected.properties.virtualserver_clientsonline,
|
||||
"Current Queries": this.current_selected.properties.virtualserver_queryclientsonline
|
||||
}));
|
||||
-->
|
||||
<script id="tmpl_selected_server" type="text/x-jsrender">
|
||||
<table class="select_info_table">
|
||||
<tr>
|
||||
<td>Name:</td>
|
||||
<td><node key="server_name"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Address:</td>
|
||||
<td>{{>server_address}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Type:</td>
|
||||
<td>TeaSpeak</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Version:</td>
|
||||
<td><a title="{{>property_virtualserver_version}}">{{*: data.property_virtualserver_version.split(" ")[0]; }}</a> on {{>property_virtualserver_platform}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Uptime:</td>
|
||||
<td class="update_onlinetime">{{:server_onlinetime}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Current Channels:</td>
|
||||
<td>{{:property_virtualserver_channelsonline}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Current Clients:</td>
|
||||
<td>{{:property_virtualserver_clientsonline}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Current Queries:</td>
|
||||
<td>{{:property_virtualserver_queryclientsonline}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</script>
|
||||
|
||||
<script id="tmpl_selected_channel" type="text/x-jsrender">
|
||||
<table class="select_info_table">
|
||||
<tr>
|
||||
<td>Name:</td>
|
||||
<td><node key="channel_name"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Topic:</td>
|
||||
<td>{{>property_channel_topic}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Codec:</td>
|
||||
<td>{{>property_channel_codec}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Codec Quality:</td>
|
||||
<td>{{>property_channel_codec_quality}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Type:</td>
|
||||
<td>{{>channel_type}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Current clients:</td>
|
||||
<td>
|
||||
{{>channel_clients}} /
|
||||
{{if property_channel_maxclients == -1}}
|
||||
Unlimited
|
||||
{{else}}
|
||||
{{>property_channel_maxclients}}
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Subscription Status:</td>
|
||||
<td>
|
||||
{{if channel_subscribed}}
|
||||
Subscribed
|
||||
{{else}}
|
||||
Unsubscribed
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Voice Data Encryption:</td>
|
||||
<td>
|
||||
{{if property_channel_codec_is_unencrypted}}
|
||||
Unencrypted
|
||||
{{else}}
|
||||
Encrypted
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue