From 5135ac9f4ee7fb735f5d651746cc6a8c84ceb327 Mon Sep 17 00:00:00 2001 From: christianrowlands <christian.rowlands@gmail.com> Date: Thu, 31 Oct 2024 16:20:43 -0400 Subject: [PATCH] WIP: Save the the nav bar selected item when navigating outside the bottom nav and adds back in the tower info icon --- .../fragments/TowerMapFragment.kt | 23 ------- .../ui/cellular/TowerMapScreen.kt | 69 ++++++++++++++++--- .../networksurvey/ui/main/HomeScreen.kt | 29 ++++---- 3 files changed, 78 insertions(+), 43 deletions(-) diff --git a/networksurvey/src/main/java/com/craxiom/networksurvey/fragments/TowerMapFragment.kt b/networksurvey/src/main/java/com/craxiom/networksurvey/fragments/TowerMapFragment.kt index 2d142771..e7e0020f 100644 --- a/networksurvey/src/main/java/com/craxiom/networksurvey/fragments/TowerMapFragment.kt +++ b/networksurvey/src/main/java/com/craxiom/networksurvey/fragments/TowerMapFragment.kt @@ -231,27 +231,4 @@ class TowerMapFragment : AServiceDataFragment(), ICellularSurveyRecordListener { ) } } - - /** - * Shows a dialog to the user explaining where the tower map data comes from and some nuances of it. - */ - private fun showTowerMapInfoDialog() { - val builder = AlertDialog.Builder(requireContext()) - builder.setTitle("Tower Map Information") - builder.setMessage( - """ - The tower locations are sourced from OpenCelliD ( https://opencellid.org ). - - Please note that these locations may not be accurate as they are generated from crowd-sourced data and based on survey results. - The tower locations are provided for your convenience, but they should not be relied upon for precise accuracy. - We recommend verifying tower locations through additional sources if accuracy is critical. - - Legend: - - Purple: Your Current Serving Cell - - Blue: Non-Serving Cells - """.trimIndent() - ) - builder.setPositiveButton("OK") { dialog, _ -> dialog.dismiss() } - builder.show() - } } diff --git a/networksurvey/src/main/java/com/craxiom/networksurvey/ui/cellular/TowerMapScreen.kt b/networksurvey/src/main/java/com/craxiom/networksurvey/ui/cellular/TowerMapScreen.kt index 26306e7d..f3514c06 100644 --- a/networksurvey/src/main/java/com/craxiom/networksurvey/ui/cellular/TowerMapScreen.kt +++ b/networksurvey/src/main/java/com/craxiom/networksurvey/ui/cellular/TowerMapScreen.kt @@ -6,21 +6,29 @@ import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Info +import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf @@ -122,6 +130,7 @@ internal fun TowerMapScreen(viewModel: TowerMapViewModel = viewModel()) { ) var expanded by remember { mutableStateOf(false) } var isFollowing by remember { mutableStateOf(false) } + var showInfoDialog by remember { mutableStateOf(false) } val statusBarHeight = paddingInsets.calculateTopPadding() Surface( @@ -141,14 +150,27 @@ internal fun TowerMapScreen(viewModel: TowerMapViewModel = viewModel()) { Box( modifier = Modifier .align(Alignment.TopEnd) - .padding(top = statusBarHeight + 2.dp, end = 16.dp) + .padding(top = statusBarHeight + 4.dp, end = 16.dp) ) { + Row { + IconButton(onClick = { showInfoDialog = true }) { + Icon( + Icons.Default.Info, + contentDescription = "About Cellular Tower Map", + tint = MaterialTheme.colorScheme.primary, + modifier = Modifier + .size(56.dp) + .padding(0.dp) + .background(color = MaterialTheme.colorScheme.onSurface) + ) + } + Spacer(modifier = Modifier.width(16.dp)) - // Button to show the DropdownMenu - Button( - onClick = { expanded = true }, - ) { - Text(text = radio) + Button( + onClick = { expanded = true }, + ) { + Text(text = radio, color = MaterialTheme.colorScheme.onSurface) + } } DropdownMenu( @@ -256,6 +278,10 @@ internal fun TowerMapScreen(viewModel: TowerMapViewModel = viewModel()) { } } } + + if (showInfoDialog) { + TowerMapInfoDialog(onDismiss = { showInfoDialog = false }) + } } if (missingApiKey) { @@ -683,7 +709,6 @@ private fun getServingCellDisplayString(message: GeneratedMessage): String { } } - @Composable fun CircleButtonWithLine( isFollowing: Boolean, @@ -720,6 +745,34 @@ fun CircleButtonWithLine( } } +@Composable +fun TowerMapInfoDialog(onDismiss: () -> Unit) { + AlertDialog( + onDismissRequest = onDismiss, + title = { + Text(text = "Tower Map Information") + }, + text = { + Text( + text = """ + The tower locations are sourced from OpenCelliD ( https://opencellid.org ). + + Please note that these locations may not be accurate as they are generated from crowd-sourced data and based on survey results. The tower locations are provided for your convenience, but they should not be relied upon for precise accuracy. We recommend verifying tower locations through additional sources if accuracy is critical. + + Legend: + - Purple: Your Current Serving Cell + - Blue: Non-Serving Cells + """.trimIndent() + ) + }, + confirmButton = { + TextButton(onClick = onDismiss) { + Text("OK") + } + } + ) +} + // The API definition for the NS Tower Service interface Api { @@ -775,4 +828,4 @@ data class Tower( data class TowerResponse( val count: Int, val cells: List<Tower> -) \ No newline at end of file +) diff --git a/networksurvey/src/main/java/com/craxiom/networksurvey/ui/main/HomeScreen.kt b/networksurvey/src/main/java/com/craxiom/networksurvey/ui/main/HomeScreen.kt index 9d2b1ffb..b09baa07 100644 --- a/networksurvey/src/main/java/com/craxiom/networksurvey/ui/main/HomeScreen.kt +++ b/networksurvey/src/main/java/com/craxiom/networksurvey/ui/main/HomeScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext @@ -51,13 +52,13 @@ fun HomeScreen( drawerState: DrawerState, mainNavController: NavHostController ) { + var bottomNavSelectedItem by rememberSaveable { mutableIntStateOf(0) } val bottomNavController: NavHostController = rememberNavController() var currentScreen by remember { mutableStateOf<MainScreens>(MainScreens.Dashboard) } var currentGnssScreen by remember { mutableStateOf(GnssScreen.GNSS_DETAILS) } var showGnssFilterDialog by remember { mutableStateOf(false) } var showGnssSortDialog by remember { mutableStateOf(false) } - Scaffold( topBar = { AppBar( @@ -72,7 +73,11 @@ fun HomeScreen( ) }, bottomBar = { - BottomNavigationBar(bottomNavController) + BottomNavigationBar( + bottomNavController, + onBottomNavigationItemSelected = { bottomNavSelectedItem = it }, + bottomNavSelectedItem + ) }, ) { padding -> NavHost( @@ -121,18 +126,15 @@ fun HomeScreen( } @Composable -fun BottomNavigationBar(navController: NavController) { - var navigationSelectedItem by remember { - mutableIntStateOf(0) - } - +fun BottomNavigationBar( + navController: NavController, + onBottomNavigationItemSelected: (Int) -> Unit, + bottomNavSelectedItem: Int +) { NavigationBar { - //getting the list of bottom navigation items for our data class BottomNavItem().bottomNavigationItems().forEachIndexed { index, navigationItem -> - - //iterating all items with their respective indexes NavigationBarItem( - selected = index == navigationSelectedItem, + selected = index == bottomNavSelectedItem, label = { Text(navigationItem.label) }, @@ -143,12 +145,15 @@ fun BottomNavigationBar(navController: NavController) { ) }, onClick = { - navigationSelectedItem = index + onBottomNavigationItemSelected(index) navController.navigate(navigationItem.route) { popUpTo(navController.graph.findStartDestination().id) { saveState = true } + // Avoid multiple copies of the same destination when + // reselecting the same item launchSingleTop = true + // Restore state when reselecting a previously selected item restoreState = true } }