[feature] add basic viewer

This commit is contained in:
Janis
2023-06-25 19:39:58 +02:00
parent c0f27e85c1
commit 40dbf72fcf
4 changed files with 108 additions and 14 deletions

View File

@@ -1,25 +1,66 @@
/* eslint-disable react-hooks/exhaustive-deps */
import "@styles/App.scss"; import "@styles/App.scss";
import { TS5Connection } from "./teamspeak5Handler"; import { TS5Connection } from "./teamspeak5Handler";
import { IChannel, IClient, IConnection } from "interfaces/teamspeak"; import { IChannel, IClient, IConnection } from "interfaces/teamspeak";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import Viewer from "./Viewer";
export default function App() { export default function App() {
const [clients, setClients] = useState<IClient[]>([]); const [clients, setClients] = useState<IClient[]>([]);
const [channels, setChannels] = useState<IChannel[]>([]); const [channels, setChannels] = useState<IChannel[]>([]);
const [connections, setConnections] = useState<IConnection[]>([]); const [connections, setConnections] = useState<IConnection[]>([]);
const [activeConnectionId, setActiveConnectionId] = useState<number>(1);
const [currentConnection, setCurrentConnection] = useState<IConnection | undefined>(undefined);
const [currentChannel, setCurrentChannel] = useState<IChannel | undefined>(undefined);
const [currentClient, setCurrentClient] = useState<IClient | undefined>(undefined);
function setCurrentStates() {
const currentConnection = connections.find((connection) => connection.id === activeConnectionId);
setCurrentConnection(currentConnection);
if (currentConnection) {
const currentClient = clients.find((client) => client.id === currentConnection.clientId);
setCurrentClient(currentClient);
if (currentClient) {
const currentChannel = channels.find((channel) => channel.id === currentClient.channel?.id);
setCurrentChannel(currentChannel);
if (currentChannel) {
return currentChannel;
}
}
}
}
useEffect(() => { useEffect(() => {
const tsConnection: TS5Connection = new TS5Connection(5899, setConnections, setChannels, setClients); const tsConnection: TS5Connection = new TS5Connection(
5899,
setConnections,
setChannels,
setClients,
setActiveConnectionId
);
tsConnection.connect(); tsConnection.connect();
}, []); }, []);
useEffect(() => { useEffect(() => {
console.log("===================================="); console.log("====================================");
}, [clients, channels, connections]); setCurrentStates();
}, [clients, channels, connections, activeConnectionId]);
// debug view of lists
return ( return (
<div className="App"> <div className="App">
{activeConnectionId}
<Viewer
clients={
clients.map((client) => {
if (client.channel?.id === currentChannel?.id) {
return client;
}
}) as IClient[]
}
channel={currentChannel}
/>
<div className="list"> <div className="list">
<h1>Channels {channels.length}</h1> <h1>Channels {channels.length}</h1>
{channels.map((channel) => ( {channels.map((channel) => (

29
src/Viewer.tsx Normal file
View File

@@ -0,0 +1,29 @@
import { IChannel, IClient } from "interfaces/teamspeak";
export default function Viewer({
clients,
channel,
}: {
clients: IClient[] | undefined;
channel: IChannel | undefined;
}) {
return (
<div>
<h1>{channel?.properties.name}</h1>
{clients?.map((client) => {
if (client) {
return (
<p key={`${client.id}-${client.channel?.connection.id}`}>
{client.talkStatus === 1 ? "🎤" : ""}
{client.properties.inputMuted ? "🎤x" : ""}
{client.properties.outputMuted ? "🔈" : ""}
{client.id} {client.properties.nickname}
</p>
);
} else {
return <></>;
}
})}
</div>
);
}

View File

@@ -22,6 +22,7 @@ export interface IAuthSenderPayload {
export interface IClient { export interface IClient {
id: number; id: number;
talkStatus: number;
channel: IChannel; channel: IChannel;
properties: IClientProperties; properties: IClientProperties;
} }

View File

@@ -15,14 +15,15 @@ export class TS5Connection {
// State setters for dataHandler // State setters for dataHandler
setConnections: React.Dispatch<React.SetStateAction<IConnection[]>>, setConnections: React.Dispatch<React.SetStateAction<IConnection[]>>,
setChannels: React.Dispatch<React.SetStateAction<IChannel[]>>, setChannels: React.Dispatch<React.SetStateAction<IChannel[]>>,
setClients: React.Dispatch<React.SetStateAction<IClient[]>> setClients: React.Dispatch<React.SetStateAction<IClient[]>>,
setActiveConnectionId: React.Dispatch<React.SetStateAction<number>>,
) { ) {
// Create websocket connection to TS5 client // Create websocket connection to TS5 client
this.ws = new WebSocket(`ws://localhost:${remoteAppPort}`); this.ws = new WebSocket(`ws://localhost:${remoteAppPort}`);
// Create dataHandler and messageHandler // Create dataHandler and messageHandler
this.dataHandler = new TS5DataHandler(setConnections, setChannels, setClients); this.dataHandler = new TS5DataHandler(setConnections, setChannels, setClients);
this.messageHandler = new TS5MessageHandler(this.ws, this.dataHandler); this.messageHandler = new TS5MessageHandler(this.ws, this.dataHandler, setActiveConnectionId);
} }
@@ -54,7 +55,6 @@ export class TS5Connection {
// See TS5MessageHandler class // See TS5MessageHandler class
this.ws.onmessage = (event) => { this.ws.onmessage = (event) => {
const data = JSON.parse(event.data); const data = JSON.parse(event.data);
switch (data.type) { switch (data.type) {
case "auth": case "auth":
this.messageHandler.handleAuthMessage(data); this.messageHandler.handleAuthMessage(data);
@@ -261,9 +261,12 @@ class TS5MessageHandler {
ws: WebSocket; ws: WebSocket;
dataHandler: TS5DataHandler; dataHandler: TS5DataHandler;
constructor(ws: WebSocket, dataHandler: TS5DataHandler) { setActiveConnectionId: React.Dispatch<React.SetStateAction<number>>;
constructor(ws: WebSocket, dataHandler: TS5DataHandler, setActiveConnectionId: React.Dispatch<React.SetStateAction<number>>) {
this.ws = ws; this.ws = ws;
this.dataHandler = dataHandler; this.dataHandler = dataHandler;
this.setActiveConnectionId = setActiveConnectionId;
} }
@@ -284,7 +287,7 @@ class TS5MessageHandler {
if (connection.channelInfos.subChannels !== null && channel.id in connection.channelInfos.subChannels) { if (connection.channelInfos.subChannels !== null && channel.id in connection.channelInfos.subChannels) {
connection.channelInfos.subChannels[channel.id].forEach((subChannel: IChannel) => { connection.channelInfos.subChannels[channel.id].forEach((subChannel: IChannel) => {
this.dataHandler.addChannel(subChannel); this.dataHandler.addChannel({ ...subChannel, connection: connection });
}); });
} }
}); });
@@ -296,6 +299,7 @@ class TS5MessageHandler {
if (clientChannel !== undefined) { if (clientChannel !== undefined) {
this.dataHandler.addClient({ this.dataHandler.addClient({
id: clientInfo.id, id: clientInfo.id,
talkStatus: 0,
channel: { ...clientChannel, connection: connection }, channel: { ...clientChannel, connection: connection },
properties: clientInfo.properties, properties: clientInfo.properties,
}); });
@@ -335,6 +339,7 @@ class TS5MessageHandler {
this.dataHandler.addClient( this.dataHandler.addClient(
{ {
id: data.payload.clientId, id: data.payload.clientId,
talkStatus: 0,
channel: newChannel, channel: newChannel,
properties: data.payload.properties, properties: data.payload.properties,
} }
@@ -343,16 +348,34 @@ class TS5MessageHandler {
} }
handleClientPropertiesUpdatedMessage(data: IClientPropertiesUpdatedMessage) { handleClientPropertiesUpdatedMessage(data: IClientPropertiesUpdatedMessage) {
// console.log("handleClientPropertiesUpdate", data); console.log("handleClientPropertiesUpdate", data);
const client: IClient | undefined = this.dataHandler.getClientById(data.payload.clientId, data.payload.connectionId);
if (client !== undefined) {
this.dataHandler.updateClient({
...client,
properties: data.payload.properties,
});
}
} }
handleTalkStatusChangedMessage(data: ITalkStatusChangedMessage) { handleTalkStatusChangedMessage(data: ITalkStatusChangedMessage) {
//console.log("handleTalkStatusChanged", data); console.log("handleTalkStatusChanged", data);
console.log(this.dataHandler.localConnections);
console.log(this.dataHandler.localChannels); const client: IClient | undefined = this.dataHandler.getClientById(data.payload.clientId, data.payload.connectionId);
console.log(this.dataHandler.localClients);
if (client !== undefined) {
this.dataHandler.updateClient({
...client,
talkStatus: data.payload.status,
});
}
} }
handleClientSelfPropertyUpdatedMessage(data: IClientSelfPropertyUpdatedMessage) { handleClientSelfPropertyUpdatedMessage(data: IClientSelfPropertyUpdatedMessage) {
// console.log("handleClientSelfPropertyUpdated", data); console.log("handleClientSelfPropertyUpdated", data);
this.setActiveConnectionId(data.payload.connectionId);
} }
} }