From 232c1955ec1e0007b9b9393b988719001baca2e3 Mon Sep 17 00:00:00 2001 From: OneWay Date: Sun, 4 Oct 2026 12:27:00 +0000 Subject: [PATCH] fix(main): compose the main route only after preferences load Show a blank frame until the first preferences snapshot arrives, so the saved bar position does not flash or jump on cold start. --- app/src/main/java/com/example/research/ui/main/MainScreen.kt | 4 ++++ .../java/com/example/research/ui/settings/SettingsUiState.kt | 1 + .../com/example/research/ui/settings/SettingsViewModel.kt | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/app/src/main/java/com/example/research/ui/main/MainScreen.kt b/app/src/main/java/com/example/research/ui/main/MainScreen.kt index 8635a8e..25360ca 100644 --- a/app/src/main/java/com/example/research/ui/main/MainScreen.kt +++ b/app/src/main/java/com/example/research/ui/main/MainScreen.kt @@ -47,6 +47,10 @@ fun MainRoute( val settingsState by settingsViewModel.uiState.collectAsStateWithLifecycle() val searchQuery by searchViewModel.searchQuery.collectAsStateWithLifecycle() + if (!settingsState.hasLoadedPreferences) { + Box(modifier = Modifier.fillMaxSize()) + return + } val isSearchBarAtBottom = settingsState.searchBarPosition == "BOTTOM" val scrollPosition = remember(searchViewModel) { 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 8f89257..cb2e790 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 @@ -25,6 +25,7 @@ data class SettingsUiState( val importState: ImportState = ImportState.Idle, val dictionarySources: List = emptyList(), val hasCompletedStartupScan: Boolean = false, + val hasLoadedPreferences: 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 db79fbe..57228dc 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 @@ -54,6 +54,7 @@ private data class OperationStateInputs( val isLanguageExpanded: Boolean, val isSearchBarExpanded: Boolean, val isDictionariesExpanded: Boolean, + val hasLoadedPreferences: Boolean, ) class SettingsViewModel( @@ -163,6 +164,7 @@ class SettingsViewModel( preferencesManager.isLanguageExpanded, preferencesManager.isSearchBarExpanded, preferencesManager.isDictionariesExpanded, + hasLoadedPreferences, ) { params: Array -> @Suppress("UNCHECKED_CAST") OperationStateInputs( @@ -176,6 +178,7 @@ class SettingsViewModel( isLanguageExpanded = params[7] as Boolean, isSearchBarExpanded = params[8] as Boolean, isDictionariesExpanded = params[9] as Boolean, + hasLoadedPreferences = params[10] as Boolean, ) } @@ -254,6 +257,7 @@ class SettingsViewModel( importState = operationState.importState, dictionaryStatus = operationState.dictionaryStatus, hasCompletedStartupScan = operationState.hasCompletedStartupScan, + hasLoadedPreferences = operationState.hasLoadedPreferences, pipelineIdle = !isIndexing && !operationState.downloadState.isActive && !operationState.importState.isActive, @@ -293,6 +297,7 @@ class SettingsViewModel( } catch (e: Exception) { android.util.Log.w("SettingsViewModel", "Failed to load search bar position: ${e.message}") } + hasLoadedPreferences.value = true hasCompletedStartupScan.value = true preferencesManager.setHadNoDictionaries( localDictionaryRepository.dictionaries.value.isEmpty()