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

View File

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

View File

@ -73,8 +73,8 @@ fun TopScreenPart(
unitTo: AbstractUnit?, unitTo: AbstractUnit?,
networkLoading: Boolean, networkLoading: Boolean,
networkError: Boolean, networkError: Boolean,
navigateToLeftScreen: () -> Unit, navigateToLeftScreen: (String) -> Unit,
navigateToRightScreen: () -> Unit, navigateToRightScreen: (unitFrom: String, unitTo: String, input: String) -> Unit,
swapUnits: () -> Unit, swapUnits: () -> Unit,
converterMode: ConverterMode, converterMode: ConverterMode,
) { ) {
@ -123,7 +123,7 @@ fun TopScreenPart(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.weight(1f), .weight(1f),
onClick = navigateToLeftScreen, onClick = { unitFrom?.let { navigateToLeftScreen(it.unitId) } },
label = unitFrom?.displayName ?: R.string.loading_label, label = unitFrom?.displayName ?: R.string.loading_label,
) )
IconButton( IconButton(
@ -143,7 +143,15 @@ fun TopScreenPart(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.weight(1f), .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, 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" const val converterRoute = "converter_route"
fun NavGraphBuilder.converterScreen( fun NavGraphBuilder.converterScreen(
navigateToLeftScreen: () -> Unit, navigateToLeftScreen: (String) -> Unit,
navigateToRightScreen: () -> Unit, navigateToRightScreen: (unitFrom: String, unitTo: String, input: String) -> Unit,
navigateToSettings: () -> Unit, navigateToSettings: () -> Unit,
viewModel: MainViewModel viewModel: MainViewModel
) { ) {

View File

@ -60,7 +60,7 @@ import java.math.BigDecimal
* Left side screen. Unit to convert from. * Left side screen. Unit to convert from.
* *
* @param viewModel [SecondViewModel]. * @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 navigateUp Action to navigate up. Called when user click back button.
* @param navigateToSettingsAction Action to perform when clicking settings chip at the end. * @param navigateToSettingsAction Action to perform when clicking settings chip at the end.
* @param selectAction Action to perform when user clicks on [UnitListItem]. * @param selectAction Action to perform when user clicks on [UnitListItem].
@ -68,7 +68,7 @@ import java.math.BigDecimal
@Composable @Composable
fun LeftSideScreen( fun LeftSideScreen(
viewModel: SecondViewModel, viewModel: SecondViewModel,
currentUnit: AbstractUnit, currentUnitId: String,
navigateUp: () -> Unit, navigateUp: () -> Unit,
navigateToSettingsAction: () -> Unit, navigateToSettingsAction: () -> Unit,
selectAction: (AbstractUnit) -> Unit selectAction: (AbstractUnit) -> Unit
@ -130,7 +130,7 @@ fun LeftSideScreen(
UnitListItem( UnitListItem(
modifier = Modifier.animateItemPlacement(), modifier = Modifier.animateItemPlacement(),
unit = unit, unit = unit,
isSelected = currentUnit == unit, isSelected = currentUnitId == unit.unitId,
selectAction = { selectAction = {
selectAction(it) selectAction(it)
viewModel.onSearchQueryChange("") viewModel.onSearchQueryChange("")
@ -169,7 +169,7 @@ fun LeftSideScreen(
@Composable @Composable
fun RightSideScreen( fun RightSideScreen(
viewModel: SecondViewModel, viewModel: SecondViewModel,
currentUnit: AbstractUnit, currentUnit: String,
navigateUp: () -> Unit, navigateUp: () -> Unit,
navigateToSettingsAction: () -> Unit, navigateToSettingsAction: () -> Unit,
selectAction: (AbstractUnit) -> Unit, selectAction: (AbstractUnit) -> Unit,
@ -230,7 +230,7 @@ fun RightSideScreen(
UnitListItem( UnitListItem(
modifier = Modifier.animateItemPlacement(), modifier = Modifier.animateItemPlacement(),
unit = unit, unit = unit,
isSelected = currentUnit == unit, isSelected = currentUnit == unit.unitId,
selectAction = { selectAction = {
selectAction(it) selectAction(it)
viewModel.onSearchQueryChange("") 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) { fun setSelectedChip(unit: String, hideBrokenCurrencies: Boolean = true) {
_chosenUnitGroup.update { unitGroup } _chosenUnitGroup.update { allUnitsRepository.getById(unit).group }
loadUnitsToShow(hideBrokenCurrencies) loadUnitsToShow(hideBrokenCurrencies)
} }

View File

@ -19,14 +19,72 @@
package com.sadellie.unitto.feature.unitslist.navigation package com.sadellie.unitto.feature.unitslist.navigation
import androidx.navigation.NavController 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 leftSideRoute = "left_side_route"
const val rightSideRoute = "right_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() { fun NavController.navigateToLeftSide(unitFromId: String) {
navigate(leftSideRoute) navigate("$leftSideRoute/$unitFromId")
} }
fun NavController.navigateToRightSide() { fun NavController.navigateToRightSide(unitFromId: String, unitToId: String, input: String) {
navigate(rightSideRoute) 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)
)
}
} }