Improve pull feeds
This commit is contained in:
parent
eda76f4445
commit
518dd6b59c
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
rssNetworkDataSource,
|
||||
accountId,
|
||||
feed,
|
||||
latest?.title,
|
||||
).also {
|
||||
if (feed.icon == null && it.isNotEmpty()) {
|
||||
rssHelper.queryRssIcon(feedDao, feed, it.first().link)
|
||||
}
|
||||
val articles = rssHelper.queryRssXml(
|
||||
rssNetworkDataSource,
|
||||
accountId,
|
||||
feed,
|
||||
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
|
||||
)
|
||||
}
|
||||
articleDao.insertList(articles)
|
||||
if (feed.isNotification) {
|
||||
notify(articles)
|
||||
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(
|
||||
|
|
|
@ -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(
|
||||
|
|
50
app/src/main/java/me/ash/reader/ui/page/home/FilterBar2.kt
Normal file
50
app/src/main/java/me/ash/reader/ui/page/home/FilterBar2.kt
Normal 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))
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ->
|
||||
|
|
|
@ -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 = "",
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user