summaryrefslogtreecommitdiff
path: root/.agent
diff options
context:
space:
mode:
Diffstat (limited to '.agent')
-rw-r--r--.agent/code-map.md48
-rw-r--r--.agent/worklog.md12
2 files changed, 49 insertions, 11 deletions
diff --git a/.agent/code-map.md b/.agent/code-map.md
index 1a36542..e5b28a1 100644
--- a/.agent/code-map.md
+++ b/.agent/code-map.md
@@ -1,7 +1,7 @@
# Code Map & Context Tips
**Purpose:** Bootstrap context for any new agent session. Read this before touching code.
-**Last updated:** 2026-06-03
+**Last updated:** 2026-06-30
---
@@ -116,10 +116,10 @@ All source lives under `org.terst.nav`.
| `LogbookRepository.kt` | Interface |
| `InMemoryLogbookRepository.kt` | Thread-safe impl (`@Synchronized` on save/getAll/reload) |
| `LogbookStorage.kt` | JSON persistence to SAF directory |
-| `LogEntry.kt` | Log entry data class (type enum, text, photo, position) |
+| `LogEntry.kt` | Log entry data class (type enum, text, photo, position, optional `trackId: Long?`) |
| `LogbookFormatter.kt` | Formats log for display |
| `LogbookPdfExporter.kt` | PDF export |
-| `VoiceLogViewModel.kt` | ViewModel for logbook + trip report tab |
+| `VoiceLogViewModel.kt` | ViewModel for logbook tab — filters to standalone entries (`trackId == null`) only; `save()` accepts optional `trackId` |
| `VoiceLogState.kt` | Sealed state for voice log UI |
### `nmea/`
@@ -170,7 +170,7 @@ Data-only classes (no logic): `WindData`, `HeadingData`, `BoatSpeedData`, `Depth
| File | Role |
|------|------|
-| `TrackRepository.kt` | Coordinates GPX + Room storage; source of truth = GPX/SAF |
+| `TrackRepository.kt` | Coordinates GPX + Room storage; source of truth = GPX/SAF; **sorted descending by `startMs`** |
| `TrackStorage.kt` | SAF primary + MediaStore fallback for GPX files |
| `TrackEntity.kt` | Room entity; `toShallowSavedTrack()` for fast list load |
| `TrackDao.kt` | Room DAO |
@@ -193,7 +193,7 @@ Data-only classes (no logic): `WindData`, `HeadingData`, `BoatSpeedData`, `Depth
| `TripReportFragment.kt` | Full trip report view (map + stats + log entries) |
| `TripReportGenerator.kt` | Generates report from track + log data |
| `TripReportViewModel.kt` | ViewModel for trip report |
-| `PreTripReportFragment.kt` | Pre-departure checklist / briefing |
+| `PreTripReportFragment.kt` | Pre-departure briefing; auto-generates on open if forecast available; `newAutoInstance()` triggers generation immediately (called when recording starts) |
| `PreTripReportGenerator.kt` | Generates pre-trip summary (weather, similar trips, watch items) |
| `PreTripReportViewModel.kt` | ViewModel for pre-trip report |
| `PreTripModels.kt` | Data classes for pre-trip report |
@@ -205,6 +205,15 @@ Data-only classes (no logic): `WindData`, `HeadingData`, `BoatSpeedData`, `Depth
|------|------|
| `VesselRepository.kt` | Crew + vessel data; in-memory + persistence |
+### `ui/fishing/`
+
+| File | Role |
+|------|------|
+| `FishingTarget.kt` | `FishingSpecies` enum, `RigRecommendation`, `FishingTarget` data classes |
+| `RigAdvisor.kt` | Pure function: `recommend(tempC, currentKt, windKt) → RigRecommendation` — Ono for warm+fast current, Mahi for moderate, BOTH otherwise |
+| `FishingModeManager.kt` | Persists `isActive` pref; `computeTarget()` returns cross-current bearing toward estimated temp break |
+| `FishingOverlayView.kt` | Custom `FrameLayout` inflating `view_fishing_overlay.xml`; `bind(FishingTarget)` updates all text views |
+
### `ui/` (top level)
| File | Role |
@@ -212,9 +221,10 @@ Data-only classes (no logic): `WindData`, `HeadingData`, `BoatSpeedData`, `Depth
| `MainViewModel.kt` | Top-level app state |
| `MobHandler.kt` | MOB activation logic; always-on-top button handler |
| `InstrumentHandler.kt` | Routes NMEA/GPS data to instrument display widgets |
-| `MapHandler.kt` | MapLibre map setup, overlay rendering, track display |
-| `MapLayerManager.kt` | Layer visibility management |
-| `LayerPickerSheet.kt` | Bottom sheet: layer toggle UI |
+| `MapHandler.kt` | MapLibre map setup, overlay rendering, track display, fishing bearing line |
+| `MapLayerManager.kt` | Layer visibility: satellite, charts, wind, SST, depth (GEBCO WMS), seamarks, FADs toggle |
+| `LayerPickerSheet.kt` | Bottom sheet: layer toggle UI; constructor takes `onSstChanged` in addition to existing callbacks |
+| `FadData.kt` | 18 Hawaii Island DLNR FAD positions in decimal degrees; `toFeatures()` returns GeoJSON for MapHandler |
| `NavLogger.kt` | In-app debug log (primary debugging tool — prefer over ADB) |
| `LocationPermissionHandler.kt` | Runtime location permission request flow |
| `DevLogSheet.kt` | Bottom sheet: shows NavLogger output |
@@ -234,7 +244,7 @@ Data-only classes (no logic): `WindData`, `HeadingData`, `BoatSpeedData`, `Depth
| File | Role |
|------|------|
-| `SafetyFragment.kt` | Safety tab: MOB, anchor alarm (depth + rode inputs, radius display) |
+| `SafetyFragment.kt` | Safety tab: MOB, CPA alerts, anchor alarm (collapsible), hardware sources (collapsible); Quit button at top of title row |
### `ui/voicelog/`
@@ -301,7 +311,10 @@ JVM-only; mirrors a subset of android-app source with no Android SDK dependencie
7. **`VoiceLogFragment`** must pass both `onSelect` and `onReport` to `SavedTrackAdapter` — omitting either causes a CI failure.
8. **MapLibre Android 11.x**: `Expression.get("color")` silently fails for `lineColor` on `LineLayer`. Use `Expression.step(Expression.get("speed"), ...)` to map speed → color literal.
9. **Speed/temp/depth in UI** must use `UnitPrefs` conversions — never raw SI values.
-10. **NMEA sentences from instruments are magnetic.** Convert to true using WMM variation from `HarmonicTideCalculator`'s companion magnetic model — not a hardcoded offset.
+10. **NMEA sentences from instruments are magnetic.**
+11. **Night vision vs system dark mode are separate.** `NavApplication` does NOT set `MODE_NIGHT_NO` — system dark mode is respected. `MainActivity` has a `fab_night_mode` FAB that toggles `Theme.Nav.NightVision` (red-on-black, 0.3× brightness) for dark adaptation at sea. These are independent; do not confuse them.
+12. **`LogEntry.trackId`**: entries saved while recording carry `trackId = mainViewModel.trackStartMs`. Ship's log (`VoiceLogFragment`) filters to `trackId == null` only — in-track notes/photos are associated with the track, not the standalone log.
+13. **Idle exit timer**: `MainActivity.resetIdleTimer()` schedules a 3-hour coroutine to `exitProcess(0)` if no user interaction. Cancelled on any `onUserInteraction()` call. Skipped entirely while recording (`isRecording == true`). Convert to true using WMM variation from `HarmonicTideCalculator`'s companion magnetic model — not a hardcoded offset.
---
@@ -328,6 +341,8 @@ Key test files by domain:
| AIS / CPA | `test-runner/.../ais/CpaCalculatorTest.kt` |
| NMEA parsing | `test-runner/.../nmea/NmeaParserTest.kt` |
| GRIB storage | `test-runner/.../data/storage/GribFileManagerTest.kt` |
+| Fishing / rig advisor | `android-app/.../ui/fishing/RigAdvisorTest.kt` (2 tests) |
+| Fishing / mode manager | `android-app/.../ui/fishing/FishingModeManagerTest.kt` (1 test) |
---
@@ -383,6 +398,19 @@ CI (`android.yml`) triggers only on pushes to `main`. Firebase App Distribution
- Report auto-generates on tab open; RETRY button appears only on error.
- Track map uses a full-bleed 260dp MapLibre instance embedded in the report fragment.
- Pirate mode Easter egg: long-press title in `TripReportFragment`.
+- **Pre-trip report** auto-generates when recording starts: `MainActivity` calls `PreTripReportFragment.newAutoInstance()` and shows it as an overlay. Use `newAutoInstance()` for immediate generation; otherwise the fragment waits for user tap.
+
+### Fishing Mode
+- `fab_fishing` (bottom-start mini FAB) toggles `FishingModeManager.isActive`; shows/hides `FishingOverlayView` and SST layer in sync.
+- `updateFishingOverlay()` in `MainActivity` is called from `marineConditions.collect` — updates whenever conditions refresh.
+- `lastCogDeg: Double` is updated from `gpsData.cog` inside `observeDataSources()` GPS collect.
+- FADs (18 Hawaii DLNR buoys) are loaded once at style setup via `FadData.toFeatures()`. They default **visible** (`fadsEnabled = true`). Layer is in MapHandler; visibility pref is in MapLayerManager.
+- Depth tiles: GEBCO-equivalent from NOAA CoastWatch ETOPO180 WMS — has full Pacific coverage. OpenSeaMap depth tiles were dropped (essentially empty for Hawaii).
+
+### LocationService notifications
+- While idle: non-persistent notification titled "Sailing Companion".
+- While recording: persistent (`setOngoing(true)`) notification titled "Recording track".
+- `MainActivity` sends `ACTION_SET_RECORDING` intent to update the notification when `isRecording` state changes.
### GRIB / Weather
- GRIB files stored via `GribFileManager`; staleness checked by `GribStalenessChecker`.
diff --git a/.agent/worklog.md b/.agent/worklog.md
index 342ffa0..1ca8a7c 100644
--- a/.agent/worklog.md
+++ b/.agent/worklog.md
@@ -2,12 +2,22 @@
## Backlog
-*(all backlog items completed as of 2026-05-27)*
+- **Additional map sources** — NOAA chart tiles, ATON vector layer, TSS overlay. Plan: `docs/superpowers/plans/2026-06-30-additional-map-sources.md` (5 tasks).
---
## Recently Completed
+### Bug Fixes (pre-fishing-mode release) — 2026-06-30
+
+1. **Restore dark mode** — removed `MODE_NIGHT_NO` from `NavApplication`; system dark mode now works. NightVision (red-on-black FAB) is separate and unaffected.
+2. **Depth tile source** — swapped empty `OpenSeaMap/depth` URL for NOAA CoastWatch ETOPO180 WMS; full Pacific/Hawaii coverage.
+3. **FADs visible by default** — changed `fadsEnabled` default from `false` to `true`.
+
+### Code Map Update — 2026-06-30
+
+Updated `code-map.md` to reflect all changes since 2026-06-03: `ui/fishing/` package, `FadData.kt`, updated `MapLayerManager`/`MapHandler`/`LayerPickerSheet` entries, `SafetyFragment` collapsible sections, `PreTripReportFragment` auto-generate, `TrackRepository` reverse sort, `LogEntry.trackId` field, `VoiceLogViewModel` standalone filtering, new invariants (night vision vs dark mode, idle timer, trackId filter), `LocationService` notification behavior, fishing mode gotchas.
+
### Fishing Mode Feature — 2026-06-30
Implemented all 7 tasks for the fishing mode feature: