Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support for horizontal pull to refresh #48

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 50 additions & 14 deletions src/Scroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,11 @@ var Scroller;
/** {Integer} Snapping height for content */
__snapHeight: 100,

/** {Boolean} Is pull to refresh horizontal? */
__refreshIsHorizontal: false,

/** {Integer} Height to assign to refresh area */
__refreshHeight: null,
__refreshSize: null,

/** {Boolean} Whether the refresh process is enabled when the event is released now */
__refreshActive: false,
Expand Down Expand Up @@ -347,20 +350,25 @@ var Scroller;
* the user event is released during visibility of this zone. This was introduced by some apps on iOS like
* the official Twitter client.
*
* @param height {Integer} Height of pull-to-refresh zone on top of rendered list
* @param isHorizontal {Boolean} If the pull to refresh is horizontal (default to false)
* @param size {Integer} Size of pull-to-refresh zone on top or left of rendered list
* @param activateCallback {Function} Callback to execute on activation. This is for signalling the user about a refresh is about to happen when he release.
* @param deactivateCallback {Function} Callback to execute on deactivation. This is for signalling the user about the refresh being cancelled.
* @param startCallback {Function} Callback to execute to start the real async refresh action. Call {@link #finishPullToRefresh} after finish of refresh.
*/
activatePullToRefresh: function(height, activateCallback, deactivateCallback, startCallback) {

var self = this;
activatePullToRefresh: function(isHorizontal, size, activateCallback, deactivateCallback, startCallback) {

self.__refreshHeight = height;
self.__refreshActivate = activateCallback;
self.__refreshDeactivate = deactivateCallback;
self.__refreshStart = startCallback;
var self = this, shift = function(a) { return Array.prototype.shift.apply(a); };

if (isHorizontal === true || isHorizontal === false) {
self.__refreshIsHorizontal = shift(arguments);
} else {
self.__refreshIsHorizontal = false;
}
self.__refreshSize = shift(arguments);
self.__refreshActivate = shift(arguments);
self.__refreshDeactivate = shift(arguments);
self.__refreshStart = shift(arguments);
},


Expand All @@ -370,7 +378,11 @@ var Scroller;
triggerPullToRefresh: function() {
// Use publish instead of scrollTo to allow scrolling to out of boundary position
// We don't need to normalize scrollLeft, zoomLevel, etc. here because we only y-scrolling when pull-to-refresh is enabled
this.__publish(this.__scrollLeft, -this.__refreshHeight, this.__zoomLevel, true);
if (this.__refreshIsHorizontal) {
this.__publish(-this.__refreshSize, this.__scrollTop, this.__zoomLevel, true);
} else {
this.__publish(this.__scrollLeft, -this.__refreshSize, this.__zoomLevel, true);
}

if (this.__refreshStart) {
this.__refreshStart();
Expand Down Expand Up @@ -815,6 +827,26 @@ var Scroller;

scrollLeft += (moveX / 2 * this.options.speedMultiplier);

// Support pull-to-refresh (only when only x is scrollable)
if (!self.__enableScrollY && self.__refreshSize != null && this.__refreshIsHorizontal) {

if (!self.__refreshActive && scrollLeft <= -self.__refreshSize) {

self.__refreshActive = true;
if (self.__refreshActivate) {
self.__refreshActivate();
}

} else if (self.__refreshActive && scrollLeft > -self.__refreshSize) {

self.__refreshActive = false;
if (self.__refreshDeactivate) {
self.__refreshDeactivate();
}

}
}

} else if (scrollLeft > maxScrollLeft) {

scrollLeft = maxScrollLeft;
Expand All @@ -841,16 +873,16 @@ var Scroller;
scrollTop += (moveY / 2 * this.options.speedMultiplier);

// Support pull-to-refresh (only when only y is scrollable)
if (!self.__enableScrollX && self.__refreshHeight != null) {
if (!self.__enableScrollX && self.__refreshSize != null && !this.__refreshIsHorizontal) {

if (!self.__refreshActive && scrollTop <= -self.__refreshHeight) {
if (!self.__refreshActive && scrollTop <= -self.__refreshSize) {

self.__refreshActive = true;
if (self.__refreshActivate) {
self.__refreshActivate();
}

} else if (self.__refreshActive && scrollTop > -self.__refreshHeight) {
} else if (self.__refreshActive && scrollTop > -self.__refreshSize) {

self.__refreshActive = false;
if (self.__refreshDeactivate) {
Expand Down Expand Up @@ -1000,7 +1032,11 @@ var Scroller;

// Use publish instead of scrollTo to allow scrolling to out of boundary position
// We don't need to normalize scrollLeft, zoomLevel, etc. here because we only y-scrolling when pull-to-refresh is enabled
self.__publish(self.__scrollLeft, -self.__refreshHeight, self.__zoomLevel, true);
if (this.__refreshIsHorizontal) {
self.__publish(-self.__refreshSize, self.__scrollTop, self.__zoomLevel, true);
} else {
self.__publish(self.__scrollLeft, -self.__refreshSize, self.__zoomLevel, true);
}

if (self.__refreshStart) {
self.__refreshStart();
Expand Down
83 changes: 82 additions & 1 deletion test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ asyncTest("Scroll Animated", 4, function() {
equal(values.top, 400);
equal(values.zoom, 1);
start();
}, 400);
}, 500);
Copy link
Author

Choose a reason for hiding this comment

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

I was having problems with tests not passing due to the too short delay ;-)


});

Expand Down Expand Up @@ -850,3 +850,84 @@ asyncTest("Pull-to-Refresh", function() {

});


asyncTest("Horizontal Pull-to-Refresh", function() {

var scroller = new Scroller(null, {
scrollingY: false
});

var phase = 0;

// Activate => Start => Done => Deactivate

var activateFunc = function() {
equal(phase, 0);
phase = 1;
};

var deactivateFunc = function() {
equal(phase, 3);
phase = 4;
start();
};

var startFunc = function() {
equal(phase, 1);
phase = 2;

setTimeout(function() {
equal(phase, 2);
phase = 3;

scroller.finishPullToRefresh();
}, 1000);
};

scroller.activatePullToRefresh(true, 50, activateFunc, deactivateFunc, startFunc);

var now = 0;

scroller.doTouchStart([{
pageY: 250,
pageX: 300
}], now+=20);

scroller.doTouchMove([{
pageY: 250,
pageX: 310
}], now+=20);

scroller.doTouchMove([{
pageY: 250,
pageX: 330
}], now+=20);

scroller.doTouchMove([{
pageY: 250,
pageX: 350
}], now+=100);

scroller.doTouchMove([{
pageY: 250,
pageX: 370
}], now+=100);

scroller.doTouchMove([{
pageY: 250,
pageX: 390
}], now+=100);

scroller.doTouchMove([{
pageY: 250,
pageX: 410
}], now+=100);

scroller.doTouchMove([{
pageY: 250,
pageX: 430
}], now+=100);

scroller.doTouchEnd(now);

});