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.LineHeightStyle
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.IntSize
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.example.research.R import com.example.research.R
import com.example.research.common.ui.theme.dictionaryTitleLarge 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.Spacing
import com.example.research.ui.theme.AppWindowInsets 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_CHARS = 1500
private const val MERGED_BLOCK_MAX_ITEMS = 12 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.SearchAction
import com.example.research.feature.search.SearchViewModel import com.example.research.feature.search.SearchViewModel
import com.example.research.ui.about.AboutScreen 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.main.MainRoute
import com.example.research.ui.settings.SettingsRoute import com.example.research.ui.settings.SettingsRoute
import com.example.research.ui.settings.SettingsViewModel import com.example.research.ui.settings.SettingsViewModel
@@ -104,6 +105,10 @@ fun AppNavigation(
} }
val articleState by searchViewModel.selectedArticle.collectAsStateWithLifecycle() val articleState by searchViewModel.selectedArticle.collectAsStateWithLifecycle()
var lastShownArticle by remember { mutableStateOf<ArticleState?>(null) }
LaunchedEffect(articleState) {
if (articleState != null) lastShownArticle = articleState
}
val effectiveScreen = when { val effectiveScreen = when {
currentScreen == Screen.About -> Screen.About currentScreen == Screen.About -> Screen.About
@@ -178,15 +183,20 @@ fun AppNavigation(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.surface color = MaterialTheme.colorScheme.surface
) { ) {
ArticleRoute( ArticleScreen(
searchViewModel = searchViewModel, articleState = articleState ?: lastShownArticle,
onNavigateBack = { onNavigateBack = {
if (searchViewModel.navigateBackFromArticle()) { if (!searchViewModel.navigateBackFromArticle()) {
return@ArticleRoute 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)
},
) )
} }
} }