Showing client channel group inheritance

master
WolverinDEV 2021-03-24 18:39:19 +01:00
parent 5a02b70fb1
commit 0ad881cd27
8 changed files with 115 additions and 17 deletions

View File

@ -3,6 +3,7 @@
- Improved the avatar upload modal (now way more intuitive)
- 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
- Showing channel group inheritance within the client info frame
* **23.03.21**
- Made the permission editor popoutable

View File

@ -25,7 +25,10 @@ export type CachedClientInfo = {
volume: { volume: number, muted: boolean },
status: ClientStatusInfo,
forumAccount: ClientForumInfo | undefined,
channelGroup: number,
channelGroupInheritedChannel: number,
serverGroups: number[],
version: ClientVersionInfo
}
@ -127,8 +130,8 @@ export class SelectedClientInfo {
this.events.fire("notify_cache_changed", { category: "description" });
}
if('client_channel_group_id' in event.updated_properties) {
this.currentClientStatus.channelGroup = event.client_properties.client_channel_group_id;
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" });
}
@ -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) {
this.currentClientStatus = {
type: client instanceof LocalClientEntry ? "self" : client.properties.client_type === ClientType.CLIENT_QUERY ? "query" : "voice",
@ -227,8 +238,12 @@ export class SelectedClientInfo {
clientId: client.clientId(),
description: client.properties.client_description,
channelGroup: client.properties.client_channel_group_id,
channelGroup: 0,
channelGroupInheritedChannel: 0,
serverGroups: client.assignedServerGroupIds(),
country: undefined,
forumAccount: undefined,
joinTimestamp: client.properties.client_lastconnected,
@ -240,6 +255,7 @@ export class SelectedClientInfo {
version: client.properties.client_version
}
};
this.updateChannelGroup(client);
this.updateCachedClientStatus(client);
this.updateCachedCountry(client);
this.updateCachedVolume(client);

View File

@ -147,7 +147,7 @@ export class ClientConnectionInfo {
export interface ClientEvents extends ChannelTreeEntryEvents {
notify_properties_updated: {
updated_properties: {[Key in keyof ClientProperties]: ClientProperties[Key]};
updated_properties: Partial<ClientProperties>;
client_properties: ClientProperties
},
notify_mute_state_change: { muted: boolean }

View File

@ -1,5 +1,5 @@
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 {openClientInfo} from "tc-shared/ui/modal/ModalClientInfo";
@ -10,6 +10,9 @@ export class ClientInfoController {
private connection: ConnectionHandler;
private listenerConnection: (() => void)[];
private listenerInheritedChannel: (() => void)[];
private inheritedChannelInfo: InheritedChannelInfo;
constructor() {
this.uiEvents = new Registry<ClientInfoEvents>();
@ -35,6 +38,7 @@ export class ClientInfoController {
spawnAvatarUpload(this.connection);
});
this.uiEvents.on("action_show_full_info", () => {
const client = this.connection?.getSelectedClientInfo().getClient();
if(client) {
@ -46,6 +50,9 @@ export class ClientInfoController {
destroy() {
this.listenerConnection.forEach(callback => callback());
this.listenerConnection = [];
this.listenerInheritedChannel?.forEach(callback => callback());
this.listenerInheritedChannel = [];
}
setConnectionHandler(connection: ConnectionHandler) {
@ -61,6 +68,7 @@ export class ClientInfoController {
this.initializeConnection(connection);
}
this.sendClient();
this.updateInheritedInfo();
}
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 => {
switch (event.category) {
case "name":
@ -105,6 +116,7 @@ export class ClientInfoController {
break;
case "group-channel":
this.updateInheritedInfo();
this.sendChannelGroup();
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 {
const uniqueServerId = this.connection?.channelTree.server.properties.virtualserver_unique_identifier;
const group = type === "channel" ? this.connection?.groups.findChannelGroup(groupId) : this.connection?.groups.findServerGroup(groupId);
@ -178,9 +227,12 @@ export class ClientInfoController {
private sendChannelGroup() {
const info = this.connection?.getSelectedClientInfo().getInfo();
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 {
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
});
}
}

View File

@ -57,6 +57,11 @@ export type ClientVersionInfo = {
version: string
}
export type InheritedChannelInfo = {
channelId: number,
channelName: string
}
export interface ClientInfoEvents {
action_show_full_info: {},
action_edit_avatar: {},
@ -75,7 +80,10 @@ export interface ClientInfoEvents {
notify_client_name: { name: 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_status: { status: ClientStatusInfo },
notify_online: { status: ClientInfoOnline },

View File

@ -359,6 +359,12 @@ $bot_thumbnail_height: 9em;
justify-content: flex-start;
flex-direction: row-reverse;
}
.channelGroupInherited {
display: flex;
flex-direction: row;
justify-content: flex-end;
}
}
&.clientTeaforoAccount {

View File

@ -8,7 +8,7 @@ import {
ClientInfoOnline,
ClientStatusInfo,
ClientVersionInfo,
ClientVolumeInfo,
ClientVolumeInfo, InheritedChannelInfo,
OptionalClientInfoInfo
} from "tc-shared/ui/frames/side/ClientInfoDefinitions";
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 {Translatable} from "tc-shared/ui/react-elements/i18n";
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 {useDependentState} from "tc-shared/ui/react-elements/Helper";
import {format_online_time} from "tc-shared/utils/TimeUtils";
@ -420,11 +420,29 @@ const ChannelGroupRenderer = () => {
return undefined;
}, [ 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;
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>&nbsp;
{inheritedChannel.channelName}
</div>
</React.Fragment>
)
} else {
body = groupRendered;
}
} else {
body = <React.Fragment key={"loading"}><Translatable>loading</Translatable> <LoadingDots /></React.Fragment>;
}

View File

@ -340,7 +340,4 @@ export function spawnAvatarUpload(connection: ConnectionHandler) {
/* Trying to prompt the user */
controller.events.fire("action_open_select");
}
(window as any).test = () => spawnAvatarUpload(server_connections.getActiveConnectionHandler());
setTimeout(() => (window as any).test(), 1500);
}