* VRFS-594; add dialog to initiate reconnect if you lose webocket connection
This commit is contained in:
parent
742c3276b8
commit
dad7ac6691
|
|
@ -95,7 +95,8 @@
|
|||
context.jamClient.connected = false;
|
||||
}
|
||||
|
||||
// TODO: reconnect
|
||||
context.JK.CurrentSessionModel.onWebsocketDisconnected();
|
||||
|
||||
};
|
||||
|
||||
server.send = function(message) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
(function(context,$) {
|
||||
|
||||
"use strict";
|
||||
|
||||
context.JK = context.JK || {};
|
||||
context.JK.Banner = (function() {
|
||||
var self = this;
|
||||
var logger = context.JK.logger;
|
||||
|
||||
// responsible for updating the contents of the update dialog
|
||||
// as well as registering for any event handlers
|
||||
function show(options) {
|
||||
var text = options.text;
|
||||
var html = options.html;
|
||||
|
||||
var newContent = null;
|
||||
if (html) {
|
||||
newContent = $('#banner .dialog-inner').html(html);
|
||||
}
|
||||
else if(text) {
|
||||
newContent = $('#banner .dialog-inner').html(text);
|
||||
}
|
||||
else {
|
||||
console.error("unable to show banner for empty message")
|
||||
return newContent;
|
||||
}
|
||||
|
||||
$('#banner').show()
|
||||
$('#banner_overlay').show()
|
||||
|
||||
// return the core of the banner so that caller can attach event handlers to newly created HTML
|
||||
return newContent;
|
||||
}
|
||||
|
||||
function hide() {
|
||||
$('#banner').hide();
|
||||
$('#banner_overlay .dialog-inner').html("");
|
||||
$('#banner_overlay').hide();
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
// Expose publics
|
||||
var me = {
|
||||
initialize: initialize,
|
||||
show : show,
|
||||
hide : hide
|
||||
}
|
||||
|
||||
return me;
|
||||
})();
|
||||
|
||||
})(window,jQuery);
|
||||
|
|
@ -270,7 +270,29 @@
|
|||
ftueSave(false);
|
||||
}
|
||||
|
||||
function videoLinkClicked(evt) {
|
||||
var myOS = jamClient.GetOSAsString();
|
||||
var link;
|
||||
if (myOS === 'MacOSX') {
|
||||
link = $(evt.currentTarget).attr('external-link-mac');
|
||||
} else if (myOS === 'Win32') {
|
||||
link = $(evt.currentTarget).attr('external-link-win');
|
||||
}
|
||||
if (link) {
|
||||
context.jamClient.OpenSystemBrowser(link);
|
||||
}
|
||||
}
|
||||
|
||||
function events() {
|
||||
$('.ftue-video-link').hover(
|
||||
function(evt) { // handlerIn
|
||||
$(this).addClass('hover');
|
||||
},
|
||||
function(evt) { // handlerOut
|
||||
$(this).removeClass('hover');
|
||||
}
|
||||
);
|
||||
$('.ftue-video-link').on('click', videoLinkClicked);
|
||||
$('[layout-wizard-step="2"] .settings-driver select').on('change', audioDriverChanged);
|
||||
$('[layout-wizard-step="2"] .settings-controls select').on('change', audioDeviceChanged);
|
||||
$('#btn-asio-control-panel').on('click', openASIOControlPanel);
|
||||
|
|
|
|||
|
|
@ -144,6 +144,15 @@
|
|||
});
|
||||
}
|
||||
|
||||
/** check if the server is alive */
|
||||
function serverHealthCheck(options) {
|
||||
return $.ajax({
|
||||
url: window.host,
|
||||
cache: false,
|
||||
dataType: "html"
|
||||
});
|
||||
}
|
||||
|
||||
function getId(options) {
|
||||
var id = options && options["id"]
|
||||
|
||||
|
|
@ -201,6 +210,7 @@
|
|||
this.getClientDownloads = getClientDownloads
|
||||
this.createInvitation = createInvitation;
|
||||
this.postFeedback = postFeedback;
|
||||
this.serverHealthCheck = serverHealthCheck;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -121,22 +121,37 @@
|
|||
}
|
||||
|
||||
function afterCurrentUserLoaded() {
|
||||
sessionModel = new context.JK.SessionModel(
|
||||
// It seems the SessionModel should be a singleton.
|
||||
// a client can only be in one session at a time,
|
||||
// and other parts of the code want to know at any certain times
|
||||
// about the current session, if any (for example, reconnect logic)
|
||||
context.JK.CurrentSessionModel = sessionModel = new context.JK.SessionModel(
|
||||
context.JK.JamServer,
|
||||
context.jamClient,
|
||||
context.JK.userMe
|
||||
context.jamClient
|
||||
);
|
||||
|
||||
sessionModel.subscribe('sessionScreen', sessionChanged);
|
||||
sessionModel.joinSession(sessionId);
|
||||
sessionModel.joinSession(sessionId)
|
||||
.fail(function(xhr, textStatus, errorMessage) {
|
||||
if(xhr.status == 404) {
|
||||
// we tried to join the session, but it's already gone. kick user back to join session screen
|
||||
window.location = "#/findSession"
|
||||
app.notify(
|
||||
{ title: "Unable to Join Session",
|
||||
text: "The session you attempted to join is over."
|
||||
},
|
||||
{ no_cancel: true });
|
||||
}else {
|
||||
app.ajaxError(xhr, textStatus, errorMessage);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function beforeHide(data) {
|
||||
// track that the screen is inactive, to disable body-level handlers
|
||||
screenActive = false;
|
||||
sessionModel.leaveCurrentSession(sessionId);
|
||||
// 'unregister' for callbacks
|
||||
context.jamClient.SessionRegisterCallback("");
|
||||
context.jamClient.SessionSetAlertCallback("");
|
||||
sessionModel.leaveCurrentSession()
|
||||
.fail(app.ajaxError)
|
||||
}
|
||||
|
||||
function sessionChanged() {
|
||||
|
|
|
|||
|
|
@ -7,12 +7,13 @@
|
|||
context.JK = context.JK || {};
|
||||
var logger = context.JK.logger;
|
||||
|
||||
context.JK.SessionModel = function(server, client, currentUser) {
|
||||
context.JK.SessionModel = function(server, client) {
|
||||
var clientId = client.clientID;
|
||||
var currentSessionId = null; // Set on join, prior to setting currentSession.
|
||||
var currentSession = null;
|
||||
var subscribers = {};
|
||||
var users = {}; // User info for session participants
|
||||
var rest = context.JK.Rest();
|
||||
|
||||
function id() {
|
||||
return currentSession.id;
|
||||
|
|
@ -32,24 +33,54 @@
|
|||
function joinSession(sessionId) {
|
||||
currentSessionId = sessionId;
|
||||
logger.debug("SessionModel.joinSession(" + sessionId + ")");
|
||||
joinSessionRest(sessionId, function() {
|
||||
refreshCurrentSession();
|
||||
});
|
||||
server.registerMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_JOIN, refreshCurrentSession);
|
||||
server.registerMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_DEPART, refreshCurrentSession);
|
||||
var deferred = joinSessionRest(sessionId);
|
||||
|
||||
deferred
|
||||
.done(function(){
|
||||
logger.debug("calling jamClient.JoinSession");
|
||||
client.JoinSession({ sessionID: sessionId });
|
||||
refreshCurrentSession();
|
||||
server.registerMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_JOIN, refreshCurrentSession);
|
||||
server.registerMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_DEPART, refreshCurrentSession);
|
||||
});
|
||||
|
||||
return deferred;
|
||||
}
|
||||
|
||||
/**
|
||||
* Leave the current session
|
||||
* Leave the current session, if there is one.
|
||||
* callback: called in all conditions; either after an attempt is made to tell the server that we are leaving,
|
||||
* or immediately if there is no session
|
||||
*/
|
||||
function leaveCurrentSession() {
|
||||
logger.debug("SessionModel.leaveCurrentSession()");
|
||||
// TODO - sessionChanged will be called with currentSession = null
|
||||
server.unregisterMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_JOIN, refreshCurrentSession);
|
||||
server.unregisterMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_DEPART, refreshCurrentSession);
|
||||
leaveSessionRest(currentSessionId, sessionChanged);
|
||||
currentSession = null;
|
||||
currentSessionId = null;
|
||||
var deferred;
|
||||
|
||||
if(currentSessionId) {
|
||||
logger.debug("SessionModel.leaveCurrentSession()");
|
||||
// TODO - sessionChanged will be called with currentSession = null
|
||||
server.unregisterMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_JOIN, refreshCurrentSession);
|
||||
server.unregisterMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_DEPART, refreshCurrentSession);
|
||||
// leave the session right away without waiting on REST. Why? If you can't contact the server, or if it takes a long
|
||||
// time, for that entire duration you'll still be sending voice data to the other users.
|
||||
// this may be bad if someone decides to badmouth others in the left-session during this time
|
||||
logger.debug("calling jamClient.LeaveSession for clientId=" + clientId);
|
||||
client.LeaveSession({ sessionID: currentSessionId });
|
||||
deferred = leaveSessionRest(currentSessionId);
|
||||
deferred.done(function() {
|
||||
sessionChanged();
|
||||
});
|
||||
|
||||
// 'unregister' for callbacks
|
||||
context.jamClient.SessionRegisterCallback("");
|
||||
context.jamClient.SessionSetAlertCallback("");
|
||||
currentSession = null;
|
||||
currentSessionId = null;
|
||||
}
|
||||
else {
|
||||
deferred = rest.serverHealthCheck();
|
||||
}
|
||||
|
||||
return deferred;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -268,7 +299,7 @@
|
|||
* Make the server calls to join the current user to
|
||||
* the session provided.
|
||||
*/
|
||||
function joinSessionRest(sessionId, callback) {
|
||||
function joinSessionRest(sessionId) {
|
||||
var tracks = context.JK.TrackHelpers.getUserTracks(context.jamClient);
|
||||
var data = {
|
||||
client_id: clientId,
|
||||
|
|
@ -277,38 +308,77 @@
|
|||
tracks: tracks
|
||||
};
|
||||
var url = "/api/sessions/" + sessionId + "/participants";
|
||||
$.ajax({
|
||||
return $.ajax({
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
contentType: 'application/json',
|
||||
url: url,
|
||||
async: false,
|
||||
data: JSON.stringify(data),
|
||||
processData:false,
|
||||
success: function(response) {
|
||||
logger.debug("calling jamClient.JoinSession");
|
||||
client.JoinSession({ sessionID: sessionId });
|
||||
callback();
|
||||
},
|
||||
error: ajaxError
|
||||
processData:false
|
||||
});
|
||||
}
|
||||
|
||||
function leaveSessionRest(sessionId, callback) {
|
||||
function leaveSessionRest(sessionId) {
|
||||
var url = "/api/participants/" + clientId;
|
||||
$.ajax({
|
||||
return $.ajax({
|
||||
type: "DELETE",
|
||||
url: url,
|
||||
async: false,
|
||||
success: function (response) {
|
||||
logger.debug("calling jamClient.LeaveSession for clientId=" + clientId);
|
||||
client.LeaveSession({ sessionID: sessionId });
|
||||
callback();
|
||||
},
|
||||
error: ajaxError
|
||||
async: false
|
||||
});
|
||||
}
|
||||
|
||||
function reconnect() {
|
||||
window.location.reload();
|
||||
}
|
||||
function registerReconnect(content) {
|
||||
$('a.disconnected-reconnect', content).click(function() {
|
||||
|
||||
var template = $('#template-reconnecting').html();
|
||||
var templateHtml = context.JK.fillTemplate(template, null);
|
||||
var content = context.JK.Banner.show({
|
||||
html : template
|
||||
});
|
||||
|
||||
context.JK.CurrentSessionModel.leaveCurrentSession()
|
||||
.done(function() {
|
||||
reconnect();
|
||||
})
|
||||
.fail(function(xhr, textStatus, errorThrown) {
|
||||
console.log("leaveCurrentSession failed: ", arguments);
|
||||
|
||||
if(xhr && xhr.status >= 100) {
|
||||
// we could connect to the server, and it's alive
|
||||
reconnect();
|
||||
}
|
||||
else {
|
||||
var template = $('#template-could-not-reconnect').html();
|
||||
var templateHtml = context.JK.fillTemplate(template, null);
|
||||
var content = context.JK.Banner.show({
|
||||
html : template
|
||||
});
|
||||
|
||||
registerReconnect(content);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function onWebsocketDisconnected() {
|
||||
var template = $('#template-disconnected').html();
|
||||
var templateHtml = context.JK.fillTemplate(template, null);
|
||||
var content = context.JK.Banner.show({
|
||||
html : template
|
||||
}) ;
|
||||
|
||||
// kill the streaming of the session immediately
|
||||
logger.debug("calling jamClient.LeaveSession for clientId=" + clientId);
|
||||
client.LeaveSession({ sessionID: currentSessionId });
|
||||
|
||||
registerReconnect(content);
|
||||
}
|
||||
|
||||
function ajaxError(jqXHR, textStatus, errorMessage) {
|
||||
logger.error("Unexpected ajax error: " + textStatus);
|
||||
}
|
||||
|
|
@ -324,6 +394,7 @@
|
|||
this.addTrack = addTrack;
|
||||
this.updateTrack = updateTrack;
|
||||
this.deleteTrack = deleteTrack;
|
||||
this.onWebsocketDisconnected = onWebsocketDisconnected;
|
||||
this.getCurrentSession = function() {
|
||||
return currentSession;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
#banner {
|
||||
display:none;
|
||||
}
|
||||
|
||||
#banner h2 {
|
||||
font-weight:bold;
|
||||
font-size:x-large;
|
||||
}
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
*= require ./genreSelector
|
||||
*= require ./sessionList
|
||||
*= require ./searchResults
|
||||
*= require ./banner
|
||||
*= require ./clientUpdate
|
||||
*= require jquery.Jcrop
|
||||
*/
|
||||
|
|
@ -18,12 +18,16 @@ div.dialog.ftue .ftue-inner div[layout-wizard-step="1"] {
|
|||
|
||||
li {
|
||||
text-align:center;
|
||||
width: 33%;
|
||||
width: 31%;
|
||||
height: 170px;
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
/*padding:0px;*/
|
||||
list-style: none;
|
||||
float:left;
|
||||
}
|
||||
li.first {
|
||||
width: 34%;
|
||||
}
|
||||
}
|
||||
div.dialog.ftue .ftue-inner div[layout-wizard-step="3"] {
|
||||
h5 {
|
||||
|
|
@ -421,3 +425,14 @@ table.audiogeartable {
|
|||
font-size:15px;
|
||||
color:#aaa;
|
||||
}
|
||||
|
||||
.ftue-video-link {
|
||||
padding:4px;
|
||||
cursor:pointer;
|
||||
background-color:#333;
|
||||
border: 1px solid #333;
|
||||
}
|
||||
.ftue-video-link.hover {
|
||||
background-color:#444;
|
||||
border: 1px solid #555;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
<!-- generic banner for use by an code -->
|
||||
<div class="overlay" id="banner_overlay"></div>
|
||||
<div id="banner" class="dialog-overlay-sm">
|
||||
|
||||
<!-- dialog header -->
|
||||
<div class="content-head">
|
||||
<%= image_tag("content/icon_alert.png", :height => '24', :width => '24', :class => "content-icon") %><h1>alert</h1>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="dialog-inner">
|
||||
<!-- contents are replaced by caller to f-->
|
||||
</div>
|
||||
<!-- end right column -->
|
||||
<br clear="all">
|
||||
|
||||
</div>
|
||||
|
|
@ -10,35 +10,37 @@
|
|||
<!-- First screen of the FTUE wizard -->
|
||||
<div layout-wizard-step="1" dialog-title="welcome!" style="display:block;">
|
||||
<p class="intro">
|
||||
Please identify which of the three types of audio gear below you are going to use with the JamKazam
|
||||
service, and click either the Windows or Mac link under the appropriate gear to watch a video on how
|
||||
to navigate this initial setup and testing process. After watching the video, click the 'NEXT'
|
||||
button to get started.
|
||||
Please identify which of the three types of audio gear below you
|
||||
are going to use with the JamKazam service, and click one to
|
||||
watch a video on how to navigate this initial setup and testing
|
||||
process. After watching the video, click the 'NEXT' button to
|
||||
get started. If you don't have your audio gear handy now, click
|
||||
Cancel.
|
||||
</p>
|
||||
|
||||
<ul class="device_type">
|
||||
<li>
|
||||
<li class="ftue-video-link first"
|
||||
external-link-win="http://www.youtube.com/watch?v=hCoQAoEM5P8"
|
||||
external-link-mac="http://www.youtube.com/watch?v=TRzb7OTlO-Q">
|
||||
AUDIO DEVICE WITH PORTS FOR INSTRUMENT OR MIC INPUT JACKS<br/>
|
||||
<p><%= image_tag "content/audio_capture_ftue.png", {:width => 243, :height => 70} %></p>
|
||||
<p><a href="http://www.youtube.com/watch?v=jM5_MWtlxxE" rel="external">Windows Video</a><br/>
|
||||
<a href="http://www.youtube.com/watch?v=TRzb7OTlO-Q" rel="external">Mac Video</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<li class="ftue-video-link"
|
||||
external-link-win="http://www.youtube.com/watch?v=IDrLa8TOXwQ"
|
||||
external-link-mac="http://www.youtube.com/watch?v=vIs7ArrjMpE">
|
||||
USB MICROPHONE<br/>
|
||||
<p><%= image_tag "content/microphone_ftue.png", {:width => 70, :height => 113} %></p>
|
||||
<p><a href="http://www.youtube.com/watch?v=IDrLa8TOXwQ" rel="external">Windows Video</a><br/>
|
||||
<a href="http://www.youtube.com/watch?v=vIs7ArrjMpE" rel="external">Mac Video</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<li class="ftue-video-link"
|
||||
external-link-win="http://www.youtube.com/watch?v=PCri4Xed4CA"
|
||||
external-link-mac="http://www.youtube.com/watch?v=Gatmd_ja47U">
|
||||
COMPUTER'S BUILT-IN MIC & SPEAKERS/HEADPHONES<br/>
|
||||
<p><%= image_tag "content/computer_ftue.png", {:width => 118, :height => 105} %></p>
|
||||
<p><a href="http://www.youtube.com/watch?v=PCri4Xed4CA" rel="external">Windows Video</a><br/>
|
||||
<a href="http://www.youtube.com/watch?v=Gatmd_ja47U" rel="external">Mac Video</a></p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="right mr30 buttonbar">
|
||||
<!-- <a class="button-grey" layout-action="close">REGISTER AS A FAN</a> -->
|
||||
<a class="button-grey" layout-action="close">CANCEL</a>
|
||||
<a class="button-orange" layout-wizard-link="2">NEXT</a>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
<script type="text/template" id="template-disconnected">
|
||||
<h2 align="center">Disconnected from Server</h2>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<div align="center">
|
||||
You have been disconnected from JamKazam.
|
||||
</div>
|
||||
<br clear="all" /><br />
|
||||
|
||||
<div class="right">
|
||||
<a href="#" class="button-orange disconnected-reconnect">RECONNECT</a>
|
||||
</div>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-reconnecting">
|
||||
<h2 align="center">Reconnecting to Server</h2>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<div align="center">
|
||||
Attempting to reestablish connection to the server...
|
||||
</div>
|
||||
<br clear="all" /><br />
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-could-not-reconnect">
|
||||
<h2 align="center">Unable to Reconnect</h2>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<div align="center">
|
||||
We were not able to reconnect to JamKazam. <br/></br/>
|
||||
Please check your internet connection, then try again later.
|
||||
</div>
|
||||
<br clear="all" /><br />
|
||||
<div class="right">
|
||||
<a href="#" class="button-orange disconnected-reconnect">TRY AGAIN TO RECONNECT</a>
|
||||
</div>
|
||||
</script>
|
||||
|
|
@ -29,6 +29,8 @@
|
|||
<%= render "account_audio_profile" %>
|
||||
<%= render "notify" %>
|
||||
<%= render "client_update" %>
|
||||
<%= render "banner" %>
|
||||
<%= render "clients/banners/disconnected" %>
|
||||
<%= render "overlay_small" %>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
|
@ -82,6 +84,8 @@
|
|||
var clientUpdate = new JK.ClientUpdate()
|
||||
clientUpdate.initialize().check()
|
||||
|
||||
|
||||
|
||||
// Some things can't be initialized until we're connected. Put them here.
|
||||
function _initAfterConnect() {
|
||||
|
||||
|
|
@ -118,6 +122,7 @@
|
|||
|
||||
// This is a helper class with a singleton. No need to instantiate.
|
||||
JK.GenreSelectorHelper.initialize();
|
||||
JK.Banner.initialize();
|
||||
|
||||
var createSessionScreen = new JK.CreateSessionScreen(JK.app);
|
||||
createSessionScreen.initialize();
|
||||
|
|
@ -155,6 +160,8 @@
|
|||
JK.app = JK.JamKazam();
|
||||
JK.app.initialize();
|
||||
JK.JamServer.connect(); // singleton here defined in JamServer.js
|
||||
// this ensures that there is always a CurrentSessionModel, even if it's for a non-active session
|
||||
JK.CurrentSessionModel = new JK.SessionModel(JK.JamServer, window.jamClient);
|
||||
|
||||
// Run a check to see if we're logged in yet. Only after that should
|
||||
// we initialize the other screens.
|
||||
|
|
|
|||
|
|
@ -32,5 +32,7 @@
|
|||
<div id="footer-container">
|
||||
<%= render "clients/footer" %>
|
||||
</div>
|
||||
|
||||
<!-- version info: <%= version %> -->
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Reference in New Issue