mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 22:37:56 +01:00 
			
		
		
		
	Use custom QueryPagingSource (#7321)
* Use custom QueryPagingSource - Adds placeholder to make the list jump around less - Fixes issue where SQLDelight QueryPagingSource would throw IndexOutOfBounds * Review Changes
This commit is contained in:
		| @@ -2,8 +2,6 @@ package eu.kanade.data | ||||
|  | ||||
| import androidx.paging.PagingSource | ||||
| import com.squareup.sqldelight.Query | ||||
| import com.squareup.sqldelight.Transacter | ||||
| import com.squareup.sqldelight.android.paging3.QueryPagingSource | ||||
| import com.squareup.sqldelight.db.SqlDriver | ||||
| import com.squareup.sqldelight.runtime.coroutines.asFlow | ||||
| import com.squareup.sqldelight.runtime.coroutines.mapToList | ||||
| @@ -63,13 +61,11 @@ class AndroidDatabaseHandler( | ||||
|  | ||||
|     override fun <T : Any> subscribeToPagingSource( | ||||
|         countQuery: Database.() -> Query<Long>, | ||||
|         transacter: Database.() -> Transacter, | ||||
|         queryProvider: Database.(Long, Long) -> Query<T>, | ||||
|     ): PagingSource<Long, T> { | ||||
|         return QueryPagingSource( | ||||
|             countQuery = countQuery(db), | ||||
|             transacter = transacter(db), | ||||
|             dispatcher = queryDispatcher, | ||||
|             handler = this, | ||||
|             countQuery = countQuery, | ||||
|             queryProvider = { limit, offset -> | ||||
|                 queryProvider.invoke(db, limit, offset) | ||||
|             }, | ||||
|   | ||||
| @@ -2,7 +2,6 @@ package eu.kanade.data | ||||
|  | ||||
| import androidx.paging.PagingSource | ||||
| import com.squareup.sqldelight.Query | ||||
| import com.squareup.sqldelight.Transacter | ||||
| import eu.kanade.tachiyomi.Database | ||||
| import kotlinx.coroutines.flow.Flow | ||||
|  | ||||
| @@ -33,7 +32,6 @@ interface DatabaseHandler { | ||||
|  | ||||
|     fun <T : Any> subscribeToPagingSource( | ||||
|         countQuery: Database.() -> Query<Long>, | ||||
|         transacter: Database.() -> Transacter, | ||||
|         queryProvider: Database.(Long, Long) -> Query<T>, | ||||
|     ): PagingSource<Long, T> | ||||
| } | ||||
|   | ||||
							
								
								
									
										72
									
								
								app/src/main/java/eu/kanade/data/QueryPagingSource.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								app/src/main/java/eu/kanade/data/QueryPagingSource.kt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| package eu.kanade.data | ||||
|  | ||||
| import androidx.paging.PagingSource | ||||
| import androidx.paging.PagingState | ||||
| import com.squareup.sqldelight.Query | ||||
| import eu.kanade.tachiyomi.Database | ||||
| import kotlin.properties.Delegates | ||||
|  | ||||
| class QueryPagingSource<RowType : Any>( | ||||
|     val handler: DatabaseHandler, | ||||
|     val countQuery: Database.() -> Query<Long>, | ||||
|     val queryProvider: Database.(Long, Long) -> Query<RowType>, | ||||
| ) : PagingSource<Long, RowType>(), Query.Listener { | ||||
|  | ||||
|     override val jumpingSupported: Boolean = true | ||||
|  | ||||
|     private var currentQuery: Query<RowType>? by Delegates.observable(null) { _, old, new -> | ||||
|         old?.removeListener(this) | ||||
|         new?.addListener(this) | ||||
|     } | ||||
|  | ||||
|     init { | ||||
|         registerInvalidatedCallback { | ||||
|             currentQuery?.removeListener(this) | ||||
|             currentQuery = null | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     override suspend fun load(params: LoadParams<Long>): LoadResult<Long, RowType> { | ||||
|         try { | ||||
|             val key = params.key ?: 0L | ||||
|             val loadSize = params.loadSize | ||||
|             val count = handler.awaitOne { countQuery() } | ||||
|  | ||||
|             val (offset, limit) = when (params) { | ||||
|                 is LoadParams.Prepend -> key - loadSize to loadSize.toLong() | ||||
|                 else -> key to loadSize.toLong() | ||||
|             } | ||||
|  | ||||
|             val data = handler.awaitList { | ||||
|                 queryProvider(limit, offset) | ||||
|                     .also { currentQuery = it } | ||||
|             } | ||||
|  | ||||
|             val (prevKey, nextKey) = when (params) { | ||||
|                 is LoadParams.Append -> { offset - loadSize to offset + loadSize } | ||||
|                 else -> { offset to offset + loadSize } | ||||
|             } | ||||
|  | ||||
|             return LoadResult.Page( | ||||
|                 data = data, | ||||
|                 prevKey = if (offset <= 0L || prevKey < 0L) null else prevKey, | ||||
|                 nextKey = if (offset + loadSize >= count) null else nextKey, | ||||
|                 itemsBefore = maxOf(0L, offset).toInt(), | ||||
|                 itemsAfter = maxOf(0L, count - (offset + loadSize)).toInt(), | ||||
|             ) | ||||
|         } catch (e: Exception) { | ||||
|             return LoadResult.Error(throwable = e) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     override fun getRefreshKey(state: PagingState<Long, RowType>): Long? { | ||||
|         return state.anchorPosition?.let { anchorPosition -> | ||||
|             val anchorPage = state.closestPageToPosition(anchorPosition) | ||||
|             anchorPage?.prevKey ?: anchorPage?.nextKey | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     override fun queryResultsChanged() { | ||||
|         invalidate() | ||||
|     } | ||||
| } | ||||
| @@ -19,7 +19,6 @@ class HistoryRepositoryImpl( | ||||
|     override fun getHistory(query: String): PagingSource<Long, HistoryWithRelations> { | ||||
|         return handler.subscribeToPagingSource( | ||||
|             countQuery = { historyViewQueries.countHistory(query) }, | ||||
|             transacter = { historyViewQueries }, | ||||
|             queryProvider = { limit, offset -> | ||||
|                 historyViewQueries.history(query, limit, offset, historyWithRelationsMapper) | ||||
|             }, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user