Loading cardinal-android/app/src/main/java/earth/maps/cardinal/ui/settings/ProfileEditorScreen.kt +118 −114 Original line number Original line Diff line number Diff line Loading @@ -128,125 +128,28 @@ fun ProfileEditorScreen( } } Column(modifier = Modifier.fillMaxSize()) { Column(modifier = Modifier.fillMaxSize()) { // Custom app bar using Row ProfileEditorAppBar( Row( onBack = { handleBackNavigation() }, modifier = Modifier title = if (isNewProfile) "Create Profile" else "Edit Profile", .fillMaxWidth() isLoading = isLoading, .padding(horizontal = dimensionResource(dimen.padding), vertical = 8.dp), onSave = { horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { IconButton(onClick = { handleBackNavigation() }) { Icon( painter = painterResource(drawable.ic_arrow_back), contentDescription = stringResource( string.content_description_back ) ) } Text( text = if (isNewProfile) "Create Profile" else "Edit Profile", style = MaterialTheme.typography.titleLarge ) if (!isLoading) { IconButton( onClick = { viewModel.saveProfile { viewModel.saveProfile { navController.popBackStack() navController.popBackStack() } } } } ) { Icon(painter = painterResource(drawable.ic_save), contentDescription = "Save") } } else { // Placeholder to maintain layout IconButton(onClick = {}, enabled = false) { Icon( painter = painterResource(drawable.ic_add), contentDescription = null, tint = Color.Transparent ) ) } } } if (isLoading) { if (isLoading) { Column( LoadingView() modifier = Modifier .fillMaxSize() .padding(top = dimensionResource(dimen.padding)), // Reduced padding since we removed TopAppBar horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { CircularProgressIndicator() } } else { } else { Column( ProfileEditorContent( modifier = Modifier profileName = profileName, .fillMaxSize() onProfileNameChange = { viewModel.updateProfileName(it) }, .padding(top = dimensionResource(dimen.padding)) // Reduced padding since we removed TopAppBar .verticalScroll(rememberScrollState()) .padding(dimensionResource(dimen.padding)), verticalArrangement = Arrangement.spacedBy(dimensionResource(dimen.padding)) ) { // Profile Name OutlinedTextField( value = profileName, onValueChange = { viewModel.updateProfileName(it) }, label = { Text("Profile Name") }, modifier = Modifier.fillMaxWidth(), singleLine = true ) // Routing Mode Selector RoutingModeSelector( selectedMode = selectedMode, selectedMode = selectedMode, onModeSelected = { viewModel.updateRoutingMode(it) } onModeSelected = { viewModel.updateRoutingMode(it) }, routingOptions = routingOptions, onRoutingOptionsChange = { viewModel.updateRoutingOptions(it) } ) ) // Options Editor based on mode when (selectedMode) { RoutingMode.AUTO -> AutoOptionsEditor(routingOptions as AutoRoutingOptions) { viewModel.updateRoutingOptions( it ) } RoutingMode.TRUCK -> TruckOptionsEditor(routingOptions as TruckRoutingOptions) { viewModel.updateRoutingOptions( it ) } RoutingMode.MOTOR_SCOOTER -> MotorScooterOptionsEditor(routingOptions as MotorScooterRoutingOptions) { viewModel.updateRoutingOptions( it ) } RoutingMode.MOTORCYCLE -> MotorcycleOptionsEditor(routingOptions as MotorcycleRoutingOptions) { viewModel.updateRoutingOptions( it ) } RoutingMode.BICYCLE -> CyclingOptionsEditor(routingOptions as CyclingRoutingOptions) { viewModel.updateRoutingOptions( it ) } RoutingMode.PEDESTRIAN -> PedestrianOptionsEditor(routingOptions as PedestrianRoutingOptions) { viewModel.updateRoutingOptions( it ) } RoutingMode.PUBLIC_TRANSPORT -> {} } } } } } } Loading Loading @@ -969,4 +872,105 @@ private fun <T : Enum<T>> EnumDropdownOption( } } } } @Composable private fun ProfileEditorAppBar( onBack: () -> Unit, title: String, isLoading: Boolean, onSave: () -> Unit ) { Row( modifier = Modifier .fillMaxWidth() .padding(horizontal = dimensionResource(dimen.padding), vertical = 8.dp), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { IconButton(onClick = onBack) { Icon( painter = painterResource(drawable.ic_arrow_back), contentDescription = stringResource(string.content_description_back) ) } Text( text = title, style = MaterialTheme.typography.titleLarge ) if (!isLoading) { IconButton(onClick = onSave) { Icon(painter = painterResource(drawable.ic_save), contentDescription = "Save") } } else { // Placeholder to maintain layout IconButton(onClick = {}, enabled = false) { Icon( painter = painterResource(drawable.ic_add), contentDescription = null, tint = Color.Transparent ) } } } } @Composable private fun LoadingView() { Column( modifier = Modifier .fillMaxSize() .padding(top = dimensionResource(dimen.padding)), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { CircularProgressIndicator() } } @Composable private fun ProfileEditorContent( profileName: String, onProfileNameChange: (String) -> Unit, selectedMode: RoutingMode, onModeSelected: (RoutingMode) -> Unit, routingOptions: RoutingOptions, onRoutingOptionsChange: (RoutingOptions) -> Unit ) { Column( modifier = Modifier .fillMaxSize() .padding(top = dimensionResource(dimen.padding)) .verticalScroll(rememberScrollState()) .padding(dimensionResource(dimen.padding)), verticalArrangement = Arrangement.spacedBy(dimensionResource(dimen.padding)) ) { // Profile Name OutlinedTextField( value = profileName, onValueChange = onProfileNameChange, label = { Text("Profile Name") }, modifier = Modifier.fillMaxWidth(), singleLine = true ) // Routing Mode Selector RoutingModeSelector( selectedMode = selectedMode, onModeSelected = onModeSelected ) // Options Editor based on mode when (selectedMode) { RoutingMode.AUTO -> AutoOptionsEditor(routingOptions as AutoRoutingOptions, onRoutingOptionsChange) RoutingMode.TRUCK -> TruckOptionsEditor(routingOptions as TruckRoutingOptions, onRoutingOptionsChange) RoutingMode.MOTOR_SCOOTER -> MotorScooterOptionsEditor(routingOptions as MotorScooterRoutingOptions, onRoutingOptionsChange) RoutingMode.MOTORCYCLE -> MotorcycleOptionsEditor(routingOptions as MotorcycleRoutingOptions, onRoutingOptionsChange) RoutingMode.BICYCLE -> CyclingOptionsEditor(routingOptions as CyclingRoutingOptions, onRoutingOptionsChange) RoutingMode.PEDESTRIAN -> PedestrianOptionsEditor(routingOptions as PedestrianRoutingOptions, onRoutingOptionsChange) RoutingMode.PUBLIC_TRANSPORT -> {} } } } private fun Double.format(digits: Int) = "%.${digits}f".format(this) private fun Double.format(digits: Int) = "%.${digits}f".format(this) Loading
cardinal-android/app/src/main/java/earth/maps/cardinal/ui/settings/ProfileEditorScreen.kt +118 −114 Original line number Original line Diff line number Diff line Loading @@ -128,125 +128,28 @@ fun ProfileEditorScreen( } } Column(modifier = Modifier.fillMaxSize()) { Column(modifier = Modifier.fillMaxSize()) { // Custom app bar using Row ProfileEditorAppBar( Row( onBack = { handleBackNavigation() }, modifier = Modifier title = if (isNewProfile) "Create Profile" else "Edit Profile", .fillMaxWidth() isLoading = isLoading, .padding(horizontal = dimensionResource(dimen.padding), vertical = 8.dp), onSave = { horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { IconButton(onClick = { handleBackNavigation() }) { Icon( painter = painterResource(drawable.ic_arrow_back), contentDescription = stringResource( string.content_description_back ) ) } Text( text = if (isNewProfile) "Create Profile" else "Edit Profile", style = MaterialTheme.typography.titleLarge ) if (!isLoading) { IconButton( onClick = { viewModel.saveProfile { viewModel.saveProfile { navController.popBackStack() navController.popBackStack() } } } } ) { Icon(painter = painterResource(drawable.ic_save), contentDescription = "Save") } } else { // Placeholder to maintain layout IconButton(onClick = {}, enabled = false) { Icon( painter = painterResource(drawable.ic_add), contentDescription = null, tint = Color.Transparent ) ) } } } if (isLoading) { if (isLoading) { Column( LoadingView() modifier = Modifier .fillMaxSize() .padding(top = dimensionResource(dimen.padding)), // Reduced padding since we removed TopAppBar horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { CircularProgressIndicator() } } else { } else { Column( ProfileEditorContent( modifier = Modifier profileName = profileName, .fillMaxSize() onProfileNameChange = { viewModel.updateProfileName(it) }, .padding(top = dimensionResource(dimen.padding)) // Reduced padding since we removed TopAppBar .verticalScroll(rememberScrollState()) .padding(dimensionResource(dimen.padding)), verticalArrangement = Arrangement.spacedBy(dimensionResource(dimen.padding)) ) { // Profile Name OutlinedTextField( value = profileName, onValueChange = { viewModel.updateProfileName(it) }, label = { Text("Profile Name") }, modifier = Modifier.fillMaxWidth(), singleLine = true ) // Routing Mode Selector RoutingModeSelector( selectedMode = selectedMode, selectedMode = selectedMode, onModeSelected = { viewModel.updateRoutingMode(it) } onModeSelected = { viewModel.updateRoutingMode(it) }, routingOptions = routingOptions, onRoutingOptionsChange = { viewModel.updateRoutingOptions(it) } ) ) // Options Editor based on mode when (selectedMode) { RoutingMode.AUTO -> AutoOptionsEditor(routingOptions as AutoRoutingOptions) { viewModel.updateRoutingOptions( it ) } RoutingMode.TRUCK -> TruckOptionsEditor(routingOptions as TruckRoutingOptions) { viewModel.updateRoutingOptions( it ) } RoutingMode.MOTOR_SCOOTER -> MotorScooterOptionsEditor(routingOptions as MotorScooterRoutingOptions) { viewModel.updateRoutingOptions( it ) } RoutingMode.MOTORCYCLE -> MotorcycleOptionsEditor(routingOptions as MotorcycleRoutingOptions) { viewModel.updateRoutingOptions( it ) } RoutingMode.BICYCLE -> CyclingOptionsEditor(routingOptions as CyclingRoutingOptions) { viewModel.updateRoutingOptions( it ) } RoutingMode.PEDESTRIAN -> PedestrianOptionsEditor(routingOptions as PedestrianRoutingOptions) { viewModel.updateRoutingOptions( it ) } RoutingMode.PUBLIC_TRANSPORT -> {} } } } } } } Loading Loading @@ -969,4 +872,105 @@ private fun <T : Enum<T>> EnumDropdownOption( } } } } @Composable private fun ProfileEditorAppBar( onBack: () -> Unit, title: String, isLoading: Boolean, onSave: () -> Unit ) { Row( modifier = Modifier .fillMaxWidth() .padding(horizontal = dimensionResource(dimen.padding), vertical = 8.dp), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { IconButton(onClick = onBack) { Icon( painter = painterResource(drawable.ic_arrow_back), contentDescription = stringResource(string.content_description_back) ) } Text( text = title, style = MaterialTheme.typography.titleLarge ) if (!isLoading) { IconButton(onClick = onSave) { Icon(painter = painterResource(drawable.ic_save), contentDescription = "Save") } } else { // Placeholder to maintain layout IconButton(onClick = {}, enabled = false) { Icon( painter = painterResource(drawable.ic_add), contentDescription = null, tint = Color.Transparent ) } } } } @Composable private fun LoadingView() { Column( modifier = Modifier .fillMaxSize() .padding(top = dimensionResource(dimen.padding)), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { CircularProgressIndicator() } } @Composable private fun ProfileEditorContent( profileName: String, onProfileNameChange: (String) -> Unit, selectedMode: RoutingMode, onModeSelected: (RoutingMode) -> Unit, routingOptions: RoutingOptions, onRoutingOptionsChange: (RoutingOptions) -> Unit ) { Column( modifier = Modifier .fillMaxSize() .padding(top = dimensionResource(dimen.padding)) .verticalScroll(rememberScrollState()) .padding(dimensionResource(dimen.padding)), verticalArrangement = Arrangement.spacedBy(dimensionResource(dimen.padding)) ) { // Profile Name OutlinedTextField( value = profileName, onValueChange = onProfileNameChange, label = { Text("Profile Name") }, modifier = Modifier.fillMaxWidth(), singleLine = true ) // Routing Mode Selector RoutingModeSelector( selectedMode = selectedMode, onModeSelected = onModeSelected ) // Options Editor based on mode when (selectedMode) { RoutingMode.AUTO -> AutoOptionsEditor(routingOptions as AutoRoutingOptions, onRoutingOptionsChange) RoutingMode.TRUCK -> TruckOptionsEditor(routingOptions as TruckRoutingOptions, onRoutingOptionsChange) RoutingMode.MOTOR_SCOOTER -> MotorScooterOptionsEditor(routingOptions as MotorScooterRoutingOptions, onRoutingOptionsChange) RoutingMode.MOTORCYCLE -> MotorcycleOptionsEditor(routingOptions as MotorcycleRoutingOptions, onRoutingOptionsChange) RoutingMode.BICYCLE -> CyclingOptionsEditor(routingOptions as CyclingRoutingOptions, onRoutingOptionsChange) RoutingMode.PEDESTRIAN -> PedestrianOptionsEditor(routingOptions as PedestrianRoutingOptions, onRoutingOptionsChange) RoutingMode.PUBLIC_TRANSPORT -> {} } } } private fun Double.format(digits: Int) = "%.${digits}f".format(this) private fun Double.format(digits: Int) = "%.${digits}f".format(this)