diff --git a/css/_connection-info.scss b/css/_connection-info.scss
index 6527cba5c2..97d9c1d127 100644
--- a/css/_connection-info.scss
+++ b/css/_connection-info.scss
@@ -37,6 +37,11 @@
color: $downloadConnectionIconColor;
}
+ &__status
+ {
+ font-weight: bold;
+ }
+
&__upload
{
@extend .connection-info__icon;
diff --git a/css/_font.scss b/css/_font.scss
index ea99cc60d1..01f66316bb 100644
--- a/css/_font.scss
+++ b/css/_font.scss
@@ -127,12 +127,6 @@
.icon-volume:before {
content: "\e91a";
}
-.icon-connection-lost:before {
- content: "\e900";
-}
-.icon-connection:before {
- content: "\e61a";
-}
.icon-recDisable:before {
content: "\e613";
}
@@ -160,3 +154,6 @@
.icon-info:before {
content: "\e922";
}
+.icon-gsm-bars:before {
+ content: "\e926";
+}
diff --git a/css/_videolayout_default.scss b/css/_videolayout_default.scss
index 21a1fedbcc..5f903f469f 100644
--- a/css/_videolayout_default.scss
+++ b/css/_videolayout_default.scss
@@ -87,6 +87,7 @@
* positioning depends on the trigger (indicator icon).
*/
.indicator {
+ margin-left: 5px;
margin-top: $toolbarIconMargin;
}
@@ -94,16 +95,6 @@
margin-left: $toolbarIconMargin;
}
- .connection-indicator,
- div.indicator-container,
- {
- margin-right: 4px;
- }
-
- div.indicator:last-child {
- margin-right: 0;
- }
-
.indicator-container {
display: inline-block;
vertical-align: top;
@@ -138,18 +129,13 @@
left: 0;
@include transform(translate(0, -50%));
- &_empty
+ &_empty,
+ &_lost
{
color: #8B8B8B;/*#FFFFFF*/
overflow: hidden;
}
- &_lost
- {
- color: #8B8B8B;
- overflow: visible;
- }
-
&_full
{
@include topLeft();
@@ -163,12 +149,15 @@
}
}
- .icon-connection,
- .icon-connection-lost {
+ .icon-gsm-bars {
cursor: pointer;
font-size: 1em;
}
}
+
+ .hide-connection-indicator {
+ display: none;
+ }
}
&__hoverOverlay {
@@ -355,7 +344,27 @@
}
.connection-indicator {
- background: $connectionIndicatorBg;
+ background: $connectionIndicatorBg;
+
+ &.status-high {
+ background: green;
+ }
+
+ &.status-med {
+ background: #FFD740;
+ }
+
+ &.status-lost {
+ background: gray;
+ }
+
+ &.status-low {
+ background: #BF2117;
+ }
+
+ &.status-other {
+ background: $connectionIndicatorBg;
+ }
}
.remote-video-menu-trigger,
diff --git a/fonts/jitsi.eot b/fonts/jitsi.eot
index c648a0f0f1..30085b44eb 100755
Binary files a/fonts/jitsi.eot and b/fonts/jitsi.eot differ
diff --git a/fonts/jitsi.svg b/fonts/jitsi.svg
index ba69548a23..f06e4c6c24 100755
--- a/fonts/jitsi.svg
+++ b/fonts/jitsi.svg
@@ -13,8 +13,6 @@
-
-
@@ -52,4 +50,5 @@
+
\ No newline at end of file
diff --git a/fonts/jitsi.ttf b/fonts/jitsi.ttf
index 2864950fb4..4f1294da8c 100755
Binary files a/fonts/jitsi.ttf and b/fonts/jitsi.ttf differ
diff --git a/fonts/jitsi.woff b/fonts/jitsi.woff
index 154426cb33..ddca319ddb 100755
Binary files a/fonts/jitsi.woff and b/fonts/jitsi.woff differ
diff --git a/fonts/selection.json b/fonts/selection.json
index 2651753d2a..fbd4e21806 100755
--- a/fonts/selection.json
+++ b/fonts/selection.json
@@ -1,6 +1,35 @@
{
"IcoMoonType": "selection",
"icons": [
+ {
+ "icon": {
+ "paths": [
+ "M896 0c70.692 0 128 57.308 128 128v768c0 70.692-57.308 128-128 128s-128-57.308-128-128v-768c0-70.692 57.308-128 128-128zM512 256c70.692 0 128 57.308 128 128v512c0 70.692-57.308 128-128 128s-128-57.308-128-128v-512c0-70.692 57.308-128 128-128zM128 640v0c70.692 0 128 57.308 128 128v128c0 70.692-57.308 128-128 128s-128-57.308-128-128v-128c0-70.692 57.308-128 128-128v0z"
+ ],
+ "attrs": [
+ {}
+ ],
+ "isMulticolor": false,
+ "isMulticolor2": false,
+ "grid": 0,
+ "tags": [
+ "gsm-bars-black"
+ ]
+ },
+ "attrs": [
+ {}
+ ],
+ "properties": {
+ "order": 901,
+ "id": 0,
+ "name": "gsm-bars-black",
+ "prevSize": 32,
+ "code": 59686
+ },
+ "setIdx": 0,
+ "setId": 1,
+ "iconIdx": 0
+ },
{
"icon": {
"paths": [
@@ -28,7 +57,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 0
+ "iconIdx": 1
},
{
"icon": {
@@ -57,7 +86,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 1
+ "iconIdx": 2
},
{
"icon": {
@@ -86,7 +115,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 2
+ "iconIdx": 3
},
{
"icon": {
@@ -115,7 +144,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 3
+ "iconIdx": 4
},
{
"icon": {
@@ -141,7 +170,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 4
+ "iconIdx": 5
},
{
"icon": {
@@ -167,7 +196,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 5
+ "iconIdx": 6
},
{
"icon": {
@@ -193,7 +222,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 6
+ "iconIdx": 7
},
{
"icon": {
@@ -219,7 +248,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 7
+ "iconIdx": 8
},
{
"icon": {
@@ -245,7 +274,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 8
+ "iconIdx": 9
},
{
"icon": {
@@ -271,7 +300,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 9
+ "iconIdx": 10
},
{
"icon": {
@@ -297,7 +326,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 10
+ "iconIdx": 11
},
{
"icon": {
@@ -323,7 +352,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 11
+ "iconIdx": 12
},
{
"icon": {
@@ -349,7 +378,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 12
+ "iconIdx": 13
},
{
"icon": {
@@ -375,7 +404,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 13
+ "iconIdx": 14
},
{
"icon": {
@@ -401,7 +430,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 14
+ "iconIdx": 15
},
{
"icon": {
@@ -427,7 +456,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 15
+ "iconIdx": 16
},
{
"icon": {
@@ -453,7 +482,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 16
+ "iconIdx": 17
},
{
"icon": {
@@ -479,7 +508,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 17
+ "iconIdx": 18
},
{
"icon": {
@@ -505,7 +534,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 18
+ "iconIdx": 19
},
{
"icon": {
@@ -531,7 +560,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 19
+ "iconIdx": 20
},
{
"icon": {
@@ -557,7 +586,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 20
+ "iconIdx": 21
},
{
"icon": {
@@ -583,7 +612,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 21
+ "iconIdx": 22
},
{
"icon": {
@@ -609,7 +638,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 22
+ "iconIdx": 23
},
{
"icon": {
@@ -635,7 +664,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 23
+ "iconIdx": 24
},
{
"icon": {
@@ -661,7 +690,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 24
+ "iconIdx": 25
},
{
"icon": {
@@ -687,7 +716,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 25
+ "iconIdx": 26
},
{
"icon": {
@@ -713,7 +742,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 26
+ "iconIdx": 27
},
{
"icon": {
@@ -739,7 +768,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 27
+ "iconIdx": 28
},
{
"icon": {
@@ -765,7 +794,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 28
+ "iconIdx": 29
},
{
"icon": {
@@ -791,7 +820,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 29
+ "iconIdx": 30
},
{
"icon": {
@@ -817,7 +846,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 30
+ "iconIdx": 31
},
{
"icon": {
@@ -843,7 +872,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 31
+ "iconIdx": 32
},
{
"icon": {
@@ -869,129 +898,8 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 32
- },
- {
- "icon": {
- "paths": [
- "M-0 724.847h196.337v187.951h-196.337v-187.951z",
- "M271.842 543.628h196.337v369.169h-196.337v-369.169z",
- "M543.656 362.438h196.337v550.36h-196.337v-550.36z",
- "M815.47 181.234v731.564h119.56c-14.589-33.025-23.125-71.503-23.232-111.943 0.132-86.42 38.697-163.851 99.656-216.468l0.348-403.153h-196.332z",
- "M1087.292-0v533.672c28.874-10.572 62.222-16.73 97.009-16.825 35.717 0.129 69.823 6.614 101.322 18.371l-1.999-535.218h-196.332z",
- "M1192.868 584.148c-0.009-0-0.020-0-0.031-0-122.247 0-221.351 98.447-221.372 219.896-0 0.007-0 0.014-0 0.021 0 121.467 99.111 219.935 221.372 219.935 0.011 0 0.021-0 0.032-0 122.248-0.014 221.345-98.477 221.345-219.935 0-0.007-0-0.013-0-0.020-0.021-121.441-99.11-219.883-221.345-219.897zM1194.706 651.393c87.601 0.006 158.614 69.787 158.614 155.866 0 0.006-0 0.012-0 0.019-0.022 86.062-71.026 155.822-158.614 155.828-87.588-0.006-158.593-69.766-158.615-155.826-0-0.007-0-0.014-0-0.020 0-86.079 71.013-155.86 158.613-155.866z",
- "M1286.795 668.318l48.348 52.528-236.375 217.567-48.348-52.528 236.375-217.567z"
- ],
- "width": 1414,
- "attrs": [
- {},
- {},
- {},
- {},
- {},
- {},
- {}
- ],
- "isMulticolor": false,
- "isMulticolor2": false,
- "tags": [
- "connection-lost"
- ],
- "grid": 0
- },
- "attrs": [
- {},
- {},
- {},
- {},
- {},
- {},
- {}
- ],
- "properties": {
- "order": 888,
- "id": 32,
- "name": "connection-lost",
- "prevSize": 32,
- "code": 59648
- },
- "setIdx": 0,
- "setId": 1,
"iconIdx": 33
},
- {
- "icon": {
- "paths": [
- "M3.881 813.165h220.26v210.835h-220.26v-210.835z",
- "M308.817 609.857h220.27v414.143h-220.27v-414.143z",
- "M613.764 406.588h220.268v617.412h-220.268v-617.412z",
- "M918.685 203.285h220.265v820.715h-220.265v-820.715z",
- "M1223.629 0h220.263v1024h-220.263v-1024z"
- ],
- "width": 1444,
- "attrs": [
- {
- "opacity": 1,
- "visibility": false
- },
- {
- "opacity": 1,
- "visibility": false
- },
- {
- "opacity": 1,
- "visibility": false
- },
- {
- "opacity": 1,
- "visibility": false
- },
- {
- "opacity": 1,
- "visibility": false
- }
- ],
- "isMulticolor": false,
- "isMulticolor2": false,
- "tags": [
- "connection-2"
- ],
- "grid": 0
- },
- "attrs": [
- {
- "opacity": 1,
- "visibility": false
- },
- {
- "opacity": 1,
- "visibility": false
- },
- {
- "opacity": 1,
- "visibility": false
- },
- {
- "opacity": 1,
- "visibility": false
- },
- {
- "opacity": 1,
- "visibility": false
- }
- ],
- "properties": {
- "order": 889,
- "id": 33,
- "prevSize": 32,
- "code": 58906,
- "name": "connection",
- "ligatures": ""
- },
- "setIdx": 0,
- "setId": 1,
- "iconIdx": 34
- },
{
"icon": {
"paths": [
@@ -1019,7 +927,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 35
+ "iconIdx": 36
},
{
"icon": {
@@ -1049,7 +957,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 36
+ "iconIdx": 37
},
{
"icon": {
@@ -1079,7 +987,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 37
+ "iconIdx": 38
},
{
"icon": {
@@ -1105,7 +1013,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 38
+ "iconIdx": 39
},
{
"icon": {
@@ -1131,7 +1039,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 39
+ "iconIdx": 40
},
{
"icon": {
@@ -1157,7 +1065,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 40
+ "iconIdx": 41
},
{
"icon": {
@@ -1184,7 +1092,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 41
+ "iconIdx": 42
},
{
"icon": {
@@ -1213,7 +1121,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 42
+ "iconIdx": 43
},
{
"icon": {
@@ -1240,7 +1148,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 43
+ "iconIdx": 44
},
{
"icon": {
@@ -1267,7 +1175,7 @@
},
"setIdx": 0,
"setId": 1,
- "iconIdx": 44
+ "iconIdx": 45
}
],
"height": 1024,
diff --git a/interface_config.js b/interface_config.js
index 7e8a882a03..a46247f626 100644
--- a/interface_config.js
+++ b/interface_config.js
@@ -98,11 +98,30 @@ var interfaceConfig = { // eslint-disable-line no-unused-vars
*
* @type {number}
*/
- MAXIMUM_ZOOMING_COEFFICIENT: 1.3
+ MAXIMUM_ZOOMING_COEFFICIENT: 1.3,
/*
* If indicated some of the error dialogs may point to the support URL for
* help.
*/
- // SUPPORT_URL: ""
+ // SUPPORT_URL: "",
+
+ /**
+ * Whether the connection indicator icon should hide itself based on
+ * connection strength. If true, the connection indicator will remain
+ * displayed while the participant has a weak connection and will hide
+ * itself after the CONNECTION_INDICATOR_HIDE_TIMEOUT when the connection is
+ * strong.
+ *
+ * @type {boolean}
+ */
+ CONNECTION_INDICATOR_AUTO_HIDE_ENABLED: false,
+
+ /**
+ * How long the connection indicator should remain displayed before hiding.
+ * Used in conjunction with CONNECTION_INDICATOR_AUTOHIDE_ENABLED.
+ *
+ * @type {number}
+ */
+ CONNECTION_INDICATOR_AUTO_HIDE_TIMEOUT: 5000
};
diff --git a/lang/main.json b/lang/main.json
index 2dc20acaa2..eb4f3962b3 100644
--- a/lang/main.json
+++ b/lang/main.json
@@ -200,7 +200,15 @@
"bandwidth": "Estimated bandwidth:",
"na": "Come back here for connection information once the conference starts",
"peer_to_peer": " (p2p)",
- "turn": " (turn)"
+ "turn": " (turn)",
+ "quality": {
+ "good": "Good",
+ "inactive": "Inactive",
+ "lost": "Lost",
+ "nonoptimal": "Nonoptimal",
+ "poor": "Poor"
+ },
+ "status": "Connection:"
},
"notify": {
"disconnected": "disconnected",
diff --git a/modules/UI/videolayout/SmallVideo.js b/modules/UI/videolayout/SmallVideo.js
index 7a63de369f..aa7e6bc201 100644
--- a/modules/UI/videolayout/SmallVideo.js
+++ b/modules/UI/videolayout/SmallVideo.js
@@ -253,10 +253,12 @@ SmallVideo.prototype.bindHoverHandler = function () {
() => {
this.videoIsHovered = true;
this.updateView();
+ this.updateIndicators();
},
() => {
this.videoIsHovered = false;
this.updateView();
+ this.updateIndicators();
}
);
};
@@ -755,6 +757,8 @@ SmallVideo.prototype.updateIndicators = function () {
= this.container.querySelector('.videocontainer__toptoolbar');
const iconSize = UIUtil.getIndicatorFontSize();
+ const showConnectionIndicator = this.videoIsHovered
+ || !interfaceConfig.CONNECTION_INDICATOR_AUTO_HIDE_ENABLED;
const tooltipPosition = interfaceConfig.VERTICAL_FILMSTRIP ? 'left' : 'top';
/* jshint ignore:start */
@@ -763,7 +767,9 @@ SmallVideo.prototype.updateIndicators = function () {
{ this._showConnectionIndicator
?
-
+
{ this._renderIcon() }
@@ -187,6 +236,83 @@ class ConnectionIndicator extends Component {
);
}
+ /**
+ * Returns a CSS class that interprets the current connection status as a
+ * color.
+ *
+ * @private
+ * @returns {string}
+ */
+ _getConnectionColorClass() {
+ const { connectionStatus } = this.props;
+ const { percent } = this.state.stats;
+ const { INACTIVE, INTERRUPTED } = JitsiParticipantConnectionStatus;
+
+ if (connectionStatus === INACTIVE) {
+ return 'status-other';
+ } else if (connectionStatus === INTERRUPTED) {
+ return 'status-lost';
+ } else if (typeof percent === 'undefined') {
+ return 'status-high';
+ }
+
+ return QUALITY_TO_WIDTH.find(x => percent >= x.percent).colorClass;
+ }
+
+ /**
+ * Returns a string that describes the current connection status.
+ *
+ * @private
+ * @returns {string}
+ */
+ _getConnectionStatusTip() {
+ let tipKey;
+
+ switch (this.props.connectionStatus) {
+ case JitsiParticipantConnectionStatus.INTERRUPTED:
+ tipKey = 'connectionindicator.quality.lost';
+ break;
+
+ case JitsiParticipantConnectionStatus.INACTIVE:
+ tipKey = 'connectionindicator.quality.inactive';
+ break;
+
+ default: {
+ const { percent } = this.state.stats;
+
+ if (typeof percent === 'undefined') {
+ // If percentage is undefined then there are no stats available
+ // yet, likely because only a local connection has been
+ // established so far. Assume a strong connection to start.
+ tipKey = 'connectionindicator.quality.good';
+ } else {
+ const config = QUALITY_TO_WIDTH.find(x => percent >= x.percent);
+
+ tipKey = config.tip;
+ }
+ }
+ }
+
+ return this.props.t(tipKey);
+ }
+
+ /**
+ * Returns additional class names to add to the root of the component. The
+ * class names are intended to be used for hiding or showing the indicator.
+ *
+ * @private
+ * @returns {string}
+ */
+ _getVisibilityClass() {
+ const { connectionStatus } = this.props;
+
+ return this.state.showIndicator
+ || this.props.alwaysVisible
+ || connectionStatus === JitsiParticipantConnectionStatus.INTERRUPTED
+ || connectionStatus === JitsiParticipantConnectionStatus.INACTIVE
+ ? 'show-connection-indicator' : 'hide-connection-indicator';
+ }
+
/**
* Callback invoked when new connection stats associated with the passed in
* user ID are available. Will update the component's display of current
@@ -209,6 +335,9 @@ class ConnectionIndicator extends Component {
this.setState({
stats: newStats
});
+
+ // Rely on React to batch setState actions.
+ this._updateIndicatorAutoHide(newStats.percent);
}
/**
@@ -229,40 +358,46 @@ class ConnectionIndicator extends Component {
* @returns {ReactElement}
*/
_renderIcon() {
- switch (this.props.connectionStatus) {
- case JitsiParticipantConnectionStatus.INTERRUPTED:
- return (
-
-
-
- );
- case JitsiParticipantConnectionStatus.INACTIVE:
+ if (this.props.connectionStatus
+ === JitsiParticipantConnectionStatus.INACTIVE) {
return (
);
- default: {
- const { percent } = this.state.stats;
- const width = QUALITY_TO_WIDTH.find(x => percent >= x.percent);
- const iconWidth = width && width.width
- ? { width: width && width.width } : {};
+ }
- return [
-
-
- ,
-
-
-
- ];
- }
+ let iconWidth;
+ let emptyIconWrapperClassName = 'connection_empty';
+
+ if (this.props.connectionStatus
+ === JitsiParticipantConnectionStatus.INTERRUPTED) {
+
+ // emptyIconWrapperClassName is used by the torture tests to
+ // identify lost connection status handling.
+ emptyIconWrapperClassName = 'connection_lost';
+ iconWidth = '0%';
+ } else if (typeof this.state.stats.percent === 'undefined') {
+ iconWidth = '100%';
+ } else {
+ const { percent } = this.state.stats;
+
+ iconWidth = QUALITY_TO_WIDTH.find(x => percent >= x.percent).width;
}
+
+ return [
+
+
+ ,
+
+
+
+ ];
}
/**
@@ -284,6 +419,7 @@ class ConnectionIndicator extends Component {
);
}
+
+ /**
+ * Updates the internal state for automatically hiding the indicator.
+ *
+ * @param {number} percent - The current connection quality percentage
+ * between the values 0 and 100.
+ * @private
+ * @returns {void}
+ */
+ _updateIndicatorAutoHide(percent) {
+ if (percent < INDICATOR_DISPLAY_THRESHOLD) {
+ clearTimeout(this.state.autoHideTimeout);
+ this.setState({
+ autoHideTimeout: null,
+ showIndicator: true
+ });
+ } else if (this.state.autoHideTimeout) {
+ // This clause is intentionally left blank because no further action
+ // is needed if the percent is below the threshold and there is an
+ // autoHideTimeout set.
+ } else {
+ this.setState({
+ autoHideTimeout: setTimeout(() => {
+ this.setState({
+ showIndicator: false
+ });
+ }, interfaceConfig.CONNECTION_INDICATOR_AUTO_HIDE_TIMEOUT)
+ });
+ }
+ }
}
-export default ConnectionIndicator;
+export default translate(ConnectionIndicator);
diff --git a/react/features/connection-stats/components/ConnectionStatsTable.js b/react/features/connection-stats/components/ConnectionStatsTable.js
index f017f63c6f..28de4ce37d 100644
--- a/react/features/connection-stats/components/ConnectionStatsTable.js
+++ b/react/features/connection-stats/components/ConnectionStatsTable.js
@@ -1,3 +1,4 @@
+import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { translate } from '../../base/i18n';
@@ -21,7 +22,7 @@ class ConnectionStatsTable extends Component {
* upload: Number
* }}
*/
- bandwidth: React.PropTypes.object,
+ bandwidth: PropTypes.object,
/**
* Statistics related to bitrate.
@@ -30,7 +31,12 @@ class ConnectionStatsTable extends Component {
* upload: Number
* }}
*/
- bitrate: React.PropTypes.object,
+ bitrate: PropTypes.object,
+
+ /**
+ * A message describing the connection quality.
+ */
+ connectionSummary: PropTypes.string,
/**
* Statistics related to framerates for each ssrc.
@@ -38,17 +44,17 @@ class ConnectionStatsTable extends Component {
* [ ssrc ]: Number
* }}
*/
- framerate: React.PropTypes.object,
+ framerate: PropTypes.object,
/**
* Whether or not the statitics are for local video.
*/
- isLocalVideo: React.PropTypes.bool,
+ isLocalVideo: PropTypes.bool,
/**
* Callback to invoke when the show additional stats link is clicked.
*/
- onShowMore: React.PropTypes.func,
+ onShowMore: PropTypes.func,
/**
* Statistics related to packet loss.
@@ -57,7 +63,7 @@ class ConnectionStatsTable extends Component {
* upload: Number
* }}
*/
- packetLoss: React.PropTypes.object,
+ packetLoss: PropTypes.object,
/**
* Statistics related to display resolutions for each ssrc.
@@ -68,23 +74,23 @@ class ConnectionStatsTable extends Component {
* }
* }}
*/
- resolution: React.PropTypes.object,
+ resolution: 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,
+ shouldShowMore: PropTypes.bool,
/**
* Invoked to obtain translated strings.
*/
- t: React.PropTypes.func,
+ t: PropTypes.func,
/**
* Statistics related to transports.
*/
- transport: React.PropTypes.array
+ transport: PropTypes.array
};
/**
@@ -184,6 +190,24 @@ class ConnectionStatsTable extends Component {
);
}
+ /**
+ * Creates a table row as a ReactElement for displaying a summary message
+ * about the current connection status.
+ *
+ * @private
+ * @returns {ReactElement}
+ */
+ _renderConnectionSummary() {
+ return (
+
+ |
+ { this.props.t('connectionindicator.status') }
+ |
+ { this.props.connectionSummary } |
+
+ );
+ }
+
/**
* Creates a table row as a ReactElement for displaying frame rate related
* statistics.
@@ -309,6 +333,7 @@ class ConnectionStatsTable extends Component {
return (
+ { this._renderConnectionSummary() }
{ this._renderBitrate() }
{ this._renderPacketLoss() }
{ this._renderResolution() }