From 021bc2418d698fe2fc08e108bcba85d609dfed4b Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 11 Apr 2026 09:42:40 +0000 Subject: Add dev shortcut to inject a synthetic test track MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Long-press the record FAB while NOT recording to immediately save a pre-built 30-minute west/return circuit from Honokohau Harbor. Uses the existing startTrack/addPoint/stopTrack pipeline so the full save flow — TrackSummarySheet, GPX file write, past-tracks list — all execute without needing to move. Points carry manually-set timestampMs values (30 min in the past, 2-min spacing) so the 2-minute duration validation passes. https://claude.ai/code/session_01HXPjBsogsJVRwCiekDGkJX --- .../src/main/kotlin/org/terst/nav/MainActivity.kt | 8 ++-- .../main/kotlin/org/terst/nav/ui/MainViewModel.kt | 44 +++++++++++++++++++++- 2 files changed, 48 insertions(+), 4 deletions(-) (limited to 'android-app/app') diff --git a/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt b/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt index 01971a6..d0b0d87 100644 --- a/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt +++ b/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt @@ -155,11 +155,13 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener { if (!viewModel.isRecording.value) viewModel.startTrack() } fabRecordTrack.setOnLongClickListener { + it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) if (viewModel.isRecording.value) { - it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) viewModel.stopTrack() - true - } else false + } else { + viewModel.injectTestTrack() + } + true } fabRecenter.setOnClickListener { mapHandler?.recenter() } diff --git a/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt b/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt index df31949..6ec8c76 100644 --- a/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt +++ b/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt @@ -90,7 +90,49 @@ class MainViewModel( } } - fun addGpsPoint(lat: Double, lon: Double, sogKnots: Double, cogDeg: Double) { + /** Dev shortcut: saves a synthetic 30-min Honokohau circuit without requiring GPS movement. */ + fun injectTestTrack() { + viewModelScope.launch { + val startMs = System.currentTimeMillis() - 30 * 60_000L + val points = buildTestTrack(startMs) + trackRepository.startTrack() + points.forEach { trackRepository.addPoint(it) } + val summary = trackRepository.stopTrack() + _pastTracks.value = trackRepository.getPastTracks() + _trackPoints.value = emptyList() + _isRecording.value = false + summary?.let { _trackSummary.emit(it) } + } + } + + private fun buildTestTrack(startMs: Long): List { + // Honokohau Harbor, Kona, HI: 19.669°N, 156.027°W + // Heads west (~270°) for first half, returns east (~90°) for second half + val baseLat = 19.669 + val baseLon = -156.027 + val nmPerDegreeLon = 60.0 * kotlin.math.cos(kotlin.math.PI / 180.0 * baseLat) + val sogKt = 4.5 + val count = 16 + return (0 until count).map { i -> + val tMs = startMs + i * 2 * 60_000L + val outbound = i < count / 2 + val legIndex = if (outbound) i else (count - 1 - i) + val distNm = sogKt * (legIndex * 2.0 / 60.0) + val lonOffset = distNm / nmPerDegreeLon + val lat = baseLat + if (!outbound) 0.003 else 0.0 // slight northing on return + val lon = baseLon - lonOffset + val cogDeg = if (outbound) 270.0 else 90.0 + val sog = sogKt + (i % 3 - 1) * 0.4 // mild variation + TrackPoint( + lat = lat, lon = lon, + sogKnots = sog, cogDeg = cogDeg, + waveHeightM = 0.6, + timestampMs = tMs + ) + } + } + +(lat: Double, lon: Double, sogKnots: Double, cogDeg: Double) { val conditions = _marineConditions.value val forecast = _forecast.value.firstOrNull() val point = TrackPoint( -- cgit v1.2.3