TeaWeb/shared/js/ui/frames/side/ChannelBarController.ts

208 lines
7.4 KiB
TypeScript

import {ConnectionHandler} from "tc-shared/ConnectionHandler";
import {Registry} from "tc-shared/events";
import {ChannelBarMode, ChannelBarUiEvents} from "tc-shared/ui/frames/side/ChannelBarDefinitions";
import {ChannelEntry, ChannelSidebarMode} from "tc-shared/tree/Channel";
import {ChannelConversationController} from "tc-shared/ui/frames/side/ChannelConversationController";
import {ChannelDescriptionController} from "tc-shared/ui/frames/side/ChannelDescriptionController";
import {LocalClientEntry} from "tc-shared/tree/Client";
import {ChannelFileBrowserController} from "tc-shared/ui/frames/side/ChannelFileBrowserController";
export class ChannelBarController {
readonly uiEvents: Registry<ChannelBarUiEvents>;
private channelConversations: ChannelConversationController;
private description: ChannelDescriptionController;
private fileBrowser: ChannelFileBrowserController;
private currentConnection: ConnectionHandler;
private listenerConnection: (() => void)[];
private currentChannel: ChannelEntry;
private listenerChannel: (() => void)[];
constructor() {
this.uiEvents = new Registry<ChannelBarUiEvents>();
this.listenerConnection = [];
this.listenerChannel = [];
this.channelConversations = new ChannelConversationController();
this.description = new ChannelDescriptionController();
this.fileBrowser = new ChannelFileBrowserController();
this.uiEvents.on("query_mode", () => this.notifyChannelMode());
this.uiEvents.on("query_channel_id", () => this.notifyChannelId());
this.uiEvents.on("query_data", event => this.notifyModeData(event.mode));
}
destroy() {
this.listenerConnection.forEach(callback => callback());
this.listenerConnection = [];
this.listenerChannel.forEach(callback => callback());
this.listenerChannel = [];
this.currentChannel = undefined;
this.currentConnection = undefined;
this.fileBrowser?.destroy();
this.fileBrowser = undefined;
this.channelConversations?.destroy();
this.channelConversations = undefined;
this.description?.destroy();
this.description = undefined;
this.uiEvents.destroy();
}
getChannelConversationController() : ChannelConversationController {
return this.channelConversations;
}
setConnectionHandler(handler: ConnectionHandler) {
if(this.currentConnection === handler) {
return;
}
this.channelConversations.setConnectionHandler(handler);
this.fileBrowser.setConnectionHandler(handler);
this.listenerConnection.forEach(callback => callback());
this.listenerConnection = [];
this.currentConnection = handler;
const selectedEntry = handler?.channelTree.getSelectedEntry();
if(selectedEntry instanceof ChannelEntry) {
this.setChannel(selectedEntry);
} else {
this.setChannel(undefined);
}
if(handler) {
this.listenerConnection.push(handler.channelTree.events.on("notify_selected_entry_changed", event => {
if(event.newEntry instanceof ChannelEntry) {
this.setChannel(event.newEntry);
} else {
this.setChannel(undefined);
}
}));
this.listenerConnection.push(handler.channelTree.events.on("notify_client_moved", event => {
if(event.client instanceof LocalClientEntry) {
if(event.oldChannel === this.currentChannel || event.newChannel === this.currentChannel) {
/* The mode may changed since we can now write in the channel */
this.notifyChannelMode();
}
}
}));
this.listenerConnection.push(handler.getChannelConversations().events.on("notify_cross_conversation_support_changed", () => {
this.notifyChannelMode();
}));
}
}
private setChannel(channel: ChannelEntry) {
if(this.currentChannel === channel) {
return;
}
this.fileBrowser.setChannel(channel);
this.description.setChannel(channel);
this.listenerChannel.forEach(callback => callback());
this.listenerChannel = [];
this.currentChannel = channel;
this.notifyChannelId();
if(channel) {
this.listenerChannel.push(channel.events.on("notify_properties_updated", event => {
if("channel_sidebar_mode" in event.updated_properties) {
this.notifyChannelMode();
}
}));
}
}
private notifyChannelId() {
this.uiEvents.fire_react("notify_channel_id", {
channelId: this.currentChannel ? this.currentChannel.channelId : -1,
handlerId: this.currentConnection ? this.currentConnection.handlerId : "unbound"
});
}
private notifyChannelMode() {
let mode: ChannelBarMode = "none";
if(this.currentChannel) {
switch(this.currentChannel.properties.channel_sidebar_mode) {
case ChannelSidebarMode.Description:
mode = "description";
break;
case ChannelSidebarMode.FileTransfer:
mode = "file-transfer";
break;
case ChannelSidebarMode.Conversation:
mode = "conversation";
break;
case ChannelSidebarMode.Unknown:
default:
if(this.currentConnection) {
const channelConversation = this.currentConnection.getChannelConversations();
if(channelConversation.hasCrossConversationSupport() || this.currentChannel === this.currentConnection.getClient().currentChannel()) {
mode = "conversation";
} else {
/* A really old TeaSpeak server or a TeamSpeak server. */
mode = "description";
}
} else {
mode = "none";
}
break;
}
}
this.uiEvents.fire_react("notify_mode", { mode: mode });
}
private notifyModeData(mode: ChannelBarMode) {
switch (mode) {
case "none":
this.uiEvents.fire_react("notify_data", { content: "none", data: {} });
break;
case "conversation":
this.uiEvents.fire_react("notify_data", {
content: "conversation",
data: {
events: this.channelConversations.getUiEvents().generateIpcDescription()
}
});
break;
case "description":
this.uiEvents.fire_react("notify_data", {
content: "description",
data: {
events: this.description.uiEvents.generateIpcDescription()
}
});
break;
case "file-transfer":
this.uiEvents.fire_react("notify_data", {
content: "file-transfer",
data: {
events: this.fileBrowser.uiEvents.generateIpcDescription()
}
});
break;
}
}
}