fuzzyworld

haunt / commit

Remove router readings bar; show distance-to-you in point list

342308739838fe6fab1984fbdffb50e80f37ee08 · Pavel Safronov · 2026-05-13 08:13:17 -0700 · parents 307881725e79

Remove router readings bar; show distance-to-you in point list

The raw BSSID distance readout at the top is gone. Each point in the
list now shows its Euclidean distance from current position in RTT
fingerprint space. The 'you' row shows nothing (it is the origin).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
 .../main/java/net/fuzzyworld/haunt/MainActivity.kt | 17 ++--------
 .../net/fuzzyworld/haunt/debug/PointsAdapter.kt    | 38 ++++++++--------------
 app/src/main/res/layout/activity_main.xml          | 11 -------
 3 files changed, 15 insertions(+), 51 deletions(-)

diff --git a/app/src/main/java/net/fuzzyworld/haunt/MainActivity.kt b/app/src/main/java/net/fuzzyworld/haunt/MainActivity.kt
index ceeacad..70c6044 100644
--- a/app/src/main/java/net/fuzzyworld/haunt/MainActivity.kt
+++ b/app/src/main/java/net/fuzzyworld/haunt/MainActivity.kt
@@ -13,6 +13,7 @@ import android.widget.ProgressBar
 import android.widget.ScrollView
 import android.widget.TextView
 import android.widget.Toast
+
 import androidx.activity.result.contract.ActivityResultContracts
 import androidx.activity.viewModels
 import androidx.appcompat.app.AlertDialog
@@ -45,10 +46,7 @@ class MainActivity : AppCompatActivity() {
 
     private val requestPermissions = registerForActivityResult(
         ActivityResultContracts.RequestMultiplePermissions()
-    ) { grants ->
-        if (grants.values.any { !it })
-            binding.readingsText.text = "Location/nearby-wifi permission required for RTT ranging"
-    }
+    ) { _ -> }
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -72,11 +70,6 @@ class MainActivity : AppCompatActivity() {
 
         lifecycleScope.launch {
             vm.readings.collectLatest { readings ->
-                binding.readingsText.text = if (readings.isEmpty()) {
-                    "Scanning… (no RTT-capable APs found)"
-                } else {
-                    readings.joinToString("\n") { "…${it.bssid.takeLast(8)}  ${String.format("%.2f", it.distanceMeters)} m" }
-                }
                 val map = readings.associate { it.bssid to it.distanceMeters }
                 binding.mapView.currentReadings = map
                 adapter.youReadings = map
@@ -110,12 +103,6 @@ class MainActivity : AppCompatActivity() {
             }
         }
 
-        lifecycleScope.launch {
-            vm.axisBssids.collectLatest { bssids ->
-                adapter.axisBssids = bssids
-                adapter.notifyDataSetChanged()
-            }
-        }
     }
 
     // --- Add Point dialog ---
diff --git a/app/src/main/java/net/fuzzyworld/haunt/debug/PointsAdapter.kt b/app/src/main/java/net/fuzzyworld/haunt/debug/PointsAdapter.kt
index b311478..48bd4b7 100644
--- a/app/src/main/java/net/fuzzyworld/haunt/debug/PointsAdapter.kt
+++ b/app/src/main/java/net/fuzzyworld/haunt/debug/PointsAdapter.kt
@@ -14,6 +14,7 @@ import androidx.recyclerview.widget.RecyclerView
 import net.fuzzyworld.haunt.R
 import net.fuzzyworld.haunt.databinding.ItemDebugPointBinding
 import net.fuzzyworld.haunt.hue.HueLightPoint
+import kotlin.math.sqrt
 
 private val PRESET_COLORS = listOf(
     Color.HSVToColor(floatArrayOf(0f,   0.75f, 0.90f)),
@@ -83,13 +84,21 @@ class PointsAdapter(
 
     private var points: List<DebugPoint> = emptyList()
     private var lightPoints: List<HueLightPoint> = emptyList()
-    var axisBssids: List<String> = emptyList()
     var youColor: Int = Color.GRAY
     var youReadings: Map<String, Double> = emptyMap()
 
     fun submitList(list: List<DebugPoint>) { points = list; notifyDataSetChanged() }
     fun submitLightList(list: List<HueLightPoint>) { lightPoints = list; notifyDataSetChanged() }
 
+    private fun distanceToYou(pointReadings: Map<String, Double>): Double? {
+        val common = youReadings.keys.intersect(pointReadings.keys)
+        if (common.isEmpty()) return null
+        return sqrt(common.sumOf { k -> (youReadings[k]!! - pointReadings[k]!!).let { it * it } })
+    }
+
+    private fun formatDistance(d: Double?) =
+        if (d != null) "${"%.2f".format(d)} m away" else ""
+
     override fun getItemCount() = 1 + lightPoints.size + points.size
 
     override fun getItemViewType(position: Int) = when {
@@ -125,14 +134,7 @@ class PointsAdapter(
             b.nameEdit.setText("you")
             b.nameEdit.isEnabled = false
             b.deleteButton.visibility = View.GONE
-
-            val x = axisBssids.getOrNull(0)?.let { youReadings[it] }
-            val y = axisBssids.getOrNull(1)?.let { youReadings[it] }
-            b.xyText.text = when {
-                x != null && y != null -> "x: ${"%.2f".format(x)} m   y: ${"%.2f".format(y)} m"
-                x != null -> "x: ${"%.2f".format(x)} m"
-                else -> "—"
-            }
+            b.xyText.text = ""
         }
     }
 
@@ -150,14 +152,7 @@ class PointsAdapter(
                 if (!hasFocus) onRenameLight(point.id, b.nameEdit.text.toString().trim().ifEmpty { point.name })
             }
             b.deleteButton.setOnClickListener { onDeleteLight(point.id) }
-
-            val x = axisBssids.getOrNull(0)?.let { point.readings[it] }
-            val y = axisBssids.getOrNull(1)?.let { point.readings[it] }
-            b.xyText.text = when {
-                x != null && y != null -> "x: ${"%.2f".format(x)} m   y: ${"%.2f".format(y)} m"
-                x != null -> "x: ${"%.2f".format(x)} m"
-                else -> ""
-            }
+            b.xyText.text = formatDistance(distanceToYou(point.readings))
         }
     }
 
@@ -176,14 +171,7 @@ class PointsAdapter(
                 if (!hasFocus) onRename(point.id, b.nameEdit.text.toString().trim().ifEmpty { point.name })
             }
             b.deleteButton.setOnClickListener { onDelete(point.id) }
-
-            val x = axisBssids.getOrNull(0)?.let { point.readings[it] }
-            val y = axisBssids.getOrNull(1)?.let { point.readings[it] }
-            b.xyText.text = when {
-                x != null && y != null -> "x: ${"%.2f".format(x)} m   y: ${"%.2f".format(y)} m"
-                x != null -> "x: ${"%.2f".format(x)} m"
-                else -> ""
-            }
+            b.xyText.text = formatDistance(distanceToYou(point.readings))
         }
     }
 }
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index ecdae6c..1a6bbfa 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -5,17 +5,6 @@
     android:orientation="vertical"
     android:fitsSystemWindows="true">
 
-    <TextView
-        android:id="@+id/readingsText"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingHorizontal="12dp"
-        android:paddingTop="8dp"
-        android:paddingBottom="4dp"
-        android:fontFamily="monospace"
-        android:textSize="12sp"
-        android:text="Scanning…" />
-
     <net.fuzzyworld.haunt.debug.MapView
         android:id="@+id/mapView"
         android:layout_width="match_parent"