From f695a2a040f74048ae4b6d74d42b3f910874c88d Mon Sep 17 00:00:00 2001 From: Zhiting Guo <35057824+frearb@users.noreply.github.com> Date: Mon, 8 Aug 2022 11:31:11 +0800 Subject: [PATCH] Enable 'Next Article' (#171) --- .../me/ash/reader/ui/page/common/HomeEntry.kt | 2 +- .../ash/reader/ui/page/home/HomeViewModel.kt | 1 + .../reader/ui/page/home/reading/BottomBar.kt | 4 ++- .../ui/page/home/reading/ReadingPage.kt | 10 ++++++ .../ui/page/home/reading/ReadingViewModel.kt | 36 +++++++++++++++++++ 5 files changed, 51 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/me/ash/reader/ui/page/common/HomeEntry.kt b/app/src/main/java/me/ash/reader/ui/page/common/HomeEntry.kt index 8a6b61f..e7a7baf 100644 --- a/app/src/main/java/me/ash/reader/ui/page/common/HomeEntry.kt +++ b/app/src/main/java/me/ash/reader/ui/page/common/HomeEntry.kt @@ -132,7 +132,7 @@ fun HomeEntry( ) } animatedComposable(route = "${RouteName.READING}/{articleId}") { - ReadingPage(navController = navController) + ReadingPage(navController = navController, homeViewModel = homeViewModel) } // Settings diff --git a/app/src/main/java/me/ash/reader/ui/page/home/HomeViewModel.kt b/app/src/main/java/me/ash/reader/ui/page/home/HomeViewModel.kt index c96eaf5..c7cd375 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/HomeViewModel.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/HomeViewModel.kt @@ -99,4 +99,5 @@ data class FilterState( data class HomeUiState( val pagingData: Flow> = emptyFlow(), val searchContent: String = "", + var nextArticleId: String = "" ) diff --git a/app/src/main/java/me/ash/reader/ui/page/home/reading/BottomBar.kt b/app/src/main/java/me/ash/reader/ui/page/home/reading/BottomBar.kt index e7534e7..1fac5b6 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/reading/BottomBar.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/reading/BottomBar.kt @@ -33,6 +33,7 @@ fun BottomBar( isFullContent: Boolean, onUnread: (isUnread: Boolean) -> Unit = {}, onStarred: (isStarred: Boolean) -> Unit = {}, + onNextArticle: () -> Unit = {}, onFullContent: (isFullContent: Boolean) -> Unit = {}, ) { val tonalElevation = LocalReadingPageTonalElevation.current @@ -95,13 +96,14 @@ fun BottomBar( onStarred(!isStarred) } CanBeDisabledIconButton( - disabled = true, + disabled = false, modifier = Modifier.size(40.dp), imageVector = Icons.Rounded.ExpandMore, contentDescription = "Next Article", tint = MaterialTheme.colorScheme.outline, ) { view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP) + onNextArticle() } CanBeDisabledIconButton( modifier = Modifier.size(36.dp), diff --git a/app/src/main/java/me/ash/reader/ui/page/home/reading/ReadingPage.kt b/app/src/main/java/me/ash/reader/ui/page/home/reading/ReadingPage.kt index d6e9c3a..74b5c9e 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/reading/ReadingPage.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/reading/ReadingPage.kt @@ -9,25 +9,32 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavHostController +import androidx.paging.compose.collectAsLazyPagingItems import me.ash.reader.data.model.preference.LocalReadingAutoHideToolbar import me.ash.reader.data.model.preference.LocalReadingPageTonalElevation import me.ash.reader.ui.component.base.RYScaffold import me.ash.reader.ui.ext.collectAsStateValue import me.ash.reader.ui.ext.isScrollDown +import me.ash.reader.ui.page.home.HomeViewModel @Composable fun ReadingPage( navController: NavHostController, + homeViewModel: HomeViewModel, readingViewModel: ReadingViewModel = hiltViewModel(), ) { val tonalElevation = LocalReadingPageTonalElevation.current val readingUiState = readingViewModel.readingUiState.collectAsStateValue() + val homeUiState = homeViewModel.homeUiState.collectAsStateValue() val isShowToolBar = if (LocalReadingAutoHideToolbar.current.value) { readingUiState.articleWithFeed != null && !readingUiState.listState.isScrollDown() } else { true } + val pagingItems = homeUiState.pagingData.collectAsLazyPagingItems().itemSnapshotList + readingViewModel.recorderNextArticle(readingUiState, homeUiState, pagingItems) + LaunchedEffect(Unit) { navController.currentBackStackEntryFlow.collect { it.arguments?.getString("articleId")?.let { @@ -90,6 +97,9 @@ fun ReadingPage( onStarred = { readingViewModel.markStarred(it) }, + onNextArticle = { + readingViewModel.nextArticle(navController, homeUiState.nextArticleId) + }, onFullContent = { if (it) readingViewModel.renderFullContent() else readingViewModel.renderDescriptionContent() diff --git a/app/src/main/java/me/ash/reader/ui/page/home/reading/ReadingViewModel.kt b/app/src/main/java/me/ash/reader/ui/page/home/reading/ReadingViewModel.kt index 8f250ec..236f5a5 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/reading/ReadingViewModel.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/reading/ReadingViewModel.kt @@ -4,6 +4,8 @@ import android.util.Log import androidx.compose.foundation.lazy.LazyListState import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import androidx.navigation.NavController +import androidx.paging.ItemSnapshotList import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow @@ -11,9 +13,12 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch +import me.ash.reader.data.model.article.ArticleFlowItem import me.ash.reader.data.model.article.ArticleWithFeed import me.ash.reader.data.repository.RssHelper import me.ash.reader.data.repository.RssRepository +import me.ash.reader.ui.page.common.RouteName +import me.ash.reader.ui.page.home.HomeUiState import javax.inject.Inject @HiltViewModel @@ -114,6 +119,13 @@ class ReadingViewModel @Inject constructor( } } + fun nextArticle(navController: NavController, nextArticleId: String) { + navController.popBackStack() + if (nextArticleId.isNotBlank()) { + navController.navigate("${RouteName.READING}/${nextArticleId}") + } + } + private fun showLoading() { _readingUiState.update { it.copy(isLoading = true) @@ -125,6 +137,30 @@ class ReadingViewModel @Inject constructor( it.copy(isLoading = false) } } + + fun recorderNextArticle( + readingUiState: ReadingUiState, homeUiState: HomeUiState, pagingItems: + ItemSnapshotList + ) { + if (pagingItems.size > 0) { + val cur = readingUiState.articleWithFeed?.article + if (cur != null) { + var found = false + for (item in pagingItems) { + if (item is ArticleFlowItem.Article) { + val itemId = item.articleWithFeed.article.id + if (itemId == cur.id) { + found = true + homeUiState.nextArticleId = "" + } else if (found) { + homeUiState.nextArticleId = itemId + break + } + } + } + } + } + } } data class ReadingUiState(