mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-15 09:57:04 +05:30
fix(android): avoid two unnecessary API calls in search
This commit is contained in:
parent
fdb79d4a6d
commit
1d3d4f7455
2 changed files with 16 additions and 10 deletions
|
@ -14,6 +14,7 @@ import dagger.assisted.AssistedFactory
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
import dev.msfjarvis.claw.android.paging.LobstersPagingSource.Companion.PAGE_SIZE
|
import dev.msfjarvis.claw.android.paging.LobstersPagingSource.Companion.PAGE_SIZE
|
||||||
import dev.msfjarvis.claw.android.paging.LobstersPagingSource.Companion.STARTING_PAGE_INDEX
|
import dev.msfjarvis.claw.android.paging.LobstersPagingSource.Companion.STARTING_PAGE_INDEX
|
||||||
|
import dev.msfjarvis.claw.api.LobstersSearchApi
|
||||||
import dev.msfjarvis.claw.core.injection.IODispatcher
|
import dev.msfjarvis.claw.core.injection.IODispatcher
|
||||||
import dev.msfjarvis.claw.model.LobstersPost
|
import dev.msfjarvis.claw.model.LobstersPost
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
@ -21,15 +22,16 @@ import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Duplicate of [LobstersPagingSource] with an additional optimization to not continue loading
|
* Specialized variant of [LobstersPagingSource] to prevent hammering the Lobsters search endpoint
|
||||||
* further pages if nothing is found in the current one. This is required to prevent the app from
|
* with unnecessary requests. Rather than abstract out the API call this paging source takes in the
|
||||||
* hammering the search endpoint with up to 70 consecutive requests for the search results of a
|
* relevant parameters to short-circuit when there is no query specified in order to avoid calling
|
||||||
* blank query.
|
* the API at all.
|
||||||
*/
|
*/
|
||||||
class SearchPagingSource
|
class SearchPagingSource
|
||||||
@AssistedInject
|
@AssistedInject
|
||||||
constructor(
|
constructor(
|
||||||
@Assisted private val remoteFetcher: RemoteFetcher<LobstersPost>,
|
private val searchApi: LobstersSearchApi,
|
||||||
|
@Assisted private val queryProvider: () -> String,
|
||||||
@IODispatcher private val ioDispatcher: CoroutineDispatcher,
|
@IODispatcher private val ioDispatcher: CoroutineDispatcher,
|
||||||
) : PagingSource<Int, LobstersPost>() {
|
) : PagingSource<Int, LobstersPost>() {
|
||||||
override fun getRefreshKey(state: PagingState<Int, LobstersPost>): Int? {
|
override fun getRefreshKey(state: PagingState<Int, LobstersPost>): Int? {
|
||||||
|
@ -39,8 +41,14 @@ constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, LobstersPost> {
|
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, LobstersPost> {
|
||||||
|
val searchQuery = queryProvider()
|
||||||
|
// If there is no query, we don't need to call the API at all.
|
||||||
|
if (searchQuery.isEmpty()) {
|
||||||
|
return LoadResult.Page(itemsBefore = 0, data = emptyList(), prevKey = null, nextKey = null)
|
||||||
|
}
|
||||||
val page = params.key ?: STARTING_PAGE_INDEX
|
val page = params.key ?: STARTING_PAGE_INDEX
|
||||||
return when (val result = withContext(ioDispatcher) { remoteFetcher.getItemsAtPage(page) }) {
|
val result = withContext(ioDispatcher) { searchApi.searchPosts(searchQuery, page) }
|
||||||
|
return when (result) {
|
||||||
is ApiResult.Success -> {
|
is ApiResult.Success -> {
|
||||||
// Optimization: prevent fetching more pages if we found no items, this means
|
// Optimization: prevent fetching more pages if we found no items, this means
|
||||||
// there is no active search query.
|
// there is no active search query.
|
||||||
|
@ -62,6 +70,6 @@ constructor(
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory {
|
interface Factory {
|
||||||
fun create(remoteFetcher: RemoteFetcher<LobstersPost>): SearchPagingSource
|
fun create(queryProvider: () -> String): SearchPagingSource
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@ import dev.msfjarvis.claw.android.paging.LobstersPagingSource.Companion.PAGE_SIZ
|
||||||
import dev.msfjarvis.claw.android.paging.LobstersPagingSource.Companion.STARTING_PAGE_INDEX
|
import dev.msfjarvis.claw.android.paging.LobstersPagingSource.Companion.STARTING_PAGE_INDEX
|
||||||
import dev.msfjarvis.claw.android.paging.SearchPagingSource
|
import dev.msfjarvis.claw.android.paging.SearchPagingSource
|
||||||
import dev.msfjarvis.claw.api.LobstersApi
|
import dev.msfjarvis.claw.api.LobstersApi
|
||||||
import dev.msfjarvis.claw.api.LobstersSearchApi
|
|
||||||
import dev.msfjarvis.claw.core.injection.IODispatcher
|
import dev.msfjarvis.claw.core.injection.IODispatcher
|
||||||
import dev.msfjarvis.claw.core.injection.MainDispatcher
|
import dev.msfjarvis.claw.core.injection.MainDispatcher
|
||||||
import dev.msfjarvis.claw.database.local.SavedPost
|
import dev.msfjarvis.claw.database.local.SavedPost
|
||||||
|
@ -57,7 +56,6 @@ class ClawViewModel
|
||||||
@Inject
|
@Inject
|
||||||
constructor(
|
constructor(
|
||||||
private val api: LobstersApi,
|
private val api: LobstersApi,
|
||||||
private val searchApi: LobstersSearchApi,
|
|
||||||
private val commentsRepository: CommentsRepository,
|
private val commentsRepository: CommentsRepository,
|
||||||
private val readPostsRepository: ReadPostsRepository,
|
private val readPostsRepository: ReadPostsRepository,
|
||||||
private val savedPostsRepository: SavedPostsRepository,
|
private val savedPostsRepository: SavedPostsRepository,
|
||||||
|
@ -79,7 +77,7 @@ constructor(
|
||||||
}
|
}
|
||||||
private val searchResultsPager =
|
private val searchResultsPager =
|
||||||
Pager(PagingConfig(pageSize = PAGE_SIZE), initialKey = STARTING_PAGE_INDEX) {
|
Pager(PagingConfig(pageSize = PAGE_SIZE), initialKey = STARTING_PAGE_INDEX) {
|
||||||
searchPagingSourceFactory.create { searchApi.searchPosts(searchQuery, it) }
|
searchPagingSourceFactory.create { searchQuery }
|
||||||
}
|
}
|
||||||
|
|
||||||
val hottestPosts
|
val hottestPosts
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue