2020-12-09 19:44:33 +00:00
|
|
|
import {ConnectionHandler, ConnectionState} from "tc-shared/ConnectionHandler";
|
|
|
|
import {
|
|
|
|
ClientForumInfo,
|
|
|
|
ClientInfoType,
|
|
|
|
ClientStatusInfo,
|
|
|
|
ClientVersionInfo
|
|
|
|
} from "tc-shared/ui/frames/side/ClientInfoDefinitions";
|
|
|
|
import {ClientEntry, ClientType, LocalClientEntry} from "tc-shared/tree/Client";
|
|
|
|
import {Registry} from "tc-shared/events";
|
2021-04-27 11:30:33 +00:00
|
|
|
import * as i18nc from "./i18n/CountryFlag";
|
2020-12-09 19:44:33 +00:00
|
|
|
|
|
|
|
export type CachedClientInfoCategory = "name" | "description" | "online-state" | "country" | "volume" | "status" | "forum-account" | "group-channel" | "groups-server" | "version";
|
|
|
|
|
|
|
|
export type CachedClientInfo = {
|
|
|
|
type: ClientInfoType;
|
|
|
|
name: string,
|
|
|
|
uniqueId: string,
|
|
|
|
databaseId: number,
|
|
|
|
clientId: number,
|
|
|
|
|
|
|
|
description: string,
|
|
|
|
joinTimestamp: number,
|
|
|
|
leaveTimestamp: number,
|
|
|
|
country: { name: string, flag: string },
|
|
|
|
volume: { volume: number, muted: boolean },
|
|
|
|
status: ClientStatusInfo,
|
|
|
|
forumAccount: ClientForumInfo | undefined,
|
2021-03-24 17:39:19 +00:00
|
|
|
|
2020-12-09 19:44:33 +00:00
|
|
|
channelGroup: number,
|
2021-03-24 17:39:19 +00:00
|
|
|
channelGroupInheritedChannel: number,
|
|
|
|
|
2020-12-09 19:44:33 +00:00
|
|
|
serverGroups: number[],
|
|
|
|
version: ClientVersionInfo
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface ClientInfoManagerEvents {
|
|
|
|
notify_client_changed: { newClient: ClientEntry | undefined },
|
|
|
|
notify_cache_changed: { category: CachedClientInfoCategory },
|
|
|
|
}
|
|
|
|
|
|
|
|
export class SelectedClientInfo {
|
|
|
|
readonly events: Registry<ClientInfoManagerEvents>;
|
|
|
|
|
|
|
|
private readonly connection: ConnectionHandler;
|
|
|
|
private readonly listenerConnection: (() => void)[];
|
|
|
|
|
|
|
|
private listenerClient: (() => void)[];
|
|
|
|
private currentClient: ClientEntry | undefined;
|
|
|
|
private currentClientStatus: CachedClientInfo | undefined;
|
|
|
|
|
|
|
|
constructor(connection: ConnectionHandler) {
|
|
|
|
this.connection = connection;
|
|
|
|
this.events = new Registry<ClientInfoManagerEvents>();
|
|
|
|
|
|
|
|
this.listenerClient = [];
|
|
|
|
this.listenerConnection = [];
|
|
|
|
this.listenerConnection.push(connection.channelTree.events.on("notify_client_leave_view", event => {
|
|
|
|
if(event.client !== this.currentClient) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.currentClientStatus.leaveTimestamp = Date.now() / 1000;
|
|
|
|
this.currentClientStatus.clientId = 0;
|
|
|
|
this.currentClient = undefined;
|
|
|
|
this.unregisterClientEvents();
|
|
|
|
this.events.fire("notify_cache_changed", { category: "online-state" });
|
|
|
|
}));
|
|
|
|
|
|
|
|
this.listenerConnection.push(connection.events().on("notify_connection_state_changed", event => {
|
|
|
|
if(event.newState !== ConnectionState.CONNECTED && this.currentClientStatus) {
|
|
|
|
this.currentClient = undefined;
|
|
|
|
this.currentClientStatus.leaveTimestamp = Date.now() / 1000;
|
|
|
|
this.events.fire("notify_cache_changed", { category: "online-state" });
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
destroy() {
|
|
|
|
this.listenerConnection.forEach(callback => callback());
|
|
|
|
this.listenerConnection.splice(0, this.listenerConnection.length);
|
|
|
|
|
|
|
|
this.unregisterClientEvents();
|
|
|
|
}
|
|
|
|
|
|
|
|
getInfo() : CachedClientInfo {
|
|
|
|
return this.currentClientStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
setClient(client: ClientEntry | undefined) {
|
|
|
|
if(this.currentClient === client) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(client.channelTree.client !== this.connection) {
|
|
|
|
throw tr("client does not belong to current connection handler");
|
|
|
|
}
|
|
|
|
|
|
|
|
this.unregisterClientEvents();
|
|
|
|
this.currentClient = client;
|
|
|
|
this.currentClientStatus = undefined;
|
|
|
|
if(this.currentClient) {
|
|
|
|
this.currentClient.updateClientVariables().then(undefined);
|
|
|
|
this.registerClientEvents(this.currentClient);
|
|
|
|
this.initializeClientInfo(this.currentClient);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.events.fire("notify_client_changed", { newClient: client });
|
|
|
|
}
|
|
|
|
|
|
|
|
getClient() : ClientEntry | undefined {
|
|
|
|
return this.currentClient;
|
|
|
|
}
|
|
|
|
|
|
|
|
private unregisterClientEvents() {
|
|
|
|
this.listenerClient.forEach(callback => callback());
|
|
|
|
this.listenerClient = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
private registerClientEvents(client: ClientEntry) {
|
|
|
|
const events = this.listenerClient;
|
|
|
|
|
|
|
|
events.push(client.events.on("notify_properties_updated", event => {
|
|
|
|
if('client_nickname' in event.updated_properties) {
|
|
|
|
this.currentClientStatus.name = event.client_properties.client_nickname;
|
|
|
|
this.events.fire("notify_cache_changed", { category: "name" });
|
|
|
|
}
|
|
|
|
|
|
|
|
if('client_description' in event.updated_properties) {
|
|
|
|
this.currentClientStatus.description = event.client_properties.client_description;
|
|
|
|
this.events.fire("notify_cache_changed", { category: "description" });
|
|
|
|
}
|
|
|
|
|
2021-03-24 17:39:19 +00:00
|
|
|
if('client_channel_group_id' in event.updated_properties || 'client_channel_group_inherited_channel_id' in event.updated_properties) {
|
|
|
|
this.updateChannelGroup(client);
|
2020-12-09 19:44:33 +00:00
|
|
|
this.events.fire("notify_cache_changed", { category: "group-channel" });
|
|
|
|
}
|
|
|
|
|
|
|
|
if('client_servergroups' in event.updated_properties) {
|
|
|
|
this.currentClientStatus.serverGroups = client.assignedServerGroupIds();
|
|
|
|
this.events.fire("notify_cache_changed", { category: "groups-server" });
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Can happen since that variable isn't in view on client appearance */
|
|
|
|
if('client_lastconnected' in event.updated_properties) {
|
|
|
|
this.currentClientStatus.joinTimestamp = event.client_properties.client_lastconnected;
|
|
|
|
this.events.fire("notify_cache_changed", { category: "online-state" });
|
|
|
|
}
|
|
|
|
|
|
|
|
if('client_country' in event.updated_properties) {
|
|
|
|
this.updateCachedCountry(client);
|
|
|
|
this.events.fire("notify_cache_changed", { category: "country" });
|
|
|
|
}
|
|
|
|
|
|
|
|
for(const key of ["client_away", "client_away_message", "client_input_muted", "client_input_hardware", "client_output_muted", "client_output_hardware"]) {
|
|
|
|
if(key in event.updated_properties) {
|
|
|
|
this.updateCachedClientStatus(client);
|
|
|
|
this.events.fire("notify_cache_changed", { category: "status" });
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if('client_platform' in event.updated_properties || 'client_version' in event.updated_properties) {
|
|
|
|
this.currentClientStatus.version = {
|
|
|
|
platform: client.properties.client_platform,
|
|
|
|
version: client.properties.client_version
|
|
|
|
};
|
|
|
|
this.events.fire("notify_cache_changed", { category: "version" });
|
|
|
|
}
|
|
|
|
|
|
|
|
if('client_teaforo_flags' in event.updated_properties || 'client_teaforo_name' in event.updated_properties || 'client_teaforo_id' in event.updated_properties) {
|
|
|
|
this.updateForumAccount(client);
|
|
|
|
this.events.fire("notify_cache_changed", { category: "forum-account" });
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
|
|
|
|
events.push(client.events.on("notify_audio_level_changed", () => {
|
|
|
|
this.updateCachedVolume(client);
|
|
|
|
this.events.fire("notify_cache_changed", { category: "volume" });
|
|
|
|
}));
|
|
|
|
|
|
|
|
events.push(client.events.on("notify_mute_state_change", () => {
|
|
|
|
this.updateCachedVolume(client);
|
|
|
|
this.events.fire("notify_cache_changed", { category: "volume" });
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private updateCachedClientStatus(client: ClientEntry) {
|
|
|
|
this.currentClientStatus.status = {
|
|
|
|
away: client.properties.client_away ? client.properties.client_away_message ? client.properties.client_away_message : true : false,
|
|
|
|
microphoneMuted: client.properties.client_input_muted,
|
|
|
|
microphoneDisabled: !client.properties.client_input_hardware,
|
|
|
|
speakerMuted: client.properties.client_output_muted,
|
|
|
|
speakerDisabled: !client.properties.client_output_hardware
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
private updateCachedCountry(client: ClientEntry) {
|
|
|
|
this.currentClientStatus.country = {
|
|
|
|
flag: client.properties.client_country,
|
2021-03-23 12:42:32 +00:00
|
|
|
name: i18nc.getCountryName(client.properties.client_country.toUpperCase()),
|
2020-12-09 19:44:33 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
private updateCachedVolume(client: ClientEntry) {
|
|
|
|
this.currentClientStatus.volume = {
|
|
|
|
volume: client.getAudioVolume(),
|
|
|
|
muted: client.isMuted()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private updateForumAccount(client: ClientEntry) {
|
|
|
|
if(client.properties.client_teaforo_id) {
|
|
|
|
this.currentClientStatus.forumAccount = {
|
|
|
|
flags: client.properties.client_teaforo_flags,
|
|
|
|
nickname: client.properties.client_teaforo_name,
|
|
|
|
userId: client.properties.client_teaforo_id
|
|
|
|
};
|
|
|
|
} else {
|
|
|
|
this.currentClientStatus.forumAccount = undefined;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-24 17:39:19 +00:00
|
|
|
private updateChannelGroup(client: ClientEntry) {
|
|
|
|
this.currentClientStatus.channelGroup = client.properties.client_channel_group_id;
|
|
|
|
this.currentClientStatus.channelGroupInheritedChannel = client.properties.client_channel_group_inherited_channel_id;
|
|
|
|
if(this.currentClientStatus.channelGroupInheritedChannel === client.currentChannel().channelId) {
|
|
|
|
this.currentClientStatus.channelGroupInheritedChannel = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-09 19:44:33 +00:00
|
|
|
private initializeClientInfo(client: ClientEntry) {
|
|
|
|
this.currentClientStatus = {
|
2021-04-27 11:30:33 +00:00
|
|
|
type: client instanceof LocalClientEntry ? "self" : client.getClientType() === ClientType.CLIENT_QUERY ? "query" : "voice",
|
2020-12-09 19:44:33 +00:00
|
|
|
name: client.properties.client_nickname,
|
|
|
|
databaseId: client.properties.client_database_id,
|
|
|
|
uniqueId: client.properties.client_unique_identifier,
|
|
|
|
clientId: client.clientId(),
|
|
|
|
|
|
|
|
description: client.properties.client_description,
|
2021-03-24 17:39:19 +00:00
|
|
|
|
|
|
|
channelGroup: 0,
|
|
|
|
channelGroupInheritedChannel: 0,
|
|
|
|
|
2020-12-09 19:44:33 +00:00
|
|
|
serverGroups: client.assignedServerGroupIds(),
|
2021-03-24 17:39:19 +00:00
|
|
|
|
2020-12-09 19:44:33 +00:00
|
|
|
country: undefined,
|
|
|
|
forumAccount: undefined,
|
|
|
|
joinTimestamp: client.properties.client_lastconnected,
|
|
|
|
leaveTimestamp: 0,
|
|
|
|
status: undefined,
|
|
|
|
volume: undefined,
|
|
|
|
version: {
|
|
|
|
platform: client.properties.client_platform,
|
|
|
|
version: client.properties.client_version
|
|
|
|
}
|
|
|
|
};
|
2021-03-24 17:39:19 +00:00
|
|
|
this.updateChannelGroup(client);
|
2020-12-09 19:44:33 +00:00
|
|
|
this.updateCachedClientStatus(client);
|
|
|
|
this.updateCachedCountry(client);
|
|
|
|
this.updateCachedVolume(client);
|
|
|
|
this.updateForumAccount(client);
|
|
|
|
}
|
|
|
|
}
|