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
                     }
                 }