diff --git a/app/src/main/java/me/ash/reader/data/repository/AbstractRssRepository.kt b/app/src/main/java/me/ash/reader/data/repository/AbstractRssRepository.kt index 1ed0d94..d340895 100644 --- a/app/src/main/java/me/ash/reader/data/repository/AbstractRssRepository.kt +++ b/app/src/main/java/me/ash/reader/data/repository/AbstractRssRepository.kt @@ -72,7 +72,7 @@ abstract class AbstractRssRepository constructor( fun pullFeeds(): Flow> { 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 { + 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> { 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() } diff --git a/app/src/main/java/me/ash/reader/data/repository/LocalRssRepository.kt b/app/src/main/java/me/ash/reader/data/repository/LocalRssRepository.kt index bd6f1a9..a850cd5 100644 --- a/app/src/main/java/me/ash/reader/data/repository/LocalRssRepository.kt +++ b/app/src/main/java/me/ash/reader/data/repository/LocalRssRepository.kt @@ -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
{ - val articles = mutableListOf
() + ): List
{ 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
, + articles: List
, ) { articles.forEach { article -> val builder = NotificationCompat.Builder( diff --git a/app/src/main/java/me/ash/reader/data/repository/RssHelper.kt b/app/src/main/java/me/ash/reader/data/repository/RssHelper.kt index 6b239fc..a5ac99b 100644 --- a/app/src/main/java/me/ash/reader/data/repository/RssHelper.kt +++ b/app/src/main/java/me/ash/reader/data/repository/RssHelper.kt @@ -92,13 +92,13 @@ class RssHelper @Inject constructor( rssNetworkDataSource: RssNetworkDataSource, accountId: Int, feed: Feed, - latestTitle: String? = null, + latestLink: String? = null, ): List
{ val a = mutableListOf
() 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( diff --git a/app/src/main/java/me/ash/reader/ui/page/home/FilterBar2.kt b/app/src/main/java/me/ash/reader/ui/page/home/FilterBar2.kt new file mode 100644 index 0000000..c5f2218 --- /dev/null +++ b/app/src/main/java/me/ash/reader/ui/page/home/FilterBar2.kt @@ -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)) + } +} \ No newline at end of file diff --git a/app/src/main/java/me/ash/reader/ui/page/home/HomeBottomNavBar.kt b/app/src/main/java/me/ash/reader/ui/page/home/HomeBottomNavBar.kt index e890885..5b355f6 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/HomeBottomNavBar.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/HomeBottomNavBar.kt @@ -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, diff --git a/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsViewModel.kt b/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsViewModel.kt index d538c3f..2849476 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsViewModel.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsViewModel.kt @@ -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() val feedImportantMap = mutableMapOf() 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) { diff --git a/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleList.kt b/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleList.kt index 9cc2727..4a5e862 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleList.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleList.kt @@ -19,12 +19,11 @@ import me.ash.reader.ui.page.home.read.ReadViewModel @OptIn(ExperimentalFoundationApi::class) fun LazyListScope.generateArticleList( context: Context, - pagingItems: LazyPagingItems?, + pagingItems: LazyPagingItems, 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 diff --git a/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowPage.kt b/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowPage.kt index 0a2511d..f917581 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowPage.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowPage.kt @@ -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 -> diff --git a/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowViewModel.kt b/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowViewModel.kt index d41bf35..591404a 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowViewModel.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowViewModel.kt @@ -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>? = null, + val pagingData: Flow> = emptyFlow(), val syncWorkInfo: String = "", )