Check for non-empty pages when falling back (#3603)

Requesting a non-existent notification ID will cause the fall-back requests to succeed but return empty lists which stops pagination.

Check for this, and in the worst case, fall back to returning the most recent notifications.
This commit is contained in:
Nik Clayton 2023-05-04 13:19:28 +02:00 committed by GitHub
parent 62b91664e9
commit 4da758c1f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -97,9 +97,10 @@ class NotificationsPagingSource @Inject constructor(
* - If there is no key, a page of the most recent notifications is returned * - If there is no key, a page of the most recent notifications is returned
* - If the notification exists, and is not filtered, a page of notifications is returned * - If the notification exists, and is not filtered, a page of notifications is returned
* - If the notification does not exist, or is filtered, the page of notifications immediately * - If the notification does not exist, or is filtered, the page of notifications immediately
* before is returned * before is returned (if non-empty)
* - If there is no page of notifications immediately before then the page immediately after * - If there is no page of notifications immediately before then the page immediately after
* is returned * is returned (if non-empty)
* - Finally, fall back to the most recent notifications
*/ */
private suspend fun getInitialPage(params: LoadParams<String>): Response<List<Notification>> = coroutineScope { private suspend fun getInitialPage(params: LoadParams<String>): Response<List<Notification>> = coroutineScope {
// If the key is null this is straightforward, just return the most recent notifications. // If the key is null this is straightforward, just return the most recent notifications.
@ -163,15 +164,25 @@ class NotificationsPagingSource @Inject constructor(
} }
// The user's last read notification was missing or is filtered. Use the page of // The user's last read notification was missing or is filtered. Use the page of
// notifications chronologically older than their desired notification. // notifications chronologically older than their desired notification. This page must
deferredNotificationPage.await().apply { // *not* be empty (as noted earlier, if it is, paging stops).
if (this.isSuccessful) return@coroutineScope this deferredNotificationPage.await().let { response ->
if (response.isSuccessful) {
if (!response.body().isNullOrEmpty()) return@coroutineScope response
}
} }
// There were no notifications older than the user's desired notification. Return the page // There were no notifications older than the user's desired notification. Return the page
// of notifications immediately newer than their desired notification. // of notifications immediately newer than their desired notification. This page must
// *not* be empty (as noted earlier, if it is, paging stops).
mastodonApi.notifications(minId = key, limit = params.loadSize, excludes = notificationFilter).let { response ->
if (response.isSuccessful) {
if (!response.body().isNullOrEmpty()) return@coroutineScope response
}
}
// Everything failed -- fallback to fetching the most recent notifications
return@coroutineScope mastodonApi.notifications( return@coroutineScope mastodonApi.notifications(
minId = key,
limit = params.loadSize, limit = params.loadSize,
excludes = notificationFilter excludes = notificationFilter
) )