344 lines
12 KiB
JavaScript
344 lines
12 KiB
JavaScript
(function (context, $) {
|
|
|
|
"use strict";
|
|
|
|
context.JK = context.JK || {};
|
|
|
|
context.JK.ClientUpdate = function (app) {
|
|
var self = this;
|
|
var EVENTS = context.JK.EVENTS;
|
|
var logger = context.JK.logger;
|
|
var ellipsesJiggleTimer = null;
|
|
var forceShow = false; // manual test helper
|
|
// updated once a download is started
|
|
var updateUri = null;
|
|
var updateSize = 0;
|
|
app.clientUpdating = false;
|
|
|
|
|
|
function cancelUpdate(e) {
|
|
if ((e.ctrlKey || e.metaKey) && e.keyCode == 78) {
|
|
logger.debug("update canceled!");
|
|
app.layout.closeDialog('client-update');
|
|
app.clientUpdating = false;
|
|
}
|
|
}
|
|
|
|
// responsible for updating the contents of the update dialog
|
|
// as well as registering for any event handlers
|
|
function updateClientUpdateDialog(templateId, options) {
|
|
options = options || {};
|
|
|
|
var template = $('#template-' + templateId).html();
|
|
var templateHtml = context._.template(template, options, {variable: 'data'});
|
|
|
|
$('#client_update .dialog-inner').html(templateHtml);
|
|
|
|
$('#client_update').attr('data-mode', templateId);
|
|
|
|
// assign click handlers
|
|
if (templateId == "update-start") {
|
|
|
|
$('body').on('keyup', cancelUpdate);
|
|
|
|
$("#client_update a.close-application").click(function () {
|
|
// noop atm
|
|
return false;
|
|
})
|
|
|
|
$("#client_update a.start-update").click(function () {
|
|
var uri = options.uri.replace('https://', 'http://');
|
|
startDownload(uri)
|
|
return false;
|
|
})
|
|
}
|
|
else if (templateId == "update-downloading") {
|
|
|
|
$('body').off('keyup', cancelUpdate);
|
|
|
|
$("#client_update a.close-application").click(function () {
|
|
// noop atm
|
|
return false;
|
|
})
|
|
}
|
|
else if (templateId == "update-restarting" || templateId == "update-error" || templateId == "manual-upgrade") {
|
|
|
|
$("#client_update a.open-downloads").click(function () {
|
|
context.JK.popExternalLink("https://www.jamkazam.com/downloads")
|
|
return false;
|
|
})
|
|
}
|
|
|
|
if(!app.layout.isDialogShowing('client-update')) {
|
|
app.layout.showDialog('client-update')
|
|
}
|
|
|
|
//$('#client_update').show()
|
|
//$('#client_update_overlay').show()
|
|
}
|
|
|
|
/***************************************/
|
|
/******** CALLBACKS FROM BACKEND *******/
|
|
/***************************************/
|
|
function clientUpdateDownloadProgress(bytesReceived, bytesTotal, downloadSpeedMegSec, timeRemaining) {
|
|
// this fires way too many times to leave in. uncomment if debugging update feature
|
|
//logger.debug("bytesReceived: " + bytesReceived, ", bytesTotal: " + bytesTotal, ", downloadSpeed: " + downloadSpeedMegSec, ", timeRemaining: " + timeRemaining + ", updateSize: " + updateSize);
|
|
|
|
bytesReceived = Number(bytesReceived)
|
|
bytesTotal = Number(bytesTotal)
|
|
// bytesTotal from Qt is not trust worthy; trust server's answer instead
|
|
var progressWidth = ((bytesReceived / updateSize) * 100).toString() + "%";
|
|
$('#progress-bar').width(progressWidth)
|
|
//$("#progressbar_detail").text(parseInt(bytesReceived) + "/" + parseInt(updateSize))
|
|
}
|
|
|
|
function clientUpdateDownloadSuccess(updateLocation) {
|
|
logger.debug("client update downloaded successfully to: " + updateLocation);
|
|
|
|
updateClientUpdateDialog("update-proceeding");
|
|
|
|
setTimeout(function () {
|
|
// This method is synchronous, and does alot of work on a mac in particular, hanging the UI.
|
|
// So, we do a sleep loop to make sure the UI is updated with the last message to the user, before we hang the UI
|
|
startUpdate(updateLocation);
|
|
}, 500);
|
|
|
|
}
|
|
|
|
function clientUpdateDownloadFailure(errorMsg) {
|
|
logger.error("client update download error: " + errorMsg)
|
|
|
|
updateClientUpdateDialog("update-error", {error_msg: "Unable to download client update. Error reason: <br/>" + errorMsg });
|
|
}
|
|
|
|
|
|
function clientUpdateLaunchSuccess(userTimeToRead) {
|
|
if(userTimeToRead === undefined) {
|
|
userTimeToRead = 1000; // older clients didn't pass this in, and exit very quickly
|
|
}
|
|
|
|
logger.debug("client update launching in: " + userTimeToRead);
|
|
|
|
// set timer to update countdown
|
|
var rounded = Math.round(userTimeToRead / 1000);
|
|
|
|
// simple countdown timer
|
|
var timer = setInterval(function(){
|
|
var $countdown = $('#client_update .countdown-secs');
|
|
var countdown = parseInt($countdown.text());
|
|
|
|
if(countdown <= 0) {
|
|
clearInterval(timer);
|
|
}
|
|
else {
|
|
$countdown.text(countdown - 1);
|
|
}
|
|
}, rounded * 1000);
|
|
|
|
updateClientUpdateDialog("update-restarting", {countdown: rounded, os: context.JK.GetOSAsString()});
|
|
}
|
|
|
|
function clientUpdateLaunchFailure(errorMsg) {
|
|
logger.error("client update launch error: " + errorMsg)
|
|
|
|
updateClientUpdateDialog("update-error", {error_msg: "Unable to launch client updater. Error reason: <br/>" + errorMsg});
|
|
}
|
|
|
|
function clientUpdateLaunchStatuses(statuses) {
|
|
logger.debug("client update launch statuses");
|
|
|
|
if (statuses) {
|
|
for (var i = 0; i < statuses.length; i++) {
|
|
var status = statuses[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
function clientUpdateLaunchStatusChange(done, status) {
|
|
logger.debug("client update launch status change. starting=" + done + ", status=" + status);
|
|
|
|
if (!done) {
|
|
var $ellipses = $('<span class="ellipses">.</span>');
|
|
$ellipses.data('count', 1);
|
|
var $status = $('<span class="status"></span>');
|
|
$status.text(status);
|
|
$status.append($ellipses);
|
|
$('#client-updater-updating').append($status);
|
|
|
|
ellipsesJiggleTimer = setInterval(function () {
|
|
var count = $ellipses.data('count');
|
|
if (!count) {
|
|
count = 0; // only the real client sometimes returns undefined for count
|
|
}
|
|
count++;
|
|
if (count > 3) {
|
|
count = 1;
|
|
}
|
|
$ellipses.text(Array(count + 1).join("."));
|
|
$ellipses.data('count', count);
|
|
}, 500);
|
|
}
|
|
else {
|
|
clearInterval(ellipsesJiggleTimer);
|
|
$('#client-updater-updating span.status').last().css('color', 'gray').find('span.ellipses').text('...');
|
|
}
|
|
|
|
}
|
|
|
|
/********************************************/
|
|
/******** END: CALLBACKS FROM BACKEND *******/
|
|
/********************************************/
|
|
|
|
// if the current version doesn't not match the server version, attempt to do an upgrade
|
|
function shouldUpdate(currentVersion, version) {
|
|
if(forceShow) return true;
|
|
|
|
if (version === undefined || version == null || version == "") {
|
|
return false;
|
|
}
|
|
else {
|
|
return currentVersion != version;
|
|
}
|
|
}
|
|
|
|
function runCheck(product, version, uri, size, currentVersion) {
|
|
|
|
if (app.clientUpdating) {
|
|
logger.debug("client is already updating; skipping")
|
|
return
|
|
}
|
|
|
|
if(currentVersion === undefined) {
|
|
currentVersion = context.jamClient.ClientUpdateVersion();
|
|
|
|
if (!forceShow && (currentVersion == null || currentVersion.indexOf("Compiled")) > -1) {
|
|
// this is a developer build; it doesn't make much sense to do an packaged update, so skip
|
|
logger.debug("skipping client update check because this is a development build ('" + currentVersion + "')")
|
|
return;
|
|
}
|
|
|
|
// # strange client oddity: remove quotes, if found, from start and finish of version.
|
|
if (currentVersion.indexOf('"') == 0 && currentVersion.lastIndexOf('"') == currentVersion.length - 1) {
|
|
currentVersion = currentVersion.substring(1, currentVersion.length - 1);
|
|
}
|
|
}
|
|
|
|
logger.debug("our client version: " + currentVersion + ", server client version: " + version);
|
|
|
|
// test url in lieu of having a configured server with a client-update available
|
|
|
|
if (shouldUpdate(currentVersion, version)) {
|
|
app.clientUpdating = true;
|
|
updateUri = uri;
|
|
updateSize = size;
|
|
|
|
if(context.SessionStore.inSession()) {
|
|
logger.debug("deferring client update because in session")
|
|
return;
|
|
}
|
|
|
|
// test metadata in lieu of having a configured server with a client-update available
|
|
//updateSize = 10000;
|
|
//version = "1.2.3"
|
|
|
|
// this will update the client dialog to how it should look when an update is just starting
|
|
// and show it front-and-center on the screen
|
|
// XXX HACK
|
|
if(updateUri && gon.global.manual_override_installer_ends_with && updateUri.endsWith(gon.global.manual_override_installer_ends_with)) {
|
|
updateClientUpdateDialog("manual-upgrade", { uri: updateUri })
|
|
}
|
|
else {
|
|
updateClientUpdateDialog("update-start", { uri: updateUri })
|
|
}
|
|
}
|
|
}
|
|
|
|
// check if updated is needed
|
|
function check() {
|
|
|
|
var os = context.JK.GetOSAsString();
|
|
//os = 'Win32'
|
|
|
|
// check kill switch before all other logic
|
|
if (!gon.check_for_client_updates) {
|
|
logger.debug("skipping client update because the server is telling us not to")
|
|
return;
|
|
}
|
|
|
|
var product = "JamClient"
|
|
var currentVersion = context.jamClient.ClientUpdateVersion();
|
|
|
|
if (!forceShow && (currentVersion == null || currentVersion.indexOf("Compiled")) > -1) {
|
|
// this is a developer build; it doesn't make much sense to do an packaged update, so skip
|
|
logger.debug("skipping client update check because this is a development build ('" + currentVersion + "')")
|
|
return;
|
|
}
|
|
|
|
// # strange client oddity: remove quotes, if found, from start and finish of version.
|
|
if (currentVersion.indexOf('"') == 0 && currentVersion.lastIndexOf('"') == currentVersion.length - 1) {
|
|
currentVersion = currentVersion.substring(1, currentVersion.length - 1);
|
|
}
|
|
|
|
$.ajax({
|
|
type: "GET",
|
|
url: "/api/versioncheck?product=" + product + "&os=" + os,
|
|
success: function (response) {
|
|
runCheck(product, response.version, response.uri, response.size, currentVersion);
|
|
},
|
|
error: function (jqXHR, textStatus, errorThrown) {
|
|
logger.error("Unable to do a client update check against /api/versioncheck");
|
|
}
|
|
});
|
|
}
|
|
|
|
function startDownload(url) {
|
|
logger.debug("starting client updater download from: " + url);
|
|
|
|
updateClientUpdateDialog("update-downloading")
|
|
|
|
context.jamClient.ClientUpdateStartDownload(url,
|
|
"JK.ClientUpdate.DownloadProgressCallback",
|
|
"JK.ClientUpdate.DownloadSuccessCallback",
|
|
"JK.ClientUpdate.DownloadFailureCallback");
|
|
}
|
|
|
|
function startUpdate(updaterFilePath) {
|
|
logger.debug("starting client update from: " + updaterFilePath)
|
|
|
|
context.jamClient.ClientUpdateStartUpdate(updaterFilePath,
|
|
"JK.ClientUpdate.LaunchUpdateSuccessCallback",
|
|
"JK.ClientUpdate.LaunchUpdateFailureCallback",
|
|
"JK.ClientUpdate.LaunchUpdateStatusesCallback",
|
|
"JK.ClientUpdate.LaunchUpdateStatusChangeCallback");
|
|
}
|
|
|
|
function initialize() {
|
|
context.JK.ClientUpdate.DownloadProgressCallback = clientUpdateDownloadProgress;
|
|
context.JK.ClientUpdate.DownloadSuccessCallback = clientUpdateDownloadSuccess;
|
|
context.JK.ClientUpdate.DownloadFailureCallback = clientUpdateDownloadFailure;
|
|
context.JK.ClientUpdate.LaunchUpdateSuccessCallback = clientUpdateLaunchSuccess;
|
|
context.JK.ClientUpdate.LaunchUpdateFailureCallback = clientUpdateLaunchFailure;
|
|
context.JK.ClientUpdate.LaunchUpdateStatusesCallback = clientUpdateLaunchStatuses;
|
|
context.JK.ClientUpdate.LaunchUpdateStatusChangeCallback = clientUpdateLaunchStatusChange;
|
|
|
|
app.bindDialog('client-update', {});
|
|
|
|
$(document).on(EVENTS.SESSION_ENDED, function(e, data){
|
|
if(app.clientUpdating) {
|
|
updateClientUpdateDialog("update-start", { uri: updateUri})
|
|
}
|
|
});
|
|
|
|
return self;
|
|
}
|
|
|
|
// Expose publics
|
|
this.initialize = initialize;
|
|
this.check = check;
|
|
this.runCheck = runCheck;
|
|
}
|
|
|
|
return this;
|
|
|
|
})(window, jQuery);
|