diff --git a/js/angular/controller/scrollController.js b/js/angular/controller/scrollController.js index b81ac2070f5..6c2992b279f 100644 --- a/js/angular/controller/scrollController.js +++ b/js/angular/controller/scrollController.js @@ -175,10 +175,12 @@ function($scope, scrollViewOptions, $timeout, $window, $location, $document, $io // activateCallback refresher.classList.add('active'); refresherScope.$onPulling(); + onPullProgress(1); }, function() { - refresher.classList.remove('active'); - refresher.classList.remove('refreshing'); - refresher.classList.remove('refreshing-tail'); + // deactivateCallback + refresher.classList.remove('active'); + refresher.classList.remove('refreshing'); + refresher.classList.remove('refreshing-tail'); }, function() { // startCallback refresher.classList.add('refreshing'); @@ -192,6 +194,11 @@ function($scope, scrollViewOptions, $timeout, $window, $location, $document, $io }, function() { // tailCallback refresher.classList.add('refreshing-tail'); - }); + }, onPullProgress); + + function onPullProgress(progress) { + $scope.$broadcast('$ionicRefresher.pullProgress', progress); + (refresherScope.$onPullProgress || angular.noop)(progress); + } }; }]); diff --git a/js/angular/directive/refresher.js b/js/angular/directive/refresher.js index d2b07daebfe..b9d98d2c066 100644 --- a/js/angular/directive/refresher.js +++ b/js/angular/directive/refresher.js @@ -48,6 +48,10 @@ * of the refresher. * @param {expression=} on-pulling Called when the user starts to pull down * on the refresher. + * @param {expression=} on-pull-progress Repeatedly called as the user is pulling down + * the refresher. The callback should have a `progress` argument which will be a number + * from `0` and `1`. For example, if the user has pulled the refresher halfway + * down, its progress would be `0.5`. * @param {string=} pulling-icon The icon to display while the user is pulling down. * Default: 'ion-arrow-down-c'. * @param {string=} pulling-text The text to display while the user is pulling down. @@ -60,7 +64,7 @@ * */ IonicModule -.directive('ionRefresher', ['$ionicBind', function($ionicBind) { +.directive('ionRefresher', ['$ionicBind', '$parse', function($ionicBind, $parse) { return { restrict: 'E', replace: true, @@ -95,6 +99,15 @@ IonicModule $onPulling: '&onPulling' }); + if (isDefined($attrs.onPullProgress)) { + var onPullProgressFn = $parse($attrs.onPullProgress); + $scope.$onPullProgress = function(progress) { + onPullProgressFn($scope, { + progress: progress + }); + }; + } + scrollCtrl._setRefresher($scope, $element[0]); $scope.$on('scroll.refreshComplete', function() { $scope.$evalAsync(function() { diff --git a/js/views/scrollView.js b/js/views/scrollView.js index 9632fd53dde..de442df6a04 100644 --- a/js/views/scrollView.js +++ b/js/views/scrollView.js @@ -532,6 +532,9 @@ ionic.views.Scroll = ionic.views.View.inherit({ /** Callback to execute to start the actual refresh. Call {@link #refreshFinish} when done */ __refreshStart: null, + /** Callback to state the progress while pulling to refresh */ + __refreshPullProgress: null, + /** Zoom level */ __zoomLevel: 1, @@ -1336,17 +1339,19 @@ ionic.views.Scroll = ionic.views.View.inherit({ * @param showCallback {Function} Callback to execute when the refresher should be shown. This is for showing the refresher during a negative scrollTop. * @param hideCallback {Function} Callback to execute when the refresher should be hidden. This is for hiding the refresher when it's behind the nav bar. * @param tailCallback {Function} Callback to execute just before the refresher returns to it's original state. This is for zooming out the refresher. + * @param pullProgressCallback Callback to state the progress while pulling to refresh */ - activatePullToRefresh: function(height, activateCallback, deactivateCallback, startCallback, showCallback, hideCallback, tailCallback) { + activatePullToRefresh: function(height, activateCallback, deactivateCallback, startCallback, showCallback, hideCallback, tailCallback, pullProgressCallback) { var self = this; self.__refreshHeight = height; - self.__refreshActivate = function(){ionic.requestAnimationFrame(activateCallback);}; - self.__refreshDeactivate = function(){ionic.requestAnimationFrame(deactivateCallback);}; - self.__refreshStart = function(){ionic.requestAnimationFrame(startCallback);}; - self.__refreshShow = function(){ionic.requestAnimationFrame(showCallback);}; - self.__refreshHide = function(){ionic.requestAnimationFrame(hideCallback);}; - self.__refreshTail = function(){ionic.requestAnimationFrame(tailCallback);}; + self.__refreshActivate = function() {ionic.requestAnimationFrame(activateCallback);}; + self.__refreshDeactivate = function() {ionic.requestAnimationFrame(deactivateCallback);}; + self.__refreshStart = function() {ionic.requestAnimationFrame(startCallback);}; + self.__refreshShow = function() {ionic.requestAnimationFrame(showCallback);}; + self.__refreshHide = function() {ionic.requestAnimationFrame(hideCallback);}; + self.__refreshTail = function() {ionic.requestAnimationFrame(tailCallback);}; + self.__refreshPullProgress = pullProgressCallback; self.__refreshTailTime = 100; self.__minSpinTime = 600; }, @@ -1377,19 +1382,19 @@ ionic.views.Scroll = ionic.views.View.inherit({ // delay to make sure the spinner has a chance to spin for a split second before it's dismissed var d = new Date(); var delay = 0; - if (self.refreshStartTime + self.__minSpinTime > d.getTime()){ + if (self.refreshStartTime + self.__minSpinTime > d.getTime()) { delay = self.refreshStartTime + self.__minSpinTime - d.getTime(); } - setTimeout(function(){ - if (self.__refreshTail){ + setTimeout(function() { + if (self.__refreshTail) { self.__refreshTail(); } - setTimeout(function(){ + setTimeout(function() { self.__refreshActive = false; if (self.__refreshDeactivate) { self.__refreshDeactivate(); } - if (self.__refreshHide){ + if (self.__refreshHide) { self.__refreshHide(); } @@ -1817,7 +1822,7 @@ ionic.views.Scroll = ionic.views.View.inherit({ if (!self.__enableScrollX && self.__refreshHeight != null) { // hide the refresher when it's behind the header bar in case of header transparency - if (scrollTop < 0){ + if (scrollTop < 0) { self.__refreshHidden = false; self.__refreshShow(); } else { @@ -1839,6 +1844,9 @@ ionic.views.Scroll = ionic.views.View.inherit({ self.__refreshDeactivate(); } + } else if (!self.__refreshActive && self.__refreshPullProgress) { + self.__refreshPullProgress(scrollTop / -self.__refreshHeight); + } } @@ -1851,7 +1859,7 @@ ionic.views.Scroll = ionic.views.View.inherit({ scrollTop = 0; } - } else if (self.__refreshHeight && !self.__refreshHidden){ + } else if (self.__refreshHeight && !self.__refreshHidden) { // if a positive scroll value and the refresher is still not hidden, hide it self.__refreshHide(); self.__refreshHidden = true; @@ -2189,7 +2197,7 @@ ionic.views.Scroll = ionic.views.View.inherit({ self.__minDecelerationScrollTop = 0; self.__maxDecelerationScrollLeft = self.__maxScrollLeft; self.__maxDecelerationScrollTop = self.__maxScrollTop; - if (self.__refreshActive) self.__minDecelerationScrollTop = self.__refreshHeight *-1; + if (self.__refreshActive) self.__minDecelerationScrollTop = self.__refreshHeight * -1; } // Wrap class method