Make foldersAndFeeds queries aware of main filters

This commit is contained in:
Shinokuni 2024-03-02 22:15:13 +01:00
parent 59d22fd311
commit c9259c5a71
6 changed files with 77 additions and 22 deletions

View File

@ -11,6 +11,7 @@ import com.readrops.db.Database
import com.readrops.db.entities.Feed
import com.readrops.db.entities.Folder
import com.readrops.db.entities.account.Account
import com.readrops.db.filters.FilterType
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
@ -46,7 +47,7 @@ class FeedViewModel(
viewModelScope.launch(context = Dispatchers.IO) {
accountEvent
.flatMapConcat { account ->
getFoldersWithFeeds.get(account.id)
getFoldersWithFeeds.get(account.id, FilterType.NO_FILTER)
}
.catch { throwable ->
_feedState.update {

View File

@ -3,6 +3,8 @@ package com.readrops.app.compose.repositories
import com.readrops.db.Database
import com.readrops.db.entities.Feed
import com.readrops.db.entities.Folder
import com.readrops.db.filters.FilterType
import com.readrops.db.queries.FoldersAndFeedsQueriesBuilder
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
@ -10,12 +12,17 @@ class GetFoldersWithFeeds(
private val database: Database,
) {
fun get(accountId: Int): Flow<Map<Folder?, List<Feed>>> {
fun get(accountId: Int, filterType: FilterType): Flow<Map<Folder?, List<Feed>>> {
val foldersAndFeedsQuery =
FoldersAndFeedsQueriesBuilder.buildFoldersAndFeedsQuery(accountId, filterType)
val feedsWithoutFolderQuery =
FoldersAndFeedsQueriesBuilder.buildFeedsWithoutFolderQuery(accountId, filterType)
return combine(
flow = database.newFolderDao()
.selectFoldersAndFeeds(accountId),
.selectFoldersAndFeeds(foldersAndFeedsQuery),
flow2 = database.newFeedDao()
.selectFeedsWithoutFolder(accountId)
.selectFeedsWithoutFolder(feedsWithoutFolderQuery)
) { folders, feedsWithoutFolder ->
val foldersWithFeeds = folders.groupBy(
keySelector = {

View File

@ -67,7 +67,7 @@ class TimelineViewModel(
)
}
getFoldersWithFeeds.get(account.id)
getFoldersWithFeeds.get(account.id, filters.filterType)
.collect { foldersAndFeeds ->
_timelineState.update {
it.copy(

View File

@ -2,7 +2,10 @@ package com.readrops.db.dao.newdao
import androidx.room.Dao
import androidx.room.Query
import androidx.room.RawQuery
import androidx.sqlite.db.SupportSQLiteQuery
import com.readrops.db.entities.Feed
import com.readrops.db.entities.Item
import com.readrops.db.pojo.FeedWithCount
import kotlinx.coroutines.flow.Flow
@ -21,12 +24,8 @@ abstract class NewFeedDao : NewBaseDao<Feed> {
@Query("Select case When :feedUrl In (Select url from Feed Where account_id = :accountId) Then 1 else 0 end")
abstract suspend fun feedExists(feedUrl: String, accountId: Int): Boolean
@Query("With main As (Select Feed.id as feedId, Feed.name as feedName, Feed.icon_url as feedIcon, " +
"Feed.url as feedUrl, Feed.siteUrl as feedSiteUrl, Feed.account_id as accountId, Item.read as itemRead " +
"From Feed Left Join Item On Feed.id = Item.feed_id Where Feed.folder_id is Null And Feed.account_id = :accountId)" +
"Select feedId, feedName, feedIcon, feedUrl, feedSiteUrl, accountId, " +
"(Select count(*) From main Where (itemRead = 0)) as unreadCount From main Group by feedId Order By feedName")
abstract fun selectFeedsWithoutFolder(accountId: Int): Flow<List<FeedWithCount>>
@RawQuery(observedEntities = [Feed::class, Item::class])
abstract fun selectFeedsWithoutFolder(query: SupportSQLiteQuery): Flow<List<FeedWithCount>>
@Query("Update Feed set name = :feedName, url = :feedUrl, folder_id = :folderId Where id = :feedId")
abstract fun updateFeedFields(feedId: Int, feedName: String, feedUrl: String, folderId: Int?)

View File

@ -2,23 +2,20 @@ package com.readrops.db.dao.newdao
import androidx.room.Dao
import androidx.room.Query
import androidx.room.RawQuery
import androidx.sqlite.db.SupportSQLiteQuery
import com.readrops.db.entities.Feed
import com.readrops.db.entities.Folder
import com.readrops.db.entities.Item
import com.readrops.db.pojo.FolderWithFeed
import kotlinx.coroutines.flow.Flow
@Dao
abstract class NewFolderDao : NewBaseDao<Folder> {
interface NewFolderDao : NewBaseDao<Folder> {
@Query("With main As (Select Folder.id As folderId, Folder.name as folderName, Feed.id As feedId, " +
"Feed.name AS feedName, Feed.icon_url As feedIcon, Feed.url as feedUrl, Feed.siteUrl as feedSiteUrl, " +
"Folder.account_id as accountId, Item.read as itemRead " +
"From Folder Left Join Feed On Folder.id = Feed.folder_id Left Join Item On Item.feed_id = Feed.id " +
"Where Feed.folder_id is NULL OR Feed.folder_id is NOT NULL And Feed.account_id = :accountId ) " +
"Select folderId, folderName, feedId, feedName, feedIcon, feedUrl, feedSiteUrl, accountId," +
" (Select count(*) From main Where (itemRead = 0)) as unreadCount " +
"From main Group by feedId, folderId Order By folderName, feedName")
abstract fun selectFoldersAndFeeds(accountId: Int): Flow<List<FolderWithFeed>>
@RawQuery(observedEntities = [Folder::class, Feed::class, Item::class])
fun selectFoldersAndFeeds(query: SupportSQLiteQuery): Flow<List<FolderWithFeed>>
@Query("Select * From Folder Where account_id = :accountId")
abstract fun selectFolders(accountId: Int): Flow<List<Folder>>
fun selectFolders(accountId: Int): Flow<List<Folder>>
}

View File

@ -0,0 +1,51 @@
package com.readrops.db.queries
import androidx.sqlite.db.SimpleSQLiteQuery
import androidx.sqlite.db.SupportSQLiteQuery
import com.readrops.db.filters.FilterType
import org.intellij.lang.annotations.Language
object FoldersAndFeedsQueriesBuilder {
fun buildFoldersAndFeedsQuery(accountId: Int, filterType: FilterType): SupportSQLiteQuery {
val filter = when (filterType) {
FilterType.STARS_FILTER -> "And Item.starred = 1"
FilterType.NEW -> "And DateTime(Round(Item.pub_date / 1000), 'unixepoch') Between DateTime(DateTime(\"now\"), \"-24 hour\") And DateTime(\"now\") "
else -> ""
}
@Language("SQL")
val query = SimpleSQLiteQuery("""
With main As (Select Folder.id As folderId, Folder.name As folderName, Feed.id As feedId,
Feed.name As feedName, Feed.icon_url As feedIcon, Feed.url As feedUrl, Feed.siteUrl As feedSiteUrl,
Folder.account_id As accountId, Item.read as itemRead
From Folder Left Join Feed On Folder.id = Feed.folder_id Left Join Item On Item.feed_id = Feed.id
Where Feed.folder_id is NULL OR Feed.folder_id is NOT NULL And Feed.account_id = $accountId $filter)
Select folderId, folderName, feedId, feedName, feedIcon, feedUrl, feedSiteUrl, accountId,
(Select count(*) From main Where (itemRead = 0)) as unreadCount
From main Group by feedId, folderId Order By folderName, feedName
""".trimIndent())
return query
}
fun buildFeedsWithoutFolderQuery(accountId: Int, filterType: FilterType): SupportSQLiteQuery {
val filter = when (filterType) {
FilterType.STARS_FILTER -> "And Item.starred = 1 "
FilterType.NEW -> "And DateTime(Round(Item.pub_date / 1000), 'unixepoch') Between DateTime(DateTime(\"now\"), \"-24 hour\") And DateTime(\"now\") "
else -> ""
}
@Language("SQL")
val query = SimpleSQLiteQuery("""
With main As (Select Feed.id As feedId, Feed.name As feedName, Feed.icon_url As feedIcon,
Feed.url As feedUrl, Feed.siteUrl As feedSiteUrl, Feed.account_id As accountId, Item.read As itemRead
From Feed Left Join Item On Feed.id = Item.feed_id Where Feed.folder_id is Null And Feed.account_id = $accountId $filter)
Select feedId, feedName, feedIcon, feedUrl, feedSiteUrl, accountId,
(Select count(*) From main Where (itemRead = 0)) as unreadCount From main Group by feedId Order By feedName
""".trimIndent())
return query
}
}