TeaWeb/js/ui/channel.ts

354 lines
12 KiB
TypeScript
Raw Normal View History

2018-02-27 17:20:49 +01:00
/// <reference path="view.ts" />
enum ChannelType {
PERMANENT,
SEMI_PERMANENT,
TEMPORARY
}
namespace ChannelType {
export function normalize(mode: ChannelType) {
let value: string = ChannelType[mode];
value = value.toLowerCase();
return value[0].toUpperCase() + value.substr(1);
}
}
class ChannelEntry {
channelTree: ChannelTree;
channelId: number;
parent?: ChannelEntry;
prevChannel?: ChannelEntry;
properties: any = {
channel_order: 0,
channel_name: "undefined",
channel_flag_permanent: 0,
channel_flag_semi_permanent: 0,
channel_flag_default: 0,
channel_flag_password: 0
};
originalHeight: number;
private _channelAlign: string;
private _rawChannelName: string;
private _htmlTag: JQuery<HTMLElement>;
private _displayMusicIcon: boolean;
constructor(channelId, channelName, parent = null, prevChannel = null) {
this.properties = {};
this.channelId = channelId;
this._rawChannelName = channelName;
this.parent = parent;
this.prevChannel = prevChannel;
this.channelTree = null;
this.__updateChannelPropertiesFromName();
}
channelName(){
return this.properties["channel_name"];
}
rawChannelName() {
return this._rawChannelName;
}
parentChannel() { return this.parent; }
hasParent(){ return this.parent != null; }
getChannelId(){ return this.channelId; }
channelClass() { return "channel_full"; }
siblings(deep = false) {
const result = [];
if(this.channelTree == null) return [];
const self = this;
this.channelTree.channels.forEach(function (entry) {
let current = entry;
if(deep) {
while(current) {
if(current.parentChannel() == self) {
result.push(entry);
break;
}
current = current.parentChannel();
}
} else
if(current.parentChannel() == self)
result.push(entry);
});
return result;
}
clients(deep = false) {
const result = [];
if(this.channelTree == null) return [];
const self = this;
this.channelTree.clients.forEach(function (entry) {
let current = entry.currentChannel();
if(deep) {
while(current) {
if(current.parentChannel() == self) {
result.push(entry);
break;
}
current = current.parentChannel();
}
} else
if(current == self)
result.push(entry);
});
return result;
}
get htmlTag() : JQuery<HTMLElement> {
if(this._htmlTag) return this._htmlTag;
2018-03-07 19:06:52 +01:00
let tag = $.spawn("div");
2018-02-27 17:20:49 +01:00
tag.attr("id", "channel_" + this.getChannelId());
tag.addClass("channel");
tag.append("<div class=\"icon_empty\"></div>");
let channelTag = $("<div></div>");
channelTag.addClass("channelLine");
channelTag.addClass(this._channelAlign); //For left
let channelType = $("<div/>");
channelType.addClass("channel_only_normal channel_type");
channelType.addClass("icon");
channelType.addClass("client-channel_green_subscribed");
channelTag.append(channelType);
channelTag.append("<a class='channel_name'>" + this.channelName() + "</a>");
let channelIcon = $("<span class='channel_only_normal'/>");
channelTag.append(channelIcon);
tag.append("<div style='position: absolute; width: calc(100% - 16px); margin: 0px'><div class=\"siblings\"></div></div>");
tag.append("<div style='position: absolute; width: calc(100% - 16px); margin: 0px'><div class=\"clients\"></div></div>");
tag.append(channelTag);
return this._htmlTag = tag;
}
get channelTag() : JQuery<HTMLElement> {
return this.htmlTag.find(".channelLine").last();
}
siblingTag() : JQuery<HTMLElement> {
return this.htmlTag.find(".siblings").first(); //Here the first because first comes the siblings tag than all other sibling comes
}
clientTag() : JQuery<HTMLElement>{
return this.htmlTag.find(".clients").last(); //Here last because from the sibling tag client tags could be before
}
adjustSize(parent = true) {
var size = this.originalHeight;
var subSize = 0;
var clientSize = 0;
var sub = this.siblings(false);
sub.forEach(function (e) {
subSize += e.htmlTag.outerHeight(true);
});
var clients = this.clients(false);
clients.forEach(function (e) {
clientSize += e.htmlTag.outerHeight(true);
});
if(sub.length >= 1) subSize -= 1;
if(clients.length >= 1) clientSize -= 1;
this.htmlTag.css({height: size + subSize + clientSize});
this.siblingTag().css("margin-top", (clientSize + 16) + "px");
this.clientTag().css({height: clientSize});
if(parent && this.parentChannel()) this.parentChannel().adjustSize(parent);
}
initializeListener(){
const _this = this;
this.channelTag.click(function () {
_this.channelTree.onSelect(_this);
});
this.channelTag.dblclick(function () {
_this.channelTree.client.serverConnection.joinChannel(_this); //TODO may ask for password
});
this.channelTag.on("contextmenu", function (event) {
event.preventDefault();
_this.channelTree.onSelect(_this);
_this.showContextMenu(event.pageX, event.pageY, () => { _this.channelTree.onSelect(undefined); });
});
}
showContextMenu(x: number, y: number, on_close: () => void = undefined) {
const _this = this;
spawnMenu(x, y, {
type: MenuEntryType.ENTRY,
icon: "client-channel_switch",
name: "<b>Switch to channel</b>",
callback: () => {
_this.channelTree.client.getServerConnection().joinChannel(_this); //TODO ask for password if required
}
},
MenuEntry.HR(),
{
type: MenuEntryType.ENTRY,
icon: "client-channel_create_sub",
name: "Create sub channel",
callback: () => {
//TODO here
}
}, {
type: MenuEntryType.ENTRY,
icon: "client-channel_create",
name: "Create channel",
callback: () => {
//TODO here
}
},
MenuEntry.CLOSE(on_close)
);
}
private __updateChannelPropertiesFromName() {
parseType:
if(this.parentChannel() == null && this._rawChannelName.charAt(0) == '[' && this._rawChannelName.indexOf(']') != -1) {
let typeData = this._rawChannelName.substr(1, this._rawChannelName.indexOf(']') - 1);
//console.log("Having spacer etc? -> " + typeData);
if(typeData.indexOf("spacer") == -1) break parseType;
let strAlign = typeData.substr(0, typeData.indexOf("spacer"));
if(strAlign.length > 0){
if(strAlign.length != 1){
if(strAlign.length != 2 || strAlign[0] != '*')
break parseType;
strAlign = strAlign.substr(1);
//TODO support repeating pattern!
}
}
if(strAlign == "") this._channelAlign = "l";
else this._channelAlign = strAlign;
var repeatData = typeData.substr(typeData.indexOf("spacer") + 6);
//console.log("Repeat data: " + repeatData);
this.properties["channel_name"] = this._rawChannelName.substr(this._rawChannelName.indexOf(']') + 1);
}
if(this.properties.channel_name == undefined) {
this.properties.channel_name = this._rawChannelName;
this._channelAlign = "l";
}
let self = this.channelTag;
if(this.properties.channel_name == this._rawChannelName) {
self.find(".channel_only_normal").show();
} else self.find(".channel_only_normal").hide();
self.find(".channel_name").text(this.channelName());
self.removeClass("l r c"); //Alignments
self.addClass(this._channelAlign);
console.log("Align: " + this._channelAlign);
}
updateProperty(key, value){
this.properties[key] = value;
console.debug("Updating channel " + this.channelId + ". Key: " + key + " Value: " + value);
if(key == "channel_name") {
this._rawChannelName = value;
this.properties.channel_name = undefined;
this.__updateChannelPropertiesFromName();
} else if(key == "channel_order") {
var order = this.channelTree.findChannel(value);
this.channelTree.moveChannel(this, order, this.parent);
} else if(key == "channel_icon_id") {
let icons = this.channelTag.find("span");
icons.find(".icon_property").detach();
if(value > 0) {
let tag = this.channelTree.client.fileManager.icons.generateTag(value);
if(icons.children().length > 0){ //Channel icons at the end :)
icons.children().last().after(tag);
} else
icons.append(tag);
console.log("Channel icon: " + value);
}
} else if(key == "channel_codec") {
this.displayMusicIcon = value == 5 || value == 3;
} else if(key == "channel_flag_default") {
let icons = this.channelTag.find("span");
icons.find(".icon_default").detach();
if(value == "1") {
console.log("Default: '" + value + "'");
let icon = $.spawn("div");
icon.addClass("icon_default icon client-channel_default");
icon.attr("title", "Default channel");
if(icons.children().length > 0){ //Music icon at the begin
icons.children().first().before(icon);
} else
icons.append(icon);
}
}
}
set displayMusicIcon(flag: boolean) {
if(this._displayMusicIcon == flag) return;
this._displayMusicIcon = flag;
let icons = this.channelTag.find("span");
icons.find(".icon_music").detach();
if(flag) {
let icon = $("<div/>");
icon.addClass("icon_music icon client-music");
icon.attr("title", "Music quality");
if(icons.children(".icon_default").length > 0){ //Music icon after default icon
icons.children(".icon_default").first().before(icon);
} else if(icons.children().length > 0){ //Music icon at the begin
icons.children().first().before(icon);
} else
icons.append(icon);
}
}
createChatTag(braces: boolean = false) : string {
2018-03-07 19:06:52 +01:00
let tag = $.spawn("div");
2018-02-27 17:20:49 +01:00
2018-03-07 19:06:52 +01:00
tag.css("display", "table");
2018-02-27 17:20:49 +01:00
tag.css("cursor", "pointer");
tag.css("font-weight", "bold");
tag.css("color", "darkblue");
if(braces)
tag.text("\"" + this.channelName() + "\"");
else
tag.text(this.channelName());
tag.attr("oncontextmenu", "chat_channel_contextmenu(this, ...arguments);");
tag.attr("channelId", this.channelId);
tag.attr("channelName", this.channelName());
return tag.wrap("<p/>").parent().html();
}
channelType() : ChannelType {
if(this.properties.channel_flag_permanent == "1") return ChannelType.PERMANENT;
if(this.properties.channel_flag_semi_permanent == "1") return ChannelType.SEMI_PERMANENT;
return ChannelType.TEMPORARY;
}
}
//Global functions
function chat_channel_contextmenu(_element: any, event: any) {
event.preventDefault();
let element = $(_element);
console.log("Context menue for " + element.attr("channelName"));
let chid : number = Number.parseInt(element.attr("channelId"));
let channel = globalClient.channelTree.findChannel(chid);
if(!channel) {
//TODO
return;
}
channel.showContextMenu(event.pageX, event.pageY);
}