diff --git a/webapp/src/actions/client-monitor-props.ts b/webapp/src/actions/client-monitor-props.ts index cec1081..521ab9c 100644 --- a/webapp/src/actions/client-monitor-props.ts +++ b/webapp/src/actions/client-monitor-props.ts @@ -28,15 +28,28 @@ import { createSignal } from 'solid-js'; import { AudioPlayoutEntry, LocalCandidateEntry, ReceiverEntry, RemoteCandidateEntry } from '@observertc/client-monitor-js/lib/entries/StatsEntryInterfaces'; // eslint-disable-next-line no-unused-vars -function getResultOrEmpty(accessor: (i: T) => ShowObjectAccessor, value?: T): ShowObjectAccessor { - if (value) return accessor(value); +// function getResultOrEmpty(accessor: (i: T) => ShowObjectAccessor, value?: T): ShowObjectAccessor { +// if (value) return accessor(value); - const [result] = createSignal({}); +// const [result] = createSignal({}); - return () => ({ - properties: result, - cleanup: () => {} - }); +// return () => ({ +// properties: result, +// cleanup: () => {} +// }); +// } + +function getResultOrEmpty(accessor: (i: T) => ShowObjectAccessor, value?: T): ShowObjectAccessor { + return () => { + if (value) return accessor(value)(); + + const [result] = createSignal({}); + + return { + properties: result, + cleanup: () => {} + }; + }; } function getPrimitiveProps(value: number | undefined | null | string): ShowObjectAccessor { @@ -102,26 +115,25 @@ export function createClientMonitorProps(monitor: ClientMonitor): ShowObjectProp sendingFractionLost: monitor.sendingFractionLost, receivingFractionLost: monitor.receivingFractionLost, - // func: () => createPeerConnectionProps(monitor.peerConnections[0]), - + peerConnections: createPeerConnectionArrayProps(monitor.peerConnections), codecs: createCodecArrayProps(monitor.codecs), inboundRtps: createInboundRtpArrayProps(monitor.inboundRtps), outboundRtps: createOutboundRtpArrayProps(monitor.outboundRtps), - // remoteInboundRtps: createRemoteInboundRtpArrayProps(monitor.remoteInboundRtps), - // remoteOutboundRtps: createRemoteOutboundRtpArrayProps(monitor.remoteOutboundRtps), - // mediaSources: createMediaSourceArrayProps(monitor.mediaSources), - // dataChannels: createDataChannelArrayProps(monitor.dataChannels), - // transports: createTransportArrayProps(monitor.transports), - // iceCandidatePairs: createIceCandidatePairArrayProps(monitor.iceCandidatePairs), - // iceLocalCandidates: createIceLocalCandidateArrayProps(monitor.iceLocalCandidates), - // iceRemoteCandidates: createIceRemoteCandidateArrayProps(monitor.iceRemoteCandidates), - // transceivers: createTransceiverArrayProps(monitor.transceivers), - // senders: createSenderArrayProps(monitor.senders), - // sctpTransports: createSctpTransportsArratProps(monitor.sctpTransports), - // certificates: createCertificateArrayProps(monitor.certificates), - // iceServers: createIceServerArrayProps(monitor.iceServers), - // contributingSources: createContributingSourcesArrayProps(monitor.contributingSources), - // receivers: createReceiverArrayProps(monitor.receivers), + remoteInboundRtps: createRemoteInboundRtpArrayProps(monitor.remoteInboundRtps), + remoteOutboundRtps: createRemoteOutboundRtpArrayProps(monitor.remoteOutboundRtps), + mediaSources: createMediaSourceArrayProps(monitor.mediaSources), + dataChannels: createDataChannelArrayProps(monitor.dataChannels), + transports: createTransportArrayProps(monitor.transports), + iceCandidatePairs: createIceCandidatePairArrayProps(monitor.iceCandidatePairs), + iceLocalCandidates: createIceLocalCandidateArrayProps(monitor.iceLocalCandidates), + iceRemoteCandidates: createIceRemoteCandidateArrayProps(monitor.iceRemoteCandidates), + transceivers: createTransceiverArrayProps(monitor.transceivers), + senders: createSenderArrayProps(monitor.senders), + sctpTransports: createSctpTransportsArratProps(monitor.sctpTransports), + certificates: createCertificateArrayProps(monitor.certificates), + iceServers: createIceServerArrayProps(monitor.iceServers), + contributingSources: createContributingSourcesArrayProps(monitor.contributingSources), + receivers: createReceiverArrayProps(monitor.receivers), // audioPlayouts: createAudioPlayoutArrayProps(monitor.audioPlayouts), }); @@ -196,23 +208,23 @@ function createPeerConnectionProps(peerConnection: PeerConnectionEntry): ShowObj connectionEstablishedDurationInMs: peerConnection.connectionEstablishedDurationInMs, - // 'codecs': createCodecArrayProps([...peerConnection.codecs()]), - // 'inboundRtps()': createInboundRtpArrayProps([...peerConnection.inboundRtps()]), - // 'outboundRtps()': createOutboundRtpArrayProps([...peerConnection.outboundRtps()]), - // 'remoteInboundRtps()': createRemoteInboundRtpArrayProps([...peerConnection.remoteInboundRtps()]), - // 'remoteOutboundRtps()': createRemoteOutboundRtpArrayProps([...peerConnection.remoteOutboundRtps()]), - // 'mediaSources()': createMediaSourceArrayProps([...peerConnection.mediaSources()]), - // 'dataChannels()': createDataChannelArrayProps([...peerConnection.dataChannels()]), - // 'transports()': createTransportArrayProps([...peerConnection.transports()]), - // 'iceCandidatePairs()': createIceCandidatePairArrayProps([...peerConnection.iceCandidatePairs()]), - // 'transceivers()': createTransceiverArrayProps([...peerConnection.transceivers()]), - // 'senders()': createSenderArrayProps([...peerConnection.senders()]), - // 'sctpTransports()': createSctpTransportsArratProps([...peerConnection.sctpTransports()]), - // 'certificates()': createCertificateArrayProps([...peerConnection.certificates()]), - // 'iceServers()': createIceServerArrayProps([...peerConnection.iceServers()]), - // 'contributingSources()': createContributingSourcesArrayProps([...peerConnection.contributingSources()]), - // 'receivers()': createReceiverArrayProps([...peerConnection.receivers()]), - // 'audioPlayouts()': createAudioPlayoutArrayProps([...peerConnection.audioPlayouts()]), + 'codecs': createCodecArrayProps([...peerConnection.codecs()]), + 'inboundRtps()': createInboundRtpArrayProps([...peerConnection.inboundRtps()]), + 'outboundRtps()': createOutboundRtpArrayProps([...peerConnection.outboundRtps()]), + 'remoteInboundRtps()': createRemoteInboundRtpArrayProps([...peerConnection.remoteInboundRtps()]), + 'remoteOutboundRtps()': createRemoteOutboundRtpArrayProps([...peerConnection.remoteOutboundRtps()]), + 'mediaSources()': createMediaSourceArrayProps([...peerConnection.mediaSources()]), + 'dataChannels()': createDataChannelArrayProps([...peerConnection.dataChannels()]), + 'transports()': createTransportArrayProps([...peerConnection.transports()]), + 'iceCandidatePairs()': createIceCandidatePairArrayProps([...peerConnection.iceCandidatePairs()]), + 'transceivers()': createTransceiverArrayProps([...peerConnection.transceivers()]), + 'senders()': createSenderArrayProps([...peerConnection.senders()]), + 'sctpTransports()': createSctpTransportsArratProps([...peerConnection.sctpTransports()]), + 'certificates()': createCertificateArrayProps([...peerConnection.certificates()]), + 'iceServers()': createIceServerArrayProps([...peerConnection.iceServers()]), + 'contributingSources()': createContributingSourcesArrayProps([...peerConnection.contributingSources()]), + 'receivers()': createReceiverArrayProps([...peerConnection.receivers()]), + 'audioPlayouts()': createAudioPlayoutArrayProps([...peerConnection.audioPlayouts()]), }); @@ -333,14 +345,14 @@ function createOutboundRtpProps(outboundRtp: OutboundRtpEntry): ShowObjectAccess sentBytes: outboundRtp.sentBytes, sentPackets: outboundRtp.sentPackets, - // getCodec: getResultOrEmpty(createCodecProps, outboundRtp.getCodec()), - // getMediaSource: getResultOrEmpty(createMediaSourceProps, outboundRtp.getMediaSource()), - // getPeerConnection: getResultOrEmpty(createPeerConnectionProps, outboundRtp.getPeerConnection()), - // getRemoteInboundRtp: getResultOrEmpty(createRemoteInboundRtpProps, outboundRtp.getRemoteInboundRtp()), - // getSender: getResultOrEmpty(createSenderProps, outboundRtp.getSender()), - // getSsrc: getResultOrEmpty(getPrimitiveProps, outboundRtp.getSsrc()), - // getTrackId: getResultOrEmpty(getPrimitiveProps, outboundRtp.getTrackId()), - // getTransport: getResultOrEmpty(createTransportProps, outboundRtp.getTransport()), + getCodec: getResultOrEmpty(createCodecProps, outboundRtp.getCodec()), + getMediaSource: getResultOrEmpty(createMediaSourceProps, outboundRtp.getMediaSource()), + getPeerConnection: getResultOrEmpty(createPeerConnectionProps, outboundRtp.getPeerConnection()), + getRemoteInboundRtp: getResultOrEmpty(createRemoteInboundRtpProps, outboundRtp.getRemoteInboundRtp()), + getSender: getResultOrEmpty(createSenderProps, outboundRtp.getSender()), + getSsrc: getResultOrEmpty(getPrimitiveProps, outboundRtp.getSsrc()), + getTrackId: getResultOrEmpty(getPrimitiveProps, outboundRtp.getTrackId()), + getTransport: getResultOrEmpty(createTransportProps, outboundRtp.getTransport()), stats: outboundRtp.stats }); diff --git a/webapp/src/components/ClientMonitor/AudioPlayoutEntryCmp.tsx b/webapp/src/components/ClientMonitor/AudioPlayoutEntryCmp.tsx deleted file mode 100644 index e87c2e8..0000000 --- a/webapp/src/components/ClientMonitor/AudioPlayoutEntryCmp.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; -import { AudioPlayoutEntry } from '@observertc/client-monitor-js/lib/entries/StatsEntryInterfaces'; - -export type AudioPlayoutEntryProps = { - entry: AudioPlayoutEntry; - next: Setter; -} - -const AudioPlayoutEntryCmp: Component = (props: AudioPlayoutEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: () => PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) - } - ]); - setIterableNavigations([ - ]); - setProperties({ - - // last property - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default AudioPlayoutEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/CertificateEntryCmp.tsx b/webapp/src/components/ClientMonitor/CertificateEntryCmp.tsx deleted file mode 100644 index 25ba5e4..0000000 --- a/webapp/src/components/ClientMonitor/CertificateEntryCmp.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { CertificateEntry } from '@observertc/client-monitor-js'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; - -export type CertificateEntryProps = { - entry: CertificateEntry; - next: Setter; -} - -const CertificateEntryCmp: Component = (props: CertificateEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: props.entry.getPeerConnection() ? () => PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) : undefined - } - ]); - setIterableNavigations([ - ]); - setProperties({ - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default CertificateEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/ClientMonitor.tsx b/webapp/src/components/ClientMonitor/ClientMonitor.tsx index 25dd348..8be350f 100644 --- a/webapp/src/components/ClientMonitor/ClientMonitor.tsx +++ b/webapp/src/components/ClientMonitor/ClientMonitor.tsx @@ -30,7 +30,7 @@ const ClientMonitor: Component = () => { return ( <>

- An instance of the ClientMonitor class has the following properties: (UNDER DEVELOPMENT) + An instance of the ClientMonitor class has the following properties:

(current: T[], newElement?: T) { - if (!newElement) return [ ...current ]; - const result = [ - ...current, - newElement - ]; - while (WINDOW_SIZE < result.length) { - result.shift(); - } - - return result; -} - -const ClientMonitorBaseCharts: Component = () => { - // const [ properties, setProperties ] = createSignal([]); - const [ timestamps, setTimestamps ] = createSignal([]); - const [ deltaDataChannelBytesReceived, setDeltaDataChannelBytesReceived ] = createSignal([]); - const [ deltaDataChannelBytesSent, setDeltaDataChannelBytesSent ] = createSignal([]); - const [ deltaInboundPacketsLost, setDeltaInboundPacketsLost ] = createSignal([]); - const [ deltaInboundPacketsReceived, setDeltaInboundPacketsReceived ] = createSignal([]); - const [ deltaOutboundPacketsLost, setDeltaOutboundPacketsLost ] = createSignal([]); - const [ deltaOutboundPacketsReceived, setDeltaOutboundPacketsReceived ] = createSignal([]); - const [ deltaOutboundPacketsSent, setDeltaOutboundPacketsSent ] = createSignal([]); - const [ deltaReceivedAudioBytes, setDeltaReceivedAudioBytes ] = createSignal([]); - const [ deltaReceivedVideoBytes, setDeltaReceivedVideoBytes ] = createSignal([]); - const [ deltaSentAudioBytes, setDeltaSentAudioBytes ] = createSignal([]); - const [ deltaSentVideoBytes, setDeltaSentVideoBytes ] = createSignal([]); - const [ totalAvailableIncomingKbps, setTotalAvailableIncomingKbps ] = createSignal([]); - const [ totalAvailableOutgoingKbps, setTotalAvailableOutgoingKbps ] = createSignal([]); - const [ totalDataChannelBytesReceived, setTotalDataChannelBytesReceived ] = createSignal([]); - const [ totalDataChannelBytesSent, setTotalDataChannelBytesSent ] = createSignal([]); - const [ totalInboundPacketsLost, setTotalInboundPacketsLost ] = createSignal([]); - const [ totalInboundPacketsReceived, setTotalInboundPacketsReceived ] = createSignal([]); - const [ totalOutboundPacketsLost, setTotalOutboundPacketsLost ] = createSignal([]); - const [ totalOutboundPacketsReceived, setTotalOutboundPacketsReceived ] = createSignal([]); - const [ totalOutboundPacketsSent, setTotalOutboundPacketsSent ] = createSignal([]); - const [ totalReceivedAudioBytes, setTotalReceivedAudioBytes ] = createSignal([]); - const [ totalReceivedVideoBytes, setTotalReceivedVideoBytes ] = createSignal([]); - const [ totalSentAudioBytes, setTotalSentAudioBytes ] = createSignal([]); - const [ totalSentVideoBytes, setTotalSentVideoBytes ] = createSignal([]); - const [ avgRttInMs, setAvgRttInMs ] = createSignal([]); - const [ sendingKbps, setSendingKbps ] = createSignal([]); - const [ receivingKbps, setReceivingKbps ] = createSignal([]); - - const onChange = () => { - const call = clientStore.call; - const monitor = call?.monitor; - - setTimestamps(windowedArray(timestamps(), Date.now())); - setDeltaDataChannelBytesReceived( - windowedArray(deltaDataChannelBytesReceived(), monitor?.deltaDataChannelBytesReceived) - ); - setDeltaDataChannelBytesSent( - windowedArray(deltaDataChannelBytesSent(), monitor?.deltaDataChannelBytesSent) - ); - setDeltaInboundPacketsLost( - windowedArray(deltaInboundPacketsLost(), monitor?.deltaInboundPacketsLost) - ); - setDeltaInboundPacketsReceived( - windowedArray(deltaInboundPacketsReceived(), monitor?.deltaInboundPacketsReceived) - ); - setDeltaOutboundPacketsLost( - windowedArray(deltaOutboundPacketsLost(), monitor?.deltaOutboundPacketsLost) - ); - setDeltaOutboundPacketsReceived( - windowedArray(deltaOutboundPacketsReceived(), monitor?.deltaOutboundPacketsReceived) - ); - setDeltaOutboundPacketsSent( - windowedArray(deltaOutboundPacketsSent(), monitor?.deltaOutboundPacketsSent) - ); - setDeltaReceivedAudioBytes( - windowedArray(deltaReceivedAudioBytes(), monitor?.deltaReceivedAudioBytes) - ); - setDeltaReceivedVideoBytes( - windowedArray(deltaReceivedVideoBytes(), monitor?.deltaReceivedVideoBytes) - ); - setDeltaSentAudioBytes( - windowedArray(deltaSentAudioBytes(), monitor?.deltaSentAudioBytes) - ); - setDeltaSentVideoBytes( - windowedArray(deltaSentVideoBytes(), monitor?.deltaSentVideoBytes) - ); - setTotalAvailableIncomingKbps( - windowedArray(totalAvailableIncomingKbps(), (monitor?.totalAvailableIncomingBitrate ?? 0) / 1000) - ); - setTotalAvailableOutgoingKbps( - windowedArray(totalAvailableOutgoingKbps(), (monitor?.totalAvailableOutgoingBitrate ?? 0) / 1000) - ); - setTotalDataChannelBytesReceived( - windowedArray(totalDataChannelBytesReceived(), monitor?.totalDataChannelBytesReceived) - ); - setTotalDataChannelBytesSent( - windowedArray(totalDataChannelBytesSent(), monitor?.totalDataChannelBytesSent) - ); - setTotalInboundPacketsLost( - windowedArray(totalInboundPacketsLost(), monitor?.totalInboundPacketsLost) - ); - setTotalInboundPacketsReceived( - windowedArray(totalInboundPacketsReceived(), monitor?.totalInboundPacketsReceived) - ); - setTotalOutboundPacketsLost( - windowedArray(totalOutboundPacketsLost(), monitor?.totalOutboundPacketsLost) - ); - setTotalOutboundPacketsReceived( - windowedArray(totalOutboundPacketsReceived(), monitor?.totalOutboundPacketsReceived) - ); - setTotalOutboundPacketsSent( - windowedArray(totalOutboundPacketsSent(), monitor?.totalOutboundPacketsSent) - ); - setTotalReceivedAudioBytes( - windowedArray(totalReceivedAudioBytes(), monitor?.totalReceivedAudioBytes) - ); - setTotalReceivedVideoBytes( - windowedArray(totalReceivedVideoBytes(), monitor?.totalReceivedVideoBytes) - ); - setTotalSentAudioBytes( - windowedArray(totalSentAudioBytes(), monitor?.totalSentAudioBytes) - ); - setTotalSentVideoBytes( - windowedArray(totalSentVideoBytes(), monitor?.totalSentVideoBytes) - ); - setAvgRttInMs( - windowedArray(avgRttInMs(), (monitor?.avgRttInSec ?? 0) * 1000) - ); - setSendingKbps( - windowedArray(sendingKbps(), ((monitor?.sendingAudioBitrate ?? 0) + (monitor?.sendingVideoBitrate ?? 0)) / 1000) - ); - setReceivingKbps( - windowedArray(receivingKbps(), ((monitor?.receivingAudioBitrate ?? 0) + (monitor?.receivingVideoBitrate ?? 0)) / 1000) - ); - - }; - - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - - {/* - - Property - value - - */} - - - {/** MEDIA BITRATES */} - - - - - {/** SENDING BITRATE + AVAILABLE OUTGOING BITRATE */} - - - - {/** RECEIVING BITRATE + AVAILABLE INCOMING BITRATE */} - - - - - - - - - {/** MEDIA PACKETS ROW */} - - - - - - - - - - - - - - - - {/** DATA CHANNEL PACKETS ROW */} - - - - - - - - - - - - - - - - {/* - {([key, values]) => ( - - - - - - )} - */} - -
-
- ); -}; - -export default ClientMonitorBaseCharts; diff --git a/webapp/src/components/ClientMonitor/ClientMonitorEntry.tsx b/webapp/src/components/ClientMonitor/ClientMonitorEntry.tsx deleted file mode 100644 index b046ae6..0000000 --- a/webapp/src/components/ClientMonitor/ClientMonitorEntry.tsx +++ /dev/null @@ -1,214 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { ClientMonitor } from '@observertc/client-monitor-js'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; - -export type ClientMonitorProps = { - entry: ClientMonitor; - next: Setter; -} - -const ClientMonitorEntryCmp: Component = (props: ClientMonitorProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - ]); - setIterableNavigations([ - // { - // name: 'codecs', - // items: [...props.entry.codecs].map((codec) => ({ - // key: `Codec ${codec.stats.payloadType}`, - // action: () => CodecEntryCmp({ entry: codec, next: props.next }) - // })) - // }, - // { - // name: 'inboundRtps', - // items: [...props.entry.inboundRtps].map((inboundRtp) => ({ - // key: `Track (${inboundRtp.getTrackId()}) ${inboundRtp.stats.ssrc}`, - // action: () => InboundRtpEntryCmp({ entry: inboundRtp, next: props.next }) - // })) - // }, - // { - // name: 'outboundRtps', - // items: [...props.entry.outboundRtps].map((outboundRtp) => ({ - // key: `Track (${outboundRtp.getTrackId()}) ${outboundRtp.stats.ssrc}`, - // action: () => OutboundRtpEntryCmp({ entry: outboundRtp, next: props.next }) - // })) - // }, - // { - // name: 'remoteInboundRtps', - // items: [...props.entry.remoteInboundRtps].map((remoteInboundRtp) => ({ - // key: `Track (${remoteInboundRtp.getOutboundRtp()?.getTrackId()}) ${remoteInboundRtp.stats.ssrc}`, - // action: () => RemoteInboundRtpEntryCmp({ entry: remoteInboundRtp, next: props.next }) - // })) - // }, - // { - // name: 'remoteOutboundRtps', - // items: [...props.entry.remoteOutboundRtps].map((remoteOutboundRtp) => ({ - // key: `Track (${remoteOutboundRtp.getInboundRtp()?.getTrackId()}) ${remoteOutboundRtp.stats.ssrc}`, - // action: () => RemoteOutboundRtpEntryCmp({ entry: remoteOutboundRtp, next: props.next }) - // })) - // }, - // { - // name: 'mediaSources', - // items: [...props.entry.mediaSources].map((mediaSource) => ({ - // key: `Media Source (id: ${mediaSource.stats.id})`, - // action: () => MediaSourceEntryCmp({ entry: mediaSource, next: props.next }) - // })) - // }, - // { - // name: 'dataChannels', - // items: [...props.entry.dataChannels].map((dataChannel) => ({ - // key: `Data Channel (id: ${dataChannel.stats.id})`, - // action: () => DataChannelEntryCmp({ entry: dataChannel, next: props.next }) - // })) - // }, - // { - // name: 'transports', - // items: [...props.entry.transports].map((transport) => ({ - // key: `Transport (id: ${transport.stats.id})`, - // action: () => TransportEntryCmp({ entry: transport, next: props.next }) - // })) - // }, - // { - // name: 'iceCandidatePairs', - // items: [...props.entry.iceCandidatePairs].map((iceCandidatePair) => ({ - // key: `ICE Candidate Pair (local: ${iceCandidatePair.getLocalCandidate()?.stats.address} remote: ${iceCandidatePair.getRemoteCandidate()?.stats.address})`, - // action: () => IceCandidatePairEntryCmp({ entry: iceCandidatePair, next: props.next }) - // })) - // }, - // { - // name: 'iceLocalCandidates', - // items: [...props.entry.iceLocalCandidates].map((iceLocalCandidate) => ({ - // key: `ICE Local Candidate (address: ${iceLocalCandidate.stats.address})`, - // action: () => LocalCandidateEntryCmp({ entry: iceLocalCandidate, next: props.next }) - // })) - // }, - // { - // name: 'iceRemoteCandidates', - // items: [...props.entry.iceRemoteCandidates].map((iceRemoteCandidate) => ({ - // key: `ICE Remote Candidate (address: ${iceRemoteCandidate.stats.address})`, - // action: () => RemoteCandidateEntryCmp({ entry: iceRemoteCandidate, next: props.next }) - // })) - // }, - // { - // name: 'transceivers', - // items: [...props.entry.transceivers].map((transceiver) => ({ - // key: `Transceiver ${transceiver.stats.kind}`, - // action: () => TransceiverEntryCmp({ entry: transceiver, next: props.next }) - // })) - // }, - // { - // name: 'senders', - // items: [...props.entry.senders].map((sender) => ({ - // key: `Sender (${sender.stats.ssrc})`, - // action: () => SenderEntryCmp({ entry: sender, next: props.next }) - // })) - // }, - // { - // name: 'receivers', - // items: [...props.entry.receivers].map((receiver) => ({ - // key: `Receiver (${receiver.stats.ssrc})`, - // action: () => ReceiverEntryCmp({ entry: receiver, next: props.next }) - // })) - // }, - // { - // name: 'sctpTransports', - // items: [...props.entry.sctpTransports].map((sctpTransport) => ({ - // key: `SCTP Transport (id: ${sctpTransport.stats.id})`, - // action: () => SctpTransportEntryCmp({ entry: sctpTransport, next: props.next }) - // })) - // }, - // { - // name: 'certificates', - // items: [...props.entry.certificates].map((certificate) => ({ - // key: `Certificate (fingerprint: ${certificate.stats.fingerprint})`, - // action: () => CertificateEntryCmp({ entry: certificate, next: props.next }) - // })) - // }, - // { - // name: 'iceServers', - // items: [...props.entry.iceServers].map((iceServer) => ({ - // key: `ICE Server (url: ${iceServer.stats.url})`, - // action: () => IceServerEntryCmp({ entry: iceServer, next: props.next }) - // })) - // }, - // { - // name: 'contributingSources', - // items: [...props.entry.contributingSources].map((contributingSource) => ({ - // key: `Contributing Source (${contributingSource.stats.id})`, - // action: () => ContributingSourceEntryCmp({ entry: contributingSource, next: props.next }) - // })) - // }, - { - name: 'peerConnections', - items: [...props.entry.peerConnections].map((peerConnection) => ({ - key: `PeerConnection (${peerConnection.peerConnectionId}, label: ${peerConnection.label})`, - action: () => PeerConnectionEntryCmp({ entry: peerConnection, next: props.next }) - })) - } - ]); - setProperties({ - // selectedIceCandidatePair: props.entry.getSelectedIceCandidatePair(), - browser: props.entry.browser, - operatingSystem: props.entry.operationSystem, - engine: props.entry.engine, - platform: props.entry.platform, - created: props.entry.created, - sendingAudioBitrate: props.entry.sendingAudioBitrate, - sendingVideoBitrate: props.entry.sendingVideoBitrate, - receivingAudioBitrate: props.entry.receivingAudioBitrate, - receivingVideoBitrate: props.entry.receivingVideoBitrate, - - totalInboundPacketsLost: props.entry.totalInboundPacketsLost, - totalInboundPacketsReceived: props.entry.totalInboundPacketsReceived, - totalOutboundPacketsSent: props.entry.totalOutboundPacketsSent, - totalOutboundPacketsReceived: props.entry.totalOutboundPacketsReceived, - totalOutboundPacketsLost: props.entry.totalOutboundPacketsLost, - totalDataChannelBytesSent: props.entry.totalDataChannelBytesSent, - totalDataChannelBytesReceived: props.entry.totalDataChannelBytesReceived, - totalSentAudioBytes: props.entry.totalSentAudioBytes, - totalSentVideoBytes: props.entry.totalSentVideoBytes, - totalReceivedAudioBytes: props.entry.totalReceivedAudioBytes, - totalReceivedVideoBytes: props.entry.totalReceivedVideoBytes, - totalAvailableIncomingBitrate: props.entry.totalAvailableIncomingBitrate, - totalAvailableOutgoingBitrate: props.entry.totalAvailableOutgoingBitrate, - - - deltaInboundPacketsLost: props.entry.deltaInboundPacketsLost, - deltaInboundPacketsReceived: props.entry.deltaInboundPacketsReceived, - deltaOutboundPacketsSent: props.entry.deltaOutboundPacketsSent, - deltaOutboundPacketsReceived: props.entry.deltaOutboundPacketsReceived, - deltaOutboundPacketsLost: props.entry.deltaOutboundPacketsLost, - deltaDataChannelBytesSent: props.entry.deltaDataChannelBytesSent, - deltaDataChannelBytesReceived: props.entry.deltaDataChannelBytesReceived, - deltaSentAudioBytes: props.entry.deltaSentAudioBytes, - deltaSentVideoBytes: props.entry.deltaSentVideoBytes, - deltaReceivedAudioBytes: props.entry.deltaReceivedAudioBytes, - deltaReceivedVideoBytes: props.entry.deltaReceivedVideoBytes, - - avgRttInSec: props.entry.avgRttInSec, - highestSeenSendingBitrate: props.entry.highestSeenSendingBitrate, - highestSeenReceivingBitrate: props.entry.highestSeenReceivingBitrate, - highestSeenAvailableOutgoingBitrate: props.entry.highestSeenAvailableOutgoingBitrate, - highestSeenAvailableIncomingBitrate: props.entry.highestSeenAvailableIncomingBitrate, - sendingFractionLost: props.entry.sendingFractionLost, - receivingFractionLost: props.entry.receivingFractionLost, - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default ClientMonitorEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/ClientMonitorShowEntry.tsx b/webapp/src/components/ClientMonitor/ClientMonitorShowEntry.tsx deleted file mode 100644 index 2282e27..0000000 --- a/webapp/src/components/ClientMonitor/ClientMonitorShowEntry.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { createSignal, type Component, JSXElement, Show } from 'solid-js'; -import Box from '../Box'; -import { clientStore } from '../../stores/LocalClientStore'; -import ClientMonitorEntryCmp from './ClientMonitorEntry'; - -export type ClientMonitorEntryRender = { - name: string; - action: () => JSXElement; -} -const ClientMonitorShowEntry: Component = () => { - const [ actualEntry, setActualEntry ] = createSignal({ - name: 'ClientMonitor', - action: () => - }); - - return ( - {entry => { - return ( - - {entry.action()} - - ); - }} - - ); -}; - -export default ClientMonitorShowEntry; diff --git a/webapp/src/components/ClientMonitor/ClientMonitorStateProperties.tsx b/webapp/src/components/ClientMonitor/ClientMonitorStateProperties.tsx deleted file mode 100644 index acd5b2c..0000000 --- a/webapp/src/components/ClientMonitor/ClientMonitorStateProperties.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import { - Paper, - Table, - TableBody, - TableCell, - TableContainer, - TableRow, -} from '@suid/material'; -import { Component, For, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; - -type HelperStruct = -{ - key: string; - value: number | string | boolean | undefined; -}; -// eslint-disable-next-line no-unused-vars - -const ClientMonitorStateProperties: Component = () => { - const [ properties, setProperties ] = createSignal([]); - const onChange = () => setProperties([ - { key: 'clientId', value: clientStore.clientId }, - { key: 'userId', value: clientStore.userId }, - { key: 'operationSystem', value: void 0 }, - { key: 'operationSystem.name', value: clientStore.call?.monitor?.operationSystem?.name }, - { key: 'operationSystem.version', value: clientStore.call?.monitor?.operationSystem?.version }, - { key: 'browser', value: void 0 }, - { key: 'browser.name', value: clientStore.call?.monitor?.browser?.name }, - { key: 'browser.version', value: clientStore.call?.monitor?.browser?.version }, - { key: 'engine', value: void 0 }, - { key: 'engine.name', value: clientStore.call?.monitor?.engine?.name }, - { key: 'engine.version', value: clientStore.call?.monitor?.engine?.version }, - ]); - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - - }); - return ( - - - {/* - - Property - value - - */} - - - {(row) => ( - - - {`monitor.${row.key}`} - - {row.value} - - )} - - -
-
- ); -}; - -export default ClientMonitorStateProperties; diff --git a/webapp/src/components/ClientMonitor/ClientMonitorStatsProperties.tsx b/webapp/src/components/ClientMonitor/ClientMonitorStatsProperties.tsx deleted file mode 100644 index ca3c694..0000000 --- a/webapp/src/components/ClientMonitor/ClientMonitorStatsProperties.tsx +++ /dev/null @@ -1,288 +0,0 @@ -import { - Paper, - Table, - TableBody, - TableCell, - TableContainer, - TableRow, -} from '@suid/material'; -import { Component, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { SimpleLineChart } from '../Charts/SimpleLineChart'; - -// eslint-disable-next-line no-unused-vars -const WINDOW_SIZE = 60; -function windowedArray(current: T[], newElement?: T) { - if (!newElement) return [ ...current ]; - const result = [ - ...current, - newElement - ]; - while (WINDOW_SIZE < result.length) { - result.shift(); - } - - return result; -} - -const ClientMonitorStatsProperties: Component = () => { - // const [ properties, setProperties ] = createSignal([]); - const [ timestamps, setTimestamps ] = createSignal([]); - const [ deltaDataChannelBytesReceived, setDeltaDataChannelBytesReceived ] = createSignal([]); - const [ deltaDataChannelBytesSent, setDeltaDataChannelBytesSent ] = createSignal([]); - const [ deltaInboundPacketsLost, setDeltaInboundPacketsLost ] = createSignal([]); - const [ deltaInboundPacketsReceived, setDeltaInboundPacketsReceived ] = createSignal([]); - const [ deltaOutboundPacketsLost, setDeltaOutboundPacketsLost ] = createSignal([]); - const [ deltaOutboundPacketsReceived, setDeltaOutboundPacketsReceived ] = createSignal([]); - const [ deltaOutboundPacketsSent, setDeltaOutboundPacketsSent ] = createSignal([]); - const [ deltaReceivedAudioBytes, setDeltaReceivedAudioBytes ] = createSignal([]); - const [ deltaReceivedVideoBytes, setDeltaReceivedVideoBytes ] = createSignal([]); - const [ deltaSentAudioBytes, setDeltaSentAudioBytes ] = createSignal([]); - const [ deltaSentVideoBytes, setDeltaSentVideoBytes ] = createSignal([]); - const [ totalAvailableIncomingBitrate, setTotalAvailableIncomingBitrate ] = createSignal([]); - const [ totalAvailableOutgoingBitrate, setTotalAvailableOutgoingBitrate ] = createSignal([]); - const [ totalDataChannelBytesReceived, setTotalDataChannelBytesReceived ] = createSignal([]); - const [ totalDataChannelBytesSent, setTotalDataChannelBytesSent ] = createSignal([]); - const [ totalInboundPacketsLost, setTotalInboundPacketsLost ] = createSignal([]); - const [ totalInboundPacketsReceived, setTotalInboundPacketsReceived ] = createSignal([]); - const [ totalOutboundPacketsLost, setTotalOutboundPacketsLost ] = createSignal([]); - const [ totalOutboundPacketsReceived, setTotalOutboundPacketsReceived ] = createSignal([]); - const [ totalOutboundPacketsSent, setTotalOutboundPacketsSent ] = createSignal([]); - const [ totalReceivedAudioBytes, setTotalReceivedAudioBytes ] = createSignal([]); - const [ totalReceivedVideoBytes, setTotalReceivedVideoBytes ] = createSignal([]); - const [ totalSentAudioBytes, setTotalSentAudioBytes ] = createSignal([]); - const [ totalSentVideoBytes, setTotalSentVideoBytes ] = createSignal([]); - - const onChange = () => { - const call = clientStore.call; - const monitor = call?.monitor; - setTimestamps([...timestamps(), Date.now()]); - setDeltaDataChannelBytesReceived( - windowedArray(deltaDataChannelBytesReceived(), monitor?.deltaDataChannelBytesReceived) - ); - setDeltaDataChannelBytesSent( - windowedArray(deltaDataChannelBytesSent(), monitor?.deltaDataChannelBytesSent) - ); - monitor?.deltaInboundPacketsLost && - setDeltaInboundPacketsLost([...deltaInboundPacketsLost(), monitor?.deltaInboundPacketsLost]); - monitor?.deltaInboundPacketsReceived && - setDeltaInboundPacketsReceived([...deltaInboundPacketsReceived(), monitor?.deltaInboundPacketsReceived]); - monitor?.deltaOutboundPacketsLost && - setDeltaOutboundPacketsLost([...deltaOutboundPacketsLost(), monitor?.deltaOutboundPacketsLost]); - monitor?.deltaOutboundPacketsReceived && - setDeltaOutboundPacketsReceived([...deltaOutboundPacketsReceived(), monitor?.deltaOutboundPacketsReceived]); - monitor?.deltaOutboundPacketsSent && - setDeltaOutboundPacketsSent([...deltaOutboundPacketsSent(), monitor?.deltaOutboundPacketsSent]); - monitor?.deltaReceivedAudioBytes && - setDeltaReceivedAudioBytes([...deltaReceivedAudioBytes(), monitor?.deltaReceivedAudioBytes]); - monitor?.deltaReceivedVideoBytes && - setDeltaReceivedVideoBytes([...deltaReceivedVideoBytes(), monitor?.deltaReceivedVideoBytes]); - monitor?.deltaSentAudioBytes && - setDeltaSentAudioBytes([...deltaSentAudioBytes(), monitor?.deltaSentAudioBytes]); - monitor?.deltaSentVideoBytes && - setDeltaSentVideoBytes([...deltaSentVideoBytes(), monitor?.deltaSentVideoBytes]); - monitor?.totalAvailableIncomingBitrate && - setTotalAvailableIncomingBitrate([...totalAvailableIncomingBitrate(), monitor?.totalAvailableIncomingBitrate]); - monitor?.totalAvailableOutgoingBitrate && - setTotalAvailableOutgoingBitrate([...totalAvailableOutgoingBitrate(), monitor?.totalAvailableOutgoingBitrate]); - monitor?.totalDataChannelBytesReceived && - setTotalDataChannelBytesReceived([...totalDataChannelBytesReceived(), monitor?.totalDataChannelBytesReceived]); - monitor?.totalDataChannelBytesSent && - setTotalDataChannelBytesSent([...totalDataChannelBytesSent(), monitor?.totalDataChannelBytesSent]); - monitor?.totalInboundPacketsLost && - setTotalInboundPacketsLost([...totalInboundPacketsLost(), monitor?.totalInboundPacketsLost]); - monitor?.totalInboundPacketsReceived && - setTotalInboundPacketsReceived([...totalInboundPacketsReceived(), monitor?.totalInboundPacketsReceived]); - monitor?.totalOutboundPacketsLost && - setTotalOutboundPacketsLost([...totalOutboundPacketsLost(), monitor?.totalOutboundPacketsLost]); - monitor?.totalOutboundPacketsReceived && - setTotalOutboundPacketsReceived([...totalOutboundPacketsReceived(), monitor?.totalOutboundPacketsReceived]); - monitor?.totalOutboundPacketsSent && - setTotalOutboundPacketsSent([...totalOutboundPacketsSent(), monitor?.totalOutboundPacketsSent]); - monitor?.totalReceivedAudioBytes && - setTotalReceivedAudioBytes([...totalReceivedAudioBytes(), monitor?.totalReceivedAudioBytes]); - monitor?.totalReceivedVideoBytes && - setTotalReceivedVideoBytes([...totalReceivedVideoBytes(), monitor?.totalReceivedVideoBytes]); - monitor?.totalSentAudioBytes && - setTotalSentAudioBytes([...totalSentAudioBytes(), monitor?.totalSentAudioBytes]); - monitor?.totalSentVideoBytes && - setTotalSentVideoBytes([...totalSentVideoBytes(), monitor?.totalSentVideoBytes]); - - }; - - // const onChange = () => setProperties([ - // getPropertyFromMonitor('deltaDataChannelBytesReceived'), - // getPropertyFromMonitor('deltaDataChannelBytesSent'), - // getPropertyFromMonitor('deltaInboundPacketsLost'), - // getPropertyFromMonitor('deltaInboundPacketsReceived'), - // getPropertyFromMonitor('deltaOutboundPacketsLost'), - // getPropertyFromMonitor('deltaOutboundPacketsReceived'), - // getPropertyFromMonitor('deltaOutboundPacketsSent'), - // getPropertyFromMonitor('deltaReceivedAudioBytes'), - // getPropertyFromMonitor('deltaReceivedVideoBytes'), - // getPropertyFromMonitor('deltaSentAudioBytes'), - // getPropertyFromMonitor('deltaSentVideoBytes'), - - // getPropertyFromMonitor('totalAvailableIncomingBitrate'), - // getPropertyFromMonitor('totalAvailableOutgoingBitrate'), - // getPropertyFromMonitor('totalDataChannelBytesReceived'), - // getPropertyFromMonitor('totalDataChannelBytesSent'), - // getPropertyFromMonitor('totalInboundPacketsLost'), - // getPropertyFromMonitor('totalInboundPacketsReceived'), - // getPropertyFromMonitor('totalOutboundPacketsLost'), - // getPropertyFromMonitor('totalOutboundPacketsReceived'), - // getPropertyFromMonitor('totalOutboundPacketsSent'), - // getPropertyFromMonitor('totalReceivedAudioBytes'), - // getPropertyFromMonitor('totalReceivedVideoBytes'), - // getPropertyFromMonitor('totalSentAudioBytes'), - // getPropertyFromMonitor('totalSentVideoBytes'), - // ]); - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - - {/* - - Property - value - - */} - - - {/** MEDIA BITRATES */} - - - - {/** SENDING BITRATE + AVAILABLE OUTGOING BITRATE */} - - - {/** RECEIVING BITRATE + AVAILABLE INCOMING BITRATE */} - - - - {/** RTT, JITTER */} - - - - - {/** MEDIA PACKETS ROW */} - - - - - - - - - - - - - - - {/** DATA CHANNEL PACKETS ROW */} - - - - - - - - - - - - - {/* - {([key, values]) => ( - - - - - - )} - */} - -
-
- ); -}; - -export default ClientMonitorStatsProperties; diff --git a/webapp/src/components/ClientMonitor/CodecEntryCmp.tsx b/webapp/src/components/ClientMonitor/CodecEntryCmp.tsx deleted file mode 100644 index 97d853c..0000000 --- a/webapp/src/components/ClientMonitor/CodecEntryCmp.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { CodecEntry } from '@observertc/client-monitor-js'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import TransportEntryCmp from './TransportEntryCmp'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; - -export type CodecEntryProps = { - entry: CodecEntry; - next: Setter; -} - -const CodecEntryCmp: Component = (props: CodecEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getTransport', - buttonName: 'Transport', - action: props.entry.getTransport() ? () => TransportEntryCmp({ entry: props.entry.getTransport()!, next: props.next }) : undefined - }, - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: props.entry.getPeerConnection() ? () => PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) : undefined - } - ]); - setIterableNavigations([ - ]); - setProperties({ - - // last property - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default CodecEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/ContributingSourceEntryCmp.tsx b/webapp/src/components/ClientMonitor/ContributingSourceEntryCmp.tsx deleted file mode 100644 index c3d13ed..0000000 --- a/webapp/src/components/ClientMonitor/ContributingSourceEntryCmp.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { ContributingSourceEntry } from '@observertc/client-monitor-js'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; - -export type ContributingSourceEntryProps = { - entry: ContributingSourceEntry; - next: Setter; -} - -const ContributingSourceEntryCmp: Component = (props: ContributingSourceEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: props.entry.getPeerConnection() ? () => PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) : undefined - } - ]); - setIterableNavigations([ - ]); - setProperties({ - - // last property - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default ContributingSourceEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/DataChannelEntry.tsx b/webapp/src/components/ClientMonitor/DataChannelEntry.tsx deleted file mode 100644 index 2bee51a..0000000 --- a/webapp/src/components/ClientMonitor/DataChannelEntry.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { DataChannelEntry } from '@observertc/client-monitor-js'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; - -export type DataChannelEntryProps = { - entry: DataChannelEntry; - next: Setter; -} - -const DataChannelEntryCmp: Component = (props: DataChannelEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: props.entry.getPeerConnection() ? () => PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) : undefined - } - ]); - setIterableNavigations([ - ]); - setProperties({ - - // last property - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default DataChannelEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/EntryBaseCmp.tsx b/webapp/src/components/ClientMonitor/EntryBaseCmp.tsx deleted file mode 100644 index 2d556fa..0000000 --- a/webapp/src/components/ClientMonitor/EntryBaseCmp.tsx +++ /dev/null @@ -1,130 +0,0 @@ -import { - Paper, - Table, - TableBody, - TableCell, - TableContainer, - TableRow, -} from '@suid/material'; -import { Component, createSignal, For, JSXElement, Setter, Show } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import JSONFormatter from 'json-formatter-js'; -import Button from '../Button'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import ClientMonitorEntryCmp from './ClientMonitorEntry'; - -export type EntryBaseCmpProps = { - properties: Record; - navigations: NavigationItem[]; - iterableNavigations: IterableNavigationItem[]; - next: Setter; -} - -export type NavigationItem = { - name: string, - buttonName: string, - action?: () => JSXElement; -}; - -export type IterableNavigationItem = { - name: string, - items: { - key: string, - action: () => JSXElement; - }[] -}; - -const EntryBaseCmp: Component = (props: EntryBaseCmpProps) => { - return ( - - - {/* - - Property - value - - */} - - - - {new JSONFormatter(props.properties, 3).render()} - - - - {(navigation) => ( - - - - - - - - )} - - 0 < item.items.length)}> - {(iterableNavigation) => ( - // 0}> - - {(item) => { - const [element, setElement] = createSignal(); - return ( - - - setElement(item.action())} >{item.key} - - {element()} - - - - - );} - } - - // - )} - - - -
-
- ); -}; - -export default EntryBaseCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/IceCandidatePairEntryCmp.tsx b/webapp/src/components/ClientMonitor/IceCandidatePairEntryCmp.tsx deleted file mode 100644 index 38bca69..0000000 --- a/webapp/src/components/ClientMonitor/IceCandidatePairEntryCmp.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { IceCandidatePairEntry } from '@observertc/client-monitor-js'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import TransportEntryCmp from './TransportEntryCmp'; -import LocalCandidateEntryCmp from './LocalCandidateEntryCmp'; -import RemoteCandidateEntryCmp from './RemoteCandidateEntryCmp'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; - -export type IceCandidatePairEntryProps = { - entry: IceCandidatePairEntry; - next: Setter; -} - -const IceCandidatePairEntryCmp: Component = (props: IceCandidatePairEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getTransport', - buttonName: 'Transport', - action: props.entry.getTransport() ? () => TransportEntryCmp({ entry: props.entry.getTransport()!, next: props.next }) : undefined - }, - { - name: 'getLocalCandidate', - buttonName: 'Local Candidate', - action: props.entry.getLocalCandidate() ? () => LocalCandidateEntryCmp({ entry: props.entry.getLocalCandidate()!, next: props.next }) : undefined - }, - { - name: 'getRemoteCandidate', - buttonName: 'Remote Candidate', - action: props.entry.getRemoteCandidate() ? () => RemoteCandidateEntryCmp({ entry: props.entry.getRemoteCandidate()!, next: props.next }) : undefined - }, - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: props.entry.getPeerConnection() ? () => PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) : undefined - } - ]); - setIterableNavigations([ - ]); - setProperties({ - - // last property - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default IceCandidatePairEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/IceServerEntryCmp.tsx b/webapp/src/components/ClientMonitor/IceServerEntryCmp.tsx deleted file mode 100644 index 194cee0..0000000 --- a/webapp/src/components/ClientMonitor/IceServerEntryCmp.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { IceServerEntry } from '@observertc/client-monitor-js'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; - -export type IceServerEntryProps = { - entry: IceServerEntry; - next: Setter; -} - -const IceServerEntryCmp: Component = (props: IceServerEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: () => props.entry.getPeerConnection() ? PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) : undefined - } - ]); - setIterableNavigations([ - ]); - setProperties({ - - // last property - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default IceServerEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/InboundRtpEntryCmp.tsx b/webapp/src/components/ClientMonitor/InboundRtpEntryCmp.tsx deleted file mode 100644 index 0b133b5..0000000 --- a/webapp/src/components/ClientMonitor/InboundRtpEntryCmp.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { InboundRtpEntry } from '@observertc/client-monitor-js'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import ReceiverEntryCmp from './ReceiverEntryCmp'; -import AudioPlayoutEntryCmp from './AudioPlayoutEntryCmp'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; -import RemoteOutboundRtpEntryCmp from './RemoteOutboundRtpEntryCmp'; - -export type InboundRtpEntryProps = { - entry: InboundRtpEntry; - next: Setter; -} - -const InboundRtpEntryCmp: Component = (props: InboundRtpEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getReceiver', - buttonName: 'Receiver', - action: props.entry.getReceiver() ? () => ReceiverEntryCmp({ entry: props.entry.getReceiver()!, next: props.next }) : undefined - }, - { - name: 'getAudioPlayout', - buttonName: 'AudioPlayout', - action: props.entry.getAudioPlayout() ? () => AudioPlayoutEntryCmp({ entry: props.entry.getAudioPlayout()!, next: props.next }) : undefined - }, - { - name: 'getRemoteOutboundRtp', - buttonName: 'RemoteOutboundRtp', - action: props.entry.getRemoteOutboundRtp() ? () => RemoteOutboundRtpEntryCmp({ entry: props.entry.getRemoteOutboundRtp()!, next: props.next }) : undefined - }, - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: props.entry.getPeerConnection() ? () => PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) : undefined - } - ]); - setIterableNavigations([ - ]); - setProperties({ - kind: props.entry.kind, - expectedFrameRate: props.entry.expectedFrameRate, - sfuStreamId: props.entry.sfuStreamId, - sfuSinkId: props.entry.sfuSinkId, - remoteClientId: props.entry.remoteClientId, - score: props.entry.score, - avgJitterBufferDelayInMs: props.entry.avgJitterBufferDelayInMs, - receivingBitrate: props.entry.receivingBitrate, - receivedBytes: props.entry.receivedBytes, - lostPackets: props.entry.lostPackets, - receivedPackets: props.entry.receivedPackets, - receivedFrames: props.entry.receivedFrames, - decodedFrames: props.entry.decodedFrames, - droppedFrames: props.entry.droppedFrames, - receivedSamples: props.entry.receivedSamples, - silentConcealedSamples: props.entry.silentConcealedSamples, - fractionLoss: props.entry.fractionLoss, - avgRttInS: props.entry.avgRttInS, - framesPerSecond: props.entry.framesPerSecond, - fpsVolatility: props.entry.fpsVolatility, - avgFramesPerSec: props.entry.avgFramesPerSec, - lastNFramesPerSec: props.entry.lastNFramesPerSec, - - getSsrc: props.entry.getSsrc(), - getTrackId: props.entry.getTrackId(), - - // last property - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default InboundRtpEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/LocalCandidateEntryCmp.tsx b/webapp/src/components/ClientMonitor/LocalCandidateEntryCmp.tsx deleted file mode 100644 index 1ad5f57..0000000 --- a/webapp/src/components/ClientMonitor/LocalCandidateEntryCmp.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { LocalCandidateEntry } from '@observertc/client-monitor-js'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import TransportEntryCmp from './TransportEntryCmp'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; - -export type LocalCandidateEntryProps = { - entry: LocalCandidateEntry; - next: Setter; -} - -const LocalCandidateEntryCmp: Component = (props: LocalCandidateEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getTransport', - buttonName: 'Transport', - action: props.entry.getTransport() ? () => TransportEntryCmp({ entry: props.entry.getTransport()!, next: props.next }) : undefined - }, - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: props.entry.getPeerConnection() ? () => PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) : undefined - } - ]); - setIterableNavigations([ - ]); - setProperties({ - - // last property - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default LocalCandidateEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/MediaSourceEntryCmp.tsx b/webapp/src/components/ClientMonitor/MediaSourceEntryCmp.tsx deleted file mode 100644 index f916e76..0000000 --- a/webapp/src/components/ClientMonitor/MediaSourceEntryCmp.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { MediaSourceEntry } from '@observertc/client-monitor-js'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; - -export type MediaSourceEntryProps = { - entry: MediaSourceEntry; - next: Setter; -} - -const MediaSourceEntryCmp: Component = (props: MediaSourceEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: props.entry.getPeerConnection() ? () => PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) : undefined - } - ]); - setIterableNavigations([ - ]); - setProperties({ - - // last property - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default MediaSourceEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/OutboundRtpEntryCmp.tsx b/webapp/src/components/ClientMonitor/OutboundRtpEntryCmp.tsx deleted file mode 100644 index cff781b..0000000 --- a/webapp/src/components/ClientMonitor/OutboundRtpEntryCmp.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { OutboundRtpEntry } from '@observertc/client-monitor-js'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; -import SenderEntryCmp from './SenderEntryCmp'; -import RemoteInboundRtpEntryCmp from './RemoteInboundRtpEntryCmp'; -import MediaSourceEntryCmp from './MediaSourceEntryCmp'; - -export type OutboundRtpEntryProps = { - entry: OutboundRtpEntry; - next: Setter; -} - - -const OutboundRtpEntryCmp: Component = (props: OutboundRtpEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - // eslint-disable-next-line no-unused-vars - setNavigations([ - { - name: 'getMediaSource', - buttonName: 'Media Source', - action: props.entry.getMediaSource() ? () => MediaSourceEntryCmp({ entry: props.entry.getMediaSource()!, next: props.next }) : undefined - }, - { - name: 'getSender', - buttonName: 'Sender', - action: props.entry.getSender() ? () => SenderEntryCmp({ entry: props.entry.getSender()!, next: props.next }) : undefined - }, - { - name: 'getRemoteInboundRtp', - buttonName: 'RemoteInboundRtp', - action: props.entry.getRemoteInboundRtp() ? () => RemoteInboundRtpEntryCmp({ entry: props.entry.getRemoteInboundRtp()!, next: props.next }) : undefined - }, - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: props.entry.getPeerConnection() ? () => PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) : undefined - } - ]); - setIterableNavigations([ - - ]); - - - const onChange = () => setProperties({ - getSsrc: props.entry.getSsrc(), - getTrackId: props.entry.getTrackId(), - kind: props.entry.kind, - sfuStreamId: props.entry.sfuStreamId, - score: props.entry.score, - sendingBitrate: props.entry.sendingBitrate, - sentBytes: props.entry.sentBytes, - sentPackets: props.entry.sentPackets, - - // last property - stats: props.entry.stats - }); - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default OutboundRtpEntryCmp; diff --git a/webapp/src/components/ClientMonitor/PeerConnectionEntryCmp.tsx b/webapp/src/components/ClientMonitor/PeerConnectionEntryCmp.tsx deleted file mode 100644 index d527b0c..0000000 --- a/webapp/src/components/ClientMonitor/PeerConnectionEntryCmp.tsx +++ /dev/null @@ -1,235 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { PeerConnectionEntry } from '@observertc/client-monitor-js'; -import OutboundRtpEntryCmp from './OutboundRtpEntryCmp'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import IceCandidatePairEntryCmp from './IceCandidatePairEntryCmp'; -import CodecEntryCmp from './CodecEntryCmp'; -import RemoteInboundRtpEntryCmp from './RemoteInboundRtpEntryCmp'; -import RemoteOutboundRtpEntryCmp from './RemoteOutboundRtpEntryCmp'; -import MediaSourceEntryCmp from './MediaSourceEntryCmp'; -import DataChannelEntryCmp from './DataChannelEntry'; -import TransportEntryCmp from './TransportEntryCmp'; -import LocalCandidateEntryCmp from './LocalCandidateEntryCmp'; -import RemoteCandidateEntryCmp from './RemoteCandidateEntryCmp'; -import TransceiverEntryCmp from './TransceiverEntryCmp'; -import SenderEntryCmp from './SenderEntryCmp'; -import ReceiverEntryCmp from './ReceiverEntryCmp'; -import SctpTransportEntryCmp from './SctpTransportEntryCmp'; -import CertificateEntryCmp from './CertificateEntryCmp'; -import IceServerEntryCmp from './IceServerEntryCmp'; -import ContributingSourceEntryCmp from './ContributingSourceEntryCmp'; -import InboundRtpEntryCmp from './InboundRtpEntryCmp'; -import AudioPlayoutEntryCmp from './AudioPlayoutEntryCmp'; - -export type PeerConnectionEntryProps = { - entry: PeerConnectionEntry; - next: Setter; -} - -const PeerConnectionEntryCmp: Component = (props: PeerConnectionEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getSelectedIceCandidatePair', - buttonName: 'Selected ICE Candidate Pair', - action: props.entry.getSelectedIceCandidatePair() ? () => IceCandidatePairEntryCmp({ entry: props.entry.getSelectedIceCandidatePair()!, next: props.next }) : undefined - }, - ]); - setIterableNavigations([ - { - name: 'codecs', - items: [...props.entry.codecs()].map((codec) => ({ - key: `Codec ${codec.stats.payloadType}`, - action: () => CodecEntryCmp({ entry: codec, next: props.next }) - })) - }, - { - name: 'inboundRtps', - items: [...props.entry.inboundRtps()].map((inboundRtp) => ({ - key: `Track (${inboundRtp.getTrackId()}) ${inboundRtp.stats.ssrc}`, - action: () => InboundRtpEntryCmp({ entry: inboundRtp, next: props.next }) - })) - }, - { - name: 'outboundRtps', - items: [...props.entry.outboundRtps()].map((outboundRtp) => ({ - key: `Track (${outboundRtp.getTrackId()}) ${outboundRtp.stats.ssrc}`, - action: () => OutboundRtpEntryCmp({ entry: outboundRtp, next: props.next }) - })) - }, - { - name: 'remoteInboundRtps', - items: [...props.entry.remoteInboundRtps()].map((remoteInboundRtp) => ({ - key: `Track (${remoteInboundRtp.getOutboundRtp()?.getTrackId()}) ${remoteInboundRtp.stats.ssrc}`, - action: () => RemoteInboundRtpEntryCmp({ entry: remoteInboundRtp, next: props.next }) - })) - }, - { - name: 'remoteOutboundRtps', - items: [...props.entry.remoteOutboundRtps()].map((remoteOutboundRtp) => ({ - key: `Track (${remoteOutboundRtp.getInboundRtp()?.getTrackId()}) ${remoteOutboundRtp.stats.ssrc}`, - action: () => RemoteOutboundRtpEntryCmp({ entry: remoteOutboundRtp, next: props.next }) - })) - }, - { - name: 'mediaSources', - items: [...props.entry.mediaSources()].map((mediaSource) => ({ - key: `Media Source (id: ${mediaSource.stats.id})`, - action: () => MediaSourceEntryCmp({ entry: mediaSource, next: props.next }) - })) - }, - { - name: 'dataChannels', - items: [...props.entry.dataChannels()].map((dataChannel) => ({ - key: `Data Channel (id: ${dataChannel.stats.id})`, - action: () => DataChannelEntryCmp({ entry: dataChannel, next: props.next }) - })) - }, - { - name: 'transports', - items: [...props.entry.transports()].map((transport) => ({ - key: `Transport (id: ${transport.stats.id})`, - action: () => TransportEntryCmp({ entry: transport, next: props.next }) - })) - }, - { - name: 'iceCandidatePairs', - items: [...props.entry.iceCandidatePairs()].map((iceCandidatePair) => ({ - key: `ICE Candidate Pair (local: ${iceCandidatePair.getLocalCandidate()?.stats.address} remote: ${iceCandidatePair.getRemoteCandidate()?.stats.address})`, - action: () => IceCandidatePairEntryCmp({ entry: iceCandidatePair, next: props.next }) - })) - }, - { - name: 'localCandidates', - items: [...props.entry.localCandidates()].map((iceLocalCandidate) => ({ - key: `ICE Local Candidate (address: ${iceLocalCandidate.stats.address})`, - action: () => LocalCandidateEntryCmp({ entry: iceLocalCandidate, next: props.next }) - })) - }, - { - name: 'remoteCandidates', - items: [...props.entry.remoteCandidates()].map((iceRemoteCandidate) => ({ - key: `ICE Remote Candidate (address: ${iceRemoteCandidate.stats.address})`, - action: () => RemoteCandidateEntryCmp({ entry: iceRemoteCandidate, next: props.next }) - })) - }, - { - name: 'audioPlayouts', - items: [...props.entry.audioPlayouts()].map((audioPlayout) => ({ - key: `Audio Playout (id: ${audioPlayout.stats.id})`, - action: () => AudioPlayoutEntryCmp({ entry: audioPlayout, next: props.next }) - })) - }, - { - name: 'transceivers', - items: [...props.entry.transceivers()].map((transceiver) => ({ - key: `Transceiver ${transceiver.stats.kind}`, - action: () => TransceiverEntryCmp({ entry: transceiver, next: props.next }) - })) - }, - { - name: 'senders', - items: [...props.entry.senders()].map((sender) => ({ - key: `Sender (${sender.stats.ssrc})`, - action: () => SenderEntryCmp({ entry: sender, next: props.next }) - })) - }, - { - name: 'receivers', - items: [...props.entry.receivers()].map((receiver) => ({ - key: `Receiver (${receiver.stats.ssrc})`, - action: () => ReceiverEntryCmp({ entry: receiver, next: props.next }) - })) - }, - { - name: 'sctpTransports', - items: [...props.entry.sctpTransports()].map((sctpTransport) => ({ - key: `SCTP Transport (id: ${sctpTransport.stats.id})`, - action: () => SctpTransportEntryCmp({ entry: sctpTransport, next: props.next }) - })) - }, - { - name: 'certificates', - items: [...props.entry.certificates()].map((certificate) => ({ - key: `Certificate (fingerprint: ${certificate.stats.fingerprint})`, - action: () => CertificateEntryCmp({ entry: certificate, next: props.next }) - })) - }, - { - name: 'iceServers', - items: [...props.entry.iceServers()].map((iceServer) => ({ - key: `ICE Server (url: ${iceServer.stats.url})`, - action: () => IceServerEntryCmp({ entry: iceServer, next: props.next }) - })) - }, - { - name: 'contributingSources', - items: [...props.entry.contributingSources()].map((contributingSource) => ({ - key: `Contributing Source (${contributingSource.stats.id})`, - action: () => ContributingSourceEntryCmp({ entry: contributingSource, next: props.next }) - })) - } - - ]); - setProperties({ - peerConnectionId: props.entry.peerConnectionId, - statsId: props.entry.statsId, - label: props.entry.label, - usingTCP: props.entry.usingTCP, - usingTURN: props.entry.usingTURN, - - totalInboundPacketsLost: props.entry.totalInboundPacketsLost, - totalInboundPacketsReceived: props.entry.totalInboundPacketsReceived, - totalOutboundPacketsLost: props.entry.totalOutboundPacketsLost, - totalOutboundPacketsReceived: props.entry.totalOutboundPacketsReceived, - totalOutboundPacketsSent: props.entry.totalOutboundPacketsSent, - totalSentAudioBytes: props.entry.totalSentAudioBytes, - totalSentVideoBytes: props.entry.totalSentVideoBytes, - totalReceivedAudioBytes: props.entry.totalReceivedAudioBytes, - totalReceivedVideoBytes: props.entry.totalReceivedVideoBytes, - totalDataChannelBytesReceived: props.entry.totalDataChannelBytesReceived, - totalDataChannelBytesSent: props.entry.totalDataChannelBytesSent, - - deltaInboundPacketsLost: props.entry.deltaInboundPacketsLost, - deltaInboundPacketsReceived: props.entry.deltaInboundPacketsReceived, - deltaOutboundPacketsLost: props.entry.deltaOutboundPacketsLost, - deltaOutboundPacketsReceived: props.entry.deltaOutboundPacketsReceived, - deltaOutboundPacketsSent: props.entry.deltaOutboundPacketsSent, - deltaSentAudioBytes: props.entry.deltaSentAudioBytes, - deltaSentVideoBytes: props.entry.deltaSentVideoBytes, - deltaReceivedAudioBytes: props.entry.deltaReceivedAudioBytes, - deltaReceivedVideoBytes: props.entry.deltaReceivedVideoBytes, - deltaDataChannelBytesSent: props.entry.deltaDataChannelBytesSent, - deltaDataChannelBytesReceived: props.entry.deltaDataChannelBytesReceived, - avgRttInS: props.entry.avgRttInS, - - sendingAudioBitrate: props.entry.sendingAudioBitrate, - sendingVideoBitrate: props.entry.sendingVideoBitrate, - sendingFractionalLoss: props.entry.sendingFractionalLoss, - receivingAudioBitrate: props.entry.receivingAudioBitrate, - receivingVideoBitrate: props.entry.receivingVideoBitrate, - receivingFractionalLoss: props.entry.receivingFractionalLoss, - - connectionState: props.entry.connectionState, - connectionEstablishedDurationInMs: props.entry.connectionEstablishedDurationInMs, - // last property - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default PeerConnectionEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/ReceiverEntryCmp.tsx b/webapp/src/components/ClientMonitor/ReceiverEntryCmp.tsx deleted file mode 100644 index e91e8aa..0000000 --- a/webapp/src/components/ClientMonitor/ReceiverEntryCmp.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { ReceiverEntry } from '@observertc/client-monitor-js'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; - -export type ReceiverEntryProps = { - entry: ReceiverEntry; - next: Setter; -} - -const ReceiverEntryCmp: Component = (props: ReceiverEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: () => PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) - } - ]); - setIterableNavigations([ - ]); - setProperties({ - - // last property - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default ReceiverEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/RemoteCandidateEntryCmp.tsx b/webapp/src/components/ClientMonitor/RemoteCandidateEntryCmp.tsx deleted file mode 100644 index dcaa005..0000000 --- a/webapp/src/components/ClientMonitor/RemoteCandidateEntryCmp.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { RemoteCandidateEntry } from '@observertc/client-monitor-js'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import TransportEntryCmp from './TransportEntryCmp'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; - -export type RemoteCandidateEntryProps = { - entry: RemoteCandidateEntry; - next: Setter; -} - -const RemoteCandidateEntryCmp: Component = (props: RemoteCandidateEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getTransport', - buttonName: 'Transport', - action: props.entry.getTransport() ? () => TransportEntryCmp({ entry: props.entry.getTransport()!, next: props.next }) : undefined - }, - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: props.entry.getPeerConnection() ? () => PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) : undefined - } - ]); - setIterableNavigations([ - ]); - setProperties({ - - // last property - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default RemoteCandidateEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/RemoteInboundRtpEntryCmp.tsx b/webapp/src/components/ClientMonitor/RemoteInboundRtpEntryCmp.tsx deleted file mode 100644 index 1722455..0000000 --- a/webapp/src/components/ClientMonitor/RemoteInboundRtpEntryCmp.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { RemoteInboundRtpEntry } from '@observertc/client-monitor-js'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import OutboundRtpEntryCmp from './OutboundRtpEntryCmp'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; - -export type RemoteInboundRtpEntryProps = { - entry: RemoteInboundRtpEntry; - next: Setter; -} - -const RemoteInboundRtpEntryCmp: Component = (props: RemoteInboundRtpEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getOutboundRtp', - buttonName: 'Outbound Rtp', - action: props.entry.getOutboundRtp() ? () => OutboundRtpEntryCmp({ entry: props.entry.getOutboundRtp()!, next: props.next }) : undefined - }, - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: () => PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) - } - ]); - setIterableNavigations([ - ]); - setProperties({ - receivedPackets: props.entry.receivedPackets, - lostPackets: props.entry.lostPackets, - // last property - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default RemoteInboundRtpEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/RemoteOutboundRtpEntryCmp.tsx b/webapp/src/components/ClientMonitor/RemoteOutboundRtpEntryCmp.tsx deleted file mode 100644 index 80db112..0000000 --- a/webapp/src/components/ClientMonitor/RemoteOutboundRtpEntryCmp.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { RemoteOutboundRtpEntry } from '@observertc/client-monitor-js'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; -import InboundRtpEntryCmp from './InboundRtpEntryCmp'; - -export type RemoteOutboundRtpEntryProps = { - entry: RemoteOutboundRtpEntry; - next: Setter; -} - -const RemoteOutboundRtpEntryCmp: Component = (props: RemoteOutboundRtpEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getInboundRtp', - buttonName: 'Inbound Rtp', - action: props.entry.getInboundRtp() ? () => InboundRtpEntryCmp({ entry: props.entry.getInboundRtp()!, next: props.next }) : undefined - }, - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: () => PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) - } - ]); - setIterableNavigations([ - ]); - setProperties({ - getSsrc: props.entry.getSsrc(), - // last property - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default RemoteOutboundRtpEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/SctpTransportEntryCmp.tsx b/webapp/src/components/ClientMonitor/SctpTransportEntryCmp.tsx deleted file mode 100644 index 4295c94..0000000 --- a/webapp/src/components/ClientMonitor/SctpTransportEntryCmp.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { SctpTransportEntry } from '@observertc/client-monitor-js'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import TransportEntryCmp from './TransportEntryCmp'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; - -export type SctpTransportEntryProps = { - entry: SctpTransportEntry; - next: Setter; -} - -const SctpTransportEntryCmp: Component = (props: SctpTransportEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getTransport', - buttonName: 'Transport', - action: props.entry.getTransport() ? () => TransportEntryCmp({ entry: props.entry.getTransport()!, next: props.next }) : undefined - }, - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: () => PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) - } - ]); - setIterableNavigations([ - ]); - setProperties({ - - // last property - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default SctpTransportEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/SenderEntryCmp.tsx b/webapp/src/components/ClientMonitor/SenderEntryCmp.tsx deleted file mode 100644 index 9a4bd0a..0000000 --- a/webapp/src/components/ClientMonitor/SenderEntryCmp.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { SenderEntry } from '@observertc/client-monitor-js'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import MediaSourceEntryCmp from './MediaSourceEntryCmp'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; - -export type SenderEntryProps = { - entry: SenderEntry; - next: Setter; -} - -const SenderEntryCmp: Component = (props: SenderEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getMediaSource', - buttonName: 'MediaSource', - action: props.entry.getMediaSource() ? () => MediaSourceEntryCmp({ entry: props.entry.getMediaSource()!, next: props.next }) : undefined - }, - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: () => PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) - } - ]); - setIterableNavigations([ - ]); - setProperties({ - - // last property - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default SenderEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/TransceiverEntryCmp.tsx b/webapp/src/components/ClientMonitor/TransceiverEntryCmp.tsx deleted file mode 100644 index 502fde1..0000000 --- a/webapp/src/components/ClientMonitor/TransceiverEntryCmp.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { TransceiverEntry } from '@observertc/client-monitor-js'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; -import SenderEntryCmp from './SenderEntryCmp'; -import ReceiverEntryCmp from './ReceiverEntryCmp'; - -export type TransceiverEntryProps = { - entry: TransceiverEntry; - next: Setter; -} - -const TransceiverEntryCmp: Component = (props: TransceiverEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getSender', - buttonName: 'Sender', - action: props.entry.getSender() ? () => SenderEntryCmp({ entry: props.entry.getSender()!, next: props.next }) : undefined - }, - { - name: 'getReceiver', - buttonName: 'Receiver', - action: props.entry.getReceiver() ? () => ReceiverEntryCmp({ entry: props.entry.getReceiver()!, next: props.next }): undefined - }, - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: () => PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) - } - ]); - setIterableNavigations([ - ]); - setProperties({ - - // last property - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default TransceiverEntryCmp; \ No newline at end of file diff --git a/webapp/src/components/ClientMonitor/TransportEntryCmp.tsx b/webapp/src/components/ClientMonitor/TransportEntryCmp.tsx deleted file mode 100644 index 9dafb9d..0000000 --- a/webapp/src/components/ClientMonitor/TransportEntryCmp.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { Component, Setter, createSignal, onCleanup, onMount } from 'solid-js'; -import { clientStore } from '../../stores/LocalClientStore'; -import { TransportEntry } from '@observertc/client-monitor-js'; -import { ClientMonitorEntryRender } from './ClientMonitorShowEntry'; -import EntryBaseCmp, { IterableNavigationItem, NavigationItem } from './EntryBaseCmp'; -import IceCandidatePairEntryCmp from './IceCandidatePairEntryCmp'; -import CertificateEntryCmp from './CertificateEntryCmp'; -import PeerConnectionEntryCmp from './PeerConnectionEntryCmp'; - -export type TransportEntryProps = { - entry: TransportEntry; - next: Setter; -} - -const TransportEntryCmp: Component = (props: TransportEntryProps) => { - const [ properties, setProperties ] = createSignal>({}); - const [ navigations, setNavigations ] = createSignal([]); - const [ iterableNavigations, setIterableNavigations ] = createSignal([]); - const onChange = () => { - setNavigations([ - { - name: 'getRtcpTransport', - buttonName: 'RTCP Transport', - action: props.entry.getRtcpTransport() ? () => TransportEntryCmp({ entry: props.entry.getRtcpTransport()!, next: props.next }) : undefined - }, - { - name: 'getSelectedIceCandidatePair', - buttonName: 'Selected ICE Candidate Pair', - action: props.entry.getSelectedIceCandidatePair() ? () => IceCandidatePairEntryCmp({ entry: props.entry.getSelectedIceCandidatePair()!, next: props.next }) : undefined - }, - { - name: 'getLocalCertificate', - buttonName: 'Local Certificate', - action: props.entry.getLocalCertificate() ? () => CertificateEntryCmp({ entry: props.entry.getLocalCertificate()!, next: props.next }) : undefined - }, - { - name: 'getRemoteCertificate', - buttonName: 'Remote Certificate', - action: props.entry.getRemoteCertificate() ? () => CertificateEntryCmp({ entry: props.entry.getRemoteCertificate()!, next: props.next }) : undefined - }, - { - name: 'getPeerConnection', - buttonName: 'Peer Connection', - action: () => PeerConnectionEntryCmp({ entry: props.entry.getPeerConnection()!, next: props.next }) - } - ]); - setIterableNavigations([ - ]); - setProperties({ - - // last property - stats: props.entry.stats - }); - }; - onMount(() => { - clientStore.call?.monitor?.on('stats-collected', onChange); - }); - onCleanup(() => { - clientStore.call?.monitor?.off('stats-collected', onChange); - }); - return ( - - ); -}; - -export default TransportEntryCmp; \ No newline at end of file diff --git a/webapp/src/views/ClientMonitorProperties.tsx b/webapp/src/views/ClientMonitorProperties.tsx index 53387bc..6731cb7 100644 --- a/webapp/src/views/ClientMonitorProperties.tsx +++ b/webapp/src/views/ClientMonitorProperties.tsx @@ -20,15 +20,6 @@ const ClientMonitorProperties: Component = () => {
-

- The ClientMonitor class from - ObserveRTC’s @observertc/client-monitor-js library is designed to monitor and gather WebRTC statistics and - performance metrics from client applications. It serves as a comprehensive - tool for tracking the health, efficiency, and performance of WebRTC connections, - allowing developers to capture real-time information and diagnostics about WebRTC - sessions in their applications. -

- Please join a call to see the ClientMonitor in action. )}> diff --git a/webapp/src/views/Main.tsx b/webapp/src/views/Main.tsx index df602fd..a5f1300 100644 --- a/webapp/src/views/Main.tsx +++ b/webapp/src/views/Main.tsx @@ -73,6 +73,14 @@ const Main: Component = () => {
+

+ The ClientMonitor class from + ObserveRTC’s @observertc/client-monitor-js library is designed to monitor and gather WebRTC statistics and + performance metrics from client applications. It serves as a comprehensive + tool for tracking the health, efficiency, and performance of WebRTC connections, + allowing developers to capture real-time information and diagnostics about WebRTC + sessions in their applications. +

setPage('client-monitor-properties')}> See ClientMonitor Properties