diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/viewmodel/ClawViewModel.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/viewmodel/ClawViewModel.kt index e96b5608..dc18da10 100644 --- a/android/src/main/kotlin/dev/msfjarvis/claw/android/viewmodel/ClawViewModel.kt +++ b/android/src/main/kotlin/dev/msfjarvis/claw/android/viewmodel/ClawViewModel.kt @@ -57,8 +57,6 @@ import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.shareIn import kotlinx.coroutines.launch -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withContext @ContributesViewModel @@ -84,7 +82,7 @@ constructor( pagingSourceFactory = { pagingSourceFactory.create(api::getHottestPosts) }, ) .flow - .map(::mapUIPost) + .map(::mapToUIPost) .cachedIn(viewModelScope) val newestPosts = @@ -94,7 +92,7 @@ constructor( pagingSourceFactory = { pagingSourceFactory.create(api::getNewestPosts) }, ) .flow - .map(::mapUIPost) + .map(::mapToUIPost) .cachedIn(viewModelScope) val searchResults = Pager( @@ -103,38 +101,33 @@ constructor( pagingSourceFactory = { searchPagingSourceFactory.create { searchQuery } }, ) .flow - .map(::mapUIPost) + .map(::mapToUIPost) - val savedPosts - get() = - savedPostsRepository.savedPosts - .map { it.map(UIPost.Companion::fromSavedPost) } - .shareIn(viewModelScope, started = SharingStarted.Lazily, Int.MAX_VALUE) + val savedPosts = + savedPostsRepository.savedPosts + .map { it.map(UIPost.Companion::fromSavedPost) } + .shareIn(viewModelScope, started = SharingStarted.Lazily, Int.MAX_VALUE) - val savedPostsByMonth - get() = savedPosts.map(::mapSavedPosts) + val savedPostsByMonth = savedPosts.map(::groupSavedPosts) var searchQuery by mutableStateOf("") - private val _savedPostsMutex = Mutex() + private var _readPosts = emptyList() private var _savedPosts = emptyList() init { - viewModelScope.launch { - savedPosts.collectLatest { - _savedPostsMutex.withLock { _savedPosts = it.map(UIPost::shortId) } - } - } + viewModelScope.launch { savedPosts.collectLatest { _savedPosts = it.map(UIPost::shortId) } } + viewModelScope.launch { readPostsRepository.readPosts.collectLatest { _readPosts = it } } } - private fun mapUIPost(pagingData: PagingData): PagingData { + private fun mapToUIPost(pagingData: PagingData): PagingData { return pagingData.map { post -> val uiPost = post.toUIPost() uiPost.copy(isSaved = isPostSaved(uiPost), isRead = isPostRead(uiPost)) } } - private fun mapSavedPosts(items: List): ImmutableMap> { + private fun groupSavedPosts(items: List): ImmutableMap> { val sorted = items.sortedWith { post1, post2 -> val post1Date = post1.createdAt.toLocalDateTime() @@ -159,7 +152,9 @@ constructor( return _savedPosts.contains(post.shortId) } - private fun isPostRead(post: UIPost) = readPostsRepository.isRead(post.shortId) + private fun isPostRead(post: UIPost): Boolean { + return _readPosts.contains(post.shortId) + } fun toggleSave(post: UIPost) { viewModelScope.launch(ioDispatcher) { diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/viewmodel/ReadPostsRepository.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/viewmodel/ReadPostsRepository.kt index b1b65ece..2b5606a1 100644 --- a/android/src/main/kotlin/dev/msfjarvis/claw/android/viewmodel/ReadPostsRepository.kt +++ b/android/src/main/kotlin/dev/msfjarvis/claw/android/viewmodel/ReadPostsRepository.kt @@ -6,6 +6,8 @@ */ package dev.msfjarvis.claw.android.viewmodel +import app.cash.sqldelight.coroutines.asFlow +import app.cash.sqldelight.coroutines.mapToList import dev.msfjarvis.claw.core.injection.DatabaseDispatcher import dev.msfjarvis.claw.database.local.ReadPostsQueries import javax.inject.Inject @@ -18,12 +20,9 @@ constructor( private val readPostsQueries: ReadPostsQueries, @DatabaseDispatcher private val dbDispatcher: CoroutineDispatcher, ) { + val readPosts = readPostsQueries.selectAllPosts().asFlow().mapToList(dbDispatcher) suspend fun markRead(postId: String) { withContext(dbDispatcher) { readPostsQueries.markRead(postId) } } - - fun isRead(postId: String): Boolean { - return readPostsQueries.isRead(postId).executeAsOneOrNull() != null - } } diff --git a/database/core/src/main/sqldelight/dev/msfjarvis/claw/database/local/ReadPosts.sq b/database/core/src/main/sqldelight/dev/msfjarvis/claw/database/local/ReadPosts.sq index f258baf3..f2398922 100644 --- a/database/core/src/main/sqldelight/dev/msfjarvis/claw/database/local/ReadPosts.sq +++ b/database/core/src/main/sqldelight/dev/msfjarvis/claw/database/local/ReadPosts.sq @@ -2,16 +2,15 @@ CREATE TABLE ReadPosts( id TEXT NOT NULL PRIMARY KEY ); +selectAllPosts: +SELECT * +FROM ReadPosts; + markRead: -INSERT OR REPLACE +INSERT OR IGNORE INTO ReadPosts(id) VALUES (?); markUnread: DELETE FROM ReadPosts WHERE id = ?; - -isRead: -SELECT * -FROM ReadPosts -WHERE id = ?; diff --git a/database/core/src/main/sqldelight/dev/msfjarvis/claw/database/local/SavedPost.sq b/database/core/src/main/sqldelight/dev/msfjarvis/claw/database/local/SavedPost.sq index c3ee41da..0165f5fb 100644 --- a/database/core/src/main/sqldelight/dev/msfjarvis/claw/database/local/SavedPost.sq +++ b/database/core/src/main/sqldelight/dev/msfjarvis/claw/database/local/SavedPost.sq @@ -36,8 +36,3 @@ deletePost: DELETE FROM SavedPost WHERE shortId = ?; - -selectPost: -SELECT * -FROM SavedPost -WHERE shortId = ?; diff --git a/database/impl/src/test/kotlin/dev/msfjarvis/claw/database/local/ReadPostsQueriesTest.kt b/database/impl/src/test/kotlin/dev/msfjarvis/claw/database/local/ReadPostsQueriesTest.kt index 052b7e6f..96522e14 100644 --- a/database/impl/src/test/kotlin/dev/msfjarvis/claw/database/local/ReadPostsQueriesTest.kt +++ b/database/impl/src/test/kotlin/dev/msfjarvis/claw/database/local/ReadPostsQueriesTest.kt @@ -1,5 +1,5 @@ /* - * Copyright © 2023 Harsh Shandilya. + * Copyright © 2023-2024 Harsh Shandilya. * Use of this source code is governed by an MIT-style * license that can be found in the LICENSE file or at * https://opensource.org/licenses/MIT. @@ -23,8 +23,8 @@ class ReadPostsQueriesTest { fun `mark post as read`() { val id = UUID.randomUUID().toString() postQueries.markRead(id) - assertThat(postQueries.isRead(id).executeAsOne()).isNotNull() + assertThat(postQueries.selectAllPosts().executeAsList()).contains(id) postQueries.markUnread(id) - assertThat(postQueries.isRead(id).executeAsOneOrNull()).isNull() + assertThat(postQueries.selectAllPosts().executeAsList()).doesNotContain(id) } } diff --git a/database/impl/src/test/kotlin/dev/msfjarvis/claw/database/local/SavedPostQueriesTest.kt b/database/impl/src/test/kotlin/dev/msfjarvis/claw/database/local/SavedPostQueriesTest.kt index e45be3e8..aa36466f 100644 --- a/database/impl/src/test/kotlin/dev/msfjarvis/claw/database/local/SavedPostQueriesTest.kt +++ b/database/impl/src/test/kotlin/dev/msfjarvis/claw/database/local/SavedPostQueriesTest.kt @@ -1,5 +1,5 @@ /* - * Copyright © 2021-2023 Harsh Shandilya. + * Copyright © 2021-2024 Harsh Shandilya. * Use of this source code is governed by an MIT-style * license that can be found in the LICENSE file or at * https://opensource.org/licenses/MIT. @@ -32,7 +32,7 @@ class SavedPostQueriesTest { @Test fun `update post in database`() { // Get 1 post - val post = createTestData(1)[0] + val post = createTestData(1).first() // Insert post into DB postQueries.insertOrReplacePost(post) @@ -46,15 +46,14 @@ class SavedPostQueriesTest { assertThat(postsCount).isEqualTo(1) // Check if post is updated - val postFromDb = postQueries.selectPost(post.shortId).executeAsOne() - + val postFromDb = postQueries.selectAllPosts().executeAsOne() assertThat(postFromDb.submitterName).isEqualTo("Fake name") } @Test fun `get post from db`() { // Get 1 post - val post = createTestData(1)[0] + val post = createTestData(1).first() // Insert post into DB postQueries.insertOrReplacePost(post)