fix(navigation): keep article content during exit animation

On back navigation the article state was cleared before the exit animation ran, so the panel animated out empty except for the back arrow. The overlay now retains the last shown article state until the exit transition completes.
This commit is contained in:
OneWay committed 2026-09-26 00:38:57 +08:00
1 parent ed4a4436b8
commit c7f658dd94
2 files changed
+18 -31

No files matched your search

@@ -25,33 +25,10 @@ import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.LineHeightStyle
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.IntSize
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.example.research.R
import com.example.research.common.ui.theme.dictionaryTitleLarge
import com.example.research.feature.search.SearchAction
import com.example.research.ui.theme.Spacing
import com.example.research.ui.theme.AppWindowInsets
import com.example.research.feature.search.SearchViewModel
import androidx.compose.runtime.getValue
@Composable
fun ArticleRoute(
searchViewModel: SearchViewModel,
onNavigateBack: () -> Unit
) {
val articleState by searchViewModel.selectedArticle.collectAsStateWithLifecycle()
ArticleScreen(
articleState = articleState,
onNavigateBack = onNavigateBack,
onRefClick = { word ->
searchViewModel.onAction(SearchAction.SearchAndLoadArticle(word))
},
onScrollPositionChanged = { index, offset ->
searchViewModel.updateArticleScrollPosition(index, offset)
},
)
}
private const val MERGED_BLOCK_MAX_CHARS = 1500
private const val MERGED_BLOCK_MAX_ITEMS = 12
@@ -23,7 +23,8 @@ import androidx.window.core.layout.WindowSizeClass.Companion.WIDTH_DP_MEDIUM_LOW
import com.example.research.feature.search.SearchAction
import com.example.research.feature.search.SearchViewModel
import com.example.research.ui.about.AboutScreen
import com.example.research.ui.article.ArticleRoute
import com.example.research.ui.article.ArticleScreen
import com.example.research.ui.article.ArticleState
import com.example.research.ui.main.MainRoute
import com.example.research.ui.settings.SettingsRoute
import com.example.research.ui.settings.SettingsViewModel
@@ -104,6 +105,10 @@ fun AppNavigation(
}
val articleState by searchViewModel.selectedArticle.collectAsStateWithLifecycle()
var lastShownArticle by remember { mutableStateOf<ArticleState?>(null) }
LaunchedEffect(articleState) {
if (articleState != null) lastShownArticle = articleState
}
val effectiveScreen = when {
currentScreen == Screen.About -> Screen.About
@@ -178,15 +183,20 @@ fun AppNavigation(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.surface
) {
ArticleRoute(
searchViewModel = searchViewModel,
ArticleScreen(
articleState = articleState ?: lastShownArticle,
onNavigateBack = {
if (searchViewModel.navigateBackFromArticle()) {
return@ArticleRoute
if (!searchViewModel.navigateBackFromArticle()) {
searchViewModel.onAction(SearchAction.ClearArticle)
if (screenStack.size > 1) screenStack.removeAt(screenStack.lastIndex)
}
searchViewModel.onAction(SearchAction.ClearArticle)
if (screenStack.size > 1) screenStack.removeAt(screenStack.lastIndex)
}
},
onRefClick = { word ->
searchViewModel.onAction(SearchAction.SearchAndLoadArticle(word))
},
onScrollPositionChanged = { index, offset ->
searchViewModel.updateArticleScrollPosition(index, offset)
},
)
}
}