Skip to content

Commit

Permalink
feat(pullToRefresh): add on-pull-progress
Browse files Browse the repository at this point in the history
Add the ability to get the progress of a user’s pull to refresh, while
they’re pulling down the refresher.
  • Loading branch information
adamdbradley committed Jan 5, 2015
1 parent 78de93b commit 955f441
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 20 deletions.
15 changes: 11 additions & 4 deletions js/angular/controller/scrollController.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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);
}
};
}]);
15 changes: 14 additions & 1 deletion js/angular/directive/refresher.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -60,7 +64,7 @@
*
*/
IonicModule
.directive('ionRefresher', ['$ionicBind', function($ionicBind) {
.directive('ionRefresher', ['$ionicBind', '$parse', function($ionicBind, $parse) {
return {
restrict: 'E',
replace: true,
Expand Down Expand Up @@ -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() {
Expand Down
38 changes: 23 additions & 15 deletions js/views/scrollView.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Expand Down Expand Up @@ -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;
},
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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 {
Expand All @@ -1839,6 +1844,9 @@ ionic.views.Scroll = ionic.views.View.inherit({
self.__refreshDeactivate();
}

} else if (!self.__refreshActive && self.__refreshPullProgress) {
self.__refreshPullProgress(scrollTop / -self.__refreshHeight);

}
}

Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down

2 comments on commit 955f441

@felquis
Copy link

@felquis felquis commented on 955f441 Jan 5, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking about a percentage progress, 0% to 100%, and sometimes it could be 120%, because the user pulled too much.

It's a great feature, I was waiting for it.

@apavillet
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not know if it's intentional not to center it but for the loader to be centered you should add a margin: auto in svg.loader class

Please sign in to comment.