mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-18 00:57:02 +05:30
src: add isCacheReady to let users know cache status
Signed-off-by: Aditya Wasan <adityawasan55@gmail.com>
This commit is contained in:
parent
23ec6ea9b1
commit
9ce33bba75
3 changed files with 39 additions and 17 deletions
|
@ -1,18 +1,21 @@
|
|||
package dev.msfjarvis.lobsters.data.remote
|
||||
|
||||
import androidx.paging.PagingSource
|
||||
import dev.msfjarvis.lobsters.data.api.LobstersApi
|
||||
import dev.msfjarvis.lobsters.data.local.LobstersPost
|
||||
import dev.msfjarvis.lobsters.data.repo.LobstersRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
class LobstersPagingSource @Inject constructor(
|
||||
private val lobstersApi: LobstersApi,
|
||||
private val lobstersRepository: LobstersRepository,
|
||||
) : PagingSource<Int, LobstersPost>() {
|
||||
|
||||
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, LobstersPost> {
|
||||
return try {
|
||||
val page = params.key ?: 1
|
||||
val posts = lobstersApi.getHottestPosts(page)
|
||||
// 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.fetchPosts(page)
|
||||
|
||||
LoadResult.Page(
|
||||
data = posts,
|
||||
|
|
|
@ -1,26 +1,22 @@
|
|||
package dev.msfjarvis.lobsters.data.repo
|
||||
|
||||
import dev.msfjarvis.lobsters.data.api.LobstersApi
|
||||
import dev.msfjarvis.lobsters.data.local.LobstersPost
|
||||
import dev.msfjarvis.lobsters.database.LobstersDatabase
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
class LobstersRepository @Inject constructor(private val lobstersDatabase: LobstersDatabase) {
|
||||
class LobstersRepository @Inject constructor(
|
||||
private val lobstersApi: LobstersApi,
|
||||
private val lobstersDatabase: LobstersDatabase,
|
||||
) {
|
||||
|
||||
private val savedPostsCache: MutableMap<String, LobstersPost> = mutableMapOf()
|
||||
private val coroutineScope = CoroutineScope(Job() + Dispatchers.IO)
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
getAllPosts().forEach {
|
||||
savedPostsCache.putIfAbsent(it.short_id, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
private val _isCacheReady = MutableStateFlow(false)
|
||||
val isCacheReady = _isCacheReady.asStateFlow()
|
||||
|
||||
fun isPostSaved(postId: String): Boolean {
|
||||
return savedPostsCache.containsKey(postId)
|
||||
|
@ -34,6 +30,20 @@ class LobstersRepository @Inject constructor(private val lobstersDatabase: Lobst
|
|||
return savedPostsCache.values.toList()
|
||||
}
|
||||
|
||||
suspend fun fetchPosts(page: Int): List<LobstersPost> = withContext(Dispatchers.IO) {
|
||||
return@withContext lobstersApi.getHottestPosts(page)
|
||||
}
|
||||
|
||||
suspend fun updateCache() {
|
||||
if (_isCacheReady.value) return
|
||||
val posts = getAllPosts()
|
||||
|
||||
posts.forEach {
|
||||
savedPostsCache.putIfAbsent(it.short_id, it)
|
||||
}
|
||||
_isCacheReady.value = true
|
||||
}
|
||||
|
||||
private suspend fun getPost(postId: String): LobstersPost? = withContext(Dispatchers.IO) {
|
||||
return@withContext lobstersDatabase.postQueries.selectPost(postId).executeAsOneOrNull()
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import dev.msfjarvis.lobsters.data.remote.LobstersPagingSource
|
|||
import dev.msfjarvis.lobsters.data.repo.LobstersRepository
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -19,12 +20,20 @@ class LobstersViewModel @Inject constructor(
|
|||
private val lobstersRepository: LobstersRepository,
|
||||
private val pagingSource: LobstersPagingSource,
|
||||
) : ViewModel() {
|
||||
private val _savedPosts = MutableStateFlow(lobstersRepository.getAllPostsFromCache())
|
||||
private val _savedPosts = MutableStateFlow<List<LobstersPost>>(emptyList())
|
||||
val savedPosts = _savedPosts.asStateFlow()
|
||||
val posts = Pager(PagingConfig(25)) {
|
||||
pagingSource
|
||||
}.flow.cachedIn(viewModelScope)
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
lobstersRepository.isCacheReady.onEach {
|
||||
_savedPosts.value = lobstersRepository.getAllPostsFromCache()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun toggleSave(post: LobstersPost) {
|
||||
viewModelScope.launch {
|
||||
val isSaved = lobstersRepository.isPostSaved(post.short_id)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue