<feed xmlns='http://www.w3.org/2005/Atom'>
<title>nav.git/android-app/app/src/main/kotlin/org/terst/nav/logbook, branch main</title>
<subtitle>nav — android navigation app
</subtitle>
<id>https://git.terst.org/nav.git/atom?h=main</id>
<link rel='self' href='https://git.terst.org/nav.git/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.terst.org/nav.git/'/>
<updated>2026-06-30T18:19:04+00:00</updated>
<entry>
<title>feat: UX improvements + HAW FAD data + fishing mode plan</title>
<updated>2026-06-30T18:19:04+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-06-30T17:16:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/nav.git/commit/?id=9af38934e8d676bfb8c08ab01e3d57fec5f36d97'/>
<id>urn:sha1:9af38934e8d676bfb8c08ab01e3d57fec5f36d97</id>
<content type='text'>
Dark mode:
- Force light mode (AppCompatDelegate.MODE_NIGHT_NO) in NavApplication

Log screen:
- Tracks sorted newest-first (sortedByDescending startMs)
- Photos/entries saved during a track tagged with trackId; ship's log
  shows only standalone entries (trackId == null)
- "Plan Trip" button moved from safety screen to log screen header row
- Pre-trip report auto-generates (newAutoInstance) when a track starts

Safety screen:
- Removed "Plan Trip" button (now in log screen)
- Quit button moved to top title row
- Anchor Watch section collapses by default (tap header to expand)
- Hardware Data Sources section collapses by default (tap header to expand)

Notifications + idle:
- Tracking notification becomes persistent (setOngoing true) while recording
- Notification title changes to "Recording track" when active
- App exits automatically after 3 hours of idle (resetIdleTimer via
  onUserInteraction + onResume; suspended while recording)

FAD layer:
- FadData.kt: 18 Hawaii Island DLNR FAD coordinates hardcoded
  (source: DLNR Division of Aquatic Resources 6/14/07)
- FAD GeoJSON populated on style load from static data

Fishing mode plan:
- docs/superpowers/plans/2026-06-30-fishing-mode.md: 7-task plan for
  RigAdvisor, SST tiles, FishingModeManager, FishingOverlayView, steering
  bearing line, and FAB integration

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Tech debt: Room list fast-path, delete AnchorWatchHandler orphan, LogbookRepository thread safety</title>
<updated>2026-05-28T07:35:00+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-05-28T07:35:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/nav.git/commit/?id=e16a5257f5c02034cd9703f465b1ec006d4bb1b0'/>
<id>urn:sha1:e16a5257f5c02034cd9703f465b1ec006d4bb1b0</id>
<content type='text'>
Room fast-path (item 3):
- TrackEntity.toShallowSavedTrack() reconstructs SavedTrack from cached summary
  data using two placeholder TrackPoints that preserve correct endMs for logbook
  filtering without parsing GPX
- TrackRepository.getSavedTracksFromRoom() returns shallow tracks sorted by startMs
- MainViewModel.init{} now shows Room data immediately (no spinner on warm start),
  then replaces with full GPX-parsed tracks once background load completes

AnchorWatchHandler orphan (item 4):
- Deleted ui/anchorwatch/AnchorWatchHandler.kt — the anchor depth/rode form was
  inlined into SafetyFragment; this Fragment had no navigation entry points left
- Deleted layout/fragment_anchor_watch.xml (only referenced by the deleted Fragment)

LogbookRepository thread safety (item 6):
- Added @Synchronized to save(), getAll(), and reload() to prevent concurrent
  mutation of the entries list and nextId counter across coroutine contexts

https://claude.ai/code/session_01KXYBuAHZkvv63DeUG6XaZD
</content>
</entry>
<entry>
<title>Fix logbook entries not reloading after SAF re-auth post-reinstall</title>
<updated>2026-05-27T15:47:26+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-05-27T15:47:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/nav.git/commit/?id=d7bc194813d98e00190d1c5627965f2fe94f57d9'/>
<id>urn:sha1:d7bc194813d98e00190d1c5627965f2fe94f57d9</id>
<content type='text'>
LogbookRepository loaded entries once at init; after reinstall the SAF
tree URI pref is wiped, so it loaded empty from the cleared legacy path
and held that empty list for the session — even after the user re-granted
SAF access.

Fix: add LogbookRepository.reload() and call it in
MainViewModel.onSafDirectorySelected() alongside reloadPastTracks().
The logbook JSON and photos already live in the SAF tree and survive
reinstall; this just ensures they're read at the right moment.

https://claude.ai/code/session_01KXYBuAHZkvv63DeUG6XaZD
</content>
</entry>
<entry>
<title>Persist logbook JSON and photos in SAF so they survive reinstall</title>
<updated>2026-05-26T20:35:38+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-05-26T20:35:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/nav.git/commit/?id=0db33911ca4841c658b22912d3ecf32477e5e827'/>
<id>urn:sha1:0db33911ca4841c658b22912d3ecf32477e5e827</id>
<content type='text'>
- LogbookStorage: reads/writes nav_logbook.json and photos into the SAF
  logbook/ subfolder, using the same saf_tree_uri pref as TrackStorage.
  Automatically migrates legacy getExternalFilesDir JSON on first SAF
  write. Falls back to external files when SAF is not yet configured.
- LogbookRepository: expose cameraDir (cache-backed temp for FileProvider),
  copyPhoto(Uri), and importPhoto(File) instead of the old photoDir.
- VoiceLogFragment / TrackDetailSheet: camera writes temp to cacheDir then
  imports to SAF after capture; gallery delegates to copyPhoto(); photo
  display and decodeThumbnail handle both content:// URIs and file paths.
- file_paths.xml: add cache-path entry so FileProvider can serve camera
  temp files from cacheDir/nav_camera/.

https://claude.ai/code/session_01KXYBuAHZkvv63DeUG6XaZD
</content>
</entry>
<entry>
<title>Fix camera to open system camera app; harden logbook storage; add backlog</title>
<updated>2026-05-26T04:57:28+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-05-26T04:57:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/nav.git/commit/?id=d35410c707900075bf4207bab518ead44d43c6e7'/>
<id>urn:sha1:d35410c707900075bf4207bab518ead44d43c6e7</id>
<content type='text'>
Camera:
- Replace ActivityResultContracts.TakePicture() with explicit
  StartActivityForResult + Intent(ACTION_IMAGE_CAPTURE) + EXTRA_OUTPUT
  so the full system camera app always opens (not a sub-view preview)
- FLAG_GRANT_WRITE_URI_PERMISSION added for camera app FileProvider access

LogbookStorage:
- getExternalFilesDir() can return null when external storage is
  unavailable; fall back to filesDir for both storageFile and photoDir
  so saves never silently fail on devices without external storage

Backlog (worklog.md):
- Add notes/photos to finished tracks + include in trip report
- Trip report voice: replace generic style picker with single Nav voice
- Fix tack detection false positives at low SOG
- Investigate/fix speed coloring in MapLibre Android 11.x

https://claude.ai/code/session_01YUbuZNDAoLea4cf9UGQ9qn
</content>
</entry>
<entry>
<title>Fix bugs from static analysis; add test coverage for new code</title>
<updated>2026-05-25T19:02:33+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-05-25T19:02:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/nav.git/commit/?id=04b5b7f6aa469a368bcf8f1d75046770d3f83d63'/>
<id>urn:sha1:04b5b7f6aa469a368bcf8f1d75046770d3f83d63</id>
<content type='text'>
Bugs fixed:
- LogbookStorage.copyFromUri: return null when ContentResolver returns null
  stream instead of returning a path to an unwritten file
- VoiceLogFragment adapter: decode photos as downsampled thumbnails
  (128x96 target) using BitmapFactory inSampleSize instead of loading
  full-resolution bitmaps on the main thread

Tests added:
- LogbookRepositoryTest: ID sequencing, insertion order, storage delegation,
  reload from persisted state, lat/lon preservation
- TripReportGeneratorTest: log entry time-range filtering, distance
  calculation, empty-points edge case, all narrative styles smoke-tested

https://claude.ai/code/session_01YUbuZNDAoLea4cf9UGQ9qn
</content>
</entry>
<entry>
<title>Persist log entries and photos; stamp with GPS location</title>
<updated>2026-05-25T18:12:11+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-05-25T18:12:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/nav.git/commit/?id=02776054778c3cbc8aefc43376b105becfec2b86'/>
<id>urn:sha1:02776054778c3cbc8aefc43376b105becfec2b86</id>
<content type='text'>
- LogbookStorage: Moshi-backed JSON persistence to getExternalFilesDir,
  photos saved to Pictures/Nav/ instead of cache
- LogbookRepository: file-backed replacement for in-memory store, loads
  saved entries on init so they survive app restarts
- VoiceLogViewModel: expose entries StateFlow, accept lat/lon in save()
- VoiceLogFragment: switch camera to TakePicture(Uri) via FileProvider for
  full-res photos; gallery copies content URI to persistent storage;
  passes current GPS position to save(); shows scrollable entries list
- MainViewModel: expose currentPosition StateFlow updated on each GPS fix
- AndroidManifest: add FileProvider for Pictures/Nav/ directory
- TripReportViewModel: updated to use LogbookRepository

https://claude.ai/code/session_01YUbuZNDAoLea4cf9UGQ9qn
</content>
</entry>
<entry>
<title>Four features: outbound link markers, offline content, log text/photo, departure picker</title>
<updated>2026-04-11T02:27:51+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-04-11T02:27:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/nav.git/commit/?id=4a2d0298ab2caa3d62cfbd54c0071ae47eb89ccf'/>
<id>urn:sha1:4a2d0298ab2caa3d62cfbd54c0071ae47eb89ccf</id>
<content type='text'>
Learn tab
- ic_open_in_new.xml: external link icon (box + arrow) applied to all browser-opening cards
- Migration guide cards retain internal › chevron; ASA/Flashcards cards show ↗ icon
- New REFERENCE section (offline, works without connectivity):
  - ColRegs Rules of the Road → colregs_reference.md (rules 1–38, lights table,
    sound signals, day shapes, memory aids)
  - Sailing Quick Reference → sailing_reference.md (points of sail, Beaufort scale,
    nav lights, knots, buoyage IALA-B, VHF channels, distress signals, tide rule of 12)
- ColRegs card moved from external ASA section to offline REFERENCE section

Log entry
- LogEntry: add photoPath field (absolute file path or content URI string)
- VoiceLogViewModel: replace confirmAndSave() with save(text, photoPath?) so the
  fragment controls text (user may edit recognized speech before saving)
- VoiceLogFragment: redesigned layout with EditText (editable, voice fills it),
  camera button (TakePicturePreview → JPEG in cacheDir), gallery button (GetContent),
  photo thumbnail with remove button, Save / Clear row
- Manifest: add android.hardware.camera uses-feature (required=false)

Departure date/time picker (trip planning)
- ic_calendar.xml: calendar icon for the picker button
- PreTripReportViewModel: _departureMs StateFlow (default = now), setDeparture(ms)
- PreTripReportGenerator.generateReport(): departureDateTimeMs param;
  findDepartureSlot() matches nearest UTC forecast item; condition window labels show
  actual local times (e.g. "2 PM") when departure is not near-now; buildWatchList
  uses departure hour for Kona trades warning instead of system clock
- fragment_pretrip_report.xml: DEPART card with label + calendar button above generate
- PreTripReportFragment: MaterialDatePicker (future dates only) → MaterialTimePicker
  chain; auto-regenerates after picker confirms

https://claude.ai/code/session_01HXPjBsogsJVRwCiekDGkJX
</content>
</entry>
<entry>
<title>refactor: unify core models and finish org.terst.nav migration</title>
<updated>2026-04-04T07:45:41+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-04-04T07:45:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/nav.git/commit/?id=97715ab4007ff3101f58edf4385cef1fc3d1615b'/>
<id>urn:sha1:97715ab4007ff3101f58edf4385cef1fc3d1615b</id>
<content type='text'>
</content>
</entry>
<entry>
<title>feat: add voice log UI with FAB, fragment container, and logbook domain models</title>
<updated>2026-03-15T05:39:21+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-03-15T05:39:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/nav.git/commit/?id=418f6ae8c8ccb968c2674548139dab36e2ab1905'/>
<id>urn:sha1:418f6ae8c8ccb968c2674548139dab36e2ab1905</id>
<content type='text'>
- Add VoiceLogFragment, VoiceLogViewModel, VoiceLogState, LogEntry, InMemoryLogbookRepository
- Wire voice log FAB in MainActivity to show/hide fragment container
- Add RECORD_AUDIO permission to manifest
- Add native CMakeLists.txt and native-lib.cpp stubs
- Fix missing BufferOverflow import in LocationService

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
