From 4da758c1f72862b4e5c0db5f8cd8dc974cf872b0 Mon Sep 17 00:00:00 2001 From: Nik Clayton Date: Thu, 4 May 2023 13:19:28 +0200 Subject: [PATCH] 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. --- .../NotificationsPagingSource.kt | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsPagingSource.kt b/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsPagingSource.kt index 5f7eafb0..a4d322f7 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsPagingSource.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsPagingSource.kt @@ -97,9 +97,10 @@ class NotificationsPagingSource @Inject constructor( * - 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 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 - * is returned + * is returned (if non-empty) + * - Finally, fall back to the most recent notifications */ private suspend fun getInitialPage(params: LoadParams): Response> = coroutineScope { // 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 - // notifications chronologically older than their desired notification. - deferredNotificationPage.await().apply { - if (this.isSuccessful) return@coroutineScope this + // notifications chronologically older than their desired notification. This page must + // *not* be empty (as noted earlier, if it is, paging stops). + 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 - // 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( - minId = key, limit = params.loadSize, excludes = notificationFilter )