import {Registry} from "tc-shared/events"; import {ChannelTreeUIEvents} from "tc-shared/ui/tree/Definitions"; import {initializeChannelTreeController} from "tc-shared/ui/tree/Controller"; import {ControlBarEvents} from "tc-shared/ui/frames/control-bar/Definitions"; import {initializePopoutControlBarController} from "tc-shared/ui/frames/control-bar/Controller"; import {ChannelTree} from "tc-shared/tree/ChannelTree"; import {ModalController} from "tc-shared/ui/react-elements/ModalDefinitions"; import {ChannelTreePopoutConstructorArguments, ChannelTreePopoutEvents} from "tc-shared/ui/tree/popout/Definitions"; import {ConnectionState} from "tc-shared/ConnectionHandler"; import {tr, tra} from "tc-shared/i18n/localize"; import {spawnModal} from "tc-shared/ui/react-elements/modal"; export class ChannelTreePopoutController { readonly channelTree: ChannelTree; private popoutInstance: ModalController; private uiEvents: Registry; private treeEvents: Registry; private controlBarEvents: Registry; private generalEvents: (() => void)[]; constructor(channelTree: ChannelTree) { this.channelTree = channelTree; this.generalEvents = []; this.generalEvents.push(this.channelTree.server.events.on("notify_properties_updated", event => { if("virtualserver_name" in event.updated_properties) { this.sendTitle(); } })); this.generalEvents.push(this.channelTree.client.events().on("notify_connection_state_changed", () => this.sendTitle())); } destroy() { this.popin(); this.generalEvents?.forEach(callback => callback()); this.generalEvents = undefined; } hasBeenPopedOut() { return !!this.popoutInstance; } popout() { if(this.popoutInstance) { /* TODO: Request focus on that window? */ return; } this.uiEvents = new Registry(); this.uiEvents.on("query_title", () => this.sendTitle()); this.treeEvents = new Registry(); initializeChannelTreeController(this.treeEvents, this.channelTree, { popoutButton: false }); this.controlBarEvents = new Registry(); initializePopoutControlBarController(this.controlBarEvents, this.channelTree.client); this.popoutInstance = spawnModal("channel-tree", [{ events: this.uiEvents.generateIpcDescription(), eventsTree: this.treeEvents.generateIpcDescription(), eventsControlBar: this.controlBarEvents.generateIpcDescription(), handlerId: this.channelTree.client.handlerId } as ChannelTreePopoutConstructorArguments], { uniqueId: "channel-tree-" + this.channelTree.client.handlerId, popedOut: true }); this.popoutInstance.getEvents().one("destroy", () => { this.treeEvents.fire("notify_destroy"); this.treeEvents.destroy(); this.treeEvents = undefined; this.controlBarEvents.fire("notify_destroy"); this.controlBarEvents.destroy(); this.controlBarEvents = undefined; this.uiEvents.destroy(); this.uiEvents = undefined; this.popoutInstance = undefined; this.channelTree.events.fire("notify_popout_state_changed", { popoutShown: false }); }); this.popoutInstance.show(); this.channelTree.events.fire("notify_popout_state_changed", { popoutShown: true }); } popin() { if(!this.popoutInstance) { return; } this.popoutInstance.destroy(); this.popoutInstance = undefined; /* not needed, but just to ensure (will be set within the destroy callback already) */ } private sendTitle() { if(!this.uiEvents) { return; } let title; switch (this.channelTree.client.connection_state) { case ConnectionState.INITIALISING: case ConnectionState.CONNECTING: case ConnectionState.AUTHENTICATING: const address = this.channelTree.server.remote_address; title = tra("Connecting to {}", address.host + (address.port === 9987 ? "" : `:${address.port}`)); break; case ConnectionState.DISCONNECTING: case ConnectionState.UNCONNECTED: title = tr("Not connected"); break; case ConnectionState.CONNECTED: title = this.channelTree.server.properties.virtualserver_name; break; } this.uiEvents.fire_react("notify_title", { title: title }); } }