Improve pull feeds

This commit is contained in:
Ash 2022-03-25 03:08:19 +08:00
parent eda76f4445
commit 518dd6b59c
9 changed files with 94 additions and 31 deletions

View File

@ -72,7 +72,7 @@ abstract class AbstractRssRepository constructor(
fun pullFeeds(): Flow<MutableList<GroupWithFeed>> {
return groupDao.queryAllGroupWithFeed(
context.dataStore.get(DataStoreKeys.CurrentAccountId) ?: 0
)
)//.flowOn(Dispatchers.IO)
}
fun pullArticles(
@ -81,6 +81,7 @@ abstract class AbstractRssRepository constructor(
isStarred: Boolean = false,
isUnread: Boolean = false,
): PagingSource<Int, ArticleWithFeed> {
Log.i("RLog", "thread:pullArticles ${Thread.currentThread().name}")
val accountId = context.dataStore.get(DataStoreKeys.CurrentAccountId) ?: 0
Log.i(
"RLog",
@ -116,6 +117,7 @@ abstract class AbstractRssRepository constructor(
isUnread: Boolean = false,
): Flow<List<ImportantCount>> {
return withContext(Dispatchers.IO) {
Log.i("RLog", "thread:pullImportant ${Thread.currentThread().name}")
val accountId = context.dataStore.get(DataStoreKeys.CurrentAccountId)!!
Log.i(
"RLog",
@ -128,7 +130,7 @@ abstract class AbstractRssRepository constructor(
.queryImportantCountWhenIsUnread(accountId, isUnread)
else -> articleDao.queryImportantCountWhenIsAll(accountId)
}
}
}//.flowOn(Dispatchers.IO)
}
suspend fun findArticleById(id: String): ArticleWithFeed? {
@ -176,7 +178,6 @@ class SyncWorker @AssistedInject constructor(
15, TimeUnit.MINUTES
).setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
).addTag(WORK_NAME).build()
}

View File

@ -87,8 +87,8 @@ class LocalRssRepository @Inject constructor(
override suspend fun sync() {
mutex.withLock {
val preTime = System.currentTimeMillis()
withContext(Dispatchers.IO) {
val preTime = System.currentTimeMillis()
val accountId = context.dataStore.get(DataStoreKeys.CurrentAccountId)
?: return@withContext
val feeds = async { feedDao.queryAll(accountId) }
@ -98,6 +98,7 @@ class LocalRssRepository @Inject constructor(
feedCount = feed.size,
)
}
Log.i("RLog", "thread:sync ${Thread.currentThread().name}")
}.map { feed ->
async {
val articles = syncFeed(accountId, feed)
@ -132,36 +133,37 @@ class LocalRssRepository @Inject constructor(
private suspend fun syncFeed(
accountId: Int,
feed: Feed
): MutableList<Article> {
val articles = mutableListOf<Article>()
): List<Article> {
val latest = articleDao.queryLatestByFeedId(accountId, feed.id)
articles.addAll(
rssHelper.queryRssXml(
val articles = rssHelper.queryRssXml(
rssNetworkDataSource,
accountId,
feed,
latest?.title,
latest?.link,
).also {
if (feed.icon == null && it.isNotEmpty()) {
rssHelper.queryRssIcon(feedDao, feed, it.first().link)
}
}
)
Log.i("RLog", "thread:syncFeed ${Thread.currentThread().name}")
updateSyncState {
it.copy(
syncedCount = it.syncedCount + 1,
currentFeedName = feed.name
)
}
if (articles.isNotEmpty()) {
articleDao.insertList(articles)
if (feed.isNotification) {
notify(articles)
}
}
return articles
}
private fun notify(
articles: MutableList<Article>,
articles: List<Article>,
) {
articles.forEach { article ->
val builder = NotificationCompat.Builder(

View File

@ -92,13 +92,13 @@ class RssHelper @Inject constructor(
rssNetworkDataSource: RssNetworkDataSource,
accountId: Int,
feed: Feed,
latestTitle: String? = null,
latestLink: String? = null,
): List<Article> {
val a = mutableListOf<Article>()
try {
val parseRss = rssNetworkDataSource.parseRss(feed.url)
parseRss.items.forEach {
if (latestTitle != null && latestTitle == it.title) return a
if (latestLink != null && latestLink == it.link) return a
Log.i("RLog", "request rss ${feed.name}: ${it.title}")
a.add(
Article(

View File

@ -0,0 +1,50 @@
package me.ash.reader.ui.page.home
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.width
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.google.accompanist.pager.ExperimentalPagerApi
import me.ash.reader.data.constant.Filter
import me.ash.reader.ui.extension.getName
@OptIn(ExperimentalPagerApi::class)
@Composable
fun FilterBar2(
modifier: Modifier = Modifier,
filter: Filter,
onSelected: (Filter) -> Unit = {},
) {
NavigationBar(
tonalElevation = 0.dp,
) {
Spacer(modifier = Modifier.width(60.dp))
listOf(
Filter.Starred,
Filter.Unread,
Filter.All,
).forEach { item ->
NavigationBarItem(
icon = {
Icon(
imageVector = if (filter == item) item.filledIcon else item.icon,
contentDescription = item.getName()
)
},
// label = { Text(text = item.getName()) },
selected = filter == item,
onClick = { onSelected(item) },
colors = NavigationBarItemDefaults.colors(
selectedIconColor = MaterialTheme.colorScheme.onSecondaryContainer,
unselectedIconColor = MaterialTheme.colorScheme.outline,
selectedTextColor = MaterialTheme.colorScheme.onSurface,
unselectedTextColor = MaterialTheme.colorScheme.onSurfaceVariant,
indicatorColor = MaterialTheme.colorScheme.secondaryContainer,
)
)
}
Spacer(modifier = Modifier.width(60.dp))
}
}

View File

@ -113,7 +113,12 @@ fun HomeBottomNavBar(
.alpha(1 - readerBarAlpha),
) {
Log.i("RLog", "AppNavigationBar: ${readerBarAlpha}, ${1f - readerBarAlpha}")
FilterBar(
// FilterBar(
// modifier = modifier,
// filter = filter,
// onSelected = filterOnClick,
// )
FilterBar2(
modifier = modifier,
filter = filter,
onSelected = filterOnClick,

View File

@ -5,6 +5,7 @@ import androidx.compose.foundation.lazy.LazyListState
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import me.ash.reader.data.account.Account
@ -67,6 +68,7 @@ class FeedsViewModel @Inject constructor(
rssRepository.get().pullFeeds(),
rssRepository.get().pullImportant(isStarred, isUnread),
) { groupWithFeedList, importantList ->
Log.i("RLog", "thread:combine ${Thread.currentThread().name}")
val groupImportantMap = mutableMapOf<String, Int>()
val feedImportantMap = mutableMapOf<String, Int>()
importantList.groupBy { it.groupId }.forEach { (i, list) ->
@ -101,6 +103,8 @@ class FeedsViewModel @Inject constructor(
}.onStart {
}.onEach { groupWithFeedList ->
Log.i("RLog", "thread:onEach ${Thread.currentThread().name}")
_viewState.update {
it.copy(
filter = when {
@ -116,7 +120,7 @@ class FeedsViewModel @Inject constructor(
}
}.catch {
Log.e("RLog", "catch in articleRepository.pullFeeds(): $this")
}.collect()
}.flowOn(Dispatchers.Default).collect()
}
private fun scrollToItem(index: Int) {

View File

@ -19,12 +19,11 @@ import me.ash.reader.ui.page.home.read.ReadViewModel
@OptIn(ExperimentalFoundationApi::class)
fun LazyListScope.generateArticleList(
context: Context,
pagingItems: LazyPagingItems<ArticleWithFeed>?,
pagingItems: LazyPagingItems<ArticleWithFeed>,
readViewModel: ReadViewModel,
homeViewModel: HomeViewModel,
scope: CoroutineScope
) {
pagingItems ?: return
var lastItemDay: String? = null
for (itemIndex in 0 until pagingItems.itemCount) {
val currentItem = pagingItems.peek(itemIndex) ?: continue

View File

@ -22,7 +22,6 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController
import androidx.paging.compose.collectAsLazyPagingItems
import kotlinx.coroutines.flow.collect
import me.ash.reader.R
import me.ash.reader.ui.extension.collectAsStateValue
import me.ash.reader.ui.extension.getName
@ -46,7 +45,7 @@ fun FlowPage(
val scope = rememberCoroutineScope()
val viewState = viewModel.viewState.collectAsStateValue()
val filterState = homeViewModel.filterState.collectAsStateValue()
val pagingItems = viewState.pagingData?.collectAsLazyPagingItems()
val pagingItems = viewState.pagingData.collectAsLazyPagingItems()
LaunchedEffect(homeViewModel.filterState) {
homeViewModel.filterState.collect { state ->

View File

@ -1,5 +1,6 @@
package me.ash.reader.ui.page.home.flow
import android.util.Log
import androidx.compose.foundation.lazy.LazyListState
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
@ -8,6 +9,7 @@ import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.cachedIn
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import me.ash.reader.data.article.ArticleWithFeed
@ -53,13 +55,14 @@ class FlowViewModel @Inject constructor(
_viewState.update {
it.copy(
pagingData = Pager(PagingConfig(pageSize = 10)) {
Log.i("RLog", "thread:Pager ${Thread.currentThread().name}")
rssRepository.get().pullArticles(
groupId = filterState.group?.id,
feedId = filterState.feed?.id,
isStarred = filterState.filter.isStarred(),
isUnread = filterState.filter.isUnread(),
)
}.flow.cachedIn(viewModelScope)
}.flow.flowOn(Dispatchers.IO).cachedIn(viewModelScope)
)
}
}
@ -81,7 +84,7 @@ data class ArticleViewState(
val filterImportant: Int = 0,
val listState: LazyListState = LazyListState(),
val isRefreshing: Boolean = false,
val pagingData: Flow<PagingData<ArticleWithFeed>>? = null,
val pagingData: Flow<PagingData<ArticleWithFeed>> = emptyFlow(),
val syncWorkInfo: String = "",
)