From c788d02a57db699202ce9297ed4d5f0d52360d70 Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Thu, 21 May 2015 17:16:38 -0400 Subject: [PATCH] Disable the angular poll channel when the browser tab is hidden Quay pages that normally poll (repo view, build logs, etc) will skip the API call(s) when the tab is hidden. --- static/js/services/angular-poll-channel.js | 9 ++- .../services/document-visibility-service.js | 60 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 static/js/services/document-visibility-service.js diff --git a/static/js/services/angular-poll-channel.js b/static/js/services/angular-poll-channel.js index adba49757..f4028a65f 100644 --- a/static/js/services/angular-poll-channel.js +++ b/static/js/services/angular-poll-channel.js @@ -1,7 +1,8 @@ /** * Specialized class for conducting an HTTP poll, while properly preventing multiple calls. */ -angular.module('quay').factory('AngularPollChannel', ['ApiService', '$timeout', function(ApiService, $timeout) { +angular.module('quay').factory('AngularPollChannel', ['ApiService', '$timeout', 'DocumentVisibilityService', + function(ApiService, $timeout, DocumentVisibilityService) { var _PollChannel = function(scope, requester, opt_sleeptime) { this.scope_ = scope; this.requester_ = requester; @@ -50,6 +51,12 @@ angular.module('quay').factory('AngularPollChannel', ['ApiService', '$timeout', _PollChannel.prototype.call_ = function() { if (this.working) { return; } + // If the document is currently hidden, skip the call. + if (DocumentVisibilityService.isHidden()) { + this.setupTimer_(); + return; + } + var that = this; this.working = true; this.scope_.$apply(function() { diff --git a/static/js/services/document-visibility-service.js b/static/js/services/document-visibility-service.js new file mode 100644 index 000000000..f56ecc633 --- /dev/null +++ b/static/js/services/document-visibility-service.js @@ -0,0 +1,60 @@ +/** + * Helper service which fires off events when the document's visibility changes, as well as allowing + * other Angular code to query the state of the document's visibility directly. + */ +angular.module('quay').constant('CORE_EVENT', { + DOC_VISIBILITY_CHANGE: 'core.event.doc_visibility_change' +}); + +angular.module('quay').factory('DocumentVisibilityService', ['$rootScope', '$document', 'CORE_EVENT', + function($rootScope, $document, CORE_EVENT) { + var document = $document[0], + features, + detectedFeature; + + function broadcastChangeEvent() { + $rootScope.$broadcast(CORE_EVENT.DOC_VISIBILITY_CHANGE, + document[detectedFeature.propertyName]); + } + + features = { + standard: { + eventName: 'visibilitychange', + propertyName: 'hidden' + }, + moz: { + eventName: 'mozvisibilitychange', + propertyName: 'mozHidden' + }, + ms: { + eventName: 'msvisibilitychange', + propertyName: 'msHidden' + }, + webkit: { + eventName: 'webkitvisibilitychange', + propertyName: 'webkitHidden' + } + }; + + Object.keys(features).some(function(feature) { + if (document[features[feature].propertyName] !== undefined) { + detectedFeature = features[feature]; + return true; + } + }); + + if (detectedFeature) { + $document.on(detectedFeature.eventName, broadcastChangeEvent); + } + + return { + /** + * Is the window currently hidden or not. + */ + isHidden: function() { + if (detectedFeature) { + return document[detectedFeature.propertyName]; + } + } + }; +}]); \ No newline at end of file