mirror of
https://github.com/Myzel394/NumberHub.git
synced 2025-06-19 08:45:27 +02:00
State flow for unit selection screens
This commit is contained in:
parent
f6c1d44be2
commit
5621848c5a
@ -45,6 +45,7 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
|
|||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.sadellie.unitto.R
|
import com.sadellie.unitto.R
|
||||||
import com.sadellie.unitto.data.units.AbstractUnit
|
import com.sadellie.unitto.data.units.AbstractUnit
|
||||||
import com.sadellie.unitto.data.units.UnitGroup
|
import com.sadellie.unitto.data.units.UnitGroup
|
||||||
@ -73,7 +74,7 @@ fun LeftSideScreen(
|
|||||||
navigateToSettingsActtion: () -> Unit,
|
navigateToSettingsActtion: () -> Unit,
|
||||||
selectAction: (AbstractUnit) -> Unit
|
selectAction: (AbstractUnit) -> Unit
|
||||||
) {
|
) {
|
||||||
val uiState = viewModel.uiState
|
val uiState = viewModel.mainFlow.collectAsStateWithLifecycle()
|
||||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||||
val chipsRowLazyListState = rememberLazyListState()
|
val chipsRowLazyListState = rememberLazyListState()
|
||||||
val focusManager = LocalFocusManager.current
|
val focusManager = LocalFocusManager.current
|
||||||
@ -96,12 +97,12 @@ fun LeftSideScreen(
|
|||||||
) {
|
) {
|
||||||
SearchBar(
|
SearchBar(
|
||||||
title = stringResource(R.string.units_screen_from),
|
title = stringResource(R.string.units_screen_from),
|
||||||
value = uiState.searchQuery,
|
value = uiState.value.searchQuery,
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
viewModel.onSearchQueryChange(it)
|
viewModel.onSearchQueryChange(it)
|
||||||
viewModel.loadUnitsToShow(true)
|
viewModel.loadUnitsToShow(true)
|
||||||
},
|
},
|
||||||
favoritesOnly = uiState.favoritesOnly,
|
favoritesOnly = uiState.value.favoritesOnly,
|
||||||
favoriteAction = {
|
favoriteAction = {
|
||||||
viewModel.toggleFavoritesOnly()
|
viewModel.toggleFavoritesOnly()
|
||||||
viewModel.loadUnitsToShow(true)
|
viewModel.loadUnitsToShow(true)
|
||||||
@ -111,8 +112,8 @@ fun LeftSideScreen(
|
|||||||
scrollBehavior = scrollBehavior
|
scrollBehavior = scrollBehavior
|
||||||
)
|
)
|
||||||
ChipsRow(
|
ChipsRow(
|
||||||
chosenUnitGroup = viewModel.uiState.chosenUnitGroup,
|
chosenUnitGroup = uiState.value.chosenUnitGroup,
|
||||||
items = uiState.shownUnitGroups,
|
items = uiState.value.shownUnitGroups,
|
||||||
selectAction = {
|
selectAction = {
|
||||||
viewModel.toggleSelectedChip(it)
|
viewModel.toggleSelectedChip(it)
|
||||||
viewModel.loadUnitsToShow(true)
|
viewModel.loadUnitsToShow(true)
|
||||||
@ -124,14 +125,14 @@ fun LeftSideScreen(
|
|||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
Crossfade(
|
Crossfade(
|
||||||
targetState = uiState.unitsToShow.isEmpty(),
|
targetState = uiState.value.unitsToShow.isEmpty(),
|
||||||
modifier = Modifier.padding(paddingValues)
|
modifier = Modifier.padding(paddingValues)
|
||||||
) { noUnits ->
|
) { noUnits ->
|
||||||
if (noUnits) {
|
if (noUnits) {
|
||||||
SearchPlaceholder(navigateToSettingsActtion = navigateToSettingsActtion)
|
SearchPlaceholder(navigateToSettingsActtion = navigateToSettingsActtion)
|
||||||
} else {
|
} else {
|
||||||
LazyColumn(Modifier.fillMaxSize()) {
|
LazyColumn(Modifier.fillMaxSize()) {
|
||||||
uiState.unitsToShow.forEach { (unitGroup, listOfUnits) ->
|
uiState.value.unitsToShow.forEach { (unitGroup, listOfUnits) ->
|
||||||
item(unitGroup.name) {
|
item(unitGroup.name) {
|
||||||
UnitGroupHeader(Modifier.animateItemPlacement(), unitGroup)
|
UnitGroupHeader(Modifier.animateItemPlacement(), unitGroup)
|
||||||
}
|
}
|
||||||
@ -163,7 +164,7 @@ fun LeftSideScreen(
|
|||||||
viewModel.setSelectedChip(currentUnit.group)
|
viewModel.setSelectedChip(currentUnit.group)
|
||||||
viewModel.loadUnitsToShow(true)
|
viewModel.loadUnitsToShow(true)
|
||||||
|
|
||||||
val groupToSelect = uiState.shownUnitGroups.indexOf(currentUnit.group)
|
val groupToSelect = uiState.value.shownUnitGroups.indexOf(currentUnit.group)
|
||||||
if (groupToSelect > -1) {
|
if (groupToSelect > -1) {
|
||||||
chipsRowLazyListState.animateScrollToItem(groupToSelect)
|
chipsRowLazyListState.animateScrollToItem(groupToSelect)
|
||||||
}
|
}
|
||||||
@ -191,7 +192,7 @@ fun RightSideScreen(
|
|||||||
inputValue: BigDecimal,
|
inputValue: BigDecimal,
|
||||||
unitFrom: AbstractUnit
|
unitFrom: AbstractUnit
|
||||||
) {
|
) {
|
||||||
val uiState = viewModel.uiState
|
val uiState = viewModel.mainFlow.collectAsStateWithLifecycle()
|
||||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||||
val focusManager = LocalFocusManager.current
|
val focusManager = LocalFocusManager.current
|
||||||
|
|
||||||
@ -200,12 +201,12 @@ fun RightSideScreen(
|
|||||||
topBar = {
|
topBar = {
|
||||||
SearchBar(
|
SearchBar(
|
||||||
title = stringResource(R.string.units_screen_from),
|
title = stringResource(R.string.units_screen_from),
|
||||||
value = uiState.searchQuery,
|
value = uiState.value.searchQuery,
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
viewModel.onSearchQueryChange(it)
|
viewModel.onSearchQueryChange(it)
|
||||||
viewModel.loadUnitsToShow(false)
|
viewModel.loadUnitsToShow(false)
|
||||||
},
|
},
|
||||||
favoritesOnly = uiState.favoritesOnly,
|
favoritesOnly = uiState.value.favoritesOnly,
|
||||||
favoriteAction = {
|
favoriteAction = {
|
||||||
viewModel.toggleFavoritesOnly()
|
viewModel.toggleFavoritesOnly()
|
||||||
viewModel.loadUnitsToShow(false)
|
viewModel.loadUnitsToShow(false)
|
||||||
@ -217,14 +218,14 @@ fun RightSideScreen(
|
|||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
Crossfade(
|
Crossfade(
|
||||||
targetState = uiState.unitsToShow.isEmpty(),
|
targetState = uiState.value.unitsToShow.isEmpty(),
|
||||||
modifier = Modifier.padding(paddingValues)
|
modifier = Modifier.padding(paddingValues)
|
||||||
) { noUnits ->
|
) { noUnits ->
|
||||||
if (noUnits) {
|
if (noUnits) {
|
||||||
SearchPlaceholder(navigateToSettingsActtion = navigateToSettingsActtion)
|
SearchPlaceholder(navigateToSettingsActtion = navigateToSettingsActtion)
|
||||||
} else {
|
} else {
|
||||||
LazyColumn(Modifier.fillMaxSize()) {
|
LazyColumn(Modifier.fillMaxSize()) {
|
||||||
uiState.unitsToShow.forEach { (unitGroup, listOfUnits) ->
|
uiState.value.unitsToShow.forEach { (unitGroup, listOfUnits) ->
|
||||||
item(unitGroup.name) {
|
item(unitGroup.name) {
|
||||||
UnitGroupHeader(Modifier.animateItemPlacement(), unitGroup)
|
UnitGroupHeader(Modifier.animateItemPlacement(), unitGroup)
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,6 @@
|
|||||||
|
|
||||||
package com.sadellie.unitto.screens.second
|
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.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.sadellie.unitto.data.units.AbstractUnit
|
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 com.sadellie.unitto.data.units.database.MyBasedUnitsRepository
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.Dispatchers
|
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.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -39,18 +40,26 @@ import javax.inject.Inject
|
|||||||
class SecondViewModel @Inject constructor(
|
class SecondViewModel @Inject constructor(
|
||||||
private val basedUnitRepository: MyBasedUnitsRepository,
|
private val basedUnitRepository: MyBasedUnitsRepository,
|
||||||
private val allUnitsRepository: AllUnitsRepository,
|
private val allUnitsRepository: AllUnitsRepository,
|
||||||
private val unitGroupsRepository: UnitGroupsRepository
|
unitGroupsRepository: UnitGroupsRepository
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
var uiState: SecondScreenUIState by mutableStateOf(SecondScreenUIState())
|
private val _uiStateFlow = MutableStateFlow(SecondScreenUIState())
|
||||||
private set
|
|
||||||
|
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() {
|
fun toggleFavoritesOnly() {
|
||||||
uiState = uiState.copy(favoritesOnly = !uiState.favoritesOnly)
|
_uiStateFlow.value = _uiStateFlow.value.copy(favoritesOnly = !_uiStateFlow.value.favoritesOnly)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onSearchQueryChange(newValue: String) {
|
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.
|
* @param unitGroup Chip to change to.
|
||||||
*/
|
*/
|
||||||
fun setSelectedChip(unitGroup: UnitGroup) {
|
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.
|
* @param unitGroup [UnitGroup], currently selected chip.
|
||||||
*/
|
*/
|
||||||
fun toggleSelectedChip(unitGroup: UnitGroup) {
|
fun toggleSelectedChip(unitGroup: UnitGroup) {
|
||||||
val newUnitGroup = if (uiState.chosenUnitGroup == unitGroup) null else unitGroup
|
val newUnitGroup = if (_uiStateFlow.value.chosenUnitGroup == unitGroup) null else unitGroup
|
||||||
uiState = uiState.copy(chosenUnitGroup = newUnitGroup)
|
_uiStateFlow.value = _uiStateFlow.value.copy(chosenUnitGroup = newUnitGroup)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -90,13 +99,13 @@ class SecondViewModel @Inject constructor(
|
|||||||
withContext(Dispatchers.Default) {
|
withContext(Dispatchers.Default) {
|
||||||
val unitsToShow = allUnitsRepository.filterUnits(
|
val unitsToShow = allUnitsRepository.filterUnits(
|
||||||
hideBrokenCurrencies = hideBrokenCurrencies,
|
hideBrokenCurrencies = hideBrokenCurrencies,
|
||||||
chosenUnitGroup = uiState.chosenUnitGroup,
|
chosenUnitGroup = _uiStateFlow.value.chosenUnitGroup,
|
||||||
favoritesOnly = uiState.favoritesOnly,
|
favoritesOnly = _uiStateFlow.value.favoritesOnly,
|
||||||
searchQuery = uiState.searchQuery,
|
searchQuery = _uiStateFlow.value.searchQuery,
|
||||||
allUnitsGroups = uiState.shownUnitGroups
|
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user