summaryrefslogtreecommitdiff
path: root/android-app/app/src/main/res
diff options
context:
space:
mode:
authorClaude <noreply@anthropic.com>2026-04-22 08:45:55 +0000
committerClaude <noreply@anthropic.com>2026-04-22 08:45:55 +0000
commit87f9cb753da3325d13fdbc442d526567e056d6e1 (patch)
treefcad4c91a817b3ce623abbaf5b12dab875d08aa3 /android-app/app/src/main/res
parent447c274999b6b412985b640f841ab92d8c23c0f8 (diff)
feat: CPA/TCPA collision alerts and live track stats
CPA/TCPA alerts: - CpaAlert data class with severity (CAUTION/WARNING/DANGER) and label() - CpaThresholds: 0.5/1.0/2.0 nm, max TCPA 30 min - MainViewModel.updateCpaAlerts() runs on every GPS update and AIS sentence; skips stationary contacts; filters TCPA ≤ 0 or > 30 min; sorts by TCPA ascending - SafetyFragment: new COLLISION AVOIDANCE card shows live alert list, color-coded by severity; clears to "No traffic alerts" when safe - MainActivity: observes cpaAlerts → safetyFragment.updateCpaAlerts() Track stats: - TrackStats data class: distanceNm, durationMs, avgSogKnots, durationFormatted (m:ss / h:mm:ss) - TrackRepository.haversineNm() + computeStats() using point timestamps - MainViewModel exposes trackStats StateFlow, cleared on stopTrack() - activity_main: dark pill overlay bar (tv_track_stats) above map - MainActivity: shows "● REC 0.00nm m:ss x.xkt avg" while recording Tests: 95 total, all GREEN (+16 new — 9 TrackStats, 7 CpaAlert) https://claude.ai/code/session_011h2dXbgXg3PesQMmQUNTCW
Diffstat (limited to 'android-app/app/src/main/res')
-rw-r--r--android-app/app/src/main/res/layout/activity_main.xml19
-rw-r--r--android-app/app/src/main/res/layout/fragment_safety.xml37
2 files changed, 55 insertions, 1 deletions
diff --git a/android-app/app/src/main/res/layout/activity_main.xml b/android-app/app/src/main/res/layout/activity_main.xml
index feeb43d..a99a8cb 100644
--- a/android-app/app/src/main/res/layout/activity_main.xml
+++ b/android-app/app/src/main/res/layout/activity_main.xml
@@ -32,6 +32,25 @@
android:visibility="gone"
android:background="?attr/colorSurface" />
+ <!-- Track stats bar — shown only while recording -->
+ <TextView
+ android:id="@+id/tv_track_stats"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top|center_horizontal"
+ android:layout_marginTop="12dp"
+ android:paddingHorizontal="14dp"
+ android:paddingVertical="6dp"
+ android:background="#CC000000"
+ android:textColor="#FFFFFFFF"
+ android:textSize="13sp"
+ android:fontFamily="monospace"
+ android:text=""
+ android:visibility="gone"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
+
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- Collapsible Instrument Bottom Sheet -->
diff --git a/android-app/app/src/main/res/layout/fragment_safety.xml b/android-app/app/src/main/res/layout/fragment_safety.xml
index 5b2397e..c270d1f 100644
--- a/android-app/app/src/main/res/layout/fragment_safety.xml
+++ b/android-app/app/src/main/res/layout/fragment_safety.xml
@@ -63,6 +63,41 @@
</com.google.android.material.card.MaterialCardView>
+ <!-- CPA / Collision Alert Section -->
+ <com.google.android.material.card.MaterialCardView
+ android:id="@+id/card_cpa"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ app:cardCornerRadius="16dp"
+ app:layout_constraintTop_toBottomOf="@id/card_mob">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="COLLISION AVOIDANCE"
+ android:textStyle="bold" />
+
+ <TextView
+ android:id="@+id/tv_cpa_status"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:text="No traffic alerts"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:fontFamily="monospace"
+ android:textSize="13sp" />
+
+ </LinearLayout>
+
+ </com.google.android.material.card.MaterialCardView>
+
<!-- Anchor Section -->
<com.google.android.material.card.MaterialCardView
android:id="@+id/card_anchor"
@@ -70,7 +105,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:cardCornerRadius="16dp"
- app:layout_constraintTop_toBottomOf="@id/card_mob">
+ app:layout_constraintTop_toBottomOf="@id/card_cpa">
<LinearLayout
android:layout_width="match_parent"