app: de-duplicate paging sources
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
@@ -1,33 +0,0 @@
|
||||
package dev.msfjarvis.lobsters.data.remote
|
||||
|
||||
import androidx.paging.PagingSource
|
||||
import androidx.paging.PagingState
|
||||
import dev.msfjarvis.lobsters.data.repo.LobstersRepository
|
||||
import dev.msfjarvis.lobsters.model.LobstersPost
|
||||
|
||||
class HottestPostsPagingSource(
|
||||
private val lobstersRepository: LobstersRepository,
|
||||
) : PagingSource<Int, LobstersPost>() {
|
||||
|
||||
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, LobstersPost> {
|
||||
return try {
|
||||
val page = params.key ?: 1
|
||||
// Update cache before fetching a list.
|
||||
// This is done to make sure that we can update the isSaved status of incoming posts.
|
||||
lobstersRepository.updateCache()
|
||||
val posts = lobstersRepository.fetchHottestPosts(page)
|
||||
|
||||
LoadResult.Page(
|
||||
data = posts,
|
||||
prevKey = if (page == 1) null else page - 1,
|
||||
nextKey = page.plus(1)
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
LoadResult.Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getRefreshKey(state: PagingState<Int, LobstersPost>): Int {
|
||||
return state.pages.size + 1
|
||||
}
|
||||
}
|
||||
+3
-7
@@ -2,20 +2,16 @@ package dev.msfjarvis.lobsters.data.remote
|
||||
|
||||
import androidx.paging.PagingSource
|
||||
import androidx.paging.PagingState
|
||||
import dev.msfjarvis.lobsters.data.repo.LobstersRepository
|
||||
import dev.msfjarvis.lobsters.model.LobstersPost
|
||||
|
||||
class NewestPostsPagingSource(
|
||||
private val lobstersRepository: LobstersRepository,
|
||||
class LobstersPagingSource(
|
||||
private val getMorePosts: suspend (Int) -> List<LobstersPost>,
|
||||
) : PagingSource<Int, LobstersPost>() {
|
||||
|
||||
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, LobstersPost> {
|
||||
return try {
|
||||
val page = params.key ?: 1
|
||||
// Update cache before fetching a list.
|
||||
// This is done to make sure that we can update the isSaved status of incoming posts.
|
||||
lobstersRepository.updateCache()
|
||||
val posts = lobstersRepository.fetchNewestPosts(page)
|
||||
val posts = getMorePosts(page)
|
||||
|
||||
LoadResult.Page(
|
||||
data = posts,
|
||||
@@ -8,9 +8,9 @@ import androidx.paging.cachedIn
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dev.msfjarvis.lobsters.data.local.SavedPost
|
||||
import dev.msfjarvis.lobsters.data.preferences.ClawPreferences
|
||||
import dev.msfjarvis.lobsters.data.remote.HottestPostsPagingSource
|
||||
import dev.msfjarvis.lobsters.data.remote.NewestPostsPagingSource
|
||||
import dev.msfjarvis.lobsters.data.remote.LobstersPagingSource
|
||||
import dev.msfjarvis.lobsters.data.repo.LobstersRepository
|
||||
import dev.msfjarvis.lobsters.model.LobstersPost
|
||||
import dev.msfjarvis.lobsters.model.LobstersPostDetails
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@@ -31,18 +31,18 @@ constructor(
|
||||
val savedPosts = _savedPosts.asStateFlow()
|
||||
val hottestPosts =
|
||||
Pager(PagingConfig(25)) {
|
||||
HottestPostsPagingSource(lobstersRepository).also { hottestPostsPagingSource = it }
|
||||
LobstersPagingSource(getPostFetcher(hottest = true)).also { hottestPostsPagingSource = it }
|
||||
}
|
||||
.flow
|
||||
.cachedIn(viewModelScope)
|
||||
val newestPosts =
|
||||
Pager(PagingConfig(25)) {
|
||||
NewestPostsPagingSource(lobstersRepository).also { newestPostsPagingSource = it }
|
||||
LobstersPagingSource(getPostFetcher(newest = true)).also { hottestPostsPagingSource = it }
|
||||
}
|
||||
.flow
|
||||
.cachedIn(viewModelScope)
|
||||
private var hottestPostsPagingSource: HottestPostsPagingSource? = null
|
||||
private var newestPostsPagingSource: NewestPostsPagingSource? = null
|
||||
private var hottestPostsPagingSource: LobstersPagingSource? = null
|
||||
private var newestPostsPagingSource: LobstersPagingSource? = null
|
||||
|
||||
init {
|
||||
lobstersRepository
|
||||
@@ -86,6 +86,26 @@ constructor(
|
||||
return lobstersRepository.isPostSaved(postId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a lambda that can be used to fetch the next round of hottest or newest posts. Having a
|
||||
* single paging source makes it significantly easier to make changes to the logic both here and
|
||||
* in [LobstersPagingSource].
|
||||
*/
|
||||
private fun getPostFetcher(
|
||||
newest: Boolean = false,
|
||||
hottest: Boolean = false,
|
||||
): suspend (page: Int) -> List<LobstersPost> {
|
||||
check(newest != hottest) { "Must pick one of newest or hottest" }
|
||||
return { page ->
|
||||
lobstersRepository.updateCache()
|
||||
if (newest) {
|
||||
lobstersRepository.fetchNewestPosts(page)
|
||||
} else {
|
||||
lobstersRepository.fetchHottestPosts(page)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun savePost(post: SavedPost) {
|
||||
viewModelScope.launch {
|
||||
lobstersRepository.addPost(post)
|
||||
|
||||
Reference in New Issue
Block a user