feat(connection-stats): convert connection stats display to react
Move all logic related to displaying a table of connection stats to a React Component. The actual parsing logic was modified as little as possible as the focus is moving display to React.
This commit is contained in:
parent
d117989b55
commit
e0d641a787
|
@ -1,6 +1,13 @@
|
|||
/* global $, APP, interfaceConfig, JitsiMeetJS */
|
||||
/* jshint -W101 */
|
||||
|
||||
/* eslint-disable no-unused-vars */
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import { ConnectionStatsTable } from '../../../react/features/connection-stats';
|
||||
/* eslint-enable no-unused-vars */
|
||||
|
||||
import JitsiPopover from "../util/JitsiPopover";
|
||||
import UIUtil from "../util/UIUtil";
|
||||
|
||||
|
@ -42,237 +49,31 @@ function ConnectionIndicator(videoContainer, videoId) {
|
|||
this.popover = null;
|
||||
this.id = videoId;
|
||||
this.create();
|
||||
|
||||
this.isLocalVideo
|
||||
= this.videoContainer.videoSpanId === 'localVideoContainer';
|
||||
this.showMore = this.showMore.bind(this);
|
||||
}
|
||||
|
||||
ConnectionIndicator.getIP = function(value) {
|
||||
return value.substring(0, value.lastIndexOf(":"));
|
||||
};
|
||||
|
||||
ConnectionIndicator.getPort = function(value) {
|
||||
return value.substring(value.lastIndexOf(":") + 1, value.length);
|
||||
};
|
||||
|
||||
ConnectionIndicator.getStringFromArray = function (array) {
|
||||
var res = "";
|
||||
for(var i = 0; i < array.length; i++) {
|
||||
res += (i === 0? "" : ", ") + array[i];
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates the html content.
|
||||
* @returns {string} the html content.
|
||||
*/
|
||||
ConnectionIndicator.prototype.generateText = function () {
|
||||
var downloadBitrate, uploadBitrate, packetLoss, i;
|
||||
|
||||
if(!this.bitrate) {
|
||||
downloadBitrate = "N/A";
|
||||
uploadBitrate = "N/A";
|
||||
}
|
||||
else {
|
||||
downloadBitrate =
|
||||
this.bitrate.download? this.bitrate.download + " Kbps" : "N/A";
|
||||
uploadBitrate =
|
||||
this.bitrate.upload? this.bitrate.upload + " Kbps" : "N/A";
|
||||
}
|
||||
|
||||
if(!this.packetLoss) {
|
||||
packetLoss = "N/A";
|
||||
} else {
|
||||
|
||||
packetLoss = "<span class='connection-info__download'>↓</span>" +
|
||||
(this.packetLoss.download !== null ?
|
||||
this.packetLoss.download : "N/A") +
|
||||
"% <span class='connection-info__upload'>↑</span>" +
|
||||
(this.packetLoss.upload !== null? this.packetLoss.upload : "N/A") +
|
||||
"%";
|
||||
}
|
||||
|
||||
// GENERATE RESOLUTIONS STRING
|
||||
const resolutions = this.resolution || {};
|
||||
const resolutionStr = Object.keys(resolutions).map(ssrc => {
|
||||
let {width, height} = resolutions[ssrc];
|
||||
return `${width}x${height}`;
|
||||
}).join(', ') || 'N/A';
|
||||
|
||||
const framerates = this.framerate || {};
|
||||
const frameRateStr = Object.keys(framerates).map(ssrc =>
|
||||
framerates[ssrc]
|
||||
).join(', ') || 'N/A';
|
||||
|
||||
let result = (
|
||||
`<table class="connection-info__container" style='width:100%'>
|
||||
<tr>
|
||||
<td>
|
||||
<span data-i18n='connectionindicator.bitrate'></span>
|
||||
</td>
|
||||
<td>
|
||||
<span class='connection-info__download'>↓</span>${downloadBitrate}
|
||||
<span class='connection-info__upload'>↑</span>${uploadBitrate}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span data-i18n='connectionindicator.packetloss'></span>
|
||||
</td>
|
||||
<td>${packetLoss}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span data-i18n='connectionindicator.resolution'></span>
|
||||
</td>
|
||||
<td>
|
||||
${resolutionStr}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span data-i18n='connectionindicator.framerate'></span>
|
||||
</td>
|
||||
<td>
|
||||
${frameRateStr}
|
||||
</td>
|
||||
</tr>
|
||||
</table>`);
|
||||
|
||||
if(this.videoContainer.videoSpanId == "localVideoContainer") {
|
||||
result += "<a class=\"jitsipopover__showmore link\" " +
|
||||
"onclick = \"APP.UI.connectionIndicatorShowMore('" +
|
||||
// FIXME: we do not know local id when this text is generated
|
||||
//this.id + "')\" data-i18n='connectionindicator." +
|
||||
"local')\" data-i18n='connectionindicator." +
|
||||
(this.showMoreValue ? "less" : "more") + "'></a>";
|
||||
}
|
||||
|
||||
if (this.showMoreValue) {
|
||||
var downloadBandwidth, uploadBandwidth, transport;
|
||||
if (!this.bandwidth) {
|
||||
downloadBandwidth = "N/A";
|
||||
uploadBandwidth = "N/A";
|
||||
} else {
|
||||
downloadBandwidth = this.bandwidth.download?
|
||||
this.bandwidth.download + " Kbps" :
|
||||
"N/A";
|
||||
uploadBandwidth = this.bandwidth.upload?
|
||||
this.bandwidth.upload + " Kbps" :
|
||||
"N/A";
|
||||
}
|
||||
|
||||
if (!this.transport || this.transport.length === 0) {
|
||||
transport = "<tr>" +
|
||||
"<td><span " +
|
||||
"data-i18n='connectionindicator.address'></span></td>" +
|
||||
"<td> N/A</td></tr>";
|
||||
} else {
|
||||
var data = {
|
||||
remoteIP: [],
|
||||
localIP:[],
|
||||
remotePort:[],
|
||||
localPort:[],
|
||||
transportType:[]};
|
||||
for(i = 0; i < this.transport.length; i++) {
|
||||
var ip = ConnectionIndicator.getIP(this.transport[i].ip);
|
||||
var port = ConnectionIndicator.getPort(this.transport[i].ip);
|
||||
var localIP =
|
||||
ConnectionIndicator.getIP(this.transport[i].localip);
|
||||
var localPort =
|
||||
ConnectionIndicator.getPort(this.transport[i].localip);
|
||||
if(data.remoteIP.indexOf(ip) == -1) {
|
||||
data.remoteIP.push(ip);
|
||||
}
|
||||
|
||||
if(data.remotePort.indexOf(port) == -1) {
|
||||
data.remotePort.push(port);
|
||||
}
|
||||
|
||||
if(data.localIP.indexOf(localIP) == -1) {
|
||||
data.localIP.push(localIP);
|
||||
}
|
||||
|
||||
if(data.localPort.indexOf(localPort) == -1) {
|
||||
data.localPort.push(localPort);
|
||||
}
|
||||
|
||||
if(data.transportType.indexOf(this.transport[i].type) == -1) {
|
||||
data.transportType.push(this.transport[i].type);
|
||||
}
|
||||
}
|
||||
|
||||
// All of the transports should be either P2P or JVB
|
||||
const isP2P = this.transport.length ? this.transport[0].p2p : false;
|
||||
|
||||
var local_address_key = "connectionindicator.localaddress";
|
||||
var remote_address_key = "connectionindicator.remoteaddress";
|
||||
var localTransport =
|
||||
"<tr><td><span data-i18n='" +
|
||||
local_address_key +"' data-i18n-options='" +
|
||||
JSON.stringify({count: data.localIP.length})
|
||||
+ "'></span></td><td> " +
|
||||
ConnectionIndicator.getStringFromArray(data.localIP) +
|
||||
"</td></tr>";
|
||||
transport =
|
||||
"<tr><td><span data-i18n='" +
|
||||
remote_address_key + "' data-i18n-options='" +
|
||||
JSON.stringify({count: data.remoteIP.length})
|
||||
+ "'></span></td><td> " +
|
||||
ConnectionIndicator.getStringFromArray(data.remoteIP);
|
||||
|
||||
// Append (p2p) to indicate the P2P type of transport
|
||||
if (isP2P) {
|
||||
transport
|
||||
+= "<span data-i18n='connectionindicator.peer_to_peer'>";
|
||||
}
|
||||
transport += "</td></tr>";
|
||||
|
||||
var key_remote = "connectionindicator.remoteport",
|
||||
key_local = "connectionindicator.localport";
|
||||
|
||||
transport += "<tr>" +
|
||||
"<td>" +
|
||||
"<span data-i18n='" + key_remote +
|
||||
"' data-i18n-options='" +
|
||||
JSON.stringify({count: this.transport.length})
|
||||
+ "'></span></td><td>";
|
||||
localTransport += "<tr>" +
|
||||
"<td>" +
|
||||
"<span data-i18n='" + key_local +
|
||||
"' data-i18n-options='" +
|
||||
JSON.stringify({count: this.transport.length})
|
||||
+ "'></span></td><td>";
|
||||
|
||||
transport +=
|
||||
ConnectionIndicator.getStringFromArray(data.remotePort);
|
||||
localTransport +=
|
||||
ConnectionIndicator.getStringFromArray(data.localPort);
|
||||
transport += "</td></tr>";
|
||||
transport += localTransport + "</td></tr>";
|
||||
transport +="<tr>" +
|
||||
"<td><span data-i18n='connectionindicator.transport' "
|
||||
+ " data-i18n-options='" +
|
||||
JSON.stringify({count: data.transportType.length})
|
||||
+ "'></span></td>" +
|
||||
"<td>"
|
||||
+ ConnectionIndicator.getStringFromArray(data.transportType);
|
||||
+ "</td></tr>";
|
||||
|
||||
}
|
||||
|
||||
result += "<table class='connection-info__container' style='width:100%'>" +
|
||||
"<tr>" +
|
||||
"<td>" +
|
||||
"<span data-i18n='connectionindicator.bandwidth'></span>" +
|
||||
"</td><td>" +
|
||||
"<span class='connection-info__download'>↓</span>" +
|
||||
downloadBandwidth +
|
||||
" <span class='connection-info__upload'>↑</span>" +
|
||||
uploadBandwidth + "</td></tr>";
|
||||
|
||||
result += transport + "</table>";
|
||||
}
|
||||
|
||||
return result;
|
||||
/* jshint ignore:start */
|
||||
return (
|
||||
<ConnectionStatsTable
|
||||
bandwidth = { this.bandwidth }
|
||||
bitrate = { this.bitrate }
|
||||
isLocalVideo = { this.isLocalVideo }
|
||||
framerate = { this.framerate }
|
||||
onShowMore = { this.showMore }
|
||||
packetLoss = { this.packetLoss}
|
||||
resolution = { this.resolution }
|
||||
shouldShowMore = { this.showMoreValue }
|
||||
transport = { this.transport } />
|
||||
);
|
||||
/* jshint ignore:end */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -443,9 +244,7 @@ ConnectionIndicator.prototype.updatePopoverData = function (force) {
|
|||
// generate content, translate it and add it to document only if
|
||||
// popover is visible or we force to do so.
|
||||
if(this.popover.popoverShown || force) {
|
||||
this.popover.updateContent(
|
||||
`<div class="connection-info">${this.generateText()}</div>`
|
||||
);
|
||||
this.popover.updateContent(this.generateText());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,499 @@
|
|||
import React, { Component } from 'react';
|
||||
|
||||
import { translate } from '../../base/i18n';
|
||||
|
||||
/**
|
||||
* React {@code Component} for displaying connection statistics.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
class ConnectionStatsTable extends Component {
|
||||
/**
|
||||
* {@code ConnectionStatsTable} component's property types.
|
||||
*
|
||||
* @static
|
||||
*/
|
||||
static propTypes = {
|
||||
/**
|
||||
* Statistics related to bandwidth.
|
||||
* {{
|
||||
* download: Number,
|
||||
* upload: Number
|
||||
* }}
|
||||
*/
|
||||
bandwidth: React.PropTypes.object,
|
||||
|
||||
/**
|
||||
* Statistics related to bitrate.
|
||||
* {{
|
||||
* download: Number,
|
||||
* upload: Number
|
||||
* }}
|
||||
*/
|
||||
bitrate: React.PropTypes.object,
|
||||
|
||||
/**
|
||||
* Statistics related to framerates for each ssrc.
|
||||
* {{
|
||||
* [ ssrc ]: Number
|
||||
* }}
|
||||
*/
|
||||
framerate: React.PropTypes.object,
|
||||
|
||||
/**
|
||||
* Whether or not the statitics are for local video.
|
||||
*/
|
||||
isLocalVideo: React.PropTypes.bool,
|
||||
|
||||
/**
|
||||
* Callback to invoke when the show additional stats link is clicked.
|
||||
*/
|
||||
onShowMore: React.PropTypes.func,
|
||||
|
||||
/**
|
||||
* Statistics related to packet loss.
|
||||
* {{
|
||||
* download: Number,
|
||||
* upload: Number
|
||||
* }}
|
||||
*/
|
||||
packetLoss: React.PropTypes.object,
|
||||
|
||||
/**
|
||||
* Statistics related to display resolutions for each ssrc.
|
||||
* {{
|
||||
* [ ssrc ]: {
|
||||
* height: Number,
|
||||
* width: Number
|
||||
* }
|
||||
* }}
|
||||
*/
|
||||
resolution: React.PropTypes.object,
|
||||
|
||||
/**
|
||||
* Whether or not additional stats about bandwidth and transport should
|
||||
* be displayed. Will not display even if true for remote participants.
|
||||
*/
|
||||
shouldShowMore: React.PropTypes.bool,
|
||||
|
||||
/**
|
||||
* Invoked to obtain translated strings.
|
||||
*/
|
||||
t: React.PropTypes.func,
|
||||
|
||||
/**
|
||||
* Statistics related to transports.
|
||||
*/
|
||||
transport: React.PropTypes.array
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements React's {@link Component#render()}.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const { isLocalVideo } = this.props;
|
||||
|
||||
return (
|
||||
<div className = 'connection-info'>
|
||||
{ this._renderStatistics() }
|
||||
{ isLocalVideo ? this._renderShowMoreLink() : null }
|
||||
{ isLocalVideo && this.props.shouldShowMore
|
||||
? this._renderAdditionalStats() : null }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a table as ReactElement that will display additional statistics
|
||||
* related to bandwidth and transport.
|
||||
*
|
||||
* @private
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderAdditionalStats() {
|
||||
return (
|
||||
<table className = 'connection-info__container'>
|
||||
<tbody>
|
||||
{ this._renderBandwidth() }
|
||||
{ this._renderTransport() }
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a table row as a ReactElement for displaying bandwidth related
|
||||
* statistics.
|
||||
*
|
||||
* @private
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderBandwidth() {
|
||||
const { download, upload } = this.props.bandwidth || {};
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<td>
|
||||
{ this.props.t('connectionindicator.bandwidth') }
|
||||
</td>
|
||||
<td>
|
||||
<span className = 'connection-info__download'>
|
||||
↓
|
||||
</span>
|
||||
{ download ? `${download} Kbps` : 'N/A' }
|
||||
<span className = 'connection-info__upload'>
|
||||
↑
|
||||
</span>
|
||||
{ upload ? `${upload} Kbps` : 'N/A' }
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a a table row as a ReactElement for displaying bitrate related
|
||||
* statistics.
|
||||
*
|
||||
* @private
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderBitrate() {
|
||||
const { download, upload } = this.props.bitrate || {};
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<td>
|
||||
<span>
|
||||
{ this.props.t('connectionindicator.bitrate') }
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span className = 'connection-info__download'>
|
||||
↓
|
||||
</span>
|
||||
{ download ? `${download} Kbps` : 'N/A' }
|
||||
<span className = 'connection-info__upload'>
|
||||
↑
|
||||
</span>
|
||||
{ upload ? `${upload} Kbps` : 'N/A' }
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a table row as a ReactElement for displaying frame rate related
|
||||
* statistics.
|
||||
*
|
||||
* @private
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderFrameRate() {
|
||||
const { framerate, t } = this.props;
|
||||
const frameRateString = Object.keys(framerate || {})
|
||||
.map(ssrc => framerate[ssrc])
|
||||
.join(', ') || 'N/A';
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<td>
|
||||
<span>{ t('connectionindicator.framerate') }</span>
|
||||
</td>
|
||||
<td>{ frameRateString }</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a tables row as a ReactElement for displaying packet loss related
|
||||
* statistics.
|
||||
*
|
||||
* @private
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderPacketLoss() {
|
||||
const { packetLoss, t } = this.props;
|
||||
let packetLossTableData;
|
||||
|
||||
if (packetLoss) {
|
||||
const { download, upload } = packetLoss;
|
||||
|
||||
// eslint-disable-next-line no-extra-parens
|
||||
packetLossTableData = (
|
||||
<td>
|
||||
<span className = 'connection-info__download'>
|
||||
↓
|
||||
</span>
|
||||
{ download === null ? 'N/A' : `${download}%` }
|
||||
<span className = 'connection-info__upload'>
|
||||
↑
|
||||
</span>
|
||||
{ upload === null ? 'N/A' : `${upload}%` }
|
||||
</td>
|
||||
);
|
||||
} else {
|
||||
packetLossTableData = <td>N/A</td>;
|
||||
}
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<td>
|
||||
<span>
|
||||
{ t('connectionindicator.packetloss') }
|
||||
</span>
|
||||
</td>
|
||||
{ packetLossTableData }
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a table row as a ReactElement for displaying resolution related
|
||||
* statistics.
|
||||
*
|
||||
* @private
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderResolution() {
|
||||
const { resolution, t } = this.props;
|
||||
const resolutionString = Object.keys(resolution || {})
|
||||
.map(ssrc => {
|
||||
const { width, height } = resolution[ssrc];
|
||||
|
||||
return `${width}x${height}`;
|
||||
})
|
||||
.join(', ') || 'N/A';
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<td>
|
||||
<span>{ t('connectionindicator.resolution') }</span>
|
||||
</td>
|
||||
<td>{ resolutionString }</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ReactElement for display a link to toggle showing additional
|
||||
* statistics.
|
||||
*
|
||||
* @private
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderShowMoreLink() {
|
||||
const translationKey
|
||||
= this.props.shouldShowMore
|
||||
? 'connectionindicator.less'
|
||||
: 'connectionindicator.more';
|
||||
|
||||
return (
|
||||
<a
|
||||
className = 'jitsipopover__showmore link'
|
||||
onClick = { this.props.onShowMore } >
|
||||
{ this.props.t(translationKey) }
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a table as a ReactElement for displaying connection statistics.
|
||||
*
|
||||
* @private
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderStatistics() {
|
||||
return (
|
||||
<table className = 'connection-info__container'>
|
||||
<tbody>
|
||||
{ this._renderBitrate() }
|
||||
{ this._renderPacketLoss() }
|
||||
{ this._renderResolution() }
|
||||
{ this._renderFrameRate() }
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates table rows as ReactElements for displaying transport related
|
||||
* statistics.
|
||||
*
|
||||
* @private
|
||||
* @returns {ReactElement[]}
|
||||
*/
|
||||
_renderTransport() {
|
||||
const { t, transport } = this.props;
|
||||
|
||||
if (!transport || transport.length === 0) {
|
||||
// eslint-disable-next-line no-extra-parens
|
||||
const NA = (
|
||||
<tr key = 'address'>
|
||||
<td>
|
||||
<span>{ t('connectionindicator.address') }</span>
|
||||
</td>
|
||||
<td>
|
||||
N/A
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
|
||||
return [ NA ];
|
||||
}
|
||||
|
||||
const data = {
|
||||
localIP: [],
|
||||
localPort: [],
|
||||
remoteIP: [],
|
||||
remotePort: [],
|
||||
transportType: []
|
||||
};
|
||||
|
||||
for (let i = 0; i < transport.length; i++) {
|
||||
const ip = getIP(transport[i].ip);
|
||||
const localIP = getIP(transport[i].localip);
|
||||
const localPort = getPort(transport[i].localip);
|
||||
const port = getPort(transport[i].ip);
|
||||
|
||||
if (!data.remoteIP.includes(ip)) {
|
||||
data.remoteIP.push(ip);
|
||||
}
|
||||
|
||||
if (!data.localIP.includes(localIP)) {
|
||||
data.localIP.push(localIP);
|
||||
}
|
||||
|
||||
if (!data.localPort.includes(localPort)) {
|
||||
data.localPort.push(localPort);
|
||||
}
|
||||
|
||||
if (!data.remotePort.includes(port)) {
|
||||
data.remotePort.push(port);
|
||||
}
|
||||
|
||||
if (!data.transportType.includes(transport[i].type)) {
|
||||
data.transportType.push(transport[i].type);
|
||||
}
|
||||
}
|
||||
|
||||
// All of the transports should be either P2P or JVB
|
||||
const isP2P = transport.length ? transport[0].p2p : false;
|
||||
|
||||
// First show remote statistics, then local, and then transport type.
|
||||
const tableRowConfigurations = [
|
||||
{
|
||||
additionalData: isP2P
|
||||
? <span>{ t('connectionindicator.peer_to_peer') }</span>
|
||||
: null,
|
||||
data: data.remoteIP,
|
||||
key: 'remoteaddress',
|
||||
label: t('connectionindicator.remoteaddress',
|
||||
{ count: data.remoteIP.length })
|
||||
},
|
||||
{
|
||||
data: data.remotePort,
|
||||
key: 'remoteport',
|
||||
label: t('connectionindicator.remoteport',
|
||||
{ count: transport.length })
|
||||
},
|
||||
{
|
||||
data: data.localIP,
|
||||
key: 'localaddress',
|
||||
label: t('connectionindicator.localaddress',
|
||||
{ count: data.localIP.length })
|
||||
},
|
||||
{
|
||||
data: data.localPort,
|
||||
key: 'localport',
|
||||
label: t('connectionindicator.localport',
|
||||
{ count: transport.length })
|
||||
},
|
||||
{
|
||||
data: data.transportType,
|
||||
key: 'transport',
|
||||
label: t('connectionindicator.transport',
|
||||
{ count: data.transportType.length })
|
||||
}
|
||||
];
|
||||
|
||||
return tableRowConfigurations.map(this._renderTransportTableRow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a table row as a ReactElement for displaying a transport related
|
||||
* statistic.
|
||||
*
|
||||
* @param {Object} config - Describes the contents of the row.
|
||||
* @param {ReactElement} config.additionalData - Extra data to display next
|
||||
* to the passed in config.data.
|
||||
* @param {Array} config.data - The transport statistics to display.
|
||||
* @param {string} config.key - The ReactElement's key. Must be unique for
|
||||
* iterating over multiple child rows.
|
||||
* @param {string} config.label - The text to display describing the data.
|
||||
* @private
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderTransportTableRow(config) {
|
||||
const { additionalData, data, key, label } = config;
|
||||
|
||||
return (
|
||||
<tr key = { key }>
|
||||
<td>
|
||||
<span>
|
||||
{ label }
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
{ getStringFromArray(data) }
|
||||
{ additionalData || null }
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for getting the IP from a transport statistics object's
|
||||
* representation of an IP.
|
||||
*
|
||||
* @param {string} value - The transport's IP to parse.
|
||||
* @private
|
||||
* @returns {string}
|
||||
*/
|
||||
function getIP(value) {
|
||||
return value.substring(0, value.lastIndexOf(':'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for getting the port from a transport statistics object's
|
||||
* representation of an IP.
|
||||
*
|
||||
* @param {string} value - The transport's IP to parse.
|
||||
* @private
|
||||
* @returns {string}
|
||||
*/
|
||||
function getPort(value) {
|
||||
return value.substring(value.lastIndexOf(':') + 1, value.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for concatenating values in an array into a comma separated string.
|
||||
*
|
||||
* @param {Array} array - Transport statistics to concatenate.
|
||||
* @private
|
||||
* @returns {string}
|
||||
*/
|
||||
function getStringFromArray(array) {
|
||||
let res = '';
|
||||
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
res += (i === 0 ? '' : ', ') + array[i];
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
export default translate(ConnectionStatsTable);
|
|
@ -0,0 +1 @@
|
|||
export { default as ConnectionStatsTable } from './ConnectionStatsTable';
|
|
@ -0,0 +1 @@
|
|||
export * from './components';
|
Loading…
Reference in New Issue