android: integrate database

This commit is contained in:
Harsh Shandilya 2021-09-27 21:37:59 +05:30
parent de93f32b96
commit 86e659a180
No known key found for this signature in database
GPG key ID: 366D7BBAD1031E80
6 changed files with 75 additions and 3 deletions

View file

@ -12,6 +12,7 @@ dependencies {
kapt(libs.dagger.hilt.compiler)
implementation(projects.api)
implementation(projects.common)
implementation(projects.database)
implementation(libs.accompanist.insets)
implementation(libs.accompanist.swiperefresh)
implementation(libs.accompanist.sysuicontroller)
@ -21,6 +22,7 @@ dependencies {
implementation(libs.androidx.lifecycle.compose)
implementation(libs.androidx.paging.compose)
implementation(libs.dagger.hilt.android)
implementation(libs.sqldelight.extensions.coroutines)
implementation(libs.retrofit.moshiConverter)
}

View file

@ -15,6 +15,7 @@ import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
@ -35,6 +36,7 @@ import com.google.accompanist.systemuicontroller.rememberSystemUiController
import dev.msfjarvis.claw.android.viewmodel.ClawViewModel
import dev.msfjarvis.claw.common.theme.LobstersTheme
import dev.msfjarvis.claw.common.urllauncher.UrlLauncher
import kotlinx.coroutines.launch
private const val ScrollDelta = 50
@ -47,6 +49,7 @@ fun LobstersApp(
val systemUiController = rememberSystemUiController()
val scaffoldState = rememberScaffoldState()
val listState = rememberLazyListState()
val coroutineScope = rememberCoroutineScope()
var isFabVisible by remember { mutableStateOf(true) }
val nestedScrollConnection = remember {
object : NestedScrollConnection {
@ -97,6 +100,8 @@ fun LobstersApp(
items = items,
launchUrl = urlLauncher::launch,
listState = listState,
isSaved = viewModel::isPostSaved,
toggleSave = { coroutineScope.launch { viewModel.toggleSave(it) } },
modifier = Modifier.padding(top = 16.dp).nestedScroll(nestedScrollConnection),
)
}

View file

@ -4,6 +4,11 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.paging.compose.LazyPagingItems
@ -11,26 +16,34 @@ import androidx.paging.compose.items
import dev.msfjarvis.claw.android.ext.toDbModel
import dev.msfjarvis.claw.api.model.LobstersPost
import dev.msfjarvis.claw.common.posts.LobstersCard
import dev.msfjarvis.claw.database.local.SavedPost
import kotlinx.coroutines.launch
@Composable
fun NetworkPosts(
items: LazyPagingItems<LobstersPost>,
listState: LazyListState,
launchUrl: (String) -> Unit,
isSaved: suspend (SavedPost) -> Boolean,
toggleSave: (SavedPost) -> Unit,
modifier: Modifier = Modifier,
) {
val coroutineScope = rememberCoroutineScope()
LazyColumn(
state = listState,
modifier = Modifier.then(modifier),
) {
items(items) { item ->
if (item != null) {
val dbModel = item.toDbModel()
var saved by remember(dbModel) { mutableStateOf(false) }
coroutineScope.launch { saved = isSaved(dbModel) }
LobstersCard(
post = item.toDbModel(),
isSaved = false,
post = dbModel,
isSaved = saved,
viewPost = { launchUrl(item.url.ifEmpty { item.commentsUrl }) },
viewComments = { launchUrl(item.commentsUrl) },
toggleSave = {},
toggleSave = { toggleSave(dbModel) },
modifier = Modifier.padding(bottom = 16.dp, start = 16.dp, end = 16.dp),
)
}

View file

@ -6,15 +6,24 @@ import androidx.paging.PagingConfig
import dagger.hilt.android.lifecycle.HiltViewModel
import dev.msfjarvis.claw.android.paging.LobstersPagingSource
import dev.msfjarvis.claw.api.LobstersApi
import dev.msfjarvis.claw.database.local.SavedPost
import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.last
import kotlinx.coroutines.flow.mapLatest
@OptIn(ExperimentalCoroutinesApi::class)
@HiltViewModel
class ClawViewModel
@Inject
constructor(
api: LobstersApi,
private val repository: SavedPostsRepository,
) : ViewModel() {
var lastPagingSource: LobstersPagingSource? = null
private val savedPosts = flow { repository.savedPosts.collect { emit(it) } }
private val pager =
Pager(PagingConfig(20)) {
LobstersPagingSource(api::getHottestPosts).also { lastPagingSource = it }
@ -23,6 +32,20 @@ constructor(
val pagerFlow
get() = pager.flow
suspend fun isPostSaved(post: SavedPost): Boolean {
return savedPosts.mapLatest { posts -> post in posts }.last()
}
suspend fun toggleSave(post: SavedPost) {
val saved = isPostSaved(post)
println("saved=$saved")
if (saved) {
repository.removePost(post)
} else {
repository.savePost(post)
}
}
fun reloadPosts() {
lastPagingSource?.invalidate()
}

View file

@ -0,0 +1,28 @@
package dev.msfjarvis.claw.android.viewmodel
import com.squareup.sqldelight.runtime.coroutines.asFlow
import com.squareup.sqldelight.runtime.coroutines.mapToList
import dev.msfjarvis.claw.database.LobstersDatabase
import dev.msfjarvis.claw.database.local.SavedPost
import javax.inject.Inject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
class SavedPostsRepository
@Inject
constructor(
database: LobstersDatabase,
) {
private val savedPostQueries = database.savedPostQueries
val savedPosts = savedPostQueries.selectAllPosts().asFlow().mapToList()
suspend fun savePost(post: SavedPost) {
println("Saving post: ${post.shortId}")
withContext(Dispatchers.IO) { savedPostQueries.insertOrReplacePost(post) }
}
suspend fun removePost(post: SavedPost) {
println("Removing post: ${post.shortId}")
withContext(Dispatchers.IO) { savedPostQueries.deletePost(post.shortId) }
}
}