From 78754d2c75f9f0b1df0ac017b7504ede54137ae4 Mon Sep 17 00:00:00 2001 From: OneWay Date: Sat, 5 Sep 2026 05:55:56 +0800 Subject: [PATCH] fix: tie back arrow to pipeline idle state Computed from operation states in SettingsViewModel instead of a fixed delay; cancel and error release the arrow immediately. --- .../feature/download/model/DownloadState.kt | 3 ++ .../research/ui/navigation/AppNavigation.kt | 31 +------------------ .../research/ui/settings/ImportState.kt | 3 ++ .../research/ui/settings/SettingsUiState.kt | 1 + .../research/ui/settings/SettingsViewModel.kt | 4 +++ 5 files changed, 12 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/com/example/research/feature/download/model/DownloadState.kt b/app/src/main/java/com/example/research/feature/download/model/DownloadState.kt index 9260a9e..8b4e2b3 100644 --- a/app/src/main/java/com/example/research/feature/download/model/DownloadState.kt +++ b/app/src/main/java/com/example/research/feature/download/model/DownloadState.kt @@ -11,3 +11,6 @@ sealed class DownloadState { data class Error(val message: String) : DownloadState() data object Cancelled : DownloadState() } + +val DownloadState.isActive: Boolean + get() = this is DownloadState.Loading || this is DownloadState.Extracting || this is DownloadState.Success diff --git a/app/src/main/java/com/example/research/ui/navigation/AppNavigation.kt b/app/src/main/java/com/example/research/ui/navigation/AppNavigation.kt index 67ff337..75046e8 100644 --- a/app/src/main/java/com/example/research/ui/navigation/AppNavigation.kt +++ b/app/src/main/java/com/example/research/ui/navigation/AppNavigation.kt @@ -9,15 +9,11 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.window.core.layout.WindowSizeClass.Companion.WIDTH_DP_MEDIUM_LOWER_BOUND import com.example.research.feature.search.SearchAction import com.example.research.feature.search.SearchViewModel -import com.example.research.feature.download.model.DownloadState import com.example.research.ui.about.AboutScreen import com.example.research.ui.article.ArticleRoute import com.example.research.ui.main.MainRoute -import com.example.research.ui.settings.ImportState import com.example.research.ui.settings.SettingsRoute import com.example.research.ui.settings.SettingsViewModel -import kotlinx.coroutines.delay -import kotlin.time.Duration.Companion.milliseconds private data class NavigationState( val shouldShowSettings: Boolean, @@ -54,35 +50,10 @@ fun AppNavigation( val currentScreen = screenStack.lastOrNull() ?: Screen.Home val settingsState by settingsViewModel.uiState.collectAsStateWithLifecycle() - val progressSnapshot by settingsViewModel.progressSnapshot.collectAsStateWithLifecycle() - val isPipelineActiveByState = remember( - progressSnapshot, - settingsState.indexingProgress.isIndexing, - settingsState.downloadState, - settingsState.importState, - ) { - progressSnapshot != null || - settingsState.indexingProgress.isIndexing || - settingsState.downloadState is DownloadState.Loading || - settingsState.downloadState is DownloadState.Extracting || - settingsState.downloadState is DownloadState.Success || - settingsState.importState is ImportState.Importing || - settingsState.importState is ImportState.Extracting || - settingsState.importState is ImportState.Success - } - var stickyPipelineActive by rememberSaveable { mutableStateOf(false) } - LaunchedEffect(isPipelineActiveByState) { - if (isPipelineActiveByState) { - stickyPipelineActive = true - } else { - delay(1500.milliseconds) - stickyPipelineActive = false - } - } val navState by remember { derivedStateOf { - val isOperationActive = stickyPipelineActive + val isOperationActive = !settingsState.pipelineIdle val hasConfirmedNoDictionaries = settingsState.hasCompletedStartupScan && settingsState.dictionaries.isEmpty() val hasSeededNoDictionaries = seedNoDictionaries && !settingsState.hasCompletedStartupScan diff --git a/app/src/main/java/com/example/research/ui/settings/ImportState.kt b/app/src/main/java/com/example/research/ui/settings/ImportState.kt index 65bc3a9..9ad4652 100644 --- a/app/src/main/java/com/example/research/ui/settings/ImportState.kt +++ b/app/src/main/java/com/example/research/ui/settings/ImportState.kt @@ -10,3 +10,6 @@ sealed interface ImportState { data object Success : ImportState data class Error(val message: String) : ImportState } + +val ImportState.isActive: Boolean + get() = this is ImportState.Importing || this is ImportState.Extracting || this is ImportState.Success diff --git a/app/src/main/java/com/example/research/ui/settings/SettingsUiState.kt b/app/src/main/java/com/example/research/ui/settings/SettingsUiState.kt index b593303..6aaf19a 100644 --- a/app/src/main/java/com/example/research/ui/settings/SettingsUiState.kt +++ b/app/src/main/java/com/example/research/ui/settings/SettingsUiState.kt @@ -23,6 +23,7 @@ data class SettingsUiState( val importState: ImportState = ImportState.Idle, val dictionarySources: List = emptyList(), val hasCompletedStartupScan: Boolean = false, + val pipelineIdle: Boolean = true, val appVersion: String = "1.0", ) diff --git a/app/src/main/java/com/example/research/ui/settings/SettingsViewModel.kt b/app/src/main/java/com/example/research/ui/settings/SettingsViewModel.kt index 8116e6c..94f3cb1 100644 --- a/app/src/main/java/com/example/research/ui/settings/SettingsViewModel.kt +++ b/app/src/main/java/com/example/research/ui/settings/SettingsViewModel.kt @@ -19,6 +19,7 @@ import com.example.research.data.local.preferences.PreferencesManager import com.example.research.data.repository.LocalDictionaryRepository import com.example.research.feature.download.DownloadManager import com.example.research.feature.download.model.DownloadState +import com.example.research.feature.download.model.isActive import com.example.research.feature.download.repository.DictionaryRepository import com.example.research.feature.import.DictionaryImportManager import kotlinx.coroutines.Dispatchers @@ -225,6 +226,9 @@ class SettingsViewModel( importState = operationState.importState, dictionaryStatus = operationState.dictionaryStatus, hasCompletedStartupScan = operationState.hasCompletedStartupScan, + pipelineIdle = !isIndexing && + !operationState.downloadState.isActive && + !operationState.importState.isActive, isThemeExpanded = operationState.isThemeExpanded, isLanguageExpanded = operationState.isLanguageExpanded, isDictionariesExpanded = operationState.isDictionariesExpanded,