diff options
Diffstat (limited to '.agent')
| -rw-r--r-- | .agent/code-map.md | 48 | ||||
| -rw-r--r-- | .agent/worklog.md | 12 |
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: |
