TeaWeb/shared/js/SelectedClientInfo.ts

264 lines
10 KiB
TypeScript
Raw Normal View History

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";
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,
channelGroup: number,
channelGroupInheritedChannel: number,
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" });
}
if('client_channel_group_id' in event.updated_properties || 'client_channel_group_inherited_channel_id' in event.updated_properties) {
this.updateChannelGroup(client);
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()),
};
}
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;
}
}
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;
}
}
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",
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,
channelGroup: 0,
channelGroupInheritedChannel: 0,
serverGroups: client.assignedServerGroupIds(),
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
}
};
this.updateChannelGroup(client);
this.updateCachedClientStatus(client);
this.updateCachedCountry(client);
this.updateCachedVolume(client);
this.updateForumAccount(client);
}
}