diff --git a/app/src/main/java/io/homeassistant/companion/android/settings/sensor/SensorDetailViewModel.kt b/app/src/main/java/io/homeassistant/companion/android/settings/sensor/SensorDetailViewModel.kt index a9e947b6e94..00088ed429e 100644 --- a/app/src/main/java/io/homeassistant/companion/android/settings/sensor/SensorDetailViewModel.kt +++ b/app/src/main/java/io/homeassistant/companion/android/settings/sensor/SensorDetailViewModel.kt @@ -36,6 +36,7 @@ import io.homeassistant.companion.android.sensors.SensorReceiver import javax.inject.Inject import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow @@ -75,6 +76,8 @@ class SensorDetailViewModel @Inject constructor( ) data class SettingDialogState( val setting: SensorSetting, + /** Indicates if this is still loading entries in the background */ + val loading: Boolean, /** List of entity ID to entity pairs */ val entries: List>, /** List of selected entity ID */ @@ -225,14 +228,27 @@ class SensorDetailViewModel @Inject constructor( fun setServersExpanded(expand: Boolean) = viewModelScope.launch { _serversDoExpand.emit(expand) } /** - * Builds a SettingDialogState based on the given Sensor Setting. + * Builds a SettingDialogState based on the given Sensor Setting. Depending on the + * device and/or connection, this may take some time. * Should trigger a dialog open in view. */ - fun onSettingWithDialogPressed(setting: SensorSetting) { + fun onSettingWithDialogPressed(setting: SensorSetting) = viewModelScope.launch { + val dialogLoadingJob = launch { + // In case getting entries takes too long, display a temporary loading dialog + delay(1000L) + sensorSettingsDialog = SettingDialogState( + setting = setting, + loading = true, + entries = listOf(), + entriesSelected = listOf() + ) + } + val listKeys = getSettingKeys(setting) val listEntries = getSettingEntries(setting, null) val state = SettingDialogState( setting = setting, + loading = false, entries = when { setting.valueType == SensorSettingType.LIST || setting.valueType == SensorSettingType.LIST_APPS || @@ -256,6 +272,7 @@ class SensorDetailViewModel @Inject constructor( emptyList() } ) + dialogLoadingJob.cancel() sensorSettingsDialog = state } diff --git a/app/src/main/java/io/homeassistant/companion/android/settings/sensor/views/SensorDetailView.kt b/app/src/main/java/io/homeassistant/companion/android/settings/sensor/views/SensorDetailView.kt index a817551be2e..a450fc4aaf8 100644 --- a/app/src/main/java/io/homeassistant/companion/android/settings/sensor/views/SensorDetailView.kt +++ b/app/src/main/java/io/homeassistant/companion/android/settings/sensor/views/SensorDetailView.kt @@ -28,6 +28,7 @@ import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.material.Card import androidx.compose.material.Checkbox +import androidx.compose.material.CircularProgressIndicator import androidx.compose.material.ContentAlpha import androidx.compose.material.Divider import androidx.compose.material.LocalContentAlpha @@ -51,7 +52,6 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment -import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.graphics.ColorFilter @@ -484,7 +484,6 @@ fun SensorDetailRow( } } -@OptIn(ExperimentalComposeUiApi::class) @Composable fun SensorDetailSettingDialog( viewModel: SensorDetailViewModel, @@ -494,14 +493,23 @@ fun SensorDetailSettingDialog( ) { val keyboardController = LocalSoftwareKeyboardController.current val listSettingDialog = state.setting.valueType.listType - val inputValue = remember { mutableStateOf(state.setting.value) } - val checkedValue = remember { mutableStateListOf().also { it.addAll(state.entriesSelected) } } + val inputValue = remember(state.loading) { mutableStateOf(state.setting.value) } + val checkedValue = remember(state.loading) { mutableStateListOf().also { it.addAll(state.entriesSelected) } } MdcAlertDialog( onDismissRequest = onDismiss, title = { Text(viewModel.getSettingTranslatedTitle(state.setting.name)) }, content = { - if (listSettingDialog) { + if (state.loading) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + horizontalArrangement = Arrangement.Center + ) { + CircularProgressIndicator() + } + } else if (listSettingDialog) { LazyColumn { items(state.entries, key = { (id) -> id }) { (id, entry) -> SensorDetailSettingRow( @@ -540,7 +548,9 @@ fun SensorDetailSettingDialog( } }, onCancel = onDismiss, - onSave = if (state.setting.valueType != SensorSettingType.LIST) { + onSave = if (state.loading) { + null + } else if (state.setting.valueType != SensorSettingType.LIST) { { if (listSettingDialog) { inputValue.value = checkedValue.joinToString().replace("[", "").replace("]", "")