Implement hideReadFeeds preference in TimelineTab

This commit is contained in:
Shinokuni 2024-07-22 15:23:48 +02:00
parent 1e5a23b722
commit 0adf55eb02
4 changed files with 96 additions and 23 deletions

View File

@ -5,6 +5,7 @@ import com.readrops.db.entities.Feed
import com.readrops.db.entities.Folder
import com.readrops.db.filters.MainFilter
import com.readrops.db.queries.FeedUnreadCountQueryBuilder
import com.readrops.db.queries.FoldersAndFeedsQueryBuilder
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
@ -15,13 +16,15 @@ class GetFoldersWithFeeds(
fun get(
accountId: Int,
mainFilter: MainFilter,
useSeparateState: Boolean
useSeparateState: Boolean,
hideReadFeeds: Boolean = false
): Flow<Map<Folder?, List<Feed>>> {
val query = FeedUnreadCountQueryBuilder.build(accountId, mainFilter, useSeparateState)
val foldersAndFeedsQuery = FoldersAndFeedsQueryBuilder.build(accountId, hideReadFeeds)
val unreadItemsCountQuery = FeedUnreadCountQueryBuilder.build(accountId, mainFilter, useSeparateState)
return combine(
flow = database.folderDao().selectFoldersAndFeeds(accountId),
flow2 = database.itemDao().selectFeedUnreadItemsCount(query)
flow = database.folderDao().selectFoldersAndFeeds(foldersAndFeedsQuery),
flow2 = database.itemDao().selectFeedUnreadItemsCount(unreadItemsCountQuery)
) { folders, itemCounts ->
val foldersWithFeeds = folders.groupBy(
keySelector = {

View File

@ -85,11 +85,15 @@ class TimelineScreenModel(
)
}
getFoldersWithFeeds.get(
account.id,
filters.mainFilter,
account.config.useSeparateState
)
preferences.hideReadFeeds.flow
.flatMapLatest { hideReadFeeds ->
getFoldersWithFeeds.get(
accountId = account.id,
mainFilter = filters.mainFilter,
useSeparateState = account.config.useSeparateState,
hideReadFeeds = hideReadFeeds
)
}
.collect { foldersAndFeeds ->
_timelineState.update {
it.copy(

View File

@ -2,8 +2,12 @@ package com.readrops.db.dao
import androidx.room.Dao
import androidx.room.Query
import androidx.room.RawQuery
import androidx.room.Transaction
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.entities.account.Account
import com.readrops.db.pojo.FolderWithFeed
import kotlinx.coroutines.flow.Flow
@ -11,20 +15,9 @@ import kotlinx.coroutines.flow.Flow
@Dao
interface FolderDao : BaseDao<Folder> {
@Query("""
Select Feed.id As feedId, Feed.name As feedName, Feed.icon_url As feedIcon, Feed.url As feedUrl,
Feed.siteUrl As feedSiteUrl, Feed.description as feedDescription, Feed.remoteId as feedRemoteId, Folder.id As folderId,
Folder.name As folderName, Feed.account_id as accountId, Folder.remoteId as folderRemoteId
From Feed Left Join Folder On Folder.id = Feed.folder_id
Where Feed.folder_id is NULL OR Feed.folder_id is NOT NULL And Feed.id is NULL Or Feed.id is NOT NULL And Feed.account_id = :accountId Group By Feed.id
UNION ALL
Select Feed.id As feedId, Feed.name As feedName, Feed.icon_url As feedIcon, Feed.url As feedUrl,
Feed.siteUrl As feedSiteUrl, Feed.description as feedDescription, Feed.remoteId as feedRemoteId, Folder.id As folderId,
Folder.name As folderName, Folder.account_id as accountId, Folder.remoteId as folderRemoteId
From Folder Left Join Feed On Folder.id = Feed.folder_id
Where Feed.id is NULL And Folder.account_id = :accountId
""")
fun selectFoldersAndFeeds(accountId: Int): Flow<List<FolderWithFeed>>
// TODO react to Item changes when this table is not part of the query might be a perf issue
@RawQuery(observedEntities = [Folder::class, Feed::class, Item::class])
fun selectFoldersAndFeeds(query: SupportSQLiteQuery): Flow<List<FolderWithFeed>>
@Query("Select * From Folder Where account_id = :accountId")
fun selectFolders(accountId: Int): Flow<List<Folder>>

View File

@ -0,0 +1,73 @@
package com.readrops.db.queries
import androidx.sqlite.db.SimpleSQLiteQuery
import androidx.sqlite.db.SupportSQLiteQuery
import androidx.sqlite.db.SupportSQLiteQueryBuilder
object FoldersAndFeedsQueryBuilder {
private val COLUMNS = arrayOf(
"Feed.id As feedId",
"Feed.name As feedName",
"Feed.icon_url As feedIcon",
"Feed.url As feedUrl",
"Feed.siteUrl As feedSiteUrl",
"Feed.description as feedDescription",
"Feed.remoteId as feedRemoteId",
"Folder.id As folderId",
"Folder.name As folderName",
"Feed.account_id as accountId",
"Folder.remoteId as folderRemoteId"
)
private val FEED_JOIN = """(Select * From Feed Where account_id = :accountId) Feed
Left Join Folder On Folder.id = Feed.folder_id """.trimMargin()
private const val FOLDER_JOIN = "Folder Left Join Feed On Folder.id = Feed.folder_id "
private const val ITEM_JOIN = " Inner Join Item On Item.feed_id = Feed.id "
private const val FEED_SELECTION = "Feed.folder_id is NULL OR Feed.folder_id is NOT NULL "
private const val FOLDER_SELECTION = "Feed.id is NULL And Folder.account_id = :accountId"
private const val ITEM_SELECTION = "And Item.read = 0"
fun build(accountId: Int, hideReadFeeds: Boolean = false): SupportSQLiteQuery {
return SimpleSQLiteQuery(
"""
${buildFeedQuery(accountId, hideReadFeeds).sql}
${
if (!hideReadFeeds) {
"""UNION ALL
${buildFolderQuery(accountId).sql}
""".trimIndent()
} else {
""
}
}""".trimIndent()
)
}
private fun buildFeedQuery(accountId: Int, hideReadFeeds: Boolean): SupportSQLiteQuery {
val tables = if (hideReadFeeds) FEED_JOIN + ITEM_JOIN else FEED_JOIN
val selection = if (hideReadFeeds) FEED_SELECTION + ITEM_SELECTION else FEED_SELECTION
return SupportSQLiteQueryBuilder.builder(tables.replace(":accountId", "$accountId")).run {
columns(COLUMNS)
selection(selection, null)
groupBy("Feed.id")
create()
}
}
private fun buildFolderQuery(accountId: Int): SupportSQLiteQuery {
return SupportSQLiteQueryBuilder.builder(FOLDER_JOIN).run {
columns(COLUMNS)
selection(FOLDER_SELECTION.replace(":accountId", "$accountId"), null)
create()
}
}
}