(function (context, $) { "use strict"; context.JK = context.JK || {}; context.JK.ClientUpdate = function (app) { var self = this; var logger = context.JK.logger; var ellipsesJiggleTimer = null; var forceShow = false; // manual test helper app.clientUpdating = false; // updated once a download is started var updateSize = 0; 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) { var template = $('#template-' + templateId).html(); var templateHtml = context.JK.fillTemplate(template, options); $('#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 () { startDownload(options.uri) return false; }) } else if (templateId == "update-downloading") { $('body').off('keyup', cancelUpdate); $("#client_update a.close-application").click(function () { // noop atm return false; }) } 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 ); bytesReceived = Number(bytesReceived) bytesTotal = Number(bytesTotal) // bytesTotal from Qt is not trust worthy; trust server's answer instead $('#progress-bar').width(((bytesReceived / updateSize) * 100).toString() + "%") //$("#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:
" + errorMsg }); } function clientUpdateLaunchSuccess(updateLocation) { logger.debug("client update launched successfully to: " + updateLocation); updateClientUpdateDialog("update-restarting"); } function clientUpdateLaunchFailure(errorMsg) { logger.error("client update launch error: " + errorMsg) updateClientUpdateDialog("update-error", {error_msg: "Unable to launch client updater. Error reason:
" + 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 = $('.'); $ellipses.data('count', 1); var $status = $(''); $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; } } // check if updated is needed function check() { // 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 os = context.jamClient.GetOSAsString() 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) { var version = response.version; 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)) { updateSize = response.size; app.clientUpdating = true; // 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 updateClientUpdateDialog("update-start", { uri: response.uri }) } }, 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', {}); return self; } // Expose publics this.initialize = initialize; this.check = check; } return this; })(window, jQuery);