From 67b033f1ecdcb2954347ea54a21bfd1ec12a83ac Mon Sep 17 00:00:00 2001 From: Ash Date: Mon, 28 Mar 2022 18:12:21 +0800 Subject: [PATCH] Fix recomposition causing repeat get of extras --- .../main/java/me/ash/reader/MainActivity.kt | 4 +- .../me/ash/reader/ui/page/common/HomeEntry.kt | 185 +++++++++--------- .../me/ash/reader/ui/page/home/HomePage.kt | 32 +-- .../ui/page/home/OpenArticleByExtras.kt | 38 ++++ 4 files changed, 137 insertions(+), 122 deletions(-) create mode 100644 app/src/main/java/me/ash/reader/ui/page/home/OpenArticleByExtras.kt diff --git a/app/src/main/java/me/ash/reader/MainActivity.kt b/app/src/main/java/me/ash/reader/MainActivity.kt index 46c48bb..b59f4d0 100644 --- a/app/src/main/java/me/ash/reader/MainActivity.kt +++ b/app/src/main/java/me/ash/reader/MainActivity.kt @@ -14,7 +14,9 @@ class MainActivity : ComponentActivity() { super.onCreate(savedInstanceState) WindowCompat.setDecorFitsSystemWindows(window, false) setContent { - HomeEntry() + HomeEntry(intent.extras).also { + intent.replaceExtras(null) + } } } } \ No newline at end of file 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 ade57d5..d1f0ca4 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 @@ -1,5 +1,6 @@ package me.ash.reader.ui.page.common +import android.os.Bundle import androidx.compose.animation.* import androidx.compose.animation.core.Spring import androidx.compose.animation.core.spring @@ -27,7 +28,9 @@ import me.ash.reader.ui.theme.AppTheme @OptIn(ExperimentalAnimationApi::class, androidx.compose.material.ExperimentalMaterialApi::class) @Composable -fun HomeEntry() { +fun HomeEntry( + extras: Bundle? = null, +) { val navController = rememberAnimatedNavController() AppTheme { @@ -40,100 +43,100 @@ fun HomeEntry() { Column(modifier = Modifier.background(MaterialTheme.colorScheme.surface)) { Row( modifier = Modifier - .weight(1f) - .statusBarsPadding() + .weight(1f) + .statusBarsPadding() + ) { + AnimatedNavHost( + navController = navController, + startDestination = RouteName.HOME, ) { - AnimatedNavHost( - navController = navController, - startDestination = RouteName.HOME, + composable( + route = RouteName.HOME, + enterTransition = { + slideInHorizontally( + animationSpec = spring( + stiffness = Spring.StiffnessLow, + dampingRatio = Spring.DampingRatioNoBouncy + ), + initialOffsetX = { -it } + ) + fadeIn(animationSpec = tween(220, delayMillis = 90)) + }, + exitTransition = { + slideOutHorizontally( + animationSpec = spring( + stiffness = Spring.StiffnessLow, + dampingRatio = Spring.DampingRatioNoBouncy + ), + targetOffsetX = { it } + ) + fadeOut(animationSpec = tween(220, delayMillis = 90)) + }, + popEnterTransition = { + slideInHorizontally( + animationSpec = spring( + stiffness = Spring.StiffnessLow, + dampingRatio = Spring.DampingRatioNoBouncy + ), + initialOffsetX = { -it } + ) + fadeIn(animationSpec = tween(220, delayMillis = 90)) + }, + popExitTransition = { + slideOutHorizontally( + animationSpec = spring( + stiffness = Spring.StiffnessLow, + dampingRatio = Spring.DampingRatioNoBouncy + ), + targetOffsetX = { it } + ) + fadeOut(animationSpec = tween(220, delayMillis = 90)) + }, ) { - composable( - route = RouteName.HOME, - enterTransition = { - slideInHorizontally( - animationSpec = spring( - stiffness = Spring.StiffnessLow, - dampingRatio = Spring.DampingRatioNoBouncy - ), - initialOffsetX = { -it } - ) + fadeIn(animationSpec = tween(220, delayMillis = 90)) - }, - exitTransition = { - slideOutHorizontally( - animationSpec = spring( - stiffness = Spring.StiffnessLow, - dampingRatio = Spring.DampingRatioNoBouncy - ), - targetOffsetX = { it } - ) + fadeOut(animationSpec = tween(220, delayMillis = 90)) - }, - popEnterTransition = { - slideInHorizontally( - animationSpec = spring( - stiffness = Spring.StiffnessLow, - dampingRatio = Spring.DampingRatioNoBouncy - ), - initialOffsetX = { -it } - ) + fadeIn(animationSpec = tween(220, delayMillis = 90)) - }, - popExitTransition = { - slideOutHorizontally( - animationSpec = spring( - stiffness = Spring.StiffnessLow, - dampingRatio = Spring.DampingRatioNoBouncy - ), - targetOffsetX = { it } - ) + fadeOut(animationSpec = tween(220, delayMillis = 90)) - }, - ) { - HomePage(navController) - } - composable( - route = RouteName.SETTINGS, - enterTransition = { - slideInHorizontally( - animationSpec = spring( - stiffness = Spring.StiffnessLow, - dampingRatio = Spring.DampingRatioNoBouncy - ), - initialOffsetX = { -it } - ) + fadeIn(animationSpec = tween(220, delayMillis = 90)) - }, - exitTransition = { - slideOutHorizontally( - animationSpec = spring( - stiffness = Spring.StiffnessLow, - dampingRatio = Spring.DampingRatioNoBouncy - ), - targetOffsetX = { -it } - ) + fadeOut(animationSpec = tween(220, delayMillis = 90)) - }, - popEnterTransition = { - slideInHorizontally( - animationSpec = spring( - stiffness = Spring.StiffnessLow, - dampingRatio = Spring.DampingRatioNoBouncy - ), - initialOffsetX = { -it } - ) + fadeIn(animationSpec = tween(220, delayMillis = 90)) - }, - popExitTransition = { - slideOutHorizontally( - animationSpec = spring( - stiffness = Spring.StiffnessLow, - dampingRatio = Spring.DampingRatioNoBouncy - ), - targetOffsetX = { -it } - ) + fadeOut(animationSpec = tween(220, delayMillis = 90)) - }, - ) { - SettingsPage(navController) - } + HomePage(navController, extras?.get(ExtraName.ARTICLE_ID)) + } + composable( + route = RouteName.SETTINGS, + enterTransition = { + slideInHorizontally( + animationSpec = spring( + stiffness = Spring.StiffnessLow, + dampingRatio = Spring.DampingRatioNoBouncy + ), + initialOffsetX = { -it } + ) + fadeIn(animationSpec = tween(220, delayMillis = 90)) + }, + exitTransition = { + slideOutHorizontally( + animationSpec = spring( + stiffness = Spring.StiffnessLow, + dampingRatio = Spring.DampingRatioNoBouncy + ), + targetOffsetX = { -it } + ) + fadeOut(animationSpec = tween(220, delayMillis = 90)) + }, + popEnterTransition = { + slideInHorizontally( + animationSpec = spring( + stiffness = Spring.StiffnessLow, + dampingRatio = Spring.DampingRatioNoBouncy + ), + initialOffsetX = { -it } + ) + fadeIn(animationSpec = tween(220, delayMillis = 90)) + }, + popExitTransition = { + slideOutHorizontally( + animationSpec = spring( + stiffness = Spring.StiffnessLow, + dampingRatio = Spring.DampingRatioNoBouncy + ), + targetOffsetX = { -it } + ) + fadeOut(animationSpec = tween(220, delayMillis = 90)) + }, + ) { + SettingsPage(navController) } } - Spacer( - modifier = Modifier - .navigationBarsHeight() + } + Spacer( + modifier = Modifier + .navigationBarsHeight() .fillMaxWidth() ) } diff --git a/app/src/main/java/me/ash/reader/ui/page/home/HomePage.kt b/app/src/main/java/me/ash/reader/ui/page/home/HomePage.kt index aea1d49..8f47ba0 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/HomePage.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/HomePage.kt @@ -9,15 +9,11 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavHostController import com.google.accompanist.pager.ExperimentalPagerApi -import kotlinx.coroutines.launch import me.ash.reader.ui.extension.collectAsStateValue -import me.ash.reader.ui.extension.findActivity -import me.ash.reader.ui.page.common.ExtraName import me.ash.reader.ui.page.home.drawer.feed.FeedOptionDrawer import me.ash.reader.ui.page.home.drawer.feed.FeedOptionViewAction import me.ash.reader.ui.page.home.drawer.feed.FeedOptionViewModel @@ -32,41 +28,17 @@ import me.ash.reader.ui.widget.ViewPager @Composable fun HomePage( navController: NavHostController, + extrasArticleId: Any? = null, viewModel: HomeViewModel = hiltViewModel(), readViewModel: ReadViewModel = hiltViewModel(), feedOptionViewModel: FeedOptionViewModel = hiltViewModel(), ) { - val context = LocalContext.current val viewState = viewModel.viewState.collectAsStateValue() val filterState = viewModel.filterState.collectAsStateValue() val readState = readViewModel.viewState.collectAsStateValue() val scope = rememberCoroutineScope() - LaunchedEffect(Unit) { - context.findActivity()?.let { activity -> - activity.intent?.let { intent -> - intent.extras?.get(ExtraName.ARTICLE_ID)?.let { - readViewModel.dispatch(ReadViewAction.ScrollToItem(2)) - scope.launch { - val article = readViewModel - .rssRepository.get() - .findArticleById(it.toString()) ?: return@launch - readViewModel.dispatch(ReadViewAction.InitData(article)) - if (article.feed.isFullContent) readViewModel.dispatch(ReadViewAction.RenderFullContent) - else readViewModel.dispatch(ReadViewAction.RenderDescriptionContent) - readViewModel.dispatch(ReadViewAction.RenderDescriptionContent) - viewModel.dispatch( - HomeViewAction.ScrollToPage( - scope = scope, - targetPage = 2, - ) - ) - } - } - intent.extras?.remove(ExtraName.ARTICLE_ID) - } - } - } + OpenArticleByExtras(extrasArticleId) BackHandler(true) { val currentPage = viewState.pagerState.currentPage diff --git a/app/src/main/java/me/ash/reader/ui/page/home/OpenArticleByExtras.kt b/app/src/main/java/me/ash/reader/ui/page/home/OpenArticleByExtras.kt new file mode 100644 index 0000000..a217df5 --- /dev/null +++ b/app/src/main/java/me/ash/reader/ui/page/home/OpenArticleByExtras.kt @@ -0,0 +1,38 @@ +package me.ash.reader.ui.page.home + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.rememberCoroutineScope +import androidx.hilt.navigation.compose.hiltViewModel +import kotlinx.coroutines.launch +import me.ash.reader.ui.page.home.read.ReadViewAction +import me.ash.reader.ui.page.home.read.ReadViewModel + +@Composable +fun OpenArticleByExtras( + extrasArticleId: Any? = null, + homeViewModel: HomeViewModel = hiltViewModel(), + readViewModel: ReadViewModel = hiltViewModel(), +) { + val scope = rememberCoroutineScope() + LaunchedEffect(extrasArticleId) { + extrasArticleId?.let { + readViewModel.dispatch(ReadViewAction.ScrollToItem(2)) + this.launch { + val article = readViewModel + .rssRepository.get() + .findArticleById(it.toString()) ?: return@launch + readViewModel.dispatch(ReadViewAction.InitData(article)) + if (article.feed.isFullContent) readViewModel.dispatch(ReadViewAction.RenderFullContent) + else readViewModel.dispatch(ReadViewAction.RenderDescriptionContent) + readViewModel.dispatch(ReadViewAction.RenderDescriptionContent) + homeViewModel.dispatch( + HomeViewAction.ScrollToPage( + scope = scope, + targetPage = 2, + ) + ) + } + } + } +} \ No newline at end of file