diff --git a/app/src/main/java/com/sadellie/unitto/screens/second/SecondScreen.kt b/app/src/main/java/com/sadellie/unitto/screens/second/SecondScreen.kt index 2d4f3e68..042060a1 100644 --- a/app/src/main/java/com/sadellie/unitto/screens/second/SecondScreen.kt +++ b/app/src/main/java/com/sadellie/unitto/screens/second/SecondScreen.kt @@ -45,6 +45,7 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.sadellie.unitto.R import com.sadellie.unitto.data.units.AbstractUnit import com.sadellie.unitto.data.units.UnitGroup @@ -73,7 +74,7 @@ fun LeftSideScreen( navigateToSettingsActtion: () -> Unit, selectAction: (AbstractUnit) -> Unit ) { - val uiState = viewModel.uiState + val uiState = viewModel.mainFlow.collectAsStateWithLifecycle() val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()) val chipsRowLazyListState = rememberLazyListState() val focusManager = LocalFocusManager.current @@ -96,12 +97,12 @@ fun LeftSideScreen( ) { SearchBar( title = stringResource(R.string.units_screen_from), - value = uiState.searchQuery, + value = uiState.value.searchQuery, onValueChange = { viewModel.onSearchQueryChange(it) viewModel.loadUnitsToShow(true) }, - favoritesOnly = uiState.favoritesOnly, + favoritesOnly = uiState.value.favoritesOnly, favoriteAction = { viewModel.toggleFavoritesOnly() viewModel.loadUnitsToShow(true) @@ -111,8 +112,8 @@ fun LeftSideScreen( scrollBehavior = scrollBehavior ) ChipsRow( - chosenUnitGroup = viewModel.uiState.chosenUnitGroup, - items = uiState.shownUnitGroups, + chosenUnitGroup = uiState.value.chosenUnitGroup, + items = uiState.value.shownUnitGroups, selectAction = { viewModel.toggleSelectedChip(it) viewModel.loadUnitsToShow(true) @@ -124,14 +125,14 @@ fun LeftSideScreen( } ) { paddingValues -> Crossfade( - targetState = uiState.unitsToShow.isEmpty(), + targetState = uiState.value.unitsToShow.isEmpty(), modifier = Modifier.padding(paddingValues) ) { noUnits -> if (noUnits) { SearchPlaceholder(navigateToSettingsActtion = navigateToSettingsActtion) } else { LazyColumn(Modifier.fillMaxSize()) { - uiState.unitsToShow.forEach { (unitGroup, listOfUnits) -> + uiState.value.unitsToShow.forEach { (unitGroup, listOfUnits) -> item(unitGroup.name) { UnitGroupHeader(Modifier.animateItemPlacement(), unitGroup) } @@ -163,7 +164,7 @@ fun LeftSideScreen( viewModel.setSelectedChip(currentUnit.group) viewModel.loadUnitsToShow(true) - val groupToSelect = uiState.shownUnitGroups.indexOf(currentUnit.group) + val groupToSelect = uiState.value.shownUnitGroups.indexOf(currentUnit.group) if (groupToSelect > -1) { chipsRowLazyListState.animateScrollToItem(groupToSelect) } @@ -191,7 +192,7 @@ fun RightSideScreen( inputValue: BigDecimal, unitFrom: AbstractUnit ) { - val uiState = viewModel.uiState + val uiState = viewModel.mainFlow.collectAsStateWithLifecycle() val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()) val focusManager = LocalFocusManager.current @@ -200,12 +201,12 @@ fun RightSideScreen( topBar = { SearchBar( title = stringResource(R.string.units_screen_from), - value = uiState.searchQuery, + value = uiState.value.searchQuery, onValueChange = { viewModel.onSearchQueryChange(it) viewModel.loadUnitsToShow(false) }, - favoritesOnly = uiState.favoritesOnly, + favoritesOnly = uiState.value.favoritesOnly, favoriteAction = { viewModel.toggleFavoritesOnly() viewModel.loadUnitsToShow(false) @@ -217,14 +218,14 @@ fun RightSideScreen( } ) { paddingValues -> Crossfade( - targetState = uiState.unitsToShow.isEmpty(), + targetState = uiState.value.unitsToShow.isEmpty(), modifier = Modifier.padding(paddingValues) ) { noUnits -> if (noUnits) { SearchPlaceholder(navigateToSettingsActtion = navigateToSettingsActtion) } else { LazyColumn(Modifier.fillMaxSize()) { - uiState.unitsToShow.forEach { (unitGroup, listOfUnits) -> + uiState.value.unitsToShow.forEach { (unitGroup, listOfUnits) -> item(unitGroup.name) { UnitGroupHeader(Modifier.animateItemPlacement(), unitGroup) } diff --git a/app/src/main/java/com/sadellie/unitto/screens/second/SecondViewModel.kt b/app/src/main/java/com/sadellie/unitto/screens/second/SecondViewModel.kt index 92b0fd1f..772427c0 100644 --- a/app/src/main/java/com/sadellie/unitto/screens/second/SecondViewModel.kt +++ b/app/src/main/java/com/sadellie/unitto/screens/second/SecondViewModel.kt @@ -18,9 +18,6 @@ package com.sadellie.unitto.screens.second -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.sadellie.unitto.data.units.AbstractUnit @@ -31,6 +28,10 @@ import com.sadellie.unitto.data.units.database.MyBasedUnit import com.sadellie.unitto.data.units.database.MyBasedUnitsRepository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import javax.inject.Inject @@ -39,18 +40,26 @@ import javax.inject.Inject class SecondViewModel @Inject constructor( private val basedUnitRepository: MyBasedUnitsRepository, private val allUnitsRepository: AllUnitsRepository, - private val unitGroupsRepository: UnitGroupsRepository + unitGroupsRepository: UnitGroupsRepository ) : ViewModel() { - var uiState: SecondScreenUIState by mutableStateOf(SecondScreenUIState()) - private set + private val _uiStateFlow = MutableStateFlow(SecondScreenUIState()) + + val mainFlow = combine(_uiStateFlow, unitGroupsRepository.shownUnitGroups) { uiState, shown -> + return@combine uiState.copy(shownUnitGroups = shown) + } + .stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5000), + initialValue = SecondScreenUIState() + ) fun toggleFavoritesOnly() { - uiState = uiState.copy(favoritesOnly = !uiState.favoritesOnly) + _uiStateFlow.value = _uiStateFlow.value.copy(favoritesOnly = !_uiStateFlow.value.favoritesOnly) } fun onSearchQueryChange(newValue: String) { - uiState = uiState.copy(searchQuery = newValue) + _uiStateFlow.value = _uiStateFlow.value.copy(searchQuery = newValue) } /** @@ -59,7 +68,7 @@ class SecondViewModel @Inject constructor( * @param unitGroup Chip to change to. */ fun setSelectedChip(unitGroup: UnitGroup) { - uiState = uiState.copy(chosenUnitGroup = unitGroup) + _uiStateFlow.value = _uiStateFlow.value.copy(chosenUnitGroup = unitGroup) } /** @@ -71,8 +80,8 @@ class SecondViewModel @Inject constructor( * @param unitGroup [UnitGroup], currently selected chip. */ fun toggleSelectedChip(unitGroup: UnitGroup) { - val newUnitGroup = if (uiState.chosenUnitGroup == unitGroup) null else unitGroup - uiState = uiState.copy(chosenUnitGroup = newUnitGroup) + val newUnitGroup = if (_uiStateFlow.value.chosenUnitGroup == unitGroup) null else unitGroup + _uiStateFlow.value = _uiStateFlow.value.copy(chosenUnitGroup = newUnitGroup) } /** @@ -90,13 +99,13 @@ class SecondViewModel @Inject constructor( withContext(Dispatchers.Default) { val unitsToShow = allUnitsRepository.filterUnits( hideBrokenCurrencies = hideBrokenCurrencies, - chosenUnitGroup = uiState.chosenUnitGroup, - favoritesOnly = uiState.favoritesOnly, - searchQuery = uiState.searchQuery, - allUnitsGroups = uiState.shownUnitGroups + chosenUnitGroup = _uiStateFlow.value.chosenUnitGroup, + favoritesOnly = _uiStateFlow.value.favoritesOnly, + searchQuery = _uiStateFlow.value.searchQuery, + allUnitsGroups = _uiStateFlow.value.shownUnitGroups ) - uiState = uiState.copy(unitsToShow = unitsToShow) + _uiStateFlow.value = _uiStateFlow.value.copy(unitsToShow = unitsToShow) } } } @@ -119,12 +128,4 @@ class SecondViewModel @Inject constructor( ) } } - - init { - viewModelScope.launch { - unitGroupsRepository.shownUnitGroups.collect { - uiState = uiState.copy(shownUnitGroups = it) - } - } - } }