diff --git a/appcompose/src/main/java/com/readrops/app/compose/repositories/GetFoldersWithFeeds.kt b/appcompose/src/main/java/com/readrops/app/compose/repositories/GetFoldersWithFeeds.kt index 0c8fd786..d52d01b8 100644 --- a/appcompose/src/main/java/com/readrops/app/compose/repositories/GetFoldersWithFeeds.kt +++ b/appcompose/src/main/java/com/readrops/app/compose/repositories/GetFoldersWithFeeds.kt @@ -3,35 +3,43 @@ package com.readrops.app.compose.repositories import com.readrops.db.Database import com.readrops.db.entities.Feed import com.readrops.db.entities.Folder -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine class GetFoldersWithFeeds( private val database: Database, - private val dispatcher: CoroutineDispatcher = Dispatchers.IO ) { - suspend fun get(accountId: Int): Map> = withContext(dispatcher) { - val foldersWithFeeds = mutableMapOf>() - val folders = database.newFolderDao().selectFoldersByAccount(accountId) - - for (folder in folders) { - val feeds = database.newFeedDao().selectFeedsByFolder(folder.id) - - for (feed in feeds) { - feed.unreadCount = database.newItemDao().selectUnreadCount(feed.id) + fun get(accountId: Int): Flow>> { + return combine( + flow = database.newFolderDao() + .selectFoldersAndFeeds(accountId), + flow2 = database.newFeedDao() + .selectFeedsWithoutFolder(accountId) + ) { folders, feedsWithoutFolder -> + val foldersWithFeeds = folders.groupBy( + keySelector = { Folder(id = it.folderId, name = it.folderName) }, + valueTransform = { + Feed( + id = it.feedId, + name = it.feedName, + iconUrl = it.feedIcon, + unreadCount = it.unreadCount + ) + } + ).mapValues { listEntry -> + if (listEntry.value.any { it.id == 0 }) { + listOf() + } else { + listEntry.value + } } - foldersWithFeeds[folder] = feeds + foldersWithFeeds + mapOf( + Pair( + null, + feedsWithoutFolder.map { it.feed.apply { unreadCount = it.unreadCount } }) + ) } - - val feedsAlone = database.newFeedDao().selectFeedsAlone(accountId) - for (feed in feedsAlone) { - feed.unreadCount = database.newItemDao().selectUnreadCount(feed.id) - } - - foldersWithFeeds[null] = feedsAlone - foldersWithFeeds.toSortedMap(nullsLast()) } } \ No newline at end of file diff --git a/appcompose/src/main/java/com/readrops/app/compose/timelime/TimelineViewModel.kt b/appcompose/src/main/java/com/readrops/app/compose/timelime/TimelineViewModel.kt index d0120568..7d799eaf 100644 --- a/appcompose/src/main/java/com/readrops/app/compose/timelime/TimelineViewModel.kt +++ b/appcompose/src/main/java/com/readrops/app/compose/timelime/TimelineViewModel.kt @@ -49,7 +49,6 @@ class TimelineViewModel( _timelineState.update { it.copy( - foldersAndFeeds = getFoldersWithFeeds.get(account.id), items = ItemState.Loaded( items = Pager( config = PagingConfig( @@ -64,6 +63,15 @@ class TimelineViewModel( ) ) } + + getFoldersWithFeeds.get(account.id) + .collect { foldersAndFeeds -> + _timelineState.update { + it.copy( + foldersAndFeeds = foldersAndFeeds + ) + } + } } } } diff --git a/db/src/main/java/com/readrops/db/dao/newdao/NewFeedDao.kt b/db/src/main/java/com/readrops/db/dao/newdao/NewFeedDao.kt index d66102fb..450d7ddf 100644 --- a/db/src/main/java/com/readrops/db/dao/newdao/NewFeedDao.kt +++ b/db/src/main/java/com/readrops/db/dao/newdao/NewFeedDao.kt @@ -3,6 +3,7 @@ package com.readrops.db.dao.newdao import androidx.room.Dao import androidx.room.Query import com.readrops.db.entities.Feed +import com.readrops.db.pojo.FeedWithCount import kotlinx.coroutines.flow.Flow @Dao @@ -20,9 +21,8 @@ abstract class NewFeedDao : NewBaseDao { @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("Select * From Feed Where folder_id = :folderId") - abstract suspend fun selectFeedsByFolder(folderId: Int): List + @Query("Select *, count(*) as unreadCount From Feed Inner Join Item On Feed.id = Item.feed_id " + + "Where Feed.folder_id is Null And Item.read = 0 And Feed.account_id = :accountId Group by Feed.id") + abstract fun selectFeedsWithoutFolder(accountId: Int): Flow> - @Query("Select * From Feed Where account_id = :accountId And folder_id Is Null") - abstract suspend fun selectFeedsAlone(accountId: Int): List } \ No newline at end of file diff --git a/db/src/main/java/com/readrops/db/dao/newdao/NewFolderDao.kt b/db/src/main/java/com/readrops/db/dao/newdao/NewFolderDao.kt index c9e40e2c..782411b1 100644 --- a/db/src/main/java/com/readrops/db/dao/newdao/NewFolderDao.kt +++ b/db/src/main/java/com/readrops/db/dao/newdao/NewFolderDao.kt @@ -3,12 +3,16 @@ package com.readrops.db.dao.newdao import androidx.room.Dao import androidx.room.Query import com.readrops.db.entities.Folder +import com.readrops.db.pojo.FolderWithFeed +import kotlinx.coroutines.flow.Flow @Dao abstract class NewFolderDao : NewBaseDao { - @Query("Select * From Folder Where account_id = :accountId Order By name ASC") - abstract suspend fun selectFoldersByAccount(accountId: Int): List - - + @Query("Select Folder.id As folderId, Folder.name as folderName, Feed.id As feedId, Feed.name AS feedName, " + + "Feed.icon_url As feedIcon, count(*) As unreadCount 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 Item.read = 0 " + + "And Feed.account_id = :accountId Group By Feed.id, Folder.id Order By Folder.id") + abstract fun selectFoldersAndFeeds(accountId: Int): Flow> } \ No newline at end of file diff --git a/db/src/main/java/com/readrops/db/pojo/FeedWithFolder.kt b/db/src/main/java/com/readrops/db/pojo/FeedWithFolder.kt index dd78e3d7..41ea9f74 100644 --- a/db/src/main/java/com/readrops/db/pojo/FeedWithFolder.kt +++ b/db/src/main/java/com/readrops/db/pojo/FeedWithFolder.kt @@ -8,6 +8,20 @@ import kotlinx.parcelize.Parcelize @Parcelize data class FeedWithFolder( - @Embedded(prefix = "feed_") val feed: Feed, - @Embedded(prefix = "folder_") val folder: Folder, -) : Parcelable \ No newline at end of file + @Embedded(prefix = "feed_") val feed: Feed, + @Embedded(prefix = "folder_") val folder: Folder, +) : Parcelable + +data class FolderWithFeed( + val folderId: Int, + val folderName: String, + val feedId: Int = 0, + val feedName: String? = null, + val feedIcon: String? = null, + val unreadCount: Int = 0 +) + +data class FeedWithCount( + @Embedded val feed: Feed, + val unreadCount: Int +) \ No newline at end of file