Merge "Fix the selected option not saved for App List"
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user