mirror of
https://github.com/readrops/Readrops.git
synced 2025-02-01 19:26:49 +01:00
Improve logic to build drawer folders and feeds list
* db requests down to 2 * react to changes when feeds/folders/items read state are modified
This commit is contained in:
parent
36f768044a
commit
03ee5deab9
@ -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<Folder?, List<Feed>> = withContext(dispatcher) {
|
||||
val foldersWithFeeds = mutableMapOf<Folder?, List<Feed>>()
|
||||
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<Map<Folder?, List<Feed>>> {
|
||||
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())
|
||||
}
|
||||
}
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<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("Select * From Feed Where folder_id = :folderId")
|
||||
abstract suspend fun selectFeedsByFolder(folderId: Int): List<Feed>
|
||||
@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<List<FeedWithCount>>
|
||||
|
||||
@Query("Select * From Feed Where account_id = :accountId And folder_id Is Null")
|
||||
abstract suspend fun selectFeedsAlone(accountId: Int): List<Feed>
|
||||
}
|
@ -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<Folder> {
|
||||
|
||||
@Query("Select * From Folder Where account_id = :accountId Order By name ASC")
|
||||
abstract suspend fun selectFoldersByAccount(accountId: Int): List<Folder>
|
||||
|
||||
|
||||
@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<List<FolderWithFeed>>
|
||||
}
|
@ -8,6 +8,20 @@ import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class FeedWithFolder(
|
||||
@Embedded(prefix = "feed_") val feed: Feed,
|
||||
@Embedded(prefix = "folder_") val folder: Folder,
|
||||
@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
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user