Fix recomposition causing repeat get of extras
This commit is contained in:
parent
a1ceb9a489
commit
67b033f1ec
|
@ -14,7 +14,9 @@ class MainActivity : ComponentActivity() {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
setContent {
|
setContent {
|
||||||
HomeEntry()
|
HomeEntry(intent.extras).also {
|
||||||
|
intent.replaceExtras(null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package me.ash.reader.ui.page.common
|
package me.ash.reader.ui.page.common
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
import androidx.compose.animation.*
|
import androidx.compose.animation.*
|
||||||
import androidx.compose.animation.core.Spring
|
import androidx.compose.animation.core.Spring
|
||||||
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)
|
@OptIn(ExperimentalAnimationApi::class, androidx.compose.material.ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun HomeEntry() {
|
fun HomeEntry(
|
||||||
|
extras: Bundle? = null,
|
||||||
|
) {
|
||||||
val navController = rememberAnimatedNavController()
|
val navController = rememberAnimatedNavController()
|
||||||
|
|
||||||
AppTheme {
|
AppTheme {
|
||||||
|
@ -40,100 +43,100 @@ fun HomeEntry() {
|
||||||
Column(modifier = Modifier.background(MaterialTheme.colorScheme.surface)) {
|
Column(modifier = Modifier.background(MaterialTheme.colorScheme.surface)) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.statusBarsPadding()
|
.statusBarsPadding()
|
||||||
|
) {
|
||||||
|
AnimatedNavHost(
|
||||||
|
navController = navController,
|
||||||
|
startDestination = RouteName.HOME,
|
||||||
) {
|
) {
|
||||||
AnimatedNavHost(
|
composable(
|
||||||
navController = navController,
|
route = RouteName.HOME,
|
||||||
startDestination = 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(
|
HomePage(navController, extras?.get(ExtraName.ARTICLE_ID))
|
||||||
route = RouteName.HOME,
|
}
|
||||||
enterTransition = {
|
composable(
|
||||||
slideInHorizontally(
|
route = RouteName.SETTINGS,
|
||||||
animationSpec = spring(
|
enterTransition = {
|
||||||
stiffness = Spring.StiffnessLow,
|
slideInHorizontally(
|
||||||
dampingRatio = Spring.DampingRatioNoBouncy
|
animationSpec = spring(
|
||||||
),
|
stiffness = Spring.StiffnessLow,
|
||||||
initialOffsetX = { -it }
|
dampingRatio = Spring.DampingRatioNoBouncy
|
||||||
) + fadeIn(animationSpec = tween(220, delayMillis = 90))
|
),
|
||||||
},
|
initialOffsetX = { -it }
|
||||||
exitTransition = {
|
) + fadeIn(animationSpec = tween(220, delayMillis = 90))
|
||||||
slideOutHorizontally(
|
},
|
||||||
animationSpec = spring(
|
exitTransition = {
|
||||||
stiffness = Spring.StiffnessLow,
|
slideOutHorizontally(
|
||||||
dampingRatio = Spring.DampingRatioNoBouncy
|
animationSpec = spring(
|
||||||
),
|
stiffness = Spring.StiffnessLow,
|
||||||
targetOffsetX = { it }
|
dampingRatio = Spring.DampingRatioNoBouncy
|
||||||
) + fadeOut(animationSpec = tween(220, delayMillis = 90))
|
),
|
||||||
},
|
targetOffsetX = { -it }
|
||||||
popEnterTransition = {
|
) + fadeOut(animationSpec = tween(220, delayMillis = 90))
|
||||||
slideInHorizontally(
|
},
|
||||||
animationSpec = spring(
|
popEnterTransition = {
|
||||||
stiffness = Spring.StiffnessLow,
|
slideInHorizontally(
|
||||||
dampingRatio = Spring.DampingRatioNoBouncy
|
animationSpec = spring(
|
||||||
),
|
stiffness = Spring.StiffnessLow,
|
||||||
initialOffsetX = { -it }
|
dampingRatio = Spring.DampingRatioNoBouncy
|
||||||
) + fadeIn(animationSpec = tween(220, delayMillis = 90))
|
),
|
||||||
},
|
initialOffsetX = { -it }
|
||||||
popExitTransition = {
|
) + fadeIn(animationSpec = tween(220, delayMillis = 90))
|
||||||
slideOutHorizontally(
|
},
|
||||||
animationSpec = spring(
|
popExitTransition = {
|
||||||
stiffness = Spring.StiffnessLow,
|
slideOutHorizontally(
|
||||||
dampingRatio = Spring.DampingRatioNoBouncy
|
animationSpec = spring(
|
||||||
),
|
stiffness = Spring.StiffnessLow,
|
||||||
targetOffsetX = { it }
|
dampingRatio = Spring.DampingRatioNoBouncy
|
||||||
) + fadeOut(animationSpec = tween(220, delayMillis = 90))
|
),
|
||||||
},
|
targetOffsetX = { -it }
|
||||||
) {
|
) + fadeOut(animationSpec = tween(220, delayMillis = 90))
|
||||||
HomePage(navController)
|
},
|
||||||
}
|
) {
|
||||||
composable(
|
SettingsPage(navController)
|
||||||
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
|
Spacer(
|
||||||
.navigationBarsHeight()
|
modifier = Modifier
|
||||||
|
.navigationBarsHeight()
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,15 +9,11 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import com.google.accompanist.pager.ExperimentalPagerApi
|
import com.google.accompanist.pager.ExperimentalPagerApi
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import me.ash.reader.ui.extension.collectAsStateValue
|
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.FeedOptionDrawer
|
||||||
import me.ash.reader.ui.page.home.drawer.feed.FeedOptionViewAction
|
import me.ash.reader.ui.page.home.drawer.feed.FeedOptionViewAction
|
||||||
import me.ash.reader.ui.page.home.drawer.feed.FeedOptionViewModel
|
import me.ash.reader.ui.page.home.drawer.feed.FeedOptionViewModel
|
||||||
|
@ -32,41 +28,17 @@ import me.ash.reader.ui.widget.ViewPager
|
||||||
@Composable
|
@Composable
|
||||||
fun HomePage(
|
fun HomePage(
|
||||||
navController: NavHostController,
|
navController: NavHostController,
|
||||||
|
extrasArticleId: Any? = null,
|
||||||
viewModel: HomeViewModel = hiltViewModel(),
|
viewModel: HomeViewModel = hiltViewModel(),
|
||||||
readViewModel: ReadViewModel = hiltViewModel(),
|
readViewModel: ReadViewModel = hiltViewModel(),
|
||||||
feedOptionViewModel: FeedOptionViewModel = hiltViewModel(),
|
feedOptionViewModel: FeedOptionViewModel = hiltViewModel(),
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
|
||||||
val viewState = viewModel.viewState.collectAsStateValue()
|
val viewState = viewModel.viewState.collectAsStateValue()
|
||||||
val filterState = viewModel.filterState.collectAsStateValue()
|
val filterState = viewModel.filterState.collectAsStateValue()
|
||||||
val readState = readViewModel.viewState.collectAsStateValue()
|
val readState = readViewModel.viewState.collectAsStateValue()
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
OpenArticleByExtras(extrasArticleId)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BackHandler(true) {
|
BackHandler(true) {
|
||||||
val currentPage = viewState.pagerState.currentPage
|
val currentPage = viewState.pagerState.currentPage
|
||||||
|
|
|
@ -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,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user