src: remove cache and simplify db logic

Signed-off-by: Aditya Wasan <adityawasan55@gmail.com>
This commit is contained in:
Aditya Wasan 2021-01-24 23:19:07 +05:30 committed by Harsh Shandilya
parent 3bcdcbdac7
commit f9fcb089a1
No known key found for this signature in database
GPG key ID: 366D7BBAD1031E80
7 changed files with 60 additions and 23 deletions

View file

@ -14,9 +14,17 @@ class LobstersPagingSource @Inject constructor(
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, LobstersPost> { override suspend fun load(params: LoadParams<Int>): LoadResult<Int, LobstersPost> {
return try { return try {
val page = params.key ?: 1 val page = params.key ?: 1
val savedPosts = lobstersRepository.getCachedPosts()
val posts = lobstersApi.getHottestPosts(page).map { post -> val posts = lobstersApi.getHottestPosts(page).map { post ->
post.copy(is_saved = savedPosts.contains(post.short_id)) // We can replace these two lines below with a getOrInsertPost repository method.
val dbPost = lobstersRepository.getPost(post.short_id)
return@map if (dbPost == null) {
// If db does not contain the post, add it and return the original post
lobstersRepository.addPostToDB(post)
post
} else {
// Otherwise return the db post
dbPost
}
} }
LoadResult.Page( LoadResult.Page(

View file

@ -8,32 +8,33 @@ import javax.inject.Inject
class LobstersRepository @Inject constructor(private val lobstersDatabase: LobstersDatabase) { class LobstersRepository @Inject constructor(private val lobstersDatabase: LobstersDatabase) {
private var savedPostCache: MutableSet<String>? = null
fun isPostSaved(postId: String): Boolean { fun isPostSaved(postId: String): Boolean {
savedPostCache ?: return false // returns the post if it exists and its is_saved property is true
return requireNotNull(savedPostCache).contains(postId) val post = lobstersDatabase.postQueries.isPostSaved(postId).executeAsOneOrNull()
return post != null
}
suspend fun getPost(postId: String): LobstersPost? = withContext(Dispatchers.IO) {
return@withContext lobstersDatabase.postQueries.selectPost(postId).executeAsOneOrNull()
}
suspend fun getSavedPosts(): List<LobstersPost> = withContext(Dispatchers.IO) {
return@withContext lobstersDatabase.postQueries.selectSavedPosts().executeAsList()
}
suspend fun addPostToDB(post: LobstersPost) = withContext(Dispatchers.IO) {
lobstersDatabase.postQueries.insertOrReplacePost(post)
} }
suspend fun savePost(post: LobstersPost) = withContext(Dispatchers.IO) { suspend fun savePost(post: LobstersPost) = withContext(Dispatchers.IO) {
val isElementAdded = getCachedPosts().add(post.short_id) if (!isPostSaved(post.short_id)) {
if (isElementAdded) {
lobstersDatabase.postQueries.savePost(post.short_id) lobstersDatabase.postQueries.savePost(post.short_id)
} }
} }
suspend fun removeSavedPost(post: LobstersPost) = withContext(Dispatchers.IO) { suspend fun removeSavedPost(post: LobstersPost) = withContext(Dispatchers.IO) {
val isElementRemoved = getCachedPosts().remove(post.short_id) if (isPostSaved(post.short_id)) {
if (isElementRemoved) {
lobstersDatabase.postQueries.removeSavedPost(post.short_id) lobstersDatabase.postQueries.removeSavedPost(post.short_id)
} }
} }
suspend fun getCachedPosts(): MutableSet<String> = withContext(Dispatchers.IO) {
if (savedPostCache != null) return@withContext requireNotNull(savedPostCache)
val dbPosts = lobstersDatabase.postQueries.selectSavedPosts().executeAsList()
savedPostCache = dbPosts.filter { it.is_saved ?: false }.map { it.short_id }.toMutableSet()
return@withContext requireNotNull(savedPostCache)
}
} }

View file

@ -12,17 +12,20 @@ import dev.msfjarvis.lobsters.data.local.LobstersPost
import dev.msfjarvis.lobsters.database.LobstersDatabase import dev.msfjarvis.lobsters.database.LobstersDatabase
import dev.msfjarvis.lobsters.model.SubmitterAdapter import dev.msfjarvis.lobsters.model.SubmitterAdapter
import dev.msfjarvis.lobsters.model.TagsAdapter import dev.msfjarvis.lobsters.model.TagsAdapter
import javax.inject.Singleton
@Module @Module
@InstallIn(SingletonComponent::class) @InstallIn(SingletonComponent::class)
object DatabaseModule { object DatabaseModule {
@Provides @Provides
@Singleton
fun providesSqlDriver(@ApplicationContext context: Context): SqlDriver { fun providesSqlDriver(@ApplicationContext context: Context): SqlDriver {
return AndroidSqliteDriver(LobstersDatabase.Schema, context) return AndroidSqliteDriver(LobstersDatabase.Schema, context)
} }
@Provides @Provides
@Singleton
fun providesLobstersDatabase(sqlDriver: SqlDriver): LobstersDatabase { fun providesLobstersDatabase(sqlDriver: SqlDriver): LobstersDatabase {
return LobstersDatabase(sqlDriver, LobstersPost.Adapter(SubmitterAdapter(), TagsAdapter())) return LobstersDatabase(sqlDriver, LobstersPost.Adapter(SubmitterAdapter(), TagsAdapter()))
} }

View file

@ -64,6 +64,8 @@ fun LobstersApp() {
val savedPosts by viewModel.savedPosts.collectAsState() val savedPosts by viewModel.savedPosts.collectAsState()
val hottestPostsListState = rememberLazyListState() val hottestPostsListState = rememberLazyListState()
viewModel.getSavedPosts()
Scaffold( Scaffold(
bottomBar = { bottomBar = {
LobstersBottomNav( LobstersBottomNav(

View file

@ -14,6 +14,10 @@ import androidx.compose.material.Surface
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.material.ripple.rememberRipple import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@ -65,6 +69,8 @@ fun LobstersItem(
onLongClick: () -> Unit, onLongClick: () -> Unit,
onSaveButtonClick: () -> Unit, onSaveButtonClick: () -> Unit,
) { ) {
var isSaved by remember { mutableStateOf(post.is_saved ?: false) }
Surface( Surface(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -121,11 +127,14 @@ fun LobstersItem(
}, },
) )
IconResource( IconResource(
resourceId = if (post.is_saved == true) R.drawable.ic_favorite_24px else R.drawable.ic_favorite_border_24px, resourceId = if (isSaved) R.drawable.ic_favorite_24px else R.drawable.ic_favorite_border_24px,
modifier = Modifier modifier = Modifier
.padding(8.dp) .padding(8.dp)
.clickable( .clickable(
onClick = onSaveButtonClick, onClick = {
onSaveButtonClick()
isSaved = isSaved.not()
},
indication = rememberRipple(), indication = rememberRipple(),
) )
.constrainAs(saveButton) { .constrainAs(saveButton) {

View file

@ -20,7 +20,7 @@ class LobstersViewModel @Inject constructor(
) : ViewModel() { ) : ViewModel() {
private val _savedPosts = MutableStateFlow<List<LobstersPost>>(emptyList()) private val _savedPosts = MutableStateFlow<List<LobstersPost>>(emptyList())
val savedPosts = _savedPosts.asStateFlow() val savedPosts = _savedPosts.asStateFlow()
val posts = Pager(PagingConfig(25)) { val posts = Pager(PagingConfig(5)) {
pagingSource pagingSource
}.flow }.flow
@ -31,17 +31,25 @@ class LobstersViewModel @Inject constructor(
} }
} }
fun getSavedPosts() {
viewModelScope.launch {
lobstersRepository.getSavedPosts().forEach {
_savedPosts.value = _savedPosts.value + it
}
}
}
private fun savePost(post: LobstersPost) { private fun savePost(post: LobstersPost) {
viewModelScope.launch { viewModelScope.launch {
lobstersRepository.savePost(post) lobstersRepository.savePost(post)
_savedPosts.value = _savedPosts.value + post _savedPosts.value = _savedPosts.value + post.copy(is_saved = true)
} }
} }
private fun removeSavedPost(post: LobstersPost) { private fun removeSavedPost(post: LobstersPost) {
viewModelScope.launch { viewModelScope.launch {
lobstersRepository.removeSavedPost(post) lobstersRepository.removeSavedPost(post)
_savedPosts.value = _savedPosts.value - post _savedPosts.value = _savedPosts.value - post.copy(is_saved = true)
} }
} }
} }

View file

@ -56,6 +56,12 @@ deleteAllPosts:
DELETE DELETE
FROM LobstersPost; FROM LobstersPost;
isPostSaved:
SELECT *
FROM LobstersPost
WHERE short_id = ?
AND is_saved = 1;
selectCount: selectCount:
SELECT COUNT(*) SELECT COUNT(*)
FROM LobstersPost; FROM LobstersPost;