fix(lib): Fix for pagination on Android. (#130)

fixes #47 
fixes #118
This commit is contained in:
Kevin Brown 2020-01-20 19:52:42 +11:00 committed by Bartol Karuza
parent 03bc028efe
commit 33dfb99d35
1 changed files with 16 additions and 15 deletions

View File

@ -280,10 +280,6 @@ public class CameraRollModule extends ReactContextBaseJavaModule {
protected void doInBackgroundGuarded(Void... params) { protected void doInBackgroundGuarded(Void... params) {
StringBuilder selection = new StringBuilder("1"); StringBuilder selection = new StringBuilder("1");
List<String> selectionArgs = new ArrayList<>(); List<String> selectionArgs = new ArrayList<>();
if (!TextUtils.isEmpty(mAfter)) {
selection.append(" AND " + SELECTION_DATE_TAKEN);
selectionArgs.add(mAfter);
}
if (!TextUtils.isEmpty(mGroupName)) { if (!TextUtils.isEmpty(mGroupName)) {
selection.append(" AND " + SELECTION_BUCKET); selection.append(" AND " + SELECTION_BUCKET);
selectionArgs.add(mGroupName); selectionArgs.add(mGroupName);
@ -317,25 +313,30 @@ public class CameraRollModule extends ReactContextBaseJavaModule {
} }
selection.replace(selection.length() - 1, selection.length(), ")"); selection.replace(selection.length() - 1, selection.length(), ")");
} }
WritableMap response = new WritableNativeMap(); WritableMap response = new WritableNativeMap();
ContentResolver resolver = mContext.getContentResolver(); ContentResolver resolver = mContext.getContentResolver();
// using LIMIT in the sortOrder is not explicitly supported by the SDK (which does not support
// setting a limit at all), but it works because this specific ContentProvider is backed by
// an SQLite DB and forwards parameters to it without doing any parsing / validation.
try { try {
// set LIMIT to first + 1 so that we know how to populate page_info
String limit = "limit=" + (mFirst + 1);
if (!TextUtils.isEmpty(mAfter)) {
limit = "limit=" + mAfter + "," + (mFirst + 1);
}
Cursor media = resolver.query( Cursor media = resolver.query(
MediaStore.Files.getContentUri("external"), MediaStore.Files.getContentUri("external").buildUpon().encodedQuery(limit).build(),
PROJECTION, PROJECTION,
selection.toString(), selection.toString(),
selectionArgs.toArray(new String[selectionArgs.size()]), selectionArgs.toArray(new String[selectionArgs.size()]),
Images.Media.DATE_ADDED + " DESC, " + Images.Media.DATE_MODIFIED + " DESC LIMIT " + Images.Media.DATE_ADDED + " DESC, " + Images.Media.DATE_MODIFIED + " DESC");
(mFirst + 1)); // set LIMIT to first + 1 so that we know how to populate page_info
if (media == null) { if (media == null) {
mPromise.reject(ERROR_UNABLE_TO_LOAD, "Could not get media"); mPromise.reject(ERROR_UNABLE_TO_LOAD, "Could not get media");
} else { } else {
try { try {
putEdges(resolver, media, response, mFirst); putEdges(resolver, media, response, mFirst);
putPageInfo(media, response, mFirst); putPageInfo(media, response, mFirst, !TextUtils.isEmpty(mAfter) ? Integer.parseInt(mAfter) : 0);
} finally { } finally {
media.close(); media.close();
mPromise.resolve(response); mPromise.resolve(response);
@ -350,14 +351,14 @@ public class CameraRollModule extends ReactContextBaseJavaModule {
} }
} }
private static void putPageInfo(Cursor media, WritableMap response, int limit) { private static void putPageInfo(Cursor media, WritableMap response, int limit, int offset) {
WritableMap pageInfo = new WritableNativeMap(); WritableMap pageInfo = new WritableNativeMap();
pageInfo.putBoolean("has_next_page", limit < media.getCount()); pageInfo.putBoolean("has_next_page", limit < media.getCount());
if (limit < media.getCount()) { if (limit < media.getCount()) {
media.moveToPosition(limit - 1);
pageInfo.putString( pageInfo.putString(
"end_cursor", "end_cursor",
media.getString(media.getColumnIndex(Images.Media.DATE_TAKEN))); Integer.toString(offset + limit)
);
} }
response.putMap("page_info", pageInfo); response.putMap("page_info", pageInfo);
} }