machinery for fetching next page of inifinite scroll before it really

needed, and use in our infinite scrolls
This commit is contained in:
howard-stearns 2018-07-18 13:00:03 -07:00
parent db212a0c99
commit 0a47672d64
6 changed files with 37 additions and 30 deletions

View file

@ -53,7 +53,7 @@ Column {
'protocol=' + encodeURIComponent(Window.protocolSignature())
];
endpoint: '/api/v1/user_stories?' + options.join('&');
itemsPerPage: 3;
itemsPerPage: 4;
processPage: function (data) {
return data.user_stories.map(makeModelData);
};
@ -106,7 +106,6 @@ Column {
highlightMoveDuration: -1;
highlightMoveVelocity: -1;
currentIndex: -1;
onAtXEndChanged: { if (scroll.atXEnd && !scroll.atXBeginning) { suggestions.getNextPage(); } }
spacing: 12;
width: parent.width;

View file

@ -61,7 +61,7 @@ Rectangle {
'username';
}
sortAscending: connectionsTable.sortIndicatorOrder === Qt.AscendingOrder;
itemsPerPage: 9;
itemsPerPage: 10;
listView: connectionsTable;
processPage: function (data) {
return data.users.map(function (user) {
@ -786,14 +786,6 @@ Rectangle {
}
model: connectionsUserModel;
Connections {
target: connectionsTable.flickableItem;
onAtYEndChanged: {
if (connectionsTable.flickableItem.atYEnd && !connectionsTable.flickableItem.atYBeginning) {
connectionsUserModel.getNextPage();
}
}
}
// This Rectangle refers to each Row in the connectionsTable.
rowDelegate: Rectangle {

View file

@ -398,7 +398,7 @@ Item {
http: root.http;
listModelName: root.listModelName;
endpoint: "/api/v1/users?filter=connections";
itemsPerPage: 8;
itemsPerPage: 9;
listView: connectionsList;
processPage: function (data) {
return data.users;
@ -520,7 +520,6 @@ Item {
visible: !connectionsLoading.visible;
clip: true;
model: connectionsModel;
onAtYEndChanged: if (connectionsList.atYEnd && !connectionsList.atYBeginning) { connectionsModel.getNextPage(); }
snapMode: ListView.SnapToItem;
// Anchors
anchors.fill: parent;

View file

@ -551,8 +551,9 @@ Rectangle {
HifiModels.PSFListModel {
id: purchasesModel;
itemsPerPage: 6;
itemsPerPage: 7;
listModelName: 'purchases';
listView: purchasesContentsList;
getPage: function () {
console.debug('getPage', purchasesModel.listModelName, root.isShowingMyItems, filterBar.primaryFilter_filterName, purchasesModel.currentPageToRetrieve, purchasesModel.itemsPerPage);
Commerce.inventory(
@ -781,14 +782,6 @@ Rectangle {
}
}
}
onAtYEndChanged: {
if (purchasesContentsList.atYEnd && !purchasesContentsList.atYBeginning) {
console.log("User scrolled to the bottom of 'Purchases'.");
purchasesModel.getNextPage();
}
}
}
Rectangle {

View file

@ -212,6 +212,7 @@ Item {
HifiModels.PSFListModel {
id: transactionHistoryModel;
listModelName: "transaction history"; // For debugging. Alternatively, we could specify endpoint for that purpose, even though it's not used directly.
listView: transactionHistory;
itemsPerPage: 6;
getPage: function () {
console.debug('getPage', transactionHistoryModel.listModelName, transactionHistoryModel.currentPageToRetrieve);
@ -346,12 +347,6 @@ Item {
}
}
}
onAtYEndChanged: {
if (transactionHistory.atYEnd && !transactionHistory.atYBeginning) {
console.log("User scrolled to the bottom of 'Recent Activity'.");
transactionHistoryModel.getNextPage();
}
}
}
Item {

View file

@ -33,7 +33,6 @@ ListModel {
// QML fires the following changed handlers even when first instantiating the Item. So we need a guard against firing them too early.
property bool initialized: false;
Component.onCompleted: initialized = true;
onEndpointChanged: if (initialized) { getFirstPage('delayClear'); }
onSortKeyChanged: if (initialized) { getFirstPage('delayClear'); }
onSearchFilterChanged: if (initialized) { getFirstPage('delayClear'); }
@ -60,7 +59,37 @@ ListModel {
// Override to return one property of data, and/or to transform the elements. Must return an array of model elements.
property var processPage: function (data) { return data; }
property var listView; // Optional. For debugging.
property var listView; // Optional. For debugging, or for having the scroll handler automatically call getNextPage.
property var flickable: listView && (listView.flickableItem || listView);
// 2: get two pages before you need it (i.e. one full page before you reach the end).
// 1: equivalent to paging when reaching end (and not before).
// 0: don't getNextPage on scroll at all here. The application code will do it.
property real pageAhead: 2.0;
function needsEarlyYFetch() {
return flickable
&& !flickable.atYBeginning
&& (flickable.contentY - flickable.originY) >= (flickable.contentHeight - (pageAhead * flickable.height));
}
function needsEarlyXFetch() {
return flickable
&& !flickable.atXBeginning
&& (flickable.contentX - flickable.originX) >= (flickable.contentWidth - (pageAhead * flickable.width));
}
function getNextPageIfHorizontalScroll() {
if (needsEarlyXFetch()) { getNextPage(); }
}
function getNextPageIfVerticalScroll() {
if (needsEarlyYFetch()) { getNextPage(); }
}
Component.onCompleted: {
initialized = true;
if (flickable && pageAhead > 0.0) {
// Pun: Scrollers are usually one direction or another, such that only one of the following will actually fire.
flickable.contentXChanged.connect(getNextPageIfHorizontalScroll);
flickable.contentYChanged.connect(getNextPageIfVerticalScroll);
}
}
property int totalPages: 0;
property int totalEntries: 0;
// Check consistency and call processPage.