diff options
| author | 2023-01-17 11:35:28 +0000 | |
|---|---|---|
| committer | 2023-01-17 11:35:28 +0000 | |
| commit | 37ea02cabfdeeed07700a04f0c5a88fdab2a191c (patch) | |
| tree | 45bf24657f973f84154ec0c19d9e69b6042aa92a | |
| parent | e0fed23b3c5a28f21b6058d29605ce107bbd10e8 (diff) | |
| parent | de7fae785bd6d693c85e63e2590d62e6cc55bc6a (diff) | |
Merge "Fix the selected option not saved for App List"
4 files changed, 17 insertions, 15 deletions
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListViewModel.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListViewModel.kt index df828f2c0fa2..6cd1c0d6a5ae 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListViewModel.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListViewModel.kt @@ -51,7 +51,7 @@ internal data class AppListData<T : AppRecord>( } internal interface IAppListViewModel<T : AppRecord> { - val option: StateFlowBridge<Int?> + val optionFlow: MutableStateFlow<Int?> val spinnerOptionsFlow: Flow<List<SpinnerOption>> val appListDataFlow: Flow<AppListData<T>> } @@ -69,7 +69,7 @@ internal open class AppListViewModelImpl<T : AppRecord>( val appListConfig = StateFlowBridge<AppListConfig>() val listModel = StateFlowBridge<AppListModel<T>>() val showSystem = StateFlowBridge<Boolean>() - final override val option = StateFlowBridge<Int?>() + final override val optionFlow = MutableStateFlow<Int?>(null) val searchQuery = StateFlowBridge<String>() private val appListRepository = appListRepositoryFactory(application) @@ -97,7 +97,7 @@ internal open class AppListViewModelImpl<T : AppRecord>( listModel.getSpinnerOptions(recordList) } - override val appListDataFlow = option.flow.flatMapLatest(::filterAndSort) + override val appListDataFlow = optionFlow.filterNotNull().flatMapLatest(::filterAndSort) .combine(searchQuery.flow) { appListData, searchQuery -> appListData.filter { it.label.contains(other = searchQuery, ignoreCase = true) diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppList.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppList.kt index 34c3ee0e2c0c..7199e3a319fe 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppList.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppList.kt @@ -24,11 +24,10 @@ import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.Dp @@ -37,7 +36,6 @@ import com.android.settingslib.spa.framework.compose.LogCompositions import com.android.settingslib.spa.framework.compose.TimeMeasurer.Companion.rememberTimeMeasurer import com.android.settingslib.spa.framework.compose.rememberLazyListStateAndHideKeyboardWhenStartScroll import com.android.settingslib.spa.framework.compose.toState -import com.android.settingslib.spa.framework.util.StateFlowBridge import com.android.settingslib.spa.widget.ui.CategoryTitle import com.android.settingslib.spa.widget.ui.PlaceholderTitle import com.android.settingslib.spa.widget.ui.Spinner @@ -52,6 +50,7 @@ import com.android.settingslib.spaprivileged.model.app.AppListViewModel import com.android.settingslib.spaprivileged.model.app.AppRecord import com.android.settingslib.spaprivileged.model.app.IAppListViewModel import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow private const val TAG = "AppList" private const val CONTENT_TYPE_HEADER = "header" @@ -88,7 +87,7 @@ internal fun <T : AppRecord> AppListInput<T>.AppListImpl( val viewModel = viewModelSupplier() Column(Modifier.fillMaxSize()) { val optionsState = viewModel.spinnerOptionsFlow.collectAsState(null, Dispatchers.IO) - SpinnerOptions(optionsState, viewModel.option) + SpinnerOptions(optionsState, viewModel.optionFlow) val appListData = viewModel.appListDataFlow.collectAsState(null, Dispatchers.IO) listModel.AppListWidget(appListData, header, bottomPadding, noItemMessage) } @@ -97,15 +96,18 @@ internal fun <T : AppRecord> AppListInput<T>.AppListImpl( @Composable private fun SpinnerOptions( optionsState: State<List<SpinnerOption>?>, - optionBridge: StateFlowBridge<Int?>, + optionFlow: MutableStateFlow<Int?>, ) { val options = optionsState.value - val selectedOption = rememberSaveable(options) { - mutableStateOf(options?.let { it.firstOrNull()?.id ?: -1 }) + LaunchedEffect(options) { + if (options != null && !options.any { it.id == optionFlow.value }) { + // Reset to first option if the available options changed, and the current selected one + // does not in the new options. + optionFlow.value = options.let { it.firstOrNull()?.id ?: -1 } + } } - optionBridge.Sync(selectedOption) if (options != null) { - Spinner(options, selectedOption.value) { selectedOption.value = it } + Spinner(options, optionFlow.collectAsState().value) { optionFlow.value = it } } } diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt index 7151439c2a2f..b1d02f57c8d7 100644 --- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt +++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt @@ -56,7 +56,7 @@ class AppListViewModelTest { viewModel.appListConfig.setIfAbsent(CONFIG) viewModel.listModel.setIfAbsent(listModel) viewModel.showSystem.setIfAbsent(false) - viewModel.option.setIfAbsent(0) + viewModel.optionFlow.value = 0 viewModel.searchQuery.setIfAbsent("") viewModel.reloadApps() return viewModel diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt index 2a1f7a4ad908..d5c7c191d3ff 100644 --- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt +++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt @@ -29,7 +29,6 @@ import androidx.compose.ui.unit.dp import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settingslib.spa.framework.compose.toState -import com.android.settingslib.spa.framework.util.StateFlowBridge import com.android.settingslib.spa.widget.ui.SpinnerOption import com.android.settingslib.spaprivileged.R import com.android.settingslib.spaprivileged.model.app.AppEntry @@ -38,6 +37,7 @@ import com.android.settingslib.spaprivileged.model.app.AppListData import com.android.settingslib.spaprivileged.model.app.IAppListViewModel import com.android.settingslib.spaprivileged.tests.testutils.TestAppListModel import com.android.settingslib.spaprivileged.tests.testutils.TestAppRecord +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flowOf import org.junit.Rule import org.junit.Test @@ -125,7 +125,7 @@ class AppListTest { bottomPadding = 0.dp, ).AppListImpl { object : IAppListViewModel<TestAppRecord> { - override val option: StateFlowBridge<Int?> = StateFlowBridge() + override val optionFlow: MutableStateFlow<Int?> = MutableStateFlow(null) override val spinnerOptionsFlow = flowOf(options.mapIndexed { index, option -> SpinnerOption(id = index, text = option) }) |