Showing client channel group inheritance
This commit is contained in:
parent
5a02b70fb1
commit
0ad881cd27
8 changed files with 115 additions and 17 deletions
|
@ -3,6 +3,7 @@
|
||||||
- Improved the avatar upload modal (now way more intuitive)
|
- Improved the avatar upload modal (now way more intuitive)
|
||||||
- Fixed a bug which cause client avatars to be stuck within the loading screen
|
- Fixed a bug which cause client avatars to be stuck within the loading screen
|
||||||
- Don't spam permission errors if we don't have the permission to view the channel description
|
- Don't spam permission errors if we don't have the permission to view the channel description
|
||||||
|
- Showing channel group inheritance within the client info frame
|
||||||
|
|
||||||
* **23.03.21**
|
* **23.03.21**
|
||||||
- Made the permission editor popoutable
|
- Made the permission editor popoutable
|
||||||
|
|
|
@ -25,7 +25,10 @@ export type CachedClientInfo = {
|
||||||
volume: { volume: number, muted: boolean },
|
volume: { volume: number, muted: boolean },
|
||||||
status: ClientStatusInfo,
|
status: ClientStatusInfo,
|
||||||
forumAccount: ClientForumInfo | undefined,
|
forumAccount: ClientForumInfo | undefined,
|
||||||
|
|
||||||
channelGroup: number,
|
channelGroup: number,
|
||||||
|
channelGroupInheritedChannel: number,
|
||||||
|
|
||||||
serverGroups: number[],
|
serverGroups: number[],
|
||||||
version: ClientVersionInfo
|
version: ClientVersionInfo
|
||||||
}
|
}
|
||||||
|
@ -127,8 +130,8 @@ export class SelectedClientInfo {
|
||||||
this.events.fire("notify_cache_changed", { category: "description" });
|
this.events.fire("notify_cache_changed", { category: "description" });
|
||||||
}
|
}
|
||||||
|
|
||||||
if('client_channel_group_id' in event.updated_properties) {
|
if('client_channel_group_id' in event.updated_properties || 'client_channel_group_inherited_channel_id' in event.updated_properties) {
|
||||||
this.currentClientStatus.channelGroup = event.client_properties.client_channel_group_id;
|
this.updateChannelGroup(client);
|
||||||
this.events.fire("notify_cache_changed", { category: "group-channel" });
|
this.events.fire("notify_cache_changed", { category: "group-channel" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,6 +221,14 @@ export class SelectedClientInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
private initializeClientInfo(client: ClientEntry) {
|
||||||
this.currentClientStatus = {
|
this.currentClientStatus = {
|
||||||
type: client instanceof LocalClientEntry ? "self" : client.properties.client_type === ClientType.CLIENT_QUERY ? "query" : "voice",
|
type: client instanceof LocalClientEntry ? "self" : client.properties.client_type === ClientType.CLIENT_QUERY ? "query" : "voice",
|
||||||
|
@ -227,8 +238,12 @@ export class SelectedClientInfo {
|
||||||
clientId: client.clientId(),
|
clientId: client.clientId(),
|
||||||
|
|
||||||
description: client.properties.client_description,
|
description: client.properties.client_description,
|
||||||
channelGroup: client.properties.client_channel_group_id,
|
|
||||||
|
channelGroup: 0,
|
||||||
|
channelGroupInheritedChannel: 0,
|
||||||
|
|
||||||
serverGroups: client.assignedServerGroupIds(),
|
serverGroups: client.assignedServerGroupIds(),
|
||||||
|
|
||||||
country: undefined,
|
country: undefined,
|
||||||
forumAccount: undefined,
|
forumAccount: undefined,
|
||||||
joinTimestamp: client.properties.client_lastconnected,
|
joinTimestamp: client.properties.client_lastconnected,
|
||||||
|
@ -240,6 +255,7 @@ export class SelectedClientInfo {
|
||||||
version: client.properties.client_version
|
version: client.properties.client_version
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
this.updateChannelGroup(client);
|
||||||
this.updateCachedClientStatus(client);
|
this.updateCachedClientStatus(client);
|
||||||
this.updateCachedCountry(client);
|
this.updateCachedCountry(client);
|
||||||
this.updateCachedVolume(client);
|
this.updateCachedVolume(client);
|
||||||
|
|
|
@ -147,7 +147,7 @@ export class ClientConnectionInfo {
|
||||||
|
|
||||||
export interface ClientEvents extends ChannelTreeEntryEvents {
|
export interface ClientEvents extends ChannelTreeEntryEvents {
|
||||||
notify_properties_updated: {
|
notify_properties_updated: {
|
||||||
updated_properties: {[Key in keyof ClientProperties]: ClientProperties[Key]};
|
updated_properties: Partial<ClientProperties>;
|
||||||
client_properties: ClientProperties
|
client_properties: ClientProperties
|
||||||
},
|
},
|
||||||
notify_mute_state_change: { muted: boolean }
|
notify_mute_state_change: { muted: boolean }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
import {ConnectionHandler} from "tc-shared/ConnectionHandler";
|
||||||
import {ClientGroupInfo, ClientInfoEvents,} from "tc-shared/ui/frames/side/ClientInfoDefinitions";
|
import {ClientGroupInfo, ClientInfoEvents, InheritedChannelInfo,} from "tc-shared/ui/frames/side/ClientInfoDefinitions";
|
||||||
|
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "tc-shared/events";
|
||||||
import {openClientInfo} from "tc-shared/ui/modal/ModalClientInfo";
|
import {openClientInfo} from "tc-shared/ui/modal/ModalClientInfo";
|
||||||
|
@ -10,6 +10,9 @@ export class ClientInfoController {
|
||||||
|
|
||||||
private connection: ConnectionHandler;
|
private connection: ConnectionHandler;
|
||||||
private listenerConnection: (() => void)[];
|
private listenerConnection: (() => void)[];
|
||||||
|
private listenerInheritedChannel: (() => void)[];
|
||||||
|
|
||||||
|
private inheritedChannelInfo: InheritedChannelInfo;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.uiEvents = new Registry<ClientInfoEvents>();
|
this.uiEvents = new Registry<ClientInfoEvents>();
|
||||||
|
@ -35,6 +38,7 @@ export class ClientInfoController {
|
||||||
|
|
||||||
spawnAvatarUpload(this.connection);
|
spawnAvatarUpload(this.connection);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.uiEvents.on("action_show_full_info", () => {
|
this.uiEvents.on("action_show_full_info", () => {
|
||||||
const client = this.connection?.getSelectedClientInfo().getClient();
|
const client = this.connection?.getSelectedClientInfo().getClient();
|
||||||
if(client) {
|
if(client) {
|
||||||
|
@ -46,6 +50,9 @@ export class ClientInfoController {
|
||||||
destroy() {
|
destroy() {
|
||||||
this.listenerConnection.forEach(callback => callback());
|
this.listenerConnection.forEach(callback => callback());
|
||||||
this.listenerConnection = [];
|
this.listenerConnection = [];
|
||||||
|
|
||||||
|
this.listenerInheritedChannel?.forEach(callback => callback());
|
||||||
|
this.listenerInheritedChannel = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
setConnectionHandler(connection: ConnectionHandler) {
|
setConnectionHandler(connection: ConnectionHandler) {
|
||||||
|
@ -61,6 +68,7 @@ export class ClientInfoController {
|
||||||
this.initializeConnection(connection);
|
this.initializeConnection(connection);
|
||||||
}
|
}
|
||||||
this.sendClient();
|
this.sendClient();
|
||||||
|
this.updateInheritedInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
private initializeConnection(connection: ConnectionHandler) {
|
private initializeConnection(connection: ConnectionHandler) {
|
||||||
|
@ -85,7 +93,10 @@ export class ClientInfoController {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.listenerConnection.push(connection.getSelectedClientInfo().events.on("notify_client_changed", () => this.sendClient()));
|
this.listenerConnection.push(connection.getSelectedClientInfo().events.on("notify_client_changed", () => {
|
||||||
|
this.updateInheritedInfo();
|
||||||
|
this.sendClient();
|
||||||
|
}));
|
||||||
this.listenerConnection.push(connection.getSelectedClientInfo().events.on("notify_cache_changed", event => {
|
this.listenerConnection.push(connection.getSelectedClientInfo().events.on("notify_cache_changed", event => {
|
||||||
switch (event.category) {
|
switch (event.category) {
|
||||||
case "name":
|
case "name":
|
||||||
|
@ -105,6 +116,7 @@ export class ClientInfoController {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "group-channel":
|
case "group-channel":
|
||||||
|
this.updateInheritedInfo();
|
||||||
this.sendChannelGroup();
|
this.sendChannelGroup();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -131,6 +143,43 @@ export class ClientInfoController {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private updateInheritedInfo() {
|
||||||
|
let newChannelId;
|
||||||
|
const selectInfo = this.connection?.getSelectedClientInfo().getInfo();
|
||||||
|
if(selectInfo?.channelGroupInheritedChannel) {
|
||||||
|
newChannelId = selectInfo.channelGroupInheritedChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.listenerInheritedChannel?.forEach(callback => callback());
|
||||||
|
this.listenerInheritedChannel = undefined;
|
||||||
|
if(!newChannelId) {
|
||||||
|
this.inheritedChannelInfo = undefined;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetChannel = this.connection.channelTree.findChannel(newChannelId);
|
||||||
|
if(!targetChannel) {
|
||||||
|
this.inheritedChannelInfo = {
|
||||||
|
channelId: newChannelId,
|
||||||
|
channelName: tr("Unknown channel")
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.inheritedChannelInfo = {
|
||||||
|
channelId: targetChannel.channelId,
|
||||||
|
channelName: targetChannel.channelName()
|
||||||
|
};
|
||||||
|
|
||||||
|
this.listenerInheritedChannel = [];
|
||||||
|
this.listenerInheritedChannel.push(targetChannel.events.on("notify_properties_updated", event => {
|
||||||
|
if("channel_name" in event.updated_properties) {
|
||||||
|
this.inheritedChannelInfo.channelName = event.channel_properties.channel_name;
|
||||||
|
this.sendChannelGroup();
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
private generateGroupInfo(groupId: number, type: "channel" | "server") : ClientGroupInfo {
|
private generateGroupInfo(groupId: number, type: "channel" | "server") : ClientGroupInfo {
|
||||||
const uniqueServerId = this.connection?.channelTree.server.properties.virtualserver_unique_identifier;
|
const uniqueServerId = this.connection?.channelTree.server.properties.virtualserver_unique_identifier;
|
||||||
const group = type === "channel" ? this.connection?.groups.findChannelGroup(groupId) : this.connection?.groups.findServerGroup(groupId);
|
const group = type === "channel" ? this.connection?.groups.findChannelGroup(groupId) : this.connection?.groups.findServerGroup(groupId);
|
||||||
|
@ -178,9 +227,12 @@ export class ClientInfoController {
|
||||||
private sendChannelGroup() {
|
private sendChannelGroup() {
|
||||||
const info = this.connection?.getSelectedClientInfo().getInfo();
|
const info = this.connection?.getSelectedClientInfo().getInfo();
|
||||||
if(typeof info === "undefined") {
|
if(typeof info === "undefined") {
|
||||||
this.uiEvents.fire_react("notify_channel_group", { group: undefined });
|
this.uiEvents.fire_react("notify_channel_group", { group: undefined, inheritedChannel: this.inheritedChannelInfo });
|
||||||
} else {
|
} else {
|
||||||
this.uiEvents.fire_react("notify_channel_group", { group: this.generateGroupInfo(info.channelGroup, "channel") });
|
this.uiEvents.fire_react("notify_channel_group", {
|
||||||
|
group: this.generateGroupInfo(info.channelGroup, "channel"),
|
||||||
|
inheritedChannel: this.inheritedChannelInfo
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,11 @@ export type ClientVersionInfo = {
|
||||||
version: string
|
version: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type InheritedChannelInfo = {
|
||||||
|
channelId: number,
|
||||||
|
channelName: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface ClientInfoEvents {
|
export interface ClientInfoEvents {
|
||||||
action_show_full_info: {},
|
action_show_full_info: {},
|
||||||
action_edit_avatar: {},
|
action_edit_avatar: {},
|
||||||
|
@ -75,7 +80,10 @@ export interface ClientInfoEvents {
|
||||||
|
|
||||||
notify_client_name: { name: string },
|
notify_client_name: { name: string },
|
||||||
notify_client_description: { description: string }
|
notify_client_description: { description: string }
|
||||||
notify_channel_group: { group: ClientGroupInfo | undefined },
|
notify_channel_group: {
|
||||||
|
group: ClientGroupInfo | undefined,
|
||||||
|
inheritedChannel: InheritedChannelInfo | undefined
|
||||||
|
},
|
||||||
notify_server_groups: { groups: ClientGroupInfo[] },
|
notify_server_groups: { groups: ClientGroupInfo[] },
|
||||||
notify_status: { status: ClientStatusInfo },
|
notify_status: { status: ClientStatusInfo },
|
||||||
notify_online: { status: ClientInfoOnline },
|
notify_online: { status: ClientInfoOnline },
|
||||||
|
|
|
@ -359,6 +359,12 @@ $bot_thumbnail_height: 9em;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.channelGroupInherited {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.clientTeaforoAccount {
|
&.clientTeaforoAccount {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
ClientInfoOnline,
|
ClientInfoOnline,
|
||||||
ClientStatusInfo,
|
ClientStatusInfo,
|
||||||
ClientVersionInfo,
|
ClientVersionInfo,
|
||||||
ClientVolumeInfo,
|
ClientVolumeInfo, InheritedChannelInfo,
|
||||||
OptionalClientInfoInfo
|
OptionalClientInfoInfo
|
||||||
} from "tc-shared/ui/frames/side/ClientInfoDefinitions";
|
} from "tc-shared/ui/frames/side/ClientInfoDefinitions";
|
||||||
import {Registry} from "tc-shared/events";
|
import {Registry} from "tc-shared/events";
|
||||||
|
@ -16,7 +16,7 @@ import {ClientAvatar, getGlobalAvatarManagerFactory} from "tc-shared/file/Avatar
|
||||||
import {AvatarRenderer} from "tc-shared/ui/react-elements/Avatar";
|
import {AvatarRenderer} from "tc-shared/ui/react-elements/Avatar";
|
||||||
import {Translatable} from "tc-shared/ui/react-elements/i18n";
|
import {Translatable} from "tc-shared/ui/react-elements/i18n";
|
||||||
import {LoadingDots} from "tc-shared/ui/react-elements/LoadingDots";
|
import {LoadingDots} from "tc-shared/ui/react-elements/LoadingDots";
|
||||||
import {ClientTag} from "tc-shared/ui/tree/EntryTags";
|
import {ChannelTag, ClientTag} from "tc-shared/ui/tree/EntryTags";
|
||||||
import {guid} from "tc-shared/crypto/uid";
|
import {guid} from "tc-shared/crypto/uid";
|
||||||
import {useDependentState} from "tc-shared/ui/react-elements/Helper";
|
import {useDependentState} from "tc-shared/ui/react-elements/Helper";
|
||||||
import {format_online_time} from "tc-shared/utils/TimeUtils";
|
import {format_online_time} from "tc-shared/utils/TimeUtils";
|
||||||
|
@ -420,11 +420,29 @@ const ChannelGroupRenderer = () => {
|
||||||
return undefined;
|
return undefined;
|
||||||
}, [ client.contextHash ]);
|
}, [ client.contextHash ]);
|
||||||
|
|
||||||
events.reactUse("notify_channel_group", event => setChannelGroup(event.group), undefined, []);
|
const [ inheritedChannel, setInheritedChannel ] = useDependentState<InheritedChannelInfo>(() => undefined, [ client.contextHash ]);
|
||||||
|
|
||||||
|
events.reactUse("notify_channel_group", event => {
|
||||||
|
setChannelGroup(event.group);
|
||||||
|
setInheritedChannel(event.inheritedChannel);
|
||||||
|
}, undefined, []);
|
||||||
|
|
||||||
let body;
|
let body;
|
||||||
if(channelGroup) {
|
if(channelGroup) {
|
||||||
body = <GroupRenderer group={channelGroup} key={"group-" + channelGroup.groupId} />;
|
let groupRendered = <GroupRenderer group={channelGroup} key={"group-" + channelGroup.groupId} />;
|
||||||
|
if(inheritedChannel) {
|
||||||
|
body = (
|
||||||
|
<React.Fragment key={"inherited"}>
|
||||||
|
{groupRendered}
|
||||||
|
<div className={cssStyle.channelGroupInherited}>
|
||||||
|
<Translatable>Inherited from</Translatable>
|
||||||
|
{inheritedChannel.channelName}
|
||||||
|
</div>
|
||||||
|
</React.Fragment>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
body = groupRendered;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
body = <React.Fragment key={"loading"}><Translatable>loading</Translatable> <LoadingDots /></React.Fragment>;
|
body = <React.Fragment key={"loading"}><Translatable>loading</Translatable> <LoadingDots /></React.Fragment>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -340,7 +340,4 @@ export function spawnAvatarUpload(connection: ConnectionHandler) {
|
||||||
|
|
||||||
/* Trying to prompt the user */
|
/* Trying to prompt the user */
|
||||||
controller.events.fire("action_open_select");
|
controller.events.fire("action_open_select");
|
||||||
}
|
}
|
||||||
|
|
||||||
(window as any).test = () => spawnAvatarUpload(server_connections.getActiveConnectionHandler());
|
|
||||||
setTimeout(() => (window as any).test(), 1500);
|
|
Loading…
Add table
Reference in a new issue