diff --git a/conference.js b/conference.js
index 9c18b06fc..d12ff9c8d 100644
--- a/conference.js
+++ b/conference.js
@@ -1197,6 +1197,10 @@ export default {
ConferenceEvents.LAST_N_ENDPOINTS_CHANGED, (ids, enteringIds) => {
APP.UI.handleLastNEndpoints(ids, enteringIds);
});
+ room.on(
+ ConferenceEvents.PARTICIPANT_CONN_STATUS_CHANGED, (id, isActive) => {
+ APP.UI.participantConnectionStatusChanged(id, isActive);
+ });
room.on(ConferenceEvents.DOMINANT_SPEAKER_CHANGED, (id) => {
if (this.isLocalId(id)) {
this.isDominantSpeaker = true;
diff --git a/modules/UI/UI.js b/modules/UI/UI.js
index 9b0e24da3..ff0ea0fd6 100644
--- a/modules/UI/UI.js
+++ b/modules/UI/UI.js
@@ -995,6 +995,17 @@ UI.handleLastNEndpoints = function (ids, enteringIds) {
VideoLayout.onLastNEndpointsChanged(ids, enteringIds);
};
+/**
+ * Will handle notification about participant's connectivity status change.
+ *
+ * @param {string} id the id of remote participant(MUC jid)
+ * @param {boolean} isActive true if the connection is ok or false if the user
+ * is having connectivity issues.
+ */
+UI.participantConnectionStatusChanged = function (id, isActive) {
+ VideoLayout.onParticipantConnectionStatusChanged(id, isActive);
+};
+
/**
* Update audio level visualization for specified user.
* @param {string} id user id
diff --git a/modules/UI/videolayout/RemoteVideo.js b/modules/UI/videolayout/RemoteVideo.js
index 382ed5c6c..52d3d6220 100644
--- a/modules/UI/videolayout/RemoteVideo.js
+++ b/modules/UI/videolayout/RemoteVideo.js
@@ -227,6 +227,49 @@ RemoteVideo.prototype.removeRemoteStreamElement = function (stream) {
this.VideoLayout.updateLargeVideo(this.id);
};
+/**
+ * Checks whether the remote user associated with this RemoteVideo
+ * has connectivity issues.
+ *
+ * @return {boolean} true if the user's connection is fine or
+ * false otherwise.
+ */
+RemoteVideo.prototype.isConnectionActive = function() {
+ return this.user.isConnectionActive();
+};
+
+/**
+ * @inheritDoc
+ */
+RemoteVideo.prototype.updateView = function () {
+ SmallVideo.prototype.updateView.call(this);
+ this.updateConnectionStatusIndicator(
+ null /* will obtain the status from 'conference' */);
+};
+
+/**
+ * Updates the UI to reflect user's connectivity status.
+ * @param isActive {boolean|null} 'true' if user's connection is active or
+ * 'false' when the use is having some connectivity issues and a warning
+ * should be displayed. When 'null' is passed then the current value will be
+ * obtained from the conference instance.
+ */
+RemoteVideo.prototype.updateConnectionStatusIndicator = function (isActive) {
+ // Check for initial value if 'isActive' is not defined
+ if (typeof isActive !== "boolean") {
+ isActive = this.isConnectionActive();
+ if (isActive === null) {
+ // Cancel processing at this point - no update
+ return;
+ }
+ }
+
+ console.debug(this.id + " thumbnail is connection active ? " + isActive);
+
+ if(this.connectionIndicator)
+ this.connectionIndicator.updateConnectionStatusIndicator(isActive);
+};
+
/**
* Removes RemoteVideo from the page.
*/
diff --git a/modules/UI/videolayout/VideoLayout.js b/modules/UI/videolayout/VideoLayout.js
index 582b25372..86aafa775 100644
--- a/modules/UI/videolayout/VideoLayout.js
+++ b/modules/UI/videolayout/VideoLayout.js
@@ -423,6 +423,8 @@ var VideoLayout = {
} else {
VideoLayout.resizeThumbnails(false, true);
}
+ // Initialize the view
+ remoteVideo.updateView();
},
videoactive (videoelem, resourceJid) {
@@ -640,6 +642,21 @@ var VideoLayout = {
}
},
+ /**
+ * Shows/hides warning about remote user's connectivity issues.
+ *
+ * @param {string} id the ID of the remote participant(MUC nickname)
+ * @param {boolean} isActive true if the connection is ok or false when
+ * the user is having connectivity issues.
+ */
+ onParticipantConnectionStatusChanged (id, isActive) {
+ // Show/hide warning on the thumbnail
+ let remoteVideo = remoteVideos[id];
+ if (remoteVideo) {
+ remoteVideo.updateConnectionStatusIndicator(isActive);
+ }
+ },
+
/**
* On last N change event.
*