summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaude <noreply@anthropic.com>2026-05-26 04:57:28 +0000
committerClaude <noreply@anthropic.com>2026-05-26 04:57:28 +0000
commitd35410c707900075bf4207bab518ead44d43c6e7 (patch)
tree53f8f63c41fe86104b4875df4a3e157e20f7bce4
parent70c1698ebc9e9661724e5326ae1c93f2b74c2b09 (diff)
Fix camera to open system camera app; harden logbook storage; add backlog
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
-rw-r--r--.agent/worklog.md10
-rw-r--r--android-app/app/src/main/kotlin/org/terst/nav/logbook/LogbookStorage.kt4
-rw-r--r--android-app/app/src/main/kotlin/org/terst/nav/ui/voicelog/VoiceLogFragment.kt17
3 files changed, 23 insertions, 8 deletions
diff --git a/.agent/worklog.md b/.agent/worklog.md
index 55fd5a7..cfae053 100644
--- a/.agent/worklog.md
+++ b/.agent/worklog.md
@@ -1,5 +1,15 @@
# SESSION_STATE.md
+## Backlog (fix later)
+
+- **Add notes/photos to a finished track** — UI to attach logbook entries to a past track by timestamp/geo proximity. Must flow into the trip report (currently only live-session entries are scoped).
+
+- **Trip report voice** — The current narrative styles (Professional / Adventurous / Journal / Pirate) are generic and not right for Nav. Nav is an opinionated sailing app; the report should have a single voice that reflects that — concise, knowledgeable, seamanlike. Rip out the style picker and write one good template.
+
+- **Tack detection is buggy, especially at low speed** — False positives at low SOG (GPS heading noise looks like tacks). Need minimum-SOG gate (e.g. skip detection when SOG < 1.5 kt) and review the stability window / MIN_DELTA thresholds against real tracks.
+
+- **Speed coloring on the map doesn't work** — `Expression.get("color")` on a FeatureCollection of 2-point LineStrings fails silently in MapLibre Android 11.x. The focused-track layer in MapHandler still uses this broken approach. Needs investigation: either find a working data-driven expression syntax for this MapLibre version, or pre-segment the GeoJSON differently.
+
## Current Task Goal
Instrument Sheet Visual Redesign — IN PROGRESS (2026-04-06)
diff --git a/android-app/app/src/main/kotlin/org/terst/nav/logbook/LogbookStorage.kt b/android-app/app/src/main/kotlin/org/terst/nav/logbook/LogbookStorage.kt
index 6b90542..51f1f09 100644
--- a/android-app/app/src/main/kotlin/org/terst/nav/logbook/LogbookStorage.kt
+++ b/android-app/app/src/main/kotlin/org/terst/nav/logbook/LogbookStorage.kt
@@ -16,10 +16,10 @@ class LogbookStorage(private val context: Context) {
private val adapter = moshi.adapter(LogEntryList::class.java)
private val storageFile: File
- get() = File(context.getExternalFilesDir(null), "nav_logbook.json")
+ get() = File(context.getExternalFilesDir(null) ?: context.filesDir, "nav_logbook.json")
val photoDir: File
- get() = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "Nav")
+ get() = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) ?: context.filesDir, "Nav")
.also { it.mkdirs() }
fun loadAll(): List<LogEntry> = runCatching {
diff --git a/android-app/app/src/main/kotlin/org/terst/nav/ui/voicelog/VoiceLogFragment.kt b/android-app/app/src/main/kotlin/org/terst/nav/ui/voicelog/VoiceLogFragment.kt
index 3638f8f..2557eb4 100644
--- a/android-app/app/src/main/kotlin/org/terst/nav/ui/voicelog/VoiceLogFragment.kt
+++ b/android-app/app/src/main/kotlin/org/terst/nav/ui/voicelog/VoiceLogFragment.kt
@@ -1,12 +1,14 @@
package org.terst.nav.ui.voicelog
import android.Manifest
+import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Build
import android.os.Bundle
+import android.provider.MediaStore
import android.speech.RecognitionListener
import android.speech.RecognizerIntent
import android.speech.SpeechRecognizer
@@ -73,9 +75,9 @@ class VoiceLogFragment : Fragment() {
private var pendingCameraUri: Uri? = null
private val cameraLauncher = registerForActivityResult(
- ActivityResultContracts.TakePicture()
- ) { success: Boolean ->
- if (success) {
+ ActivityResultContracts.StartActivityForResult()
+ ) { result ->
+ if (result.resultCode == Activity.RESULT_OK) {
val path = pendingPhotoPath ?: return@registerForActivityResult
setPhoto(path) {
val bm = BitmapFactory.decodeFile(path)
@@ -140,13 +142,16 @@ class VoiceLogFragment : Fragment() {
fabMic.setOnClickListener { startListening() }
btnCamera.setOnClickListener {
- val dir = NavApplication.logbookRepository.photoDir
- val file = File(dir, "log_${System.currentTimeMillis()}.jpg")
+ val file = File(NavApplication.logbookRepository.photoDir, "log_${System.currentTimeMillis()}.jpg")
pendingPhotoPath = file.absolutePath
pendingCameraUri = FileProvider.getUriForFile(
requireContext(), "${requireContext().packageName}.fileprovider", file
)
- cameraLauncher.launch(pendingCameraUri!!)
+ val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE).apply {
+ putExtra(MediaStore.EXTRA_OUTPUT, pendingCameraUri)
+ addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
+ }
+ cameraLauncher.launch(intent)
}
btnGallery.setOnClickListener { galleryLauncher.launch("image/*") }