Heavily improved channel tree loading performance (Especially when joining or switching servers)
This commit is contained in:
parent
3d8bc807ba
commit
0bd30c6587
4 changed files with 211 additions and 68 deletions
|
@ -366,7 +366,7 @@ export class ConnectionCommandHandler extends AbstractCommandHandler {
|
||||||
|
|
||||||
handleCommandChannelListFinished() {
|
handleCommandChannelListFinished() {
|
||||||
this.connection.client.channelTree.channelsInitialized = true;
|
this.connection.client.channelTree.channelsInitialized = true;
|
||||||
this.connection.client.channelTree.events.fire_react("notify_channel_list_received");
|
this.connection.client.channelTree.events.fire("notify_channel_list_received");
|
||||||
|
|
||||||
if(this.batchTreeUpdateFinishedTimeout) {
|
if(this.batchTreeUpdateFinishedTimeout) {
|
||||||
clearTimeout(this.batchTreeUpdateFinishedTimeout);
|
clearTimeout(this.batchTreeUpdateFinishedTimeout);
|
||||||
|
|
|
@ -2,10 +2,10 @@ import {ChannelTree, ChannelTreeEvents} from "tc-shared/tree/ChannelTree";
|
||||||
import {ChannelTreeEntry as ChannelTreeEntryModel, ChannelTreeEntryEvents} from "tc-shared/tree/ChannelTreeEntry";
|
import {ChannelTreeEntry as ChannelTreeEntryModel, ChannelTreeEntryEvents} from "tc-shared/tree/ChannelTreeEntry";
|
||||||
import {EventHandler, Registry} from "tc-shared/events";
|
import {EventHandler, Registry} from "tc-shared/events";
|
||||||
import {
|
import {
|
||||||
|
ChannelEntryInfo,
|
||||||
ChannelIcons,
|
ChannelIcons,
|
||||||
ChannelTreeEntry,
|
ChannelTreeUIEvents, ClientIcons, ClientNameInfo,
|
||||||
ChannelTreeUIEvents,
|
ClientTalkIconState, FullChannelTreeEntry,
|
||||||
ClientTalkIconState,
|
|
||||||
ServerState
|
ServerState
|
||||||
} from "tc-shared/ui/tree/Definitions";
|
} from "tc-shared/ui/tree/Definitions";
|
||||||
import {ChannelTreeRenderer} from "./Renderer";
|
import {ChannelTreeRenderer} from "./Renderer";
|
||||||
|
@ -140,7 +140,7 @@ class ChannelTreeController {
|
||||||
private handleConnectionStateChanged(event: ConnectionEvents["notify_connection_state_changed"]) {
|
private handleConnectionStateChanged(event: ConnectionEvents["notify_connection_state_changed"]) {
|
||||||
if(event.newState !== ConnectionState.CONNECTED) {
|
if(event.newState !== ConnectionState.CONNECTED) {
|
||||||
this.channelTree.channelsInitialized = false;
|
this.channelTree.channelsInitialized = false;
|
||||||
this.sendChannelTreeEntries();
|
this.sendChannelTreeEntriesFull([]);
|
||||||
}
|
}
|
||||||
this.sendServerStatus(this.channelTree.server);
|
this.sendServerStatus(this.channelTree.server);
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ class ChannelTreeController {
|
||||||
this.channelTree.channelsInitialized = true;
|
this.channelTree.channelsInitialized = true;
|
||||||
this.channelTree.channels.forEach(channel => this.initializeChannelEvents(channel));
|
this.channelTree.channels.forEach(channel => this.initializeChannelEvents(channel));
|
||||||
this.channelTree.clients.forEach(channel => this.initializeClientEvents(channel));
|
this.channelTree.clients.forEach(channel => this.initializeClientEvents(channel));
|
||||||
this.sendChannelTreeEntries();
|
this.sendChannelTreeEntriesFull(undefined);
|
||||||
this.sendSelectedEntry();
|
this.sendSelectedEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,13 +207,13 @@ class ChannelTreeController {
|
||||||
private handleChannelCreated(event: ChannelTreeEvents["notify_channel_created"]) {
|
private handleChannelCreated(event: ChannelTreeEvents["notify_channel_created"]) {
|
||||||
if(!this.channelTree.channelsInitialized) { return; }
|
if(!this.channelTree.channelsInitialized) { return; }
|
||||||
this.initializeChannelEvents(event.channel);
|
this.initializeChannelEvents(event.channel);
|
||||||
this.sendChannelTreeEntries();
|
this.sendChannelTreeEntriesFull([event.channel.uniqueEntryId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler<ChannelTreeEvents>("notify_channel_moved")
|
@EventHandler<ChannelTreeEvents>("notify_channel_moved")
|
||||||
private handleChannelMoved(event: ChannelTreeEvents["notify_channel_moved"]) {
|
private handleChannelMoved(event: ChannelTreeEvents["notify_channel_moved"]) {
|
||||||
if(!this.channelTree.channelsInitialized) { return; }
|
if(!this.channelTree.channelsInitialized) { return; }
|
||||||
this.sendChannelTreeEntries();
|
this.sendChannelTreeEntriesFull([]);
|
||||||
|
|
||||||
if(event.previousParent && !event.previousParent.child_channel_head) {
|
if(event.previousParent && !event.previousParent.child_channel_head) {
|
||||||
/* the collapsed state arrow changed */
|
/* the collapsed state arrow changed */
|
||||||
|
@ -229,7 +229,7 @@ class ChannelTreeController {
|
||||||
private handleChannelDeleted(event: ChannelTreeEvents["notify_channel_deleted"]) {
|
private handleChannelDeleted(event: ChannelTreeEvents["notify_channel_deleted"]) {
|
||||||
if(!this.channelTree.channelsInitialized) { return; }
|
if(!this.channelTree.channelsInitialized) { return; }
|
||||||
this.finalizeEvents(event.channel);
|
this.finalizeEvents(event.channel);
|
||||||
this.sendChannelTreeEntries();
|
this.sendChannelTreeEntriesFull([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler<ChannelTreeEvents>("notify_client_enter_view")
|
@EventHandler<ChannelTreeEvents>("notify_client_enter_view")
|
||||||
|
@ -239,7 +239,7 @@ class ChannelTreeController {
|
||||||
this.initializeClientEvents(event.client);
|
this.initializeClientEvents(event.client);
|
||||||
this.sendChannelInfo(event.targetChannel);
|
this.sendChannelInfo(event.targetChannel);
|
||||||
this.sendChannelStatusIcon(event.targetChannel);
|
this.sendChannelStatusIcon(event.targetChannel);
|
||||||
this.sendChannelTreeEntries();
|
this.sendChannelTreeEntriesFull([event.client.uniqueEntryId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler<ChannelTreeEvents>("notify_client_leave_view")
|
@EventHandler<ChannelTreeEvents>("notify_client_leave_view")
|
||||||
|
@ -249,7 +249,7 @@ class ChannelTreeController {
|
||||||
this.finalizeEvents(event.client);
|
this.finalizeEvents(event.client);
|
||||||
this.sendChannelInfo(event.sourceChannel);
|
this.sendChannelInfo(event.sourceChannel);
|
||||||
this.sendChannelStatusIcon(event.sourceChannel);
|
this.sendChannelStatusIcon(event.sourceChannel);
|
||||||
this.sendChannelTreeEntries();
|
this.sendChannelTreeEntriesFull([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler<ChannelTreeEvents>("notify_client_moved")
|
@EventHandler<ChannelTreeEvents>("notify_client_moved")
|
||||||
|
@ -261,7 +261,7 @@ class ChannelTreeController {
|
||||||
|
|
||||||
this.sendChannelInfo(event.newChannel);
|
this.sendChannelInfo(event.newChannel);
|
||||||
this.sendChannelStatusIcon(event.newChannel);
|
this.sendChannelStatusIcon(event.newChannel);
|
||||||
this.sendChannelTreeEntries();
|
this.sendChannelTreeEntriesFull([]);
|
||||||
|
|
||||||
this.sendClientTalkStatus(event.client);
|
this.sendClientTalkStatus(event.client);
|
||||||
}
|
}
|
||||||
|
@ -287,7 +287,7 @@ class ChannelTreeController {
|
||||||
this.initializeTreeEntryEvents(channel, events);
|
this.initializeTreeEntryEvents(channel, events);
|
||||||
events.push(channel.events.on("notify_collapsed_state_changed", () => {
|
events.push(channel.events.on("notify_collapsed_state_changed", () => {
|
||||||
this.sendChannelInfo(channel);
|
this.sendChannelInfo(channel);
|
||||||
this.sendChannelTreeEntries();
|
this.sendChannelTreeEntriesFull([]);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
events.push(channel.events.on("notify_properties_updated", event => {
|
events.push(channel.events.on("notify_properties_updated", event => {
|
||||||
|
@ -380,14 +380,14 @@ class ChannelTreeController {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public sendChannelTreeEntries() {
|
private buildFlatChannelTree() : { entry: ChannelTreeEntryModel<any>, depth: number }[] {
|
||||||
const entries = [] as ChannelTreeEntry[];
|
const entries: { entry: ChannelTreeEntryModel<any>, depth: number }[] = [];
|
||||||
|
|
||||||
/* at first comes the server */
|
/* at first comes the server */
|
||||||
entries.push({ type: "server", entryId: this.channelTree.server.uniqueEntryId, depth: 0 });
|
entries.push({ entry: this.channelTree.server, depth: 0 });
|
||||||
|
|
||||||
const buildSubTree = (channel: ChannelEntry, depth: number) => {
|
const buildSubTree = (channel: ChannelEntry, depth: number) => {
|
||||||
entries.push({ type: "channel", entryId: channel.uniqueEntryId, depth: depth });
|
entries.push({ entry: channel, depth: depth });
|
||||||
if(channel.isCollapsed()) {
|
if(channel.isCollapsed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -397,17 +397,94 @@ class ChannelTreeController {
|
||||||
clients = clients.filter(client => client.properties.client_type_exact !== ClientType.CLIENT_QUERY);
|
clients = clients.filter(client => client.properties.client_type_exact !== ClientType.CLIENT_QUERY);
|
||||||
}
|
}
|
||||||
|
|
||||||
entries.push(...clients.map(client => { return {
|
entries.push(...clients.map(client => {
|
||||||
type: client instanceof LocalClientEntry ? "client-local" : "client",
|
return {
|
||||||
depth: depth + 1,
|
entry: client,
|
||||||
entryId: client.uniqueEntryId
|
depth: depth + 1
|
||||||
} as ChannelTreeEntry }));
|
}
|
||||||
|
}));
|
||||||
channel.children(false).forEach(channel => buildSubTree(channel, depth + 1));
|
channel.children(false).forEach(channel => buildSubTree(channel, depth + 1));
|
||||||
};
|
};
|
||||||
|
|
||||||
this.channelTree.rootChannel().forEach(entry => buildSubTree(entry, 1));
|
this.channelTree.rootChannel().forEach(entry => buildSubTree(entry, 1));
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
this.events.fire_react("notify_tree_entries", { entries: entries });
|
/**
|
||||||
|
* @param fullInfoEntries If `undefined` full entry info will be send.
|
||||||
|
* Else only infos for entries which are contained within the entry id array will be send.
|
||||||
|
*/
|
||||||
|
public sendChannelTreeEntriesFull(fullInfoEntries: number[] | undefined) {
|
||||||
|
const entries = [] as FullChannelTreeEntry[];
|
||||||
|
|
||||||
|
for(const entry of this.buildFlatChannelTree()) {
|
||||||
|
if(!fullInfoEntries || fullInfoEntries.indexOf(entry.entry.uniqueEntryId) !== -1) {
|
||||||
|
if(entry.entry instanceof ServerEntry) {
|
||||||
|
entries.push({
|
||||||
|
type: "server",
|
||||||
|
entryId: entry.entry.uniqueEntryId,
|
||||||
|
depth: entry.depth,
|
||||||
|
fullInfo: true,
|
||||||
|
state: this.generateServerStatus(entry.entry),
|
||||||
|
unread: entry.entry.isUnread()
|
||||||
|
});
|
||||||
|
} else if(entry.entry instanceof ClientEntry) {
|
||||||
|
const talkStatus = this.generateClientTalkStatus(entry.entry);
|
||||||
|
entries.push({
|
||||||
|
type: entry.entry instanceof LocalClientEntry ? "client-local" : "client",
|
||||||
|
entryId: entry.entry.uniqueEntryId,
|
||||||
|
depth: entry.depth,
|
||||||
|
fullInfo: true,
|
||||||
|
unread: entry.entry.isUnread(),
|
||||||
|
name: this.generateClientNameInfo(entry.entry),
|
||||||
|
icons: this.generateClientIcons(entry.entry),
|
||||||
|
status: entry.entry.getStatusIcon(),
|
||||||
|
talkStatus: talkStatus.status,
|
||||||
|
talkRequestMessage: talkStatus.requestMessage
|
||||||
|
});
|
||||||
|
} else if(entry.entry instanceof ChannelEntry) {
|
||||||
|
entries.push({
|
||||||
|
type: "channel",
|
||||||
|
entryId: entry.entry.uniqueEntryId,
|
||||||
|
depth: entry.depth,
|
||||||
|
fullInfo: true,
|
||||||
|
unread: entry.entry.isUnread(),
|
||||||
|
icons: this.generateChannelIcons(entry.entry),
|
||||||
|
info: this.generateChannelInfo(entry.entry),
|
||||||
|
icon: entry.entry.getStatusIcon()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
throw tr("Invalid flat channel tree entry");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(entry.entry instanceof ServerEntry) {
|
||||||
|
entries.push({
|
||||||
|
type: "server",
|
||||||
|
entryId: entry.entry.uniqueEntryId,
|
||||||
|
depth: entry.depth,
|
||||||
|
fullInfo: false
|
||||||
|
});
|
||||||
|
} else if(entry.entry instanceof ClientEntry) {
|
||||||
|
entries.push({
|
||||||
|
type: entry.entry instanceof LocalClientEntry ? "client-local" : "client",
|
||||||
|
entryId: entry.entry.uniqueEntryId,
|
||||||
|
depth: entry.depth,
|
||||||
|
fullInfo: false
|
||||||
|
});
|
||||||
|
} else if(entry.entry instanceof ChannelEntry) {
|
||||||
|
entries.push({
|
||||||
|
type: "channel",
|
||||||
|
entryId: entry.entry.uniqueEntryId,
|
||||||
|
depth: entry.depth,
|
||||||
|
fullInfo: false
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
throw tr("Invalid flat channel tree entry");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.events.fire_react("notify_tree_entries_full", { entries: entries });
|
||||||
}
|
}
|
||||||
|
|
||||||
public sendSelectedEntry() {
|
public sendSelectedEntry() {
|
||||||
|
@ -415,14 +492,18 @@ class ChannelTreeController {
|
||||||
this.events.fire_react("notify_selected_entry", { treeEntryId: selectedEntry ? selectedEntry.uniqueEntryId : 0 });
|
this.events.fire_react("notify_selected_entry", { treeEntryId: selectedEntry ? selectedEntry.uniqueEntryId : 0 });
|
||||||
}
|
}
|
||||||
|
|
||||||
public sendChannelInfo(channel: ChannelEntry) {
|
private generateChannelInfo(channel: ChannelEntry) : ChannelEntryInfo {
|
||||||
this.events.fire_react("notify_channel_info", {
|
return {
|
||||||
treeEntryId: channel.uniqueEntryId,
|
|
||||||
info: {
|
|
||||||
collapsedState: channel.child_channel_head || channel.channelClientsOrdered().length > 0 ? channel.isCollapsed() ? "collapsed" : "expended" : "unset",
|
collapsedState: channel.child_channel_head || channel.channelClientsOrdered().length > 0 ? channel.isCollapsed() ? "collapsed" : "expended" : "unset",
|
||||||
name: channel.parsed_channel_name.text,
|
name: channel.parsed_channel_name.text,
|
||||||
nameStyle: channel.parsed_channel_name.alignment
|
nameStyle: channel.parsed_channel_name.alignment
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sendChannelInfo(channel: ChannelEntry) {
|
||||||
|
this.events.fire_react("notify_channel_info", {
|
||||||
|
treeEntryId: channel.uniqueEntryId,
|
||||||
|
info: this.generateChannelInfo(channel)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,7 +511,7 @@ class ChannelTreeController {
|
||||||
this.events.fire_react("notify_channel_icon", { icon: channel.getStatusIcon(), treeEntryId: channel.uniqueEntryId });
|
this.events.fire_react("notify_channel_icon", { icon: channel.getStatusIcon(), treeEntryId: channel.uniqueEntryId });
|
||||||
}
|
}
|
||||||
|
|
||||||
public sendChannelIcons(channel: ChannelEntry) {
|
private generateChannelIcons(channel: ChannelEntry) : ChannelIcons {
|
||||||
let icons: ChannelIcons = {
|
let icons: ChannelIcons = {
|
||||||
musicQuality: channel.properties.channel_codec === 3 || channel.properties.channel_codec === 5,
|
musicQuality: channel.properties.channel_codec === 3 || channel.properties.channel_codec === 5,
|
||||||
codecUnsupported: true,
|
codecUnsupported: true,
|
||||||
|
@ -455,10 +536,14 @@ class ChannelTreeController {
|
||||||
icons.codecUnsupported = true;
|
icons.codecUnsupported = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.events.fire_react("notify_channel_icons", { icons: icons, treeEntryId: channel.uniqueEntryId });
|
return icons;
|
||||||
}
|
}
|
||||||
|
|
||||||
public sendClientNameInfo(client: ClientEntry) {
|
public sendChannelIcons(channel: ChannelEntry) {
|
||||||
|
this.events.fire_react("notify_channel_icons", { icons: this.generateChannelIcons(channel), treeEntryId: channel.uniqueEntryId });
|
||||||
|
}
|
||||||
|
|
||||||
|
private generateClientNameInfo(client: ClientEntry) : ClientNameInfo {
|
||||||
let prefix = [];
|
let prefix = [];
|
||||||
let suffix = [];
|
let suffix = [];
|
||||||
for(const groupId of client.assignedServerGroupIds()) {
|
for(const groupId of client.assignedServerGroupIds()) {
|
||||||
|
@ -484,18 +569,22 @@ class ChannelTreeController {
|
||||||
}
|
}
|
||||||
|
|
||||||
const afkMessage = client.properties.client_away ? client.properties.client_away_message : undefined;
|
const afkMessage = client.properties.client_away ? client.properties.client_away_message : undefined;
|
||||||
this.events.fire_react("notify_client_name", {
|
return {
|
||||||
info: {
|
|
||||||
name: client.clientNickName(),
|
name: client.clientNickName(),
|
||||||
awayMessage: afkMessage,
|
awayMessage: afkMessage,
|
||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
suffix: suffix
|
suffix: suffix
|
||||||
},
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public sendClientNameInfo(client: ClientEntry) {
|
||||||
|
this.events.fire_react("notify_client_name", {
|
||||||
|
info: this.generateClientNameInfo(client),
|
||||||
treeEntryId: client.uniqueEntryId
|
treeEntryId: client.uniqueEntryId
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public sendClientIcons(client: ClientEntry) {
|
private generateClientIcons(client: ClientEntry) : ClientIcons {
|
||||||
const uniqueServerId = this.channelTree.client.getCurrentServerUniqueId();
|
const uniqueServerId = this.channelTree.client.getCurrentServerUniqueId();
|
||||||
|
|
||||||
const serverGroupIcons = client.assignedServerGroupIds()
|
const serverGroupIcons = client.assignedServerGroupIds()
|
||||||
|
@ -510,17 +599,21 @@ class ChannelTreeController {
|
||||||
.map(group => { return { iconId: group.properties.iconid, groupName: group.name, groupId: group.id, serverUniqueId: uniqueServerId }; });
|
.map(group => { return { iconId: group.properties.iconid, groupName: group.name, groupId: group.id, serverUniqueId: uniqueServerId }; });
|
||||||
|
|
||||||
const clientIcon = client.properties.client_icon_id === 0 ? [] : [client.properties.client_icon_id];
|
const clientIcon = client.properties.client_icon_id === 0 ? [] : [client.properties.client_icon_id];
|
||||||
this.events.fire_react("notify_client_icons", {
|
return {
|
||||||
icons: {
|
|
||||||
serverGroupIcons: serverGroupIcons,
|
serverGroupIcons: serverGroupIcons,
|
||||||
channelGroupIcon: channelGroupIcon[0],
|
channelGroupIcon: channelGroupIcon[0],
|
||||||
clientIcon: clientIcon.length > 0 ? { iconId: clientIcon[0], serverUniqueId: uniqueServerId } : undefined
|
clientIcon: clientIcon.length > 0 ? { iconId: clientIcon[0], serverUniqueId: uniqueServerId } : undefined
|
||||||
},
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public sendClientIcons(client: ClientEntry) {
|
||||||
|
this.events.fire_react("notify_client_icons", {
|
||||||
|
icons: this.generateClientIcons(client),
|
||||||
treeEntryId: client.uniqueEntryId
|
treeEntryId: client.uniqueEntryId
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public sendClientTalkStatus(client: ClientEntry) {
|
private generateClientTalkStatus(client: ClientEntry) : { status: ClientTalkIconState, requestMessage?: string } {
|
||||||
let status: ClientTalkIconState = "unset";
|
let status: ClientTalkIconState = "unset";
|
||||||
|
|
||||||
if(client.properties.client_is_talker) {
|
if(client.properties.client_is_talker) {
|
||||||
|
@ -533,37 +626,42 @@ class ChannelTreeController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.events.fire_react("notify_client_talk_status", { treeEntryId: client.uniqueEntryId, requestMessage: client.properties.client_talk_request_msg, status: status });
|
return {
|
||||||
|
requestMessage: client.properties.client_talk_request_msg,
|
||||||
|
status: status
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sendServerStatus(serverEntry: ServerEntry) {
|
public sendClientTalkStatus(client: ClientEntry) {
|
||||||
let status: ServerState;
|
const status = this.generateClientTalkStatus(client);
|
||||||
|
this.events.fire_react("notify_client_talk_status", { treeEntryId: client.uniqueEntryId, requestMessage: status.requestMessage, status: status.status });
|
||||||
|
}
|
||||||
|
|
||||||
|
private generateServerStatus(serverEntry: ServerEntry) : ServerState {
|
||||||
switch (this.channelTree.client.connection_state) {
|
switch (this.channelTree.client.connection_state) {
|
||||||
case ConnectionState.AUTHENTICATING:
|
case ConnectionState.AUTHENTICATING:
|
||||||
case ConnectionState.CONNECTING:
|
case ConnectionState.CONNECTING:
|
||||||
case ConnectionState.INITIALISING:
|
case ConnectionState.INITIALISING:
|
||||||
status = {
|
return {
|
||||||
state: "connecting",
|
state: "connecting",
|
||||||
targetAddress: serverEntry.remote_address.host + (serverEntry.remote_address.port === 9987 ? "" : `:${serverEntry.remote_address.port}`)
|
targetAddress: serverEntry.remote_address.host + (serverEntry.remote_address.port === 9987 ? "" : `:${serverEntry.remote_address.port}`)
|
||||||
};
|
};
|
||||||
break;
|
|
||||||
|
|
||||||
case ConnectionState.DISCONNECTING:
|
case ConnectionState.DISCONNECTING:
|
||||||
case ConnectionState.UNCONNECTED:
|
case ConnectionState.UNCONNECTED:
|
||||||
status = { state: "disconnected" };
|
return { state: "disconnected" };
|
||||||
break;
|
|
||||||
|
|
||||||
case ConnectionState.CONNECTED:
|
case ConnectionState.CONNECTED:
|
||||||
status = {
|
return {
|
||||||
state: "connected",
|
state: "connected",
|
||||||
name: serverEntry.properties.virtualserver_name,
|
name: serverEntry.properties.virtualserver_name,
|
||||||
icon: { iconId: serverEntry.properties.virtualserver_icon_id, serverUniqueId: serverEntry.properties.virtualserver_unique_identifier }
|
icon: { iconId: serverEntry.properties.virtualserver_icon_id, serverUniqueId: serverEntry.properties.virtualserver_unique_identifier }
|
||||||
};
|
};
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.events.fire_react("notify_server_state", { treeEntryId: serverEntry.uniqueEntryId, state: status });
|
public sendServerStatus(serverEntry: ServerEntry) {
|
||||||
|
this.events.fire_react("notify_server_state", { treeEntryId: serverEntry.uniqueEntryId, state: this.generateServerStatus(serverEntry) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,7 +686,7 @@ export function initializeChannelTreeController(events: Registry<ChannelTreeUIEv
|
||||||
|
|
||||||
events.on("notify_destroy", channelTree.client.events().on("notify_visibility_changed", event => events.fire("notify_visibility_changed", event)));
|
events.on("notify_destroy", channelTree.client.events().on("notify_visibility_changed", event => events.fire("notify_visibility_changed", event)));
|
||||||
|
|
||||||
events.on("query_tree_entries", () => controller.sendChannelTreeEntries());
|
events.on("query_tree_entries", event => controller.sendChannelTreeEntriesFull(event.fullInfo ? undefined : []));
|
||||||
events.on("query_channel_info", event => {
|
events.on("query_channel_info", event => {
|
||||||
const entry = channelTree.findEntryId(event.treeEntryId);
|
const entry = channelTree.findEntryId(event.treeEntryId);
|
||||||
if(!entry || !(entry instanceof ChannelEntry)) {
|
if(!entry || !(entry instanceof ChannelEntry)) {
|
||||||
|
|
|
@ -16,6 +16,31 @@ export type ChannelIcons = {
|
||||||
export type ChannelEntryInfo = { name: string, nameStyle: ChannelNameAlignment, collapsedState: CollapsedState };
|
export type ChannelEntryInfo = { name: string, nameStyle: ChannelNameAlignment, collapsedState: CollapsedState };
|
||||||
export type ChannelTreeEntry = { type: "channel" | "server" | "client" | "client-local", entryId: number, depth: number };
|
export type ChannelTreeEntry = { type: "channel" | "server" | "client" | "client-local", entryId: number, depth: number };
|
||||||
|
|
||||||
|
export type FullChannelTreeEntry = {
|
||||||
|
entryId: number,
|
||||||
|
depth: number,
|
||||||
|
} & ( { fullInfo: true, unread: boolean } & (
|
||||||
|
{
|
||||||
|
type: "channel",
|
||||||
|
info: ChannelEntryInfo;
|
||||||
|
icon: ClientIcon;
|
||||||
|
icons: ChannelIcons;
|
||||||
|
} | {
|
||||||
|
type: "server",
|
||||||
|
state: ServerState;
|
||||||
|
} | {
|
||||||
|
type: "client" | "client-local",
|
||||||
|
name: ClientNameInfo;
|
||||||
|
status: ClientIcon;
|
||||||
|
icons: ClientIcons;
|
||||||
|
|
||||||
|
talkStatus?: ClientTalkIconState;
|
||||||
|
talkRequestMessage?: string;
|
||||||
|
}
|
||||||
|
) | { fullInfo: false } & {
|
||||||
|
type: "channel" | "server" | "client" | "client-local"
|
||||||
|
});
|
||||||
|
|
||||||
export type ClientNameInfo = { name: string, prefix: string[], suffix: string[], awayMessage: string };
|
export type ClientNameInfo = { name: string, prefix: string[], suffix: string[], awayMessage: string };
|
||||||
export type ClientTalkIconState = "unset" | "prohibited" | "requested" | "granted";
|
export type ClientTalkIconState = "unset" | "prohibited" | "requested" | "granted";
|
||||||
export type ClientIcons = {
|
export type ClientIcons = {
|
||||||
|
@ -41,7 +66,7 @@ export interface ChannelTreeUIEvents {
|
||||||
action_move_channels: { targetTreeEntry: number, mode: "before" | "after" | "child", entries: ChannelTreeDragEntry[] },
|
action_move_channels: { targetTreeEntry: number, mode: "before" | "after" | "child", entries: ChannelTreeDragEntry[] },
|
||||||
|
|
||||||
/* queries */
|
/* queries */
|
||||||
query_tree_entries: {},
|
query_tree_entries: { fullInfo: boolean },
|
||||||
query_popout_state: {},
|
query_popout_state: {},
|
||||||
query_selected_entry: {},
|
query_selected_entry: {},
|
||||||
|
|
||||||
|
@ -59,7 +84,7 @@ export interface ChannelTreeUIEvents {
|
||||||
query_server_state: { treeEntryId: number },
|
query_server_state: { treeEntryId: number },
|
||||||
|
|
||||||
/* notifies */
|
/* notifies */
|
||||||
notify_tree_entries: { entries: ChannelTreeEntry[] },
|
notify_tree_entries_full: { entries: FullChannelTreeEntry[] },
|
||||||
notify_popout_state: { shown: boolean, showButton: boolean },
|
notify_popout_state: { shown: boolean, showButton: boolean },
|
||||||
notify_selected_entry: { treeEntryId: number | 0 },
|
notify_selected_entry: { treeEntryId: number | 0 },
|
||||||
|
|
||||||
|
|
|
@ -455,7 +455,7 @@ export class RDPChannelTree {
|
||||||
document.addEventListener("focusout", this.documentDragStopListener);
|
document.addEventListener("focusout", this.documentDragStopListener);
|
||||||
document.addEventListener("mouseout", this.documentDragStopListener);
|
document.addEventListener("mouseout", this.documentDragStopListener);
|
||||||
|
|
||||||
this.events.fire("query_tree_entries");
|
this.events.fire("query_tree_entries", { fullInfo: true });
|
||||||
this.events.fire("query_popout_state");
|
this.events.fire("query_popout_state");
|
||||||
this.events.fire("query_selected_entry");
|
this.events.fire("query_selected_entry");
|
||||||
}
|
}
|
||||||
|
@ -644,8 +644,8 @@ export class RDPChannelTree {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler<ChannelTreeUIEvents>("notify_tree_entries")
|
@EventHandler<ChannelTreeUIEvents>("notify_tree_entries_full")
|
||||||
private handleNotifyTreeEntries(event: ChannelTreeUIEvents["notify_tree_entries"]) {
|
private handleNotifyTreeEntries(event: ChannelTreeUIEvents["notify_tree_entries_full"]) {
|
||||||
const oldEntryInstances = this.treeEntries;
|
const oldEntryInstances = this.treeEntries;
|
||||||
this.treeEntries = {};
|
this.treeEntries = {};
|
||||||
|
|
||||||
|
@ -657,23 +657,45 @@ export class RDPChannelTree {
|
||||||
} else {
|
} else {
|
||||||
switch (entry.type) {
|
switch (entry.type) {
|
||||||
case "channel":
|
case "channel":
|
||||||
result = new RDPChannel(this, entry.entryId);
|
const channel = new RDPChannel(this, entry.entryId);
|
||||||
|
if(entry.fullInfo) {
|
||||||
|
channel.info = entry.info;
|
||||||
|
channel.icon = entry.icon;
|
||||||
|
channel.icons = entry.icons;
|
||||||
|
} else {
|
||||||
|
channel.queryState();
|
||||||
|
}
|
||||||
|
result = channel;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "client":
|
case "client":
|
||||||
case "client-local":
|
case "client-local":
|
||||||
result = new RDPClient(this, entry.entryId, entry.type === "client-local");
|
const client = new RDPClient(this, entry.entryId, entry.type === "client-local");
|
||||||
|
if(entry.fullInfo) {
|
||||||
|
client.name = entry.name;
|
||||||
|
client.status = entry.status;
|
||||||
|
client.icons = entry.icons;
|
||||||
|
client.talkStatus = entry.talkStatus;
|
||||||
|
client.talkRequestMessage = entry.talkRequestMessage;
|
||||||
|
} else {
|
||||||
|
client.queryState();
|
||||||
|
}
|
||||||
|
result = client;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "server":
|
case "server":
|
||||||
result = new RDPServer(this, entry.entryId);
|
const server = new RDPServer(this, entry.entryId);
|
||||||
|
if(entry.fullInfo) {
|
||||||
|
server.state = entry.state;
|
||||||
|
} else {
|
||||||
|
server.queryState();
|
||||||
|
}
|
||||||
|
result = server;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw "invalid channel entry type " + entry.type;
|
throw "invalid channel entry type " + (entry as any).type;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.queryState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.treeEntries[entry.entryId] = result;
|
this.treeEntries[entry.entryId] = result;
|
||||||
|
@ -698,7 +720,6 @@ export class RDPChannelTree {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@EventHandler<ChannelTreeUIEvents>("notify_popout_state")
|
@EventHandler<ChannelTreeUIEvents>("notify_popout_state")
|
||||||
private handleNotifyPopoutState(event: ChannelTreeUIEvents["notify_popout_state"]) {
|
private handleNotifyPopoutState(event: ChannelTreeUIEvents["notify_popout_state"]) {
|
||||||
this.popoutShown = event.shown;
|
this.popoutShown = event.shown;
|
||||||
|
@ -902,7 +923,6 @@ export class RDPClient extends RDPEntry {
|
||||||
|
|
||||||
name: ClientNameInfo;
|
name: ClientNameInfo;
|
||||||
status: ClientIcon;
|
status: ClientIcon;
|
||||||
info: ClientNameInfo;
|
|
||||||
icons: ClientIcons;
|
icons: ClientIcons;
|
||||||
|
|
||||||
rename: boolean = false;
|
rename: boolean = false;
|
||||||
|
|
Loading…
Add table
Reference in a new issue