Start making the select info frame more change/designable
parent
8ca6fe7e01
commit
6bb0179958
|
@ -1,9 +1,10 @@
|
|||
/// <reference path="log.ts" />
|
||||
/// <reference path="voice/AudioController.ts" />
|
||||
/// <reference path="proto.ts" />
|
||||
/// <reference path="ui/view.ts" />
|
||||
/// <reference path="connection.ts" />
|
||||
/// <reference path="settings.ts" />
|
||||
/// <reference path="InfoBar.ts" />
|
||||
/// <reference path="ui/frames/SelectedItemInfo.ts" />
|
||||
/// <reference path="FileManager.ts" />
|
||||
/// <reference path="permission/PermissionManager.ts" />
|
||||
/// <reference path="permission/GroupManager.ts" />
|
||||
|
@ -194,7 +195,7 @@ class TSClient {
|
|||
break;
|
||||
}
|
||||
|
||||
this.selectInfo.currentSelected = null;
|
||||
this.selectInfo.setCurrentSelected(null);
|
||||
this.channelTree.reset();
|
||||
this.voiceConnection.dropSession();
|
||||
if(this.serverConnection) this.serverConnection.disconnect();
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/// <reference path="ui/channel.ts" />
|
||||
/// <reference path="client.ts" />
|
||||
/// <reference path="ui/MusicClient.ts" />
|
||||
|
||||
class CommandResult {
|
||||
success: boolean;
|
||||
|
|
14
js/load.ts
14
js/load.ts
|
@ -146,12 +146,13 @@ function loadDebug() {
|
|||
"js/ui/modal/ModalConnect.js",
|
||||
"js/ui/modal/ModalChangeVolume.js",
|
||||
"js/ui/modal/ModalBanClient.js",
|
||||
"js/ui/modal/ModalYesNo.js",
|
||||
|
||||
"js/ui/channel.js",
|
||||
"js/ui/client.js",
|
||||
"js/ui/server.js",
|
||||
"js/ui/view.js",
|
||||
"js/ui/ControlBar.js",
|
||||
"js/ui/MusicClient.js",
|
||||
|
||||
//Load permissions
|
||||
"js/permission/PermissionManager.js",
|
||||
|
@ -175,7 +176,7 @@ function loadDebug() {
|
|||
"js/FileManager.js",
|
||||
"js/client.js",
|
||||
"js/chat.js",
|
||||
"js/InfoBar.js",
|
||||
"js/ui/frames/SelectedItemInfo.js",
|
||||
"js/Identity.js"
|
||||
])).then(() => {
|
||||
awaitLoad(loadScripts(["js/main.js"])).then(() => {
|
||||
|
@ -188,11 +189,14 @@ function loadDebug() {
|
|||
function awaitLoad(promises: {path: string, promise: Promise<Boolean>}[]) : Promise<Boolean> {
|
||||
return new Promise<Boolean>((resolve, reject) => {
|
||||
let awaiting = promises.length;
|
||||
let success = true;
|
||||
|
||||
for(let entry of promises) {
|
||||
entry.promise.then(() => {
|
||||
awaiting--;
|
||||
if(awaiting == 0) resolve();
|
||||
}).catch(error => {
|
||||
success = false;
|
||||
if(error instanceof TypeError) {
|
||||
console.error(error);
|
||||
let name = (error as any).fileName + "@" + (error as any).lineNumber + ":" + (error as any).columnNumber;
|
||||
|
@ -236,6 +240,9 @@ function loadTemplates() {
|
|||
let root = document.getElementById("templates");
|
||||
while(tags.length > 0)
|
||||
root.appendChild(tags.item(0));
|
||||
root = document.getElementById("script");
|
||||
while(tags.length > 0)
|
||||
root.appendChild(tags.item(0));
|
||||
}).catch(error => {
|
||||
console.error("Could not load templates!");
|
||||
console.log(error);
|
||||
|
@ -254,7 +261,8 @@ function loadSide() {
|
|||
["vendor/jquery/jquery.min.js", /*"https://code.jquery.com/jquery-latest.min.js"*/],
|
||||
["https://webrtc.github.io/adapter/adapter-latest.js"]
|
||||
])).then(() => awaitLoad(loadScripts([
|
||||
["https://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"]
|
||||
//["https://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"]
|
||||
["vendor/jsrender/jsrender.min.js"]
|
||||
]))).then(() => {
|
||||
//Load the teaweb scripts
|
||||
loadScript("js/proto.js").then(loadDebug).catch(loadRelease);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
/// <reference path="ui/modal/ModalConnect.ts" />
|
||||
/// <reference path="ui/modal/ModalCreateChannel.ts" />
|
||||
/// <reference path="ui/modal/ModalBanClient.ts" />
|
||||
/// <reference path="ui/modal/ModalYesNo.ts" />
|
||||
/// <reference path="codec/CodecWrapper.ts" />
|
||||
/// <reference path="settings.ts" />
|
||||
/// <reference path="log.ts" />
|
||||
|
@ -16,6 +17,7 @@ let chat: ChatBox;
|
|||
let forumIdentity: TeaForumIdentity;
|
||||
|
||||
function main() {
|
||||
$.views.settings.allowCode(true);
|
||||
//localhost:63343/Web-Client/index.php?disableUnloadDialog=1&default_connect_type=forum&default_connect_url=localhost
|
||||
//disableUnloadDialog=1&default_connect_type=forum&default_connect_url=localhost&loader_ignore_age=1
|
||||
AudioController.initializeAudioController();
|
||||
|
@ -73,6 +75,11 @@ function main() {
|
|||
*/
|
||||
|
||||
//Modals.spawnSettingsModal();
|
||||
/*
|
||||
Modals.spawnYesNo("Are your sure?", "Do you really want to exit?", flag => {
|
||||
console.log("Response: " + flag);
|
||||
})
|
||||
*/
|
||||
}
|
||||
|
||||
app.loadedListener.push(() => main());
|
|
@ -13,6 +13,7 @@ interface JQueryStatic<TElement extends Node = HTMLElement> {
|
|||
spawn<K extends keyof HTMLElementTagNameMap>(tagName: K): JQuery<HTMLElementTagNameMap[K]>;
|
||||
}
|
||||
|
||||
|
||||
interface String {
|
||||
format(...fmt): string;
|
||||
format(arguments: string[]): string;
|
||||
|
@ -50,6 +51,12 @@ if(typeof ($) !== "undefined") {
|
|||
return $(document.createElement(tagName));
|
||||
}
|
||||
}
|
||||
if(!$.prototype.tmpl) {
|
||||
$.prototype.tmpl = function (values?: any) : JQuery {
|
||||
return this.render(values);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!String.prototype.format) {
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
/// <reference path="client.ts" />
|
||||
|
||||
class MusicClientProperties extends ClientProperties {
|
||||
music_volume: number = 0;
|
||||
music_track_id: number = 0;
|
||||
}
|
||||
|
||||
class MusicClientEntry extends ClientEntry {
|
||||
constructor(clientId, clientName) {
|
||||
super(clientId, clientName, new MusicClientProperties());
|
||||
}
|
||||
|
||||
get properties() : MusicClientProperties {
|
||||
return this._properties as MusicClientProperties;
|
||||
}
|
||||
|
||||
showContextMenu(x: number, y: number, on_close: () => void = undefined): void {
|
||||
spawnMenu(x, y,
|
||||
{
|
||||
name: "<b>Change bot name</b>",
|
||||
icon: "client-change_nickname",
|
||||
disabled: true,
|
||||
callback: () => {},
|
||||
type: MenuEntryType.ENTRY
|
||||
}, {
|
||||
name: "Change bot description",
|
||||
icon: "client-edit",
|
||||
disabled: true,
|
||||
callback: () => {},
|
||||
type: MenuEntryType.ENTRY
|
||||
}, {
|
||||
name: "Open music panel",
|
||||
icon: "client-edit",
|
||||
disabled: true,
|
||||
callback: () => {},
|
||||
type: MenuEntryType.ENTRY
|
||||
},
|
||||
MenuEntry.HR(),
|
||||
{
|
||||
name: "Delete bot",
|
||||
icon: "client-delete",
|
||||
disabled: true,
|
||||
callback: () => {},
|
||||
type: MenuEntryType.ENTRY
|
||||
},
|
||||
MenuEntry.CLOSE(on_close)
|
||||
);
|
||||
}
|
||||
|
||||
initializeListener(): void {
|
||||
super.initializeListener();
|
||||
}
|
||||
}
|
|
@ -544,4 +544,58 @@ class LocalClientEntry extends ClientEntry {
|
|||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class MusicClientProperties extends ClientProperties {
|
||||
music_volume: number = 0;
|
||||
music_track_id: number = 0;
|
||||
}
|
||||
|
||||
class MusicClientEntry extends ClientEntry {
|
||||
constructor(clientId, clientName) {
|
||||
super(clientId, clientName, new MusicClientProperties());
|
||||
}
|
||||
|
||||
get properties() : MusicClientProperties {
|
||||
return this._properties as MusicClientProperties;
|
||||
}
|
||||
|
||||
showContextMenu(x: number, y: number, on_close: () => void = undefined): void {
|
||||
spawnMenu(x, y,
|
||||
{
|
||||
name: "<b>Change bot name</b>",
|
||||
icon: "client-change_nickname",
|
||||
disabled: true,
|
||||
callback: () => {},
|
||||
type: MenuEntryType.ENTRY
|
||||
}, {
|
||||
name: "Change bot description",
|
||||
icon: "client-edit",
|
||||
disabled: true,
|
||||
callback: () => {},
|
||||
type: MenuEntryType.ENTRY
|
||||
}, {
|
||||
name: "Open music panel",
|
||||
icon: "client-edit",
|
||||
disabled: true,
|
||||
callback: () => {},
|
||||
type: MenuEntryType.ENTRY
|
||||
},
|
||||
MenuEntry.HR(),
|
||||
{
|
||||
name: "Delete bot",
|
||||
icon: "client-delete",
|
||||
disabled: true,
|
||||
callback: () => {
|
||||
//TODO
|
||||
},
|
||||
type: MenuEntryType.ENTRY
|
||||
},
|
||||
MenuEntry.CLOSE(on_close)
|
||||
);
|
||||
}
|
||||
|
||||
initializeListener(): void {
|
||||
super.initializeListener();
|
||||
}
|
||||
}
|
|
@ -1,17 +1,57 @@
|
|||
/// <reference path="client.ts" />
|
||||
/// <reference path="../../client.ts" />
|
||||
|
||||
abstract class InfoManagerBase {
|
||||
private timers: NodeJS.Timer[] = [];
|
||||
private intervals: number[] = [];
|
||||
|
||||
protected resetTimers() {
|
||||
for(let interval of this.intervals)
|
||||
clearInterval(interval);
|
||||
}
|
||||
|
||||
protected resetIntervals() {
|
||||
for(let timer of this.timers)
|
||||
clearTimeout(timer);
|
||||
}
|
||||
|
||||
protected registerTimer(timer: NodeJS.Timer) {
|
||||
this.timers.push(timer);
|
||||
}
|
||||
|
||||
protected registerInterval(interval: number) {
|
||||
this.intervals.push(interval);
|
||||
}
|
||||
|
||||
abstract available<V>(object: V) : boolean;
|
||||
}
|
||||
|
||||
abstract class InfoManager<T> extends InfoManagerBase {
|
||||
abstract createFrame(object: T, html_tag: JQuery<HTMLElement>);
|
||||
abstract updateFrame(object: T, html_tag: JQuery<HTMLElement>);
|
||||
|
||||
finalizeFrame(object: T, frame: JQuery<HTMLElement>) {
|
||||
this.resetIntervals();
|
||||
this.resetTimers();
|
||||
}
|
||||
}
|
||||
|
||||
class InfoBar {
|
||||
readonly handle: TSClient;
|
||||
|
||||
private _currentSelected?: ServerEntry | ChannelEntry | ClientEntry;
|
||||
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[] = [];
|
||||
|
||||
constructor(client: TSClient, htmlTag: JQuery<HTMLElement>) {
|
||||
this.handle = client;
|
||||
this._htmlTag = htmlTag;
|
||||
|
||||
this.managers.push(new ClientInfoManager());
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,54 +73,66 @@ class InfoBar {
|
|||
return table;
|
||||
}
|
||||
|
||||
set currentSelected(entry: ServerEntry | ChannelEntry | ClientEntry) {
|
||||
if(this._currentSelected == entry) return;
|
||||
this._currentSelected = entry;
|
||||
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 = null;
|
||||
this.current_selected = null;
|
||||
}
|
||||
this._htmlTag.empty();
|
||||
|
||||
this.buildBar();
|
||||
this.current_selected = entry;
|
||||
for(let manager of this.managers) {
|
||||
if(manager.available(this.current_selected)) {
|
||||
this.current_manager = manager;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
get currentSelected() : ServerEntry | ChannelEntry | ClientEntry | undefined {
|
||||
return this._currentSelected;
|
||||
get currentSelected() {
|
||||
return this.current_selected;
|
||||
}
|
||||
|
||||
update(){
|
||||
this.buildBar();
|
||||
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._currentSelected as ServerEntry).calculateUptime()));
|
||||
this._htmlTag.find(".uptime").text(formatDate((this.current_selected as ServerEntry).calculateUptime()));
|
||||
}
|
||||
|
||||
private updateClientTimings() {
|
||||
this._htmlTag.find(".online").text(formatDate((this._currentSelected as ClientEntry).calculateOnlineTime()));
|
||||
this._htmlTag.find(".online").text(formatDate((this.current_selected as ClientEntry).calculateOnlineTime()));
|
||||
}
|
||||
|
||||
private buildBar() {
|
||||
this._htmlTag.empty();
|
||||
if(!this._currentSelected) return;
|
||||
if(!this.current_selected) return;
|
||||
|
||||
for(let timer of this.timers)
|
||||
clearTimeout(timer);
|
||||
for(let timer of this.intervals)
|
||||
clearInterval(timer);
|
||||
|
||||
if(this._currentSelected instanceof ServerEntry) {
|
||||
if(this._currentSelected.shouldUpdateProperties()) this._currentSelected.updateProperties();
|
||||
if(this.current_selected instanceof ServerEntry) {
|
||||
if(this.current_selected.shouldUpdateProperties()) this.current_selected.updateProperties();
|
||||
|
||||
let version = this._currentSelected.properties.virtualserver_version;
|
||||
let version = this.current_selected.properties.virtualserver_version;
|
||||
if(version.startsWith("TeaSpeak ")) version = version.substr("TeaSpeak ".length);
|
||||
|
||||
this._htmlTag.append(this.createInfoTable({
|
||||
"Name": this._currentSelected.properties.virtualserver_name,
|
||||
"Name": this.current_selected.properties.virtualserver_name,
|
||||
"Address": "unknown",
|
||||
"Type": "TeaSpeak",
|
||||
"Version": version + " on " + this._currentSelected.properties.virtualserver_platform,
|
||||
"Uptime": "<a class='uptime'>" + formatDate(this._currentSelected.calculateUptime()) + "</a>",
|
||||
"Current Channels": this._currentSelected.properties.virtualserver_channelsonline,
|
||||
"Current Clients": this._currentSelected.properties.virtualserver_clientsonline,
|
||||
"Current Queries": this._currentSelected.properties.virtualserver_queryclientsonline
|
||||
"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%"));
|
||||
|
@ -88,7 +140,7 @@ class InfoBar {
|
|||
requestUpdate.css("min-height", "16px");
|
||||
requestUpdate.css("bottom", 0);
|
||||
requestUpdate.text("update info");
|
||||
if(this._currentSelected.shouldUpdateProperties())
|
||||
if(this.current_selected.shouldUpdateProperties())
|
||||
requestUpdate.css("color", "green");
|
||||
else {
|
||||
requestUpdate.attr("disabled", "true");
|
||||
|
@ -96,7 +148,7 @@ class InfoBar {
|
|||
}
|
||||
this._htmlTag.append(requestUpdate);
|
||||
|
||||
const _server : ServerEntry = this._currentSelected;
|
||||
const _server : ServerEntry = this.current_selected;
|
||||
const _this = this;
|
||||
requestUpdate.click(function () {
|
||||
_server.updateProperties();
|
||||
|
@ -107,25 +159,25 @@ class InfoBar {
|
|||
requestUpdate.removeAttr("disabled");
|
||||
}, _server.nextInfoRequest - new Date().getTime()));
|
||||
this.intervals.push(setInterval(this.updateServerTimings.bind(this),1000));
|
||||
} else if(this._currentSelected instanceof ChannelEntry) {
|
||||
let props = this._currentSelected.properties;
|
||||
} else if(this.current_selected instanceof ChannelEntry) {
|
||||
let props = this.current_selected.properties;
|
||||
this._htmlTag.append(this.createInfoTable({
|
||||
"Name": this._currentSelected.createChatTag(),
|
||||
"Topic": this._currentSelected.properties.channel_topic,
|
||||
"Codec": this._currentSelected.properties.channel_codec,
|
||||
"Codec Quality": this._currentSelected.properties.channel_codec_quality,
|
||||
"Type": ChannelType.normalize(this._currentSelected.channelType()),
|
||||
"Current clients": this._currentSelected.channelTree.clientsByChannel(this._currentSelected).length + " / " + (props.channel_maxclients == -1 ? "Unlimited" : props.channel_maxclients),
|
||||
"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._currentSelected instanceof MusicClientEntry) {
|
||||
} else if(this.current_selected instanceof MusicClientEntry) {
|
||||
this._htmlTag.append("Im a music bot!");
|
||||
let frame = $("#tmpl_music_frame" + (this._currentSelected.properties.music_track_id == 0 ? "_empty" : "")).tmpl({
|
||||
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._currentSelected.properties.music_track_id == 0) {
|
||||
if(this.current_selected.properties.music_track_id == 0) {
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -133,21 +185,22 @@ class InfoBar {
|
|||
|
||||
this._htmlTag.append(frame);
|
||||
//TODO
|
||||
} else if(this._currentSelected instanceof ClientEntry) { this._currentSelected.updateClientVariables();
|
||||
let version: string = this._currentSelected.properties.client_version;
|
||||
} 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._currentSelected.createChatTag(),
|
||||
"Description": this._currentSelected.properties.client_description,
|
||||
"Version": MessageHelper.formatMessage("{0} on {1}", $.spawn("a").attr("title", version).text(version.split(" ")[0]), this._currentSelected.properties.client_platform),
|
||||
"Online since": $.spawn("a").addClass("online").text(formatDate(this._currentSelected.calculateOnlineTime())),
|
||||
"Volume": this._currentSelected.audioController.volume * 100 + " %"
|
||||
"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._currentSelected.properties.client_teaforum_id > 0) {
|
||||
if(this.current_selected.properties.client_teaforum_id > 0) {
|
||||
infos["TeaSpeak Account"] = $.spawn("a")
|
||||
.attr("href", "//forum.teaspeak.de/index.php?members/" + this._currentSelected.properties.client_teaforum_id)
|
||||
.attr("href", "//forum.teaspeak.de/index.php?members/" + this.current_selected.properties.client_teaforum_id)
|
||||
.attr("target", "_blank")
|
||||
.text(this._currentSelected.properties.client_teaforum_id);
|
||||
.text(this.current_selected.properties.client_teaforum_id);
|
||||
}
|
||||
this._htmlTag.append(this.createInfoTable(infos));
|
||||
|
||||
|
@ -166,7 +219,7 @@ class InfoBar {
|
|||
$.spawn("div").text("Server groups:").css("margin-left", "3px").css("font-weight", "bold").appendTo(header);
|
||||
header.appendTo(serverGroups);
|
||||
|
||||
for(let groupId of this._currentSelected.assignedServerGroupIds()) {
|
||||
for(let groupId of this.current_selected.assignedServerGroupIds()) {
|
||||
let group = this.handle.groups.serverGroup(groupId);
|
||||
if(!group) continue;
|
||||
|
||||
|
@ -200,7 +253,7 @@ class InfoBar {
|
|||
$.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._currentSelected.assignedChannelGroup());
|
||||
let group = this.handle.groups.channelGroup(this.current_selected.assignedChannelGroup());
|
||||
if(group) {
|
||||
let groupTag = $.spawn("div");
|
||||
groupTag
|
||||
|
@ -218,8 +271,8 @@ class InfoBar {
|
|||
}
|
||||
|
||||
{
|
||||
if(this._currentSelected.properties.client_flag_avatar.length > 0)
|
||||
this.handle.fileManager.avatars.generateTag(this._currentSelected)
|
||||
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);
|
||||
}
|
||||
|
@ -231,21 +284,80 @@ class InfoBar {
|
|||
.append($.spawn("a").text(description).css("align-self", "center"));
|
||||
};
|
||||
|
||||
if(!this._currentSelected.properties.client_output_hardware)
|
||||
if(!this.current_selected.properties.client_output_hardware)
|
||||
spawnTag("hardware_output_muted", "Speakers/Headphones disabled").appendTo(this._htmlTag);
|
||||
|
||||
|
||||
if(!this._currentSelected.properties.client_input_hardware)
|
||||
if(!this.current_selected.properties.client_input_hardware)
|
||||
spawnTag("hardware_input_muted", "Microphone disabled").appendTo(this._htmlTag);
|
||||
|
||||
if(this._currentSelected.properties.client_output_muted)
|
||||
if(this.current_selected.properties.client_output_muted)
|
||||
spawnTag("output_muted", "Speakers/Headphones Muted").appendTo(this._htmlTag);
|
||||
|
||||
if(this._currentSelected.properties.client_input_muted)
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ClientInfoManager extends InfoManager<ClientEntry> {
|
||||
available<V>(object: V): boolean {
|
||||
return typeof object == "object" && object instanceof ClientEntry;
|
||||
}
|
||||
|
||||
createFrame(client: ClientEntry, html_tag: JQuery<HTMLElement>) {
|
||||
client.updateClientVariables();
|
||||
this.updateFrame(client, html_tag);
|
||||
}
|
||||
|
||||
updateFrame(client: ClientEntry, html_tag: JQuery<HTMLElement>) {
|
||||
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;
|
||||
|
||||
properties["group_server"] = [];
|
||||
for(let groupId of client.assignedServerGroupIds()) {
|
||||
let group = client.channelTree.client.groups.serverGroup(groupId);
|
||||
if(!group) continue;
|
||||
|
||||
let group_property = {};
|
||||
|
||||
group_property["group_id"] = groupId;
|
||||
group_property["group_name"] = group.name;
|
||||
properties["group_server"].push(group_property);
|
||||
properties["group_" + groupId + "_icon"] = client.channelTree.client.fileManager.icons.generateTag(group.properties.iconid);
|
||||
}
|
||||
|
||||
let group = client.channelTree.client.groups.channelGroup(client.assignedChannelGroup());
|
||||
if(group) {
|
||||
properties["group_channel"] = group.id;
|
||||
properties["group_" + group.id + "_name"] = group.name;
|
||||
properties["group_" + group.id + "_icon"] = client.channelTree.client.fileManager.icons.generateTag(group.properties.iconid);
|
||||
}
|
||||
|
||||
for(let key in client.properties)
|
||||
properties["property_" + key] = client.properties[key];
|
||||
|
||||
if(client.properties.client_teaforum_id > 0) {
|
||||
properties["teaspeak_forum"] = $.spawn("a")
|
||||
.attr("href", "//forum.teaspeak.de/index.php?members/" + client.properties.client_teaforum_id)
|
||||
.attr("target", "_blank")
|
||||
.text(client.properties.client_teaforum_id);
|
||||
}
|
||||
|
||||
let rendered = $($("#tmpl_selected_client").render([properties]));
|
||||
rendered.find("node").each((index, element) => { $(element).replaceWith(properties[$(element).attr("key")]); });
|
||||
html_tag.append(rendered);
|
||||
console.log(properties);
|
||||
}
|
||||
}
|
|
@ -12,7 +12,6 @@ namespace Modals {
|
|||
let tag = $("#tmpl_connect").contents().clone();
|
||||
|
||||
let updateFields = function () {
|
||||
console.log("UPDATE!");
|
||||
if(connectIdentity) tag.find(".connect_nickname").attr("placeholder", connectIdentity.name());
|
||||
else tag.find(".connect_nickname").attr("");
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/// <reference path="../../utils/modal.ts" />
|
||||
|
||||
namespace Modals {
|
||||
export function spawnYesNo(header: BodyCreator, body: BodyCreator, callback: (_: boolean) => any) {
|
||||
let modal;
|
||||
modal = createModal({
|
||||
header: header,
|
||||
body: body,
|
||||
footer: () => {
|
||||
let footer = $.spawn("div");
|
||||
footer.addClass("modal-button-group");
|
||||
footer.css("margin-top", "5px");
|
||||
footer.css("margin-bottom", "5px");
|
||||
footer.css("text-align", "right");
|
||||
|
||||
let button_yes = $.spawn("button");
|
||||
button_yes.text("Yes");
|
||||
button_yes.click(() => {
|
||||
modal.close();
|
||||
callback(true);
|
||||
});
|
||||
footer.append(button_yes);
|
||||
|
||||
let button_no = $.spawn("button");
|
||||
button_no.text("No");
|
||||
button_no.click(() => {
|
||||
modal.close();
|
||||
callback(false);
|
||||
});
|
||||
footer.append(button_no);
|
||||
|
||||
return footer;
|
||||
},
|
||||
width: 750
|
||||
});
|
||||
modal.open();
|
||||
}
|
||||
}
|
|
@ -222,7 +222,7 @@ class ChannelTree {
|
|||
(entry as ClientEntry).tag.addClass("selected");
|
||||
else if(entry instanceof ServerEntry)
|
||||
(entry as ServerEntry).htmlTag.addClass("selected");
|
||||
this.client.selectInfo.currentSelected = entry;
|
||||
this.client.selectInfo.setCurrentSelected(entry);
|
||||
}
|
||||
|
||||
clientsByGroup(group: Group) : ClientEntry[] {
|
||||
|
|
|
@ -173,7 +173,6 @@ class VoiceRecorder {
|
|||
if(this.microphoneStream) this.microphoneStream.disconnect();
|
||||
this.microphoneStream = undefined;
|
||||
|
||||
/*
|
||||
if(this.mediaStream) {
|
||||
if(this.mediaStream.stop)
|
||||
this.mediaStream.stop();
|
||||
|
@ -182,7 +181,6 @@ class VoiceRecorder {
|
|||
value.stop();
|
||||
});
|
||||
}
|
||||
*/
|
||||
this.mediaStream = undefined;
|
||||
}
|
||||
|
||||
|
@ -195,11 +193,6 @@ class VoiceRecorder {
|
|||
this.mediaStream = stream;
|
||||
this.microphoneStream = this.audioContext.createMediaStreamSource(stream);
|
||||
this.microphoneStream.connect(this.processor);
|
||||
chat.serverChat().appendMessage("Mic channels " + this.microphoneStream.channelCount);
|
||||
chat.serverChat().appendMessage("Mic channel mode " + this.microphoneStream.channelCountMode);
|
||||
chat.serverChat().appendMessage("Max channel count " + this.audioContext.destination.maxChannelCount);
|
||||
chat.serverChat().appendMessage("Sample rate " + this.audioContext.sampleRate);
|
||||
chat.serverChat().appendMessage("Stream ID " + stream.id);
|
||||
this.vadHandler.initialiseNewStream(oldStream, this.microphoneStream);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -302,5 +302,66 @@
|
|||
<a>Not playing any music</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script id="tmpl_selected_client" type="text/x-jsrender">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Name:</td>
|
||||
<td class="info_key"><node key="client_name"/></td>
|
||||
</tr>
|
||||
{{if property_client_description.length > 0}}
|
||||
<tr>
|
||||
<td>Description:</td>
|
||||
<td class="info_key">{{>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>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Online since:</td>
|
||||
<td class="info_key update_onlinetime">{{:client_onlinetime}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Volume:</td>
|
||||
<td class="info_key">{{: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>
|
||||
</tr>
|
||||
{{/if}}
|
||||
</table>
|
||||
<!-- Server groups -->
|
||||
<div style="display: flex; flex-direction: column;">
|
||||
<div style="display:flex;margin-top:5px;align-items:center">
|
||||
<div class="icon client-permission_server_groups"></div>
|
||||
<div style="margin-left:3px;font-weight:bold">Server groups:</div>
|
||||
</div>
|
||||
|
||||
{{for group_server}}
|
||||
<div style="display: flex; margin-top: 1px; margin-left: 10px; align-items: center;">
|
||||
<node key="group_{{:group_id}}_icon"/>
|
||||
<div style="margin-left: 3px">{{:group_name}}</div>
|
||||
</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
|
||||
<!-- Channel group -->
|
||||
<div style="display: flex; flex-direction: column; margin-bottom: 20px">
|
||||
<div style="display:flex;margin-top:10px;align-items:center">
|
||||
<div class="icon client-permission_channel"></div>
|
||||
<div style="margin-left:3px;font-weight:bold">Channel group:</div>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; margin-top: 1px; margin-left: 10px; align-items: center;">
|
||||
<node key="group_{{:group_channel}}_icon"/>
|
||||
<div style="margin-left: 3px">{{*: data["group_" + data.group_channel + "_name"]}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue