From 79c243a20b51cd11ab11a2c5d333f235ca745f87 Mon Sep 17 00:00:00 2001 From: Seth Call Date: Mon, 7 Apr 2014 17:36:08 +0100 Subject: [PATCH 01/26] * automatic reconnect dialog will guide user without having to click - VRFS-1404 --- web/app/assets/javascripts/banner.js | 2 +- web/app/assets/javascripts/sessionModel.js | 154 ++++++++++++++---- .../assets/stylesheets/client/banner.css.scss | 4 + .../stylesheets/minimal/minimal_main.css.scss | 5 + web/app/controllers/videos_controller.rb | 8 - web/app/views/clients/_banner.html.erb | 2 +- web/app/views/clients/_jamServer.html.haml | 1 + .../clients/banners/_disconnected.html.erb | 33 +--- web/app/views/clients/index.html.erb | 1 + web/app/views/layouts/minimal.html.erb | 7 +- web/app/views/videos/show_dialog.html.haml | 0 web/config/routes.rb | 2 - 12 files changed, 142 insertions(+), 77 deletions(-) delete mode 100644 web/app/controllers/videos_controller.rb create mode 100644 web/app/views/clients/_jamServer.html.haml delete mode 100644 web/app/views/videos/show_dialog.html.haml diff --git a/web/app/assets/javascripts/banner.js b/web/app/assets/javascripts/banner.js index d0aa78aa7..535d841c3 100644 --- a/web/app/assets/javascripts/banner.js +++ b/web/app/assets/javascripts/banner.js @@ -25,7 +25,7 @@ return newContent; } - $('#banner').show() + $('#banner').attr('data-type', options.type).show() $('#banner_overlay').show() // return the core of the banner so that caller can attach event handlers to newly created HTML diff --git a/web/app/assets/javascripts/sessionModel.js b/web/app/assets/javascripts/sessionModel.js index 31a057e14..d283aba19 100644 --- a/web/app/assets/javascripts/sessionModel.js +++ b/web/app/assets/javascripts/sessionModel.js @@ -22,6 +22,12 @@ // 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 countdownInterval = null; + var reconnectAttemptLookup = [2, 2, 2, 4, 8, 15, 30]; + var reconnectAttempt = 0; + var reconnectingWaitPeriodStart = null; + var reconnectDueTime = null; + function id() { return currentSession ? currentSession.id : null; } @@ -386,38 +392,124 @@ }); } - function registerReconnect(content) { - $('a.disconnected-reconnect', content).click(function() { + function renderDisconnected() { + var template = $('#template-disconnected').html(); + var templateHtml = context.JK.fillTemplate(template, { + countdown: formatDelaySecs(reconnectDelaySecs()) + }); + var content = context.JK.Banner.show({ + html : templateHtml, + type: 'reconnect' + }) ; - var template = $('#template-reconnecting').html(); - var templateHtml = context.JK.fillTemplate(template, null); - var content = context.JK.Banner.show({ - html : template - }); + return content; + } - rest.serverHealthCheck() - .done(function() { - reconnect(); - }) - .fail(function(xhr, textStatus, errorThrown) { + function formatDelaySecs(secs) { + return secs == 1 ? '1 second' : secs + ' seconds' + } - 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 - }); + function setCountdown(parent) { + parent.find('.reconnect-countdown').text(formatDelaySecs(reconnectDelaySecs())); + } - registerReconnect(content); - } - }); + function renderCouldNotReconnect() { + renderDisconnected(); + } - return false; + function renderReconnecting() { + $('#banner .reconnect-progress-msg').text('Attempting to reconnect.') + $('#banner .disconnected-reconnect').removeClass('button-orange').addClass('button-grey'); + } + + + function failedReconnect() { + + reconnectAttempt += 1; + + var content = renderCouldNotReconnect(); + + beginReconnectPeriod(content); + } + + function attemptReconnect() { + + var start = new Date().getTime(); + + function guardAgainstRapidTransition(nextStep) { + var now = new Date().getTime(); + + if ((now - start) < 1500) { + setTimeout(function() { + nextStep(); + }, 1500 - (now - start)) + } + else { + nextStep(); + } + } + + renderReconnecting(); + + rest.serverHealthCheck() + .done(function() { + guardAgainstRapidTransition(reconnect); + }) + .fail(function(xhr, textStatus, errorThrown) { + + if(xhr && xhr.status >= 100) { + // we could connect to the server, and it's alive + guardAgainstRapidTransition(reconnect); + } + else { + guardAgainstRapidTransition(failedReconnect); + } }); + + return false; + } + + function clearReconnectTimers() { + if(countdownInterval) { + clearInterval(countdownInterval); + countdownInterval = null; + } + } + + function beginReconnectPeriod(content) { + + // allow user to force reconnect + $('a.disconnected-reconnect', content).unbind('click').click(function() { + if($(this).is('.button-orange')) { + clearReconnectTimers(); + attemptReconnect(); + } + }); + + reconnectingWaitPeriodStart = new Date().getTime(); + reconnectDueTime = reconnectingWaitPeriodStart + reconnectDelaySecs() * 1000; + + // update count down timer periodically + countdownInterval = setInterval(function() { + var now = new Date().getTime(); + if(now > reconnectDueTime) { + clearReconnectTimers(); + attemptReconnect(); + } + else { + var secondsUntilReconnect = Math.ceil((reconnectDueTime - now) / 1000); + $('.reconnect-countdown').text(formatDelaySecs(secondsUntilReconnect)); + } + }, 333); + } + + function reconnectDelaySecs() { + if (reconnectAttempt > reconnectAttemptLookup.length - 1) { + return reconnectAttemptLookup[reconnectAttemptLookup.length - 1]; + } + else { + return reconnectAttemptLookup[reconnectAttempt]; + } } function onWebsocketDisconnected(in_error) { @@ -432,13 +524,11 @@ logger.debug("calling jamClient.LeaveSession for clientId=" + clientId); client.LeaveSession({ sessionID: currentSessionId }); + reconnectAttempt = 0; + if(in_error) { - var template = $('#template-disconnected').html(); - var templateHtml = context.JK.fillTemplate(template, null); - var content = context.JK.Banner.show({ - html : template - }) ; - registerReconnect(content); + var content = renderDisconnected(); + beginReconnectPeriod(content); } } diff --git a/web/app/assets/stylesheets/client/banner.css.scss b/web/app/assets/stylesheets/client/banner.css.scss index e3b8de209..34aada30c 100644 --- a/web/app/assets/stylesheets/client/banner.css.scss +++ b/web/app/assets/stylesheets/client/banner.css.scss @@ -1,5 +1,9 @@ #banner { display:none; + + &[data-type="reconnect"] { + height:240px; + } } #banner h2 { diff --git a/web/app/assets/stylesheets/minimal/minimal_main.css.scss b/web/app/assets/stylesheets/minimal/minimal_main.css.scss index 5a170e128..50feaf50f 100644 --- a/web/app/assets/stylesheets/minimal/minimal_main.css.scss +++ b/web/app/assets/stylesheets/minimal/minimal_main.css.scss @@ -9,3 +9,8 @@ body { height:100%; margin:0 !important; } + +.wrapper { + width:1280px; + margin:0 auto; +} \ No newline at end of file diff --git a/web/app/controllers/videos_controller.rb b/web/app/controllers/videos_controller.rb deleted file mode 100644 index a63343776..000000000 --- a/web/app/controllers/videos_controller.rb +++ /dev/null @@ -1,8 +0,0 @@ - -class VideosController < ApplicationController - - def show_dialog - @video_id = @params[:video_id] - end - -end \ No newline at end of file diff --git a/web/app/views/clients/_banner.html.erb b/web/app/views/clients/_banner.html.erb index 9a932e3a9..4a7cd1d6e 100644 --- a/web/app/views/clients/_banner.html.erb +++ b/web/app/views/clients/_banner.html.erb @@ -1,7 +1,7 @@ -