diff --git a/web/app/assets/javascripts/backend_alerts.js b/web/app/assets/javascripts/backend_alerts.js
new file mode 100644
index 000000000..c00693ff3
--- /dev/null
+++ b/web/app/assets/javascripts/backend_alerts.js
@@ -0,0 +1,100 @@
+(function(context,$) {
+
+ "use strict";
+
+ context.JK = context.JK || {};
+
+ // Class to intercept and delegate out all backend alerts as necessary
+ // better if modules that needed certain events would just register for them.
+ context.JK.BackendAlerts = function(app) {
+
+ var ALERT_TYPE = context.JK.ALERT_TYPE;
+
+ function onNoValidAudioConfig(type, text) {
+ app.notify({
+ "title": ALERT_TYPE[type].title,
+ "text": text,
+ "icon_url": "/assets/content/icon_alert_big.png"
+ });
+ context.location = "/client#"; // leaveSession will be called in beforeHide below
+ }
+
+ function onStunEvent() {
+ var testResults = context.jamClient.NetworkTestResult();
+
+ $.each(testResults, function (index, val) {
+ if (val.bStunFailed) {
+ // if true we could not reach a stun server
+ }
+ else if (val.bRemoteUdpBocked) {
+ // if true the user cannot communicate with peer via UDP, although they could do LAN based session
+ }
+ });
+ }
+
+ function onGenericEvent(type, text) {
+ context.setTimeout(function() {
+ var alert = ALERT_TYPE[type];
+
+ if(alert && alert.title) {
+ app.notify({
+ "title": ALERT_TYPE[type].title,
+ "text": text,
+ "icon_url": "/assets/content/icon_alert_big.png"
+ });
+ }
+ else {
+ logger.debug("Unknown Backend Event type %o, data %o", type, text)
+ }
+ }, 1);
+ }
+
+ function alertCallback(type, text) {
+
+ function timeCallback() {
+ var start = new Date();
+ setTimeout(function() {
+ var timed = new Date().getTime() - start.getTime();
+ if(timed > 250) {
+ logger.warn("SLOW AlERT_CALLBACK. type: %o text: %o time: %o", type, text, timed);
+ }
+ }, 1);
+ }
+
+ timeCallback();
+
+ logger.debug("alert callback", type, text);
+
+ if (type === 2) { // BACKEND_MIXER_CHANGE
+ context.JK.CurrentSessionModel.onBackendMixerChanged(type, text)
+ }
+ else if (type === 19) { // NO_VALID_AUDIO_CONFIG
+ onNoValidAudioConfig(type, text);
+ }
+ else if (type === 24) {
+ onStunEvent();
+ }
+ else if (type === 26) { // DEAD_USER_REMOVE_EVENT
+ context.JK.CurrentSessionModel.onDeadUserRemove(type, text);
+ }
+ else if (type === 27) { // WINDOW_CLOSE_BACKGROUND_MODE
+ context.JK.CurrentSessionModel.onWindowBackgrounded(type, text);
+ }
+ else if(type != 30 && type != 31 && type != 21){ // these are handled elsewhere
+ onGenericEvent(type, text);
+ }
+ }
+
+ function initialize() {
+ context.jamClient.SessionSetAlertCallback("JK.AlertCallback");
+ }
+
+ this.initialize = initialize;
+
+
+ context.JK.AlertCallback = alertCallback;
+
+ return this;
+ }
+
+})(window, jQuery);
\ No newline at end of file
diff --git a/web/app/assets/javascripts/chatPanel.js b/web/app/assets/javascripts/chatPanel.js
index bf5b05eca..45a13014b 100644
--- a/web/app/assets/javascripts/chatPanel.js
+++ b/web/app/assets/javascripts/chatPanel.js
@@ -274,7 +274,6 @@
if(response.next == null) {
// if we less results than asked for, end searching
$chatMessagesScroller.infinitescroll('pause');
- logger.debug("end of chatss");
if(currentPage > 0) {
// there are bugs with infinitescroll not removing the 'loading'.
diff --git a/web/app/assets/javascripts/globals.js b/web/app/assets/javascripts/globals.js
index 623670af6..f0c81c1d7 100644
--- a/web/app/assets/javascripts/globals.js
+++ b/web/app/assets/javascripts/globals.js
@@ -31,6 +31,58 @@
DIALOG_CLOSED : 'dialog_closed'
}
+ // recreate eThresholdType enum from MixerDialog.h
+ context.JK.ALERT_TYPE = {
+ 0: {"title": "", "message": ""}, // NO_EVENT,
+ 1: {"title": "", "message": ""}, // BACKEND_ERROR: generic error - eg P2P message error
+ 2: {"title": "", "message": ""}, // BACKEND_MIXER_CHANGE, - event that controls have been regenerated
+ 3: {"title": "High Packet Jitter", "message": "Your network connection is currently experiencing packet jitter at a level that is too high to deliver good audio quality. For troubleshooting tips, click here."}, // PACKET_JTR,
+ 4: {"title": "High Packet Loss", "message": "Your network connection is currently experiencing packet loss at a rate that is too high to deliver good audio quality. For troubleshooting tips, click here." }, // PACKET_LOSS
+ 5: {"title": "High Packet Late", "message": "Your network connection is currently experiencing packet loss at a rate that is too high to deliver good audio quality. For troubleshooting tips, click here."}, // PACKET_LATE,
+ 6: {"title": "Large Jitter Queue", "message": "Your network connection is currently experiencing packet jitter at a level that is too high to deliver good audio quality. For troubleshooting tips, click here."}, // JTR_QUEUE_DEPTH,
+ 7: {"title": "High Network Jitter", "message": "Your network connection is currently experiencing network jitter at a level that is too high to deliver good audio quality. For troubleshooting tips, click here."}, // NETWORK_JTR,
+ 8: {"title": "High Session Latency", "message": "The latency of your audio device combined with your Internet connection has become high enough to impact your session quality. For troubleshooting tips, click here." }, // NETWORK_PING,
+ 9: {"title": "Bandwidth Throttled", "message": "The available bandwidth on your network has diminished, and this may impact your audio quality. For troubleshooting tips, click here."}, // BITRATE_THROTTLE_WARN,
+ 10:{"title": "Low Bandwidth", "message": "The available bandwidth on your network has become too low, and this may impact your audio quality. For troubleshooting tips, click here." }, // BANDWIDTH_LOW
+
+ // IO related events
+ 11:{"title": "Variable Input Rate", "message": "The input rate of your audio device is varying too much to deliver good audio quality. For troubleshooting tips, click here." }, // INPUT_IO_RATE
+ 12:{"title": "High Input Jitter", "message": "The input rate of your audio device is varying too much to deliver good audio quality. For troubleshooting tips, click here."}, // INPUT_IO_JTR,
+ 13:{"title": "Variable Output Rate", "message": "The output rate of your audio device is varying too much to deliver good audio quality. For troubleshooting tips, click here." }, // OUTPUT_IO_RATE
+ 14:{"title": "High Output Jitter", "message": "The output rate of your audio device is varying too much to deliver good audio quality. For troubleshooting tips, click here."}, // OUTPUT_IO_JTR,
+
+ // CPU load related
+ 15: { "title": "CPU Utilization High", "message": "The CPU of your computer is unable to keep up with the current processing load, and this may impact your audio quality. For troubleshooting tips, click here." }, // CPU_LOAD
+ 16: {"title": "Decode Violations", "message": ""}, // DECODE_VIOLATIONS,
+ 17: {"title": "", "message": ""}, // LAST_THRESHOLD
+ 18: {"title": "Wifi Alert", "message": ""}, // WIFI_NETWORK_ALERT, //user or peer is using wifi
+ 19: {"title": "No Audio Configuration", "message": "You cannot join the session because you do not have a valid audio configuration."}, // NO_VALID_AUDIO_CONFIG,
+ 20: {"title": "Audio Device Not Present", "message": ""}, // AUDIO_DEVICE_NOT_PRESENT, // the audio device is not connected
+ 21: {"title": "", "message": ""}, // RECORD_PLAYBACK_STATE, // record/playback events have occurred
+ 22: {"title": "", "message": ""}, // RUN_UPDATE_CHECK_BACKGROUND, //this is auto check - do
+ 23: {"title": "", "message": ""}, // RUN_UPDATE_CHECK_INTERACTIVE, //this is initiated by user
+ 24: {"title": "", "message": ""}, // STUN_EVENT, // system completed stun test... come get the result
+ 25: {"title": "No Audio", "message": "Your system is no longer transmitting audio. Other session members are unable to hear you."}, // DEAD_USER_WARN_EVENT, //the backend is not receiving audio from this peer
+ 26: {"title": "No Audio", "message": "Your system is no longer transmitting audio. Other session members are unable to hear you."}, // DEAD_USER_REMOVE_EVENT, //the backend is removing the user from session as no audio is coming from this peer
+ 27: {"title": "", "message": ""}, // WINDOW_CLOSE_BACKGROUND_MODE, //the user has closed the window and the client is now in background mode
+ 28: {"title": "", "message": ""}, // WINDOW_OPEN_FOREGROUND_MODE, //the user has opened the window and the client is now in forground mode/
+
+ 29: {"title": "Failed to Broadcast", "message": ""}, // SESSION_LIVEBROADCAST_FAIL, //error of some sort - so can't broadcast
+ 30: {"title": "", "message": ""}, // SESSION_LIVEBROADCAST_ACTIVE, //active
+ 31: {"title": "", "message": ""}, // SESSION_LIVEBROADCAST_STOPPED, //stopped by server/user
+ 32: {"title": "Client Pinned", "message": "This client will be the source of a broadcast."}, // SESSION_LIVEBROADCAST_PINNED, //node pinned by user
+ 33: {"title": "Client No Longer Pinned", "message": "This client is no longer designated as the source of the broadcast."}, // SESSION_LIVEBROADCAST_UNPINNED, //node unpinned by user
+
+ 34: {"title": "", "message": ""}, // BACKEND_STATUS_MSG, //status/informational message
+ 35: {"title": "LAN Unpredictable", "message": "Your local network is adding considerable variance to transmit times. For troubleshooting tips, click here."}, // LOCAL_NETWORK_VARIANCE_HIGH,//the ping time via a hairpin for the user network is unnaturally high or variable.
+
+ //indicates problem with user computer stack or network itself (wifi, antivirus etc)
+ 36: {"title": "LAN High Latency", "message": "Your local network is adding considerable latency. For troubleshooting tips, click here."}, // LOCAL_NETWORK_LATENCY_HIGH,
+ 37: {"title": "", "message": ""}, // RECORDING_CLOSE, //update and remove tracks from front-end
+ 38: {"title": "No Audio Sent", "message": ""}, // PEER_REPORTS_NO_AUDIO_RECV, //update and remove tracks from front-end
+ 39: {"title": "", "message": ""} // LAST_ALERT
+ };
+
context.JK.MAX_TRACKS = 6;
context.JK.MAX_OUTPUTS = 2;
diff --git a/web/app/assets/javascripts/session.js b/web/app/assets/javascripts/session.js
index 20fae6390..dd6cdf78d 100644
--- a/web/app/assets/javascripts/session.js
+++ b/web/app/assets/javascripts/session.js
@@ -30,7 +30,6 @@
var claimedRecording = null;
var playbackControls = null;
var promptLeave = false;
- var backendMixerAlertThrottleTimer = null;
var rateSessionDialog = null;
var rest = context.JK.Rest();
@@ -77,59 +76,6 @@
};
- // recreate eThresholdType enum from MixerDialog.h
- var alert_type = {
- 0: {"title": "", "message": ""}, // NO_EVENT,
- 1: {"title": "", "message": ""}, // BACKEND_ERROR: generic error - eg P2P message error
- 2: {"title": "", "message": ""}, // BACKEND_MIXER_CHANGE, - event that controls have been regenerated
- 3: {"title": "High Packet Jitter", "message": "Your network connection is currently experiencing packet jitter at a level that is too high to deliver good audio quality. For troubleshooting tips, click here."}, // PACKET_JTR,
- 4: {"title": "High Packet Loss", "message": "Your network connection is currently experiencing packet loss at a rate that is too high to deliver good audio quality. For troubleshooting tips, click here." }, // PACKET_LOSS
- 5: {"title": "High Packet Late", "message": "Your network connection is currently experiencing packet loss at a rate that is too high to deliver good audio quality. For troubleshooting tips, click here."}, // PACKET_LATE,
- 6: {"title": "Large Jitter Queue", "message": "Your network connection is currently experiencing packet jitter at a level that is too high to deliver good audio quality. For troubleshooting tips, click here."}, // JTR_QUEUE_DEPTH,
- 7: {"title": "High Network Jitter", "message": "Your network connection is currently experiencing network jitter at a level that is too high to deliver good audio quality. For troubleshooting tips, click here."}, // NETWORK_JTR,
- 8: {"title": "High Session Latency", "message": "The latency of your audio device combined with your Internet connection has become high enough to impact your session quality. For troubleshooting tips, click here." }, // NETWORK_PING,
- 9: {"title": "Bandwidth Throttled", "message": "The available bandwidth on your network has diminished, and this may impact your audio quality. For troubleshooting tips, click here."}, // BITRATE_THROTTLE_WARN,
- 10:{"title": "Low Bandwidth", "message": "The available bandwidth on your network has become too low, and this may impact your audio quality. For troubleshooting tips, click here." }, // BANDWIDTH_LOW
-
- // IO related events
- 11:{"title": "Variable Input Rate", "message": "The input rate of your audio device is varying too much to deliver good audio quality. For troubleshooting tips, click here." }, // INPUT_IO_RATE
- 12:{"title": "High Input Jitter", "message": "The input rate of your audio device is varying too much to deliver good audio quality. For troubleshooting tips, click here."}, // INPUT_IO_JTR,
- 13:{"title": "Variable Output Rate", "message": "The output rate of your audio device is varying too much to deliver good audio quality. For troubleshooting tips, click here." }, // OUTPUT_IO_RATE
- 14:{"title": "High Output Jitter", "message": "The output rate of your audio device is varying too much to deliver good audio quality. For troubleshooting tips, click here."}, // OUTPUT_IO_JTR,
-
- // CPU load related
- 15: { "title": "CPU Utilization High", "message": "The CPU of your computer is unable to keep up with the current processing load, and this may impact your audio quality. For troubleshooting tips, click here." }, // CPU_LOAD
- 16: {"title": "Decode Violations", "message": ""}, // DECODE_VIOLATIONS,
- 17: {"title": "", "message": ""}, // LAST_THRESHOLD
- 18: {"title": "Wifi Alert", "message": ""}, // WIFI_NETWORK_ALERT, //user or peer is using wifi
- 19: {"title": "No Audio Configuration", "message": "You cannot join the session because you do not have a valid audio configuration."}, // NO_VALID_AUDIO_CONFIG,
- 20: {"title": "Audio Device Not Present", "message": ""}, // AUDIO_DEVICE_NOT_PRESENT, // the audio device is not connected
- 21: {"title": "", "message": ""}, // RECORD_PLAYBACK_STATE, // record/playback events have occurred
- 22: {"title": "", "message": ""}, // RUN_UPDATE_CHECK_BACKGROUND, //this is auto check - do
- 23: {"title": "", "message": ""}, // RUN_UPDATE_CHECK_INTERACTIVE, //this is initiated by user
- 24: {"title": "", "message": ""}, // STUN_EVENT, // system completed stun test... come get the result
- 25: {"title": "No Audio", "message": "Your system is no longer transmitting audio. Other session members are unable to hear you."}, // DEAD_USER_WARN_EVENT, //the backend is not receiving audio from this peer
- 26: {"title": "No Audio", "message": "Your system is no longer transmitting audio. Other session members are unable to hear you."}, // DEAD_USER_REMOVE_EVENT, //the backend is removing the user from session as no audio is coming from this peer
- 27: {"title": "", "message": ""}, // WINDOW_CLOSE_BACKGROUND_MODE, //the user has closed the window and the client is now in background mode
- 28: {"title": "", "message": ""}, // WINDOW_OPEN_FOREGROUND_MODE, //the user has opened the window and the client is now in forground mode/
-
- 29: {"title": "Failed to Broadcast", "message": ""}, // SESSION_LIVEBROADCAST_FAIL, //error of some sort - so can't broadcast
- 30: {"title": "", "message": ""}, // SESSION_LIVEBROADCAST_ACTIVE, //active
- 31: {"title": "", "message": ""}, // SESSION_LIVEBROADCAST_STOPPED, //stopped by server/user
- 32: {"title": "Client Pinned", "message": "This client will be the source of a broadcast."}, // SESSION_LIVEBROADCAST_PINNED, //node pinned by user
- 33: {"title": "Client No Longer Pinned", "message": "This client is no longer designated as the source of the broadcast."}, // SESSION_LIVEBROADCAST_UNPINNED, //node unpinned by user
-
- 34: {"title": "", "message": ""}, // BACKEND_STATUS_MSG, //status/informational message
- 35: {"title": "LAN Unpredictable", "message": "Your local network is adding considerable variance to transmit times. For troubleshooting tips, click here."}, // LOCAL_NETWORK_VARIANCE_HIGH,//the ping time via a hairpin for the user network is unnaturally high or variable.
-
- //indicates problem with user computer stack or network itself (wifi, antivirus etc)
- 36: {"title": "LAN High Latency", "message": "Your local network is adding considerable latency. For troubleshooting tips, click here."}, // LOCAL_NETWORK_LATENCY_HIGH,
- 37: {"title": "", "message": ""}, // RECORDING_CLOSE, //update and remove tracks from front-end
- 38: {"title": "No Audio Sent", "message": ""}, // PEER_REPORTS_NO_AUDIO_RECV, //update and remove tracks from front-end
- 39: {"title": "", "message": ""} // LAST_ALERT
- };
-
-
function beforeShow(data) {
sessionId = data.id;
promptLeave = true;
@@ -144,114 +90,6 @@
return { freezeInteraction: true };
}
- function alertCallback(type, text) {
-
- function timeCallback() {
- var start = new Date();
- setTimeout(function() {
- var timed = new Date().getTime() - start.getTime();
- if(timed > 250) {
- logger.warn("SLOW AlERT_CALLBACK. type: %o text: %o time: %o", type, text, timed);
- }
- }, 1);
- }
-
- timeCallback();
-
- logger.debug("alert callback", type, text);
-
- if (type === 2) { // BACKEND_MIXER_CHANGE
- logger.debug("BACKEND_MIXER_CHANGE alert. reason:" + text);
-
- if(sessionModel.id() && text == "RebuildAudioIoControl") {
-
- // the backend will send these events rapid-fire back to back.
- // the server can still perform correctly, but it is nicer to wait 100 ms to let them all fall through
- if(backendMixerAlertThrottleTimer) {clearTimeout(backendMixerAlertThrottleTimer);}
-
- backendMixerAlertThrottleTimer = setTimeout(function() {
- // this is a local change to our tracks. we need to tell the server about our updated track information
- var inputTracks = context.JK.TrackHelpers.getUserTracks(context.jamClient);
-
- // create a trackSync request based on backend data
- var syncTrackRequest = {};
- syncTrackRequest.client_id = app.clientId;
- syncTrackRequest.tracks = inputTracks;
- syncTrackRequest.id = sessionModel.id();
-
- rest.putTrackSyncChange(syncTrackRequest)
- .done(function() {
- })
- .fail(function() {
- app.notify({
- "title": "Can't Sync Local Tracks",
- "text": "The client is unable to sync local track information with the server. You should rejoin the session to ensure a good experience.",
- "icon_url": "/assets/content/icon_alert_big.png"
- });
- })
- }, 100);
- }
- else if(sessionModel.id() && (text == 'RebuildMediaControl' || text == 'RebuildRemoteUserControl')) {
- sessionModel.refreshCurrentSession(true);
- }
- }
- else if (type === 19) { // NO_VALID_AUDIO_CONFIG
- app.notify({
- "title": alert_type[type].title,
- "text": text,
- "icon_url": "/assets/content/icon_alert_big.png"
- });
- context.location = "/client#"; // leaveSession will be called in beforeHide below
- }
- else if (type === 24) { // STUN_EVENT
- var testResults = context.jamClient.NetworkTestResult();
-
- $.each(testResults, function(index, val) {
- if (val.bStunFailed) {
- // if true we could not reach a stun server
- }
- else if (val.bRemoteUdpBocked) {
- // if true the user cannot communicate with peer via UDP, although they could do LAN based session
- }
- });
- }
- else if (type === 26) {
- var clientId = text;
- var participant = sessionModel.getParticipant(clientId);
- if(participant) {
- app.notify({
- "title": alert_type[type].title,
- "text": participant.user.name + " is no longer sending audio.",
- "icon_url": context.JK.resolveAvatarUrl(participant.user.photo_url)
- });
- var $track = $('div.track[client-id="' + clientId + '"]');
- $('.disabled-track-overlay', $track).show();
- }
- }
- else if (type === 27) { // WINDOW_CLOSE_BACKGROUND_MODE
- // the window was closed; just attempt to nav to home, which will cause all the right REST calls to happen
- promptLeave = false;
- context.location = '/client#/home'
- }
- else if(type != 30 && type != 31 && type != 21){ // these are handled elsewhere
- context.setTimeout(function() {
- var alert = alert_type[type];
-
- if(alert && alert.title) {
- app.notify({
- "title": alert_type[type].title,
- "text": text,
- "icon_url": "/assets/content/icon_alert_big.png"
- });
- }
- else {
- logger.debug("Unknown Backend Event type %o, data %o", type, text)
- }
- }, 1);
-
- }
- }
-
function initializeSession() {
// indicate that the screen is active, so that
// body-scoped drag handlers can go active
@@ -327,7 +165,8 @@
context.JK.CurrentSessionModel = sessionModel = new context.JK.SessionModel(
context.JK.app,
context.JK.JamServer,
- context.jamClient
+ context.jamClient,
+ self
);
$(sessionModel.recordingModel)
@@ -1567,7 +1406,6 @@
context.JK.HandleVolumeChangeCallback = handleVolumeChangeCallback;
context.JK.HandleBridgeCallback = handleBridgeCallback;
- context.JK.AlertCallback = alertCallback;
};
})(window,jQuery);
\ No newline at end of file
diff --git a/web/app/assets/javascripts/sessionModel.js b/web/app/assets/javascripts/sessionModel.js
index e5b33c2f3..7f359d274 100644
--- a/web/app/assets/javascripts/sessionModel.js
+++ b/web/app/assets/javascripts/sessionModel.js
@@ -7,7 +7,10 @@
context.JK = context.JK || {};
var logger = context.JK.logger;
- context.JK.SessionModel = function(app, server, client) {
+ // screen can be null
+ context.JK.SessionModel = function(app, server, client, sessionScreen) {
+ var ALERT_TYPE = context.JK.ALERT_TYPE;
+
var clientId = client.clientID;
var currentSessionId = null; // Set on join, prior to setting currentSession.
var currentSession = null;
@@ -19,6 +22,7 @@
var pendingSessionRefresh = false;
var recordingModel = new context.JK.RecordingModel(app, this, rest, context.jamClient);
var currentTrackChanges = 0;
+ var backendMixerAlertThrottleTimer = null;
// we track all the clientIDs of all the participants ever seen by this session, so that we can reliably convert a clientId from the backend into a username/avatar
var participantsEverSeen = {};
var $self = $(this);
@@ -29,6 +33,10 @@
return currentSession ? currentSession.id : null;
}
+ function inSession() {
+ return !!currentSessionId;
+ }
+
function participants() {
if (currentSession) {
return currentSession.participants;
@@ -214,6 +222,12 @@
* the provided callback when complete.
*/
function refreshCurrentSessionRest(callback, force) {
+
+ if(!inSession()) {
+ logger.debug("refreshCurrentSession skipped: ")
+ return;
+ }
+
var url = "/api/sessions/" + currentSessionId;
if(requestingSessionRefresh) {
// if someone asks for a refresh while one is going on, we ask for another to queue up
@@ -239,7 +253,14 @@
logger.info("ignoring refresh because we already have current: " + currentTrackChanges + ", seen: " + response.track_changes_counter);
}
},
- error: function(jqXHR) { app.notifyServerError(jqXHR, "Unable to refresh session data") },
+ error: function(jqXHR) {
+ if(jqXHR.status != 404) {
+ app.notifyServerError(jqXHR, "Unable to refresh session data")
+ }
+ else {
+ logger.debug("refreshCurrentSessionRest: could not refresh data for session because it's gone")
+ }
+ },
complete: function() {
requestingSessionRefresh = false;
if(pendingSessionRefresh) {
@@ -411,6 +432,70 @@
return $.Deferred().reject().promise();
}
+ function onDeadUserRemove(type, text) {
+ var clientId = text;
+ var participant = participantsEverSeen[clientId];
+ if(participant) {
+ app.notify({
+ "title": ALERT_TYPE[type].title,
+ "text": participant.user.name + " is no longer sending audio.",
+ "icon_url": context.JK.resolveAvatarUrl(participant.user.photo_url)
+ });
+ var $track = $('div.track[client-id="' + clientId + '"]');
+ $('.disabled-track-overlay', $track).show();
+ }
+ }
+
+ function onWindowBackgrounded(type, text) {
+ // the window was closed; just attempt to nav to home, which will cause all the right REST calls to happen
+ if(sessionScreen) {
+ sessionScreen.setPromptLeave(false);
+ context.location = '/client#/home'
+ }
+ }
+
+ function onBackendMixerChanged(type, text) {
+ logger.debug("BACKEND_MIXER_CHANGE alert. reason:" + text);
+
+ if(inSession() && text == "RebuildAudioIoControl") {
+
+ // the backend will send these events rapid-fire back to back.
+ // the server can still perform correctly, but it is nicer to wait 100 ms to let them all fall through
+ if(backendMixerAlertThrottleTimer) {clearTimeout(backendMixerAlertThrottleTimer);}
+
+ backendMixerAlertThrottleTimer = setTimeout(function() {
+ // this is a local change to our tracks. we need to tell the server about our updated track information
+ var inputTracks = context.JK.TrackHelpers.getUserTracks(context.jamClient);
+
+ // create a trackSync request based on backend data
+ var syncTrackRequest = {};
+ syncTrackRequest.client_id = app.clientId;
+ syncTrackRequest.tracks = inputTracks;
+ syncTrackRequest.id = id();
+
+ rest.putTrackSyncChange(syncTrackRequest)
+ .done(function() {
+ })
+ .fail(function() {
+ if(jqXHR.status != 404) {
+ app.notify({
+ "title": "Can't Sync Local Tracks",
+ "text": "The client is unable to sync local track information with the server. You should rejoin the session to ensure a good experience.",
+ "icon_url": "/assets/content/icon_alert_big.png"
+ });
+ }
+ else {
+ logger.debug("Unable to sync local tracks because session is gone.")
+ }
+
+ })
+ }, 100);
+ }
+ else if(inSession() && (text == 'RebuildMediaControl' || text == 'RebuildRemoteUserControl')) {
+ refreshCurrentSession(true);
+ }
+ }
+
// Public interface
this.id = id;
this.recordedTracks = recordedTracks;
@@ -425,6 +510,12 @@
this.onWebsocketDisconnected = onWebsocketDisconnected;
this.recordingModel = recordingModel;
this.findUserBy = findUserBy;
+
+ // ALERT HANDLERS
+ this.onBackendMixerChanged = onBackendMixerChanged;
+ this.onDeadUserRemove = onDeadUserRemove;
+ this.onWindowBackgrounded = onWindowBackgrounded;
+
this.getCurrentSession = function() {
return currentSession;
};
diff --git a/web/app/views/clients/index.html.erb b/web/app/views/clients/index.html.erb
index 3c946bcb3..6b4169cbf 100644
--- a/web/app/views/clients/index.html.erb
+++ b/web/app/views/clients/index.html.erb
@@ -298,8 +298,12 @@
});
// this ensures that there is always a CurrentSessionModel, even if it's for a non-active session
- JK.CurrentSessionModel = new JK.SessionModel(JK.app, JK.JamServer, window.jamClient);
+ JK.CurrentSessionModel = new JK.SessionModel(JK.app, JK.JamServer, window.jamClient, null);
}
+
+ // make surethe CurrentSessionModel exists before initializing backend alerts
+ var backendAlerts = new JK.BackendAlerts(JK.app);
+ backendAlerts.initialize();
JK.bindHoverEvents();
})