2020-09-24 09:24:31 +00:00
|
|
|
import {ConnectionHandler, DisconnectReason} from "./ConnectionHandler";
|
|
|
|
import {Registry} from "./events";
|
2020-09-24 13:51:22 +00:00
|
|
|
import * as loader from "tc-loader";
|
|
|
|
import {Stage} from "tc-loader";
|
2020-11-16 20:02:18 +00:00
|
|
|
import {FooterRenderer} from "tc-shared/ui/frames/footer/Renderer";
|
|
|
|
import * as React from "react";
|
|
|
|
import * as ReactDOM from "react-dom";
|
2020-12-09 19:44:33 +00:00
|
|
|
import {SideBarController} from "tc-shared/ui/frames/SideBarController";
|
2019-04-04 19:47:52 +00:00
|
|
|
|
2020-04-09 13:10:14 +00:00
|
|
|
export let server_connections: ConnectionManager;
|
2020-09-24 13:51:22 +00:00
|
|
|
|
2020-11-07 12:16:07 +00:00
|
|
|
class ReplaceableContainer {
|
|
|
|
placeholder: HTMLDivElement;
|
|
|
|
container: HTMLDivElement;
|
|
|
|
|
|
|
|
constructor(container: HTMLDivElement, placeholder?: HTMLDivElement) {
|
|
|
|
this.container = container;
|
|
|
|
this.placeholder = placeholder || document.createElement("div");
|
|
|
|
}
|
|
|
|
|
|
|
|
replaceWith(target: HTMLDivElement | undefined) {
|
|
|
|
target = target || this.placeholder;
|
|
|
|
this.container.replaceWith(target);
|
|
|
|
this.container = target;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-09 13:10:14 +00:00
|
|
|
export class ConnectionManager {
|
|
|
|
private readonly event_registry: Registry<ConnectionManagerEvents>;
|
2019-04-04 19:47:52 +00:00
|
|
|
private connection_handlers: ConnectionHandler[] = [];
|
|
|
|
private active_handler: ConnectionHandler | undefined;
|
|
|
|
|
2019-07-09 22:52:08 +00:00
|
|
|
private _container_log_server: JQuery;
|
2019-04-04 19:47:52 +00:00
|
|
|
private _container_channel_tree: JQuery;
|
2019-08-21 08:00:01 +00:00
|
|
|
private _container_hostbanner: JQuery;
|
2020-11-07 12:16:07 +00:00
|
|
|
private containerChannelVideo: ReplaceableContainer;
|
2020-12-09 17:45:11 +00:00
|
|
|
private containerSideBar: HTMLDivElement;
|
2020-11-16 20:02:18 +00:00
|
|
|
private containerFooter: HTMLDivElement;
|
2019-04-04 19:47:52 +00:00
|
|
|
|
2020-12-09 19:44:33 +00:00
|
|
|
private sideBarController: SideBarController;
|
|
|
|
|
2020-09-25 16:29:42 +00:00
|
|
|
constructor() {
|
2020-04-09 13:10:14 +00:00
|
|
|
this.event_registry = new Registry<ConnectionManagerEvents>();
|
2020-07-20 17:08:13 +00:00
|
|
|
this.event_registry.enableDebug("connection-manager");
|
2020-04-09 13:10:14 +00:00
|
|
|
|
2020-12-09 19:44:33 +00:00
|
|
|
this.sideBarController = new SideBarController();
|
|
|
|
|
2020-11-07 12:16:07 +00:00
|
|
|
this.containerChannelVideo = new ReplaceableContainer(document.getElementById("channel-video") as HTMLDivElement);
|
2019-07-09 22:52:08 +00:00
|
|
|
this._container_log_server = $("#server-log");
|
2019-04-04 19:47:52 +00:00
|
|
|
this._container_channel_tree = $("#channelTree");
|
2019-08-21 08:00:01 +00:00
|
|
|
this._container_hostbanner = $("#hostbanner");
|
2020-11-16 20:02:18 +00:00
|
|
|
this.containerFooter = document.getElementById("container-footer") as HTMLDivElement;
|
2019-04-04 19:47:52 +00:00
|
|
|
|
2020-12-09 19:44:33 +00:00
|
|
|
this.sideBarController.renderInto(document.getElementById("chat") as HTMLDivElement);
|
2020-04-09 13:10:14 +00:00
|
|
|
this.set_active_connection(undefined);
|
|
|
|
}
|
|
|
|
|
2020-11-16 20:02:18 +00:00
|
|
|
initializeFooter() {
|
|
|
|
ReactDOM.render(React.createElement(FooterRenderer), this.containerFooter);
|
|
|
|
}
|
|
|
|
|
2020-04-09 13:10:14 +00:00
|
|
|
events() : Registry<ConnectionManagerEvents> {
|
|
|
|
return this.event_registry;
|
2019-04-04 19:47:52 +00:00
|
|
|
}
|
|
|
|
|
2020-04-09 13:10:14 +00:00
|
|
|
spawn_server_connection() : ConnectionHandler {
|
2019-04-04 19:47:52 +00:00
|
|
|
const handler = new ConnectionHandler();
|
2020-04-09 13:10:14 +00:00
|
|
|
handler.initialize_client_state(this.active_handler);
|
2019-04-04 19:47:52 +00:00
|
|
|
this.connection_handlers.push(handler);
|
2020-04-09 13:10:14 +00:00
|
|
|
|
2020-09-24 13:51:22 +00:00
|
|
|
this.event_registry.fire("notify_handler_created", { handler: handler, handlerId: handler.handlerId });
|
2019-04-04 19:47:52 +00:00
|
|
|
return handler;
|
|
|
|
}
|
|
|
|
|
2020-04-09 13:10:14 +00:00
|
|
|
destroy_server_connection(handler: ConnectionHandler) {
|
|
|
|
if(this.connection_handlers.length <= 1)
|
|
|
|
throw "cannot deleted the last connection handler";
|
|
|
|
|
|
|
|
if(!this.connection_handlers.remove(handler))
|
|
|
|
throw "unknown connection handler";
|
|
|
|
|
2019-04-04 19:47:52 +00:00
|
|
|
if(handler.serverConnection) {
|
|
|
|
const connected = handler.connected;
|
|
|
|
handler.serverConnection.disconnect("handler destroyed");
|
|
|
|
handler.handleDisconnect(DisconnectReason.HANDLER_DESTROYED, connected);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(handler === this.active_handler)
|
2020-04-09 13:10:14 +00:00
|
|
|
this.set_active_connection_(this.connection_handlers[0]);
|
2020-09-24 13:51:22 +00:00
|
|
|
this.event_registry.fire("notify_handler_deleted", { handler: handler, handlerId: handler.handlerId });
|
2019-08-21 08:00:01 +00:00
|
|
|
|
|
|
|
/* destroy all elements */
|
|
|
|
handler.destroy();
|
2019-04-04 19:47:52 +00:00
|
|
|
}
|
|
|
|
|
2020-04-09 13:10:14 +00:00
|
|
|
set_active_connection(handler: ConnectionHandler) {
|
2019-04-04 19:47:52 +00:00
|
|
|
if(handler && this.connection_handlers.indexOf(handler) == -1)
|
2019-08-21 08:00:01 +00:00
|
|
|
throw "Handler hasn't been registered or is already obsolete!";
|
2020-04-09 13:10:14 +00:00
|
|
|
if(handler === this.active_handler)
|
|
|
|
return;
|
|
|
|
this.set_active_connection_(handler);
|
|
|
|
}
|
2019-04-04 19:47:52 +00:00
|
|
|
|
2020-09-25 18:54:26 +00:00
|
|
|
swapHandlerOrder(handlerA: ConnectionHandler, handlerB: ConnectionHandler) {
|
|
|
|
const indexA = this.connection_handlers.findIndex(handler => handlerA === handler);
|
|
|
|
const indexB = this.connection_handlers.findIndex(handler => handlerB === handler);
|
|
|
|
|
|
|
|
if(indexA === -1 || indexB === -1 || indexA === indexB) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let temp = this.connection_handlers[indexA];
|
|
|
|
this.connection_handlers[indexA] = this.connection_handlers[indexB];
|
|
|
|
this.connection_handlers[indexB] = temp;
|
|
|
|
this.events().fire("notify_handler_order_changed");
|
|
|
|
}
|
|
|
|
|
2020-04-09 13:10:14 +00:00
|
|
|
private set_active_connection_(handler: ConnectionHandler) {
|
2020-12-09 19:44:33 +00:00
|
|
|
this.sideBarController.setConnection(handler);
|
|
|
|
|
2019-04-04 19:47:52 +00:00
|
|
|
this._container_channel_tree.children().detach();
|
2019-07-09 22:52:08 +00:00
|
|
|
this._container_log_server.children().detach();
|
2019-08-21 08:00:01 +00:00
|
|
|
this._container_hostbanner.children().detach();
|
2020-11-07 12:16:07 +00:00
|
|
|
this.containerChannelVideo.replaceWith(handler?.video_frame.getContainer());
|
2019-04-04 19:47:52 +00:00
|
|
|
|
|
|
|
if(handler) {
|
2019-08-21 08:00:01 +00:00
|
|
|
this._container_hostbanner.append(handler.hostbanner.html_tag);
|
2019-04-04 19:47:52 +00:00
|
|
|
this._container_channel_tree.append(handler.channelTree.tag_tree());
|
2020-07-21 22:55:28 +00:00
|
|
|
this._container_log_server.append(handler.log.getHTMLTag());
|
2019-04-04 19:47:52 +00:00
|
|
|
}
|
2020-12-09 19:44:33 +00:00
|
|
|
|
2020-04-09 13:10:14 +00:00
|
|
|
const old_handler = this.active_handler;
|
2019-04-04 19:47:52 +00:00
|
|
|
this.active_handler = handler;
|
2020-04-09 13:10:14 +00:00
|
|
|
this.event_registry.fire("notify_active_handler_changed", {
|
2020-09-24 13:51:22 +00:00
|
|
|
oldHandler: old_handler,
|
|
|
|
newHandler: handler,
|
|
|
|
|
|
|
|
oldHandlerId: old_handler?.handlerId,
|
|
|
|
newHandlerId: handler?.handlerId
|
2020-04-09 13:10:14 +00:00
|
|
|
});
|
2020-06-11 09:17:56 +00:00
|
|
|
old_handler?.events().fire("notify_visibility_changed", { visible: false });
|
|
|
|
handler?.events().fire("notify_visibility_changed", { visible: true });
|
2019-04-04 19:47:52 +00:00
|
|
|
}
|
2020-07-20 17:08:13 +00:00
|
|
|
|
|
|
|
findConnection(handlerId: string) : ConnectionHandler | undefined {
|
|
|
|
return this.connection_handlers.find(e => e.handlerId === handlerId);
|
|
|
|
}
|
2019-04-04 19:47:52 +00:00
|
|
|
|
2020-04-09 13:10:14 +00:00
|
|
|
active_connection() : ConnectionHandler | undefined {
|
2019-04-04 19:47:52 +00:00
|
|
|
return this.active_handler;
|
|
|
|
}
|
|
|
|
|
2020-04-09 13:10:14 +00:00
|
|
|
all_connections() : ConnectionHandler[] {
|
2019-04-04 19:47:52 +00:00
|
|
|
return this.connection_handlers;
|
|
|
|
}
|
2020-04-09 13:10:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export interface ConnectionManagerEvents {
|
|
|
|
notify_handler_created: {
|
2020-09-24 13:51:22 +00:00
|
|
|
handlerId: string,
|
2020-04-09 13:10:14 +00:00
|
|
|
handler: ConnectionHandler
|
|
|
|
},
|
|
|
|
|
|
|
|
/* This will also trigger when a connection gets deleted. So if you're just interested to connect event handler to the active connection,
|
|
|
|
unregister them from the old handler and register them for the new handler every time */
|
|
|
|
notify_active_handler_changed: {
|
2020-09-24 13:51:22 +00:00
|
|
|
oldHandler: ConnectionHandler | undefined,
|
|
|
|
newHandler: ConnectionHandler | undefined,
|
|
|
|
|
|
|
|
oldHandlerId: string | undefined,
|
|
|
|
newHandlerId: string | undefined
|
2020-04-09 13:10:14 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/* Will never fire on an active connection handler! */
|
|
|
|
notify_handler_deleted: {
|
2020-09-24 13:51:22 +00:00
|
|
|
handlerId: string,
|
2020-04-09 13:10:14 +00:00
|
|
|
handler: ConnectionHandler
|
2020-09-25 18:54:26 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
notify_handler_order_changed: { }
|
2020-09-24 13:51:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
loader.register_task(Stage.JAVASCRIPT_INITIALIZING, {
|
|
|
|
name: "server manager init",
|
|
|
|
function: async () => {
|
2020-09-25 16:29:42 +00:00
|
|
|
server_connections = new ConnectionManager();
|
2020-11-16 20:02:18 +00:00
|
|
|
server_connections.initializeFooter();
|
2020-09-24 13:51:22 +00:00
|
|
|
},
|
|
|
|
priority: 80
|
|
|
|
});
|