Correctly handling the server side bar

master
WolverinDEV 2021-01-05 16:26:26 +01:00
parent f1d24df7ac
commit b112a79113
10 changed files with 120 additions and 5 deletions

View File

@ -42,6 +42,10 @@ export class SideBarManager {
this.setSideBarContent("channel"); this.setSideBarContent("channel");
} }
showServer() {
this.setSideBarContent("server");
}
showClientInfo(client: ClientEntry) { showClientInfo(client: ClientEntry) {
this.connection.getSelectedClientInfo().setClient(client); this.connection.getSelectedClientInfo().setClient(client);
this.setSideBarContent("client-info"); this.setSideBarContent("client-info");

View File

@ -189,7 +189,7 @@ export class ChannelTree {
if(settings.static_global(Settings.KEY_SWITCH_INSTANT_CHAT)) { if(settings.static_global(Settings.KEY_SWITCH_INSTANT_CHAT)) {
const conversation = this.client.getChannelConversations().findOrCreateConversation(0); const conversation = this.client.getChannelConversations().findOrCreateConversation(0);
this.client.getChannelConversations().setSelectedConversation(conversation); this.client.getChannelConversations().setSelectedConversation(conversation);
this.client.getSideBar().showChannel(); this.client.getSideBar().showServer();
} }
} }
} }

View File

@ -193,7 +193,7 @@ export class ServerEntry extends ChannelTreeEntry<ServerEvents> {
name: tr("Join server text channel"), name: tr("Join server text channel"),
callback: () => { callback: () => {
this.channelTree.client.getChannelConversations().setSelectedConversation(this.channelTree.client.getChannelConversations().findOrCreateConversation(0)); this.channelTree.client.getChannelConversations().setSelectedConversation(this.channelTree.client.getChannelConversations().findOrCreateConversation(0));
this.channelTree.client.getSideBar().showChannel(); this.channelTree.client.getSideBar().showServer();
}, },
visible: !settings.static_global(Settings.KEY_SWITCH_INSTANT_CHAT) visible: !settings.static_global(Settings.KEY_SWITCH_INSTANT_CHAT)
}, { }, {

View File

@ -118,6 +118,16 @@ export class SideBarController {
}); });
break; break;
case "server":
this.uiEvents.fire_react("notify_content_data", {
content: "server",
data: this.currentConnection ? {
chatEvents: this.channelBar.getChannelConversationController().getUiEvents(),
handlerId: this.currentConnection.handlerId
} : undefined
});
break;
case "private-chat": case "private-chat":
if(!this.currentConnection) { if(!this.currentConnection) {
logWarn(LogCategory.GENERAL, tr("Received private chat content data request without an active connection.")); logWarn(LogCategory.GENERAL, tr("Received private chat content data request without an active connection."));

View File

@ -5,10 +5,11 @@ import {SideHeaderEvents} from "tc-shared/ui/frames/side/HeaderDefinitions";
import {ChannelBarUiEvents} from "tc-shared/ui/frames/side/ChannelBarDefinitions"; import {ChannelBarUiEvents} from "tc-shared/ui/frames/side/ChannelBarDefinitions";
import {MusicBotUiEvents} from "tc-shared/ui/frames/side/MusicBotDefinitions"; import {MusicBotUiEvents} from "tc-shared/ui/frames/side/MusicBotDefinitions";
import {MusicPlaylistUiEvents} from "tc-shared/ui/frames/side/MusicPlaylistDefinitions"; import {MusicPlaylistUiEvents} from "tc-shared/ui/frames/side/MusicPlaylistDefinitions";
import {ChannelConversationUiEvents} from "tc-shared/ui/frames/side/ChannelConversationDefinitions";
/* TODO: Somehow outsource the event registries to IPC? */ /* TODO: Somehow outsource the event registries to IPC? */
export type SideBarType = "none" | "channel" | "private-chat" | "client-info" | "music-manage"; export type SideBarType = "none" | "server" | "channel" | "private-chat" | "client-info" | "music-manage";
export interface SideBarTypeData { export interface SideBarTypeData {
"none": {}, "none": {},
"channel": { "channel": {
@ -24,6 +25,10 @@ export interface SideBarTypeData {
"music-manage": { "music-manage": {
botEvents: Registry<MusicBotUiEvents>, botEvents: Registry<MusicBotUiEvents>,
playlistEvents: Registry<MusicPlaylistUiEvents> playlistEvents: Registry<MusicPlaylistUiEvents>
},
"server": {
handlerId: string,
chatEvents: Registry<ChannelConversationUiEvents>
} }
} }

View File

@ -10,6 +10,7 @@ import {LogCategory, logWarn} from "tc-shared/log";
import React = require("react"); import React = require("react");
import {ErrorBoundary} from "tc-shared/ui/react-elements/ErrorBoundary"; import {ErrorBoundary} from "tc-shared/ui/react-elements/ErrorBoundary";
import {MusicBotRenderer} from "tc-shared/ui/frames/side/MusicBotRenderer"; import {MusicBotRenderer} from "tc-shared/ui/frames/side/MusicBotRenderer";
import {ConversationPanel} from "tc-shared/ui/frames/side/AbstractConversationRenderer";
const cssStyle = require("./SideBarRenderer.scss"); const cssStyle = require("./SideBarRenderer.scss");
@ -38,6 +39,21 @@ const ContentRendererChannel = () => {
); );
}; };
const ContentRendererServer = () => {
const contentData = useContentData("server");
if(!contentData) { return null; }
return (
<ConversationPanel
key={"server"}
events={contentData.chatEvents}
handlerId={contentData.handlerId}
messagesDeletable={true}
noFirstMessageOverlay={false}
/>
);
};
const ContentRendererPrivateConversation = () => { const ContentRendererPrivateConversation = () => {
const contentData = useContentData("private-chat"); const contentData = useContentData("private-chat");
if(!contentData) { return null; } if(!contentData) { return null; }
@ -75,6 +91,12 @@ const ContentRendererMusicManage = () => {
const SideBarFrame = (props: { type: SideBarType }) => { const SideBarFrame = (props: { type: SideBarType }) => {
switch (props.type) { switch (props.type) {
case "server":
return (
<ErrorBoundary key={props.type}>
<ContentRendererServer />
</ErrorBoundary>
)
case "channel": case "channel":
return ( return (
<ErrorBoundary key={props.type}> <ErrorBoundary key={props.type}>
@ -116,6 +138,10 @@ const SideBarHeader = (props: { type: SideBarType, eventsHeader: Registry<SideHe
headerState = { state: "none" }; headerState = { state: "none" };
break; break;
case "server":
headerState = { state: "conversation", mode: "server" };
break;
case "channel": case "channel":
headerState = { state: "conversation", mode: "channel" }; headerState = { state: "conversation", mode: "channel" };
break; break;

View File

@ -56,6 +56,10 @@ export class ChannelBarController {
this.uiEvents.destroy(); this.uiEvents.destroy();
} }
getChannelConversationController() : ChannelConversationController {
return this.channelConversations;
}
setConnectionHandler(handler: ConnectionHandler) { setConnectionHandler(handler: ConnectionHandler) {
if(this.currentConnection === handler) { if(this.currentConnection === handler) {
return; return;

View File

@ -89,6 +89,7 @@ export class SideHeaderController {
this.uiEvents.on("query_current_channel_state", event => this.sendChannelState(event.mode)); this.uiEvents.on("query_current_channel_state", event => this.sendChannelState(event.mode));
this.uiEvents.on("query_private_conversations", () => this.sendPrivateConversationInfo()); this.uiEvents.on("query_private_conversations", () => this.sendPrivateConversationInfo());
this.uiEvents.on("query_ping", () => this.sendPing()); this.uiEvents.on("query_ping", () => this.sendPing());
this.uiEvents.on("query_server_info", () => this.sendServerInfo());
} }
private initializeConnection() { private initializeConnection() {
@ -144,6 +145,11 @@ export class SideHeaderController {
this.listenerConnection.push(this.connection.getPrivateConversations().events.on("notify_unread_count_changed", () => this.sendPrivateConversationInfo())); this.listenerConnection.push(this.connection.getPrivateConversations().events.on("notify_unread_count_changed", () => this.sendPrivateConversationInfo()));
this.listenerConnection.push(this.connection.getPrivateConversations().events.on(["notify_conversation_destroyed", "notify_conversation_destroyed"], () => this.sendPrivateConversationInfo())); this.listenerConnection.push(this.connection.getPrivateConversations().events.on(["notify_conversation_destroyed", "notify_conversation_destroyed"], () => this.sendPrivateConversationInfo()));
this.listenerConnection.push(this.connection.getSelectedClientInfo().events.on("notify_client_changed", () => this.sendClientInfoOwnClient())); this.listenerConnection.push(this.connection.getSelectedClientInfo().events.on("notify_client_changed", () => this.sendClientInfoOwnClient()));
this.listenerConnection.push(this.connection.channelTree.server.events.on("notify_properties_updated", event => {
if("virtualserver_icon_id" in event.updated_properties || "virtualserver_name" in event.updated_properties) {
this.sendServerInfo();
}
}));
} }
setConnectionHandler(connection: ConnectionHandler) { setConnectionHandler(connection: ConnectionHandler) {
@ -303,4 +309,21 @@ export class SideHeaderController {
this.uiEvents.fire_react("notify_client_info_own_client", { isOwnClient: false }); this.uiEvents.fire_react("notify_client_info_own_client", { isOwnClient: false });
} }
} }
private sendServerInfo() {
if(this.connection?.connected) {
this.uiEvents.fire_react("notify_server_info", {
info: {
name: this.connection.channelTree.server.properties.virtualserver_name,
icon: {
handlerId: this.connection.handlerId,
serverUniqueId: this.connection.getCurrentServerUniqueId(),
iconId: this.connection.channelTree.server.properties.virtualserver_icon_id
}
}
})
} else {
this.uiEvents.fire_react("notify_server_info", { info: undefined });
}
}
} }

View File

@ -7,7 +7,7 @@ export type SideHeaderStateNone = {
export type SideHeaderStateConversation = { export type SideHeaderStateConversation = {
state: "conversation", state: "conversation",
mode: "channel" | "private" mode: "channel" | "private" | "server"
}; };
export type SideHeaderStateClient = { export type SideHeaderStateClient = {
@ -38,12 +38,18 @@ export type PrivateConversationInfo = {
open: number open: number
}; };
export type SideHeaderServerInfo = {
name: string,
icon: RemoteIconInfo
}
export interface SideHeaderEvents { export interface SideHeaderEvents {
action_bot_manage: {}, action_bot_manage: {},
action_bot_add_song: {}, action_bot_add_song: {},
action_switch_channel_chat: {}, action_switch_channel_chat: {},
action_open_conversation: {}, action_open_conversation: {},
query_server_info: {},
query_current_channel_state: { mode: "voice" | "text" }, query_current_channel_state: { mode: "voice" | "text" },
query_private_conversations: {}, query_private_conversations: {},
query_client_info_own_client: {}, query_client_info_own_client: {},
@ -61,5 +67,8 @@ export interface SideHeaderEvents {
}, },
notify_client_info_own_client: { notify_client_info_own_client: {
isOwnClient: boolean isOwnClient: boolean
},
notify_server_info: {
info: SideHeaderServerInfo | undefined
} }
} }

View File

@ -4,7 +4,7 @@ import {
SideHeaderEvents, SideHeaderEvents,
SideHeaderState, SideHeaderState,
SideHeaderChannelState, SideHeaderChannelState,
SideHeaderPingInfo, PrivateConversationInfo SideHeaderPingInfo, PrivateConversationInfo, SideHeaderServerInfo
} from "tc-shared/ui/frames/side/HeaderDefinitions"; } from "tc-shared/ui/frames/side/HeaderDefinitions";
import {Translatable, VariadicTranslatable} from "tc-shared/ui/react-elements/i18n"; import {Translatable, VariadicTranslatable} from "tc-shared/ui/react-elements/i18n";
import {useContext, useState} from "react"; import {useContext, useState} from "react";
@ -74,6 +74,38 @@ const BlockChannelState = (props: { mode: "voice" | "text" }) => {
); );
} }
const ServerInfoRenderer = React.memo((props: { info: SideHeaderServerInfo | undefined }) => {
if(!props.info) {
return <div className={cssStyle.value} key={"not-connected"}><Translatable>Not connected</Translatable></div>;
}
let icon;
if(props.info.icon.iconId !== 0) {
const remoteIcon = getIconManager().resolveIcon(props.info.icon.iconId, props.info.icon.serverUniqueId, props.info.icon.handlerId);
icon = <RemoteIconRenderer icon={remoteIcon} className={cssStyle.icon} key={"icon-" + props.info.icon.iconId} />;
}
return (
<div className={cssStyle.value} key={"connected"}>{icon}{props.info.name}</div>
);
});
const BlockServerState = () => {
const events = useContext(EventsContext);
const [ info, setInfo ] = useState<SideHeaderServerInfo | undefined>(() => {
events.fire("query_server_info");
return undefined;
});
events.reactUse("notify_server_info", event => setInfo(event.info));
return (
<Block target={"left"}>
<Translatable>You're chatting on Server</Translatable>
<ServerInfoRenderer info={info} />
</Block>
);
}
const BlockPing = () => { const BlockPing = () => {
const events = useContext(EventsContext); const events = useContext(EventsContext);
const [ pingInfo, setPingInfo ] = useState<SideHeaderPingInfo>(() => { const [ pingInfo, setPingInfo ] = useState<SideHeaderPingInfo>(() => {
@ -221,6 +253,8 @@ const BlockBottomLeft = () => {
case "conversation": case "conversation":
if(state.mode === "private") { if(state.mode === "private") {
return <BlockButtonSwitchToChannelChat key={"switch-channel-chat"} />; return <BlockButtonSwitchToChannelChat key={"switch-channel-chat"} />;
} else if(state.mode === "server") {
return <BlockServerState key={"server"} />
} else { } else {
return <BlockChannelState mode={"text"} key={"text-state"} />; return <BlockChannelState mode={"text"} key={"text-state"} />;
} }