diff --git a/static/js/app.js b/static/js/app.js index 07b0a53ff..57ef53b29 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -105,6 +105,86 @@ function getMarkedDown(string) { quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'angular-tour', 'restangular', 'angularMoment', 'angulartics', /*'angulartics.google.analytics',*/ 'angulartics.mixpanel', 'mgcrea.ngStrap', 'ngCookies', 'ngSanitize', 'angular-md5', 'pasvaz.bindonce', 'ansiToHtml', 'ngAnimate'], function($provide, cfpLoadingBarProvider) { cfpLoadingBarProvider.includeSpinner = false; + /** + * Specialized wrapper around array which provides a toggle() method for viewing the contents of the + * array in a manner that is asynchronously filled in over a short time period. This prevents long + * pauses in the UI for ngRepeat's when the array is significant in size. + */ + $provide.factory('AngularViewArray', ['$interval', function($interval) { + var ADDTIONAL_COUNT = 50; + + function _ViewArray() { + this.isVisible = false; + this.visibleEntries = null; + this.hasEntries = false; + this.entries = []; + + this.timerRef_ = null; + this.currentIndex_ = 0; + } + + _ViewArray.prototype.push = function(elem) { + this.entries.push(elem); + this.hasEntries = true; + + if (this.isVisible) { + this.setVisible(true); + } + }; + + _ViewArray.prototype.toggle = function() { + this.setVisible(!this.isVisible); + }; + + _ViewArray.prototype.setVisible = function(newState) { + this.isVisible = newState; + + this.visibleEntries = []; + this.currentIndex_ = 0; + + if (newState) { + this.showAdditionalEntries_(); + this.startTimer_(); + } else { + this.stopTimer_(); + } + }; + + _ViewArray.prototype.showAdditionalEntries_ = function() { + var i = 0; + for (i = this.currentIndex_; i < (this.currentIndex_ + ADDTIONAL_COUNT) && i < this.entries.length; ++i) { + this.visibleEntries.push(this.entries[i]); + } + + this.currentIndex_ = i; + if (this.currentIndex_ >= this.entries.length) { + this.stopTimer_(); + } + }; + + _ViewArray.prototype.startTimer_ = function() { + var that = this; + this.timerRef_ = $interval(function() { + that.showAdditionalEntries_(); + }, 10); + }; + + _ViewArray.prototype.stopTimer_ = function() { + if (this.timerRef_) { + $interval.cancel(this.timerRef_); + this.timerRef_ = null; + } + }; + + var service = { + 'create': function() { + return new _ViewArray(); + } + }; + + return service; + }]); + $provide.factory('UtilService', ['$sanitize', function($sanitize) { var utilService = {}; diff --git a/static/js/controllers.js b/static/js/controllers.js index 7d3378c31..9eb307da8 100644 --- a/static/js/controllers.js +++ b/static/js/controllers.js @@ -924,7 +924,8 @@ function BuildPackageCtrl($scope, Restangular, ApiService, $routeParams, $rootSc getBuildInfo(); } -function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $location, $interval, $sanitize, ansi2html) { +function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $location, $interval, $sanitize, + ansi2html, AngularViewArray) { var namespace = $routeParams.namespace; var name = $routeParams.name; var pollTimerHandle = null; @@ -990,19 +991,9 @@ function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope }; $scope.hasLogs = function(container) { - return ((container.logs && container.logs.length) || (container._logs && container._logs.length)); + return container.logs.hasEntries; }; - $scope.toggleLogs = function(container) { - if (container._logs) { - container.logs = container._logs; - container._logs = null; - } else { - container._logs = container.logs; - container.logs = null; - } - }; - $scope.setCurrentBuild = function(buildId, opt_updateURL) { if (!$scope.builds) { return; } @@ -1090,17 +1081,13 @@ function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope var entry = logs[i]; var type = entry['type'] || 'entry'; if (type == 'command' || type == 'phase' || type == 'error') { - entry['_logs'] = []; + entry['logs'] = AngularViewArray.create(); entry['index'] = startIndex + i; $scope.logEntries.push(entry); - $scope.currentParentEntry = entry; + $scope.currentParentEntry = entry; } else if ($scope.currentParentEntry) { - if ($scope.currentParentEntry['logs']) { - $scope.currentParentEntry['logs'].push(entry); - } else { - $scope.currentParentEntry['_logs'].push(entry); - } + $scope.currentParentEntry['logs'].push(entry); } } }; diff --git a/static/partials/repo-build.html b/static/partials/repo-build.html index f7aec4838..7feed76a0 100644 --- a/static/partials/repo-build.html +++ b/static/partials/repo-build.html @@ -70,9 +70,9 @@