Actually fixed navigation for unit selection screens

This commit is contained in:
Sad Ellie 2023-01-13 23:57:58 +04:00
parent c0acd70acc
commit 8b9db717c4
7 changed files with 107 additions and 65 deletions

View File

@ -19,10 +19,8 @@
package com.sadellie.unitto
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import com.sadellie.unitto.feature.converter.MainViewModel
import com.sadellie.unitto.feature.converter.navigation.converterRoute
import com.sadellie.unitto.feature.converter.navigation.converterScreen
@ -30,13 +28,11 @@ import com.sadellie.unitto.feature.settings.SettingsViewModel
import com.sadellie.unitto.feature.settings.navigation.navigateToSettings
import com.sadellie.unitto.feature.settings.navigation.navigateToUnitGroups
import com.sadellie.unitto.feature.settings.navigation.settingGraph
import com.sadellie.unitto.feature.unitslist.LeftSideScreen
import com.sadellie.unitto.feature.unitslist.RightSideScreen
import com.sadellie.unitto.feature.unitslist.SecondViewModel
import com.sadellie.unitto.feature.unitslist.navigation.leftSideRoute
import com.sadellie.unitto.feature.unitslist.navigation.leftScreen
import com.sadellie.unitto.feature.unitslist.navigation.navigateToLeftSide
import com.sadellie.unitto.feature.unitslist.navigation.navigateToRightSide
import com.sadellie.unitto.feature.unitslist.navigation.rightSideRoute
import com.sadellie.unitto.feature.unitslist.navigation.rightScreen
import io.github.sadellie.themmo.ThemmoController
@Composable
@ -52,47 +48,27 @@ fun UnittoNavigation(
startDestination = converterRoute
) {
converterScreen(
navigateToLeftScreen = { navController.navigateToLeftSide() },
navigateToRightScreen = { navController.navigateToRightSide() },
navigateToLeftScreen = { navController.navigateToLeftSide(it) },
navigateToRightScreen = { unitFrom, unitTo, input ->
navController.navigateToRightSide(unitFrom, unitTo, input)
},
navigateToSettings = { navController.navigateToSettings() },
viewModel = mainViewModel
)
composable(leftSideRoute) {
// Don't do this in your app
val mainUiState = mainViewModel.uiStateFlow.collectAsState()
val unitFrom = mainUiState.value.unitFrom ?: return@composable
// Initial group
secondViewModel.setSelectedChip(unitFrom.group, true)
leftScreen(
viewModel = secondViewModel,
navigateUp = { navController.navigateUp() },
navigateToUnitGroups = { navController.navigateToUnitGroups() },
onSelect = { mainViewModel.updateUnitFrom(it) }
)
LeftSideScreen(
viewModel = secondViewModel,
currentUnit = unitFrom,
navigateUp = { navController.navigateUp() },
navigateToSettingsAction = { navController.navigateToUnitGroups() },
selectAction = { mainViewModel.updateUnitFrom(it) }
)
}
composable(rightSideRoute) {
// Don't do this in your app
val mainUiState = mainViewModel.uiStateFlow.collectAsState()
val unitFrom = mainUiState.value.unitFrom ?: return@composable
val unitTo = mainUiState.value.unitTo ?: return@composable
// Initial group
secondViewModel.setSelectedChip(unitFrom.group, false)
RightSideScreen(
viewModel = secondViewModel,
currentUnit = unitTo,
navigateUp = { navController.navigateUp() },
navigateToSettingsAction = { navController.navigateToUnitGroups() },
selectAction = { mainViewModel.updateUnitTo(it) },
inputValue = mainViewModel.getInputValue(),
unitFrom = unitFrom
)
}
rightScreen(
viewModel = secondViewModel,
navigateUp = { navController.navigateUp() },
navigateToUnitGroups = { navController.navigateToUnitGroups() },
onSelect = { mainViewModel.updateUnitTo(it) }
)
settingGraph(
settingsViewModel = settingsViewModel,

View File

@ -45,8 +45,8 @@ import kotlinx.coroutines.delay
@Composable
fun MainScreen(
navigateToLeftScreen: () -> Unit,
navigateToRightScreen: () -> Unit,
navigateToLeftScreen: (String) -> Unit,
navigateToRightScreen: (unitFrom: String, unitTo: String, input: String) -> Unit,
navigateToSettings: () -> Unit,
viewModel: MainViewModel = viewModel()
) {
@ -101,8 +101,8 @@ fun MainScreen(
private fun MainScreenContent(
modifier: Modifier,
mainScreenUIState: MainScreenUIState,
navigateToLeftScreen: () -> Unit,
navigateToRightScreen: () -> Unit,
navigateToLeftScreen: (String) -> Unit,
navigateToRightScreen: (unitFrom: String, unitTo: String, input: String) -> Unit,
swapMeasurements: () -> Unit = {},
processInput: (String) -> Unit = {},
deleteDigit: () -> Unit = {},

View File

@ -73,8 +73,8 @@ fun TopScreenPart(
unitTo: AbstractUnit?,
networkLoading: Boolean,
networkError: Boolean,
navigateToLeftScreen: () -> Unit,
navigateToRightScreen: () -> Unit,
navigateToLeftScreen: (String) -> Unit,
navigateToRightScreen: (unitFrom: String, unitTo: String, input: String) -> Unit,
swapUnits: () -> Unit,
converterMode: ConverterMode,
) {
@ -123,7 +123,7 @@ fun TopScreenPart(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
onClick = navigateToLeftScreen,
onClick = { unitFrom?.let { navigateToLeftScreen(it.unitId) } },
label = unitFrom?.displayName ?: R.string.loading_label,
)
IconButton(
@ -143,7 +143,15 @@ fun TopScreenPart(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
onClick = navigateToRightScreen,
onClick = {
if (unitTo == null) return@UnitSelectionButton
if (unitFrom == null) return@UnitSelectionButton
navigateToRightScreen(
unitFrom.unitId,
unitTo.unitId,
calculatedValue ?: inputValue
)
},
label = unitTo?.displayName ?: R.string.loading_label,
)
}

View File

@ -26,8 +26,8 @@ import com.sadellie.unitto.feature.converter.MainViewModel
const val converterRoute = "converter_route"
fun NavGraphBuilder.converterScreen(
navigateToLeftScreen: () -> Unit,
navigateToRightScreen: () -> Unit,
navigateToLeftScreen: (String) -> Unit,
navigateToRightScreen: (unitFrom: String, unitTo: String, input: String) -> Unit,
navigateToSettings: () -> Unit,
viewModel: MainViewModel
) {

View File

@ -60,7 +60,7 @@ import java.math.BigDecimal
* Left side screen. Unit to convert from.
*
* @param viewModel [SecondViewModel].
* @param currentUnit Currently selected [AbstractUnit].
* @param currentUnitId Currently selected [AbstractUnit] (by ID).
* @param navigateUp Action to navigate up. Called when user click back button.
* @param navigateToSettingsAction Action to perform when clicking settings chip at the end.
* @param selectAction Action to perform when user clicks on [UnitListItem].
@ -68,7 +68,7 @@ import java.math.BigDecimal
@Composable
fun LeftSideScreen(
viewModel: SecondViewModel,
currentUnit: AbstractUnit,
currentUnitId: String,
navigateUp: () -> Unit,
navigateToSettingsAction: () -> Unit,
selectAction: (AbstractUnit) -> Unit
@ -130,7 +130,7 @@ fun LeftSideScreen(
UnitListItem(
modifier = Modifier.animateItemPlacement(),
unit = unit,
isSelected = currentUnit == unit,
isSelected = currentUnitId == unit.unitId,
selectAction = {
selectAction(it)
viewModel.onSearchQueryChange("")
@ -169,7 +169,7 @@ fun LeftSideScreen(
@Composable
fun RightSideScreen(
viewModel: SecondViewModel,
currentUnit: AbstractUnit,
currentUnit: String,
navigateUp: () -> Unit,
navigateToSettingsAction: () -> Unit,
selectAction: (AbstractUnit) -> Unit,
@ -230,7 +230,7 @@ fun RightSideScreen(
UnitListItem(
modifier = Modifier.animateItemPlacement(),
unit = unit,
isSelected = currentUnit == unit,
isSelected = currentUnit == unit.unitId,
selectAction = {
selectAction(it)
viewModel.onSearchQueryChange("")

View File

@ -80,12 +80,12 @@ class SecondViewModel @Inject constructor(
}
/**
* Changes currently selected chip.
* Changes currently selected chip. Used only when navigating
*
* @param unitGroup Chip to change to.
* @param unit Will find group for unit with this id.
*/
fun setSelectedChip(unitGroup: UnitGroup, hideBrokenCurrencies: Boolean = true) {
_chosenUnitGroup.update { unitGroup }
fun setSelectedChip(unit: String, hideBrokenCurrencies: Boolean = true) {
_chosenUnitGroup.update { allUnitsRepository.getById(unit).group }
loadUnitsToShow(hideBrokenCurrencies)
}

View File

@ -19,14 +19,72 @@
package com.sadellie.unitto.feature.unitslist.navigation
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.units.AllUnitsRepository
import com.sadellie.unitto.feature.unitslist.LeftSideScreen
import com.sadellie.unitto.feature.unitslist.RightSideScreen
import com.sadellie.unitto.feature.unitslist.SecondViewModel
const val leftSideRoute = "left_side_route"
const val rightSideRoute = "right_side_route"
private const val unitFromIdArg = "unitFromId"
private const val unitToIdArg = "unitToId"
private const val inputArg = "input"
fun NavController.navigateToLeftSide() {
navigate(leftSideRoute)
fun NavController.navigateToLeftSide(unitFromId: String) {
navigate("$leftSideRoute/$unitFromId")
}
fun NavController.navigateToRightSide() {
navigate(rightSideRoute)
fun NavController.navigateToRightSide(unitFromId: String, unitToId: String, input: String) {
navigate("$rightSideRoute/$unitFromId/$unitToId/$input")
}
fun NavGraphBuilder.leftScreen(
viewModel: SecondViewModel,
navigateUp: () -> Unit,
navigateToUnitGroups: () -> Unit,
onSelect: (AbstractUnit) -> Unit
) {
composable(
route = "$leftSideRoute/{$unitFromIdArg}"
) {
val unitFromId = it.arguments?.getString(unitFromIdArg) ?: return@composable
viewModel.setSelectedChip(unitFromId)
LeftSideScreen(
viewModel = viewModel,
currentUnitId = unitFromId,
navigateUp = navigateUp,
navigateToSettingsAction = navigateToUnitGroups,
selectAction = onSelect
)
}
}
fun NavGraphBuilder.rightScreen(
viewModel: SecondViewModel,
navigateUp: () -> Unit,
navigateToUnitGroups: () -> Unit,
onSelect: (AbstractUnit) -> Unit
) {
composable(
route = "$rightSideRoute/{$unitFromIdArg}/{$unitToIdArg}/{$inputArg}"
) {
val unitFromId = it.arguments?.getString(unitFromIdArg) ?: return@composable
val unitToId = it.arguments?.getString(unitToIdArg) ?: return@composable
val input = it.arguments?.getString(inputArg) ?: return@composable
viewModel.setSelectedChip(unitFromId, false)
RightSideScreen(
viewModel = viewModel,
currentUnit = unitToId,
navigateUp = navigateUp,
navigateToSettingsAction = navigateToUnitGroups,
selectAction = onSelect,
inputValue = input,
unitFrom = AllUnitsRepository().getById(unitFromId)
)
}
}