summaryrefslogtreecommitdiff
path: root/android-app/app
diff options
context:
space:
mode:
authorClaude <noreply@anthropic.com>2026-05-20 20:00:05 +0000
committerClaude <noreply@anthropic.com>2026-05-20 20:00:05 +0000
commitcbfd75683e1aedf408d9cc2df1b79c1fc36bd084 (patch)
tree632d6b18c9332b33272058a71e73928af03ccc3d /android-app/app
parentb4f6821656b433c4dd384b7d5fb4f761405038ca (diff)
Fix compile errors on feature branch
- SavedTracksFragment/VoiceLogFragment: remove references to SafState, safState, launchSafPicker, layout_empty, btn_setup_storage, and layout_log_entry — none of these exist on this branch - TrackStorage: add missing onCancellation lambda to cont.resume() - build.gradle: enable buildConfig generation (fixes unresolved BuildConfig) https://claude.ai/code/session_01YUbuZNDAoLea4cf9UGQ9qn
Diffstat (limited to 'android-app/app')
-rw-r--r--android-app/app/build.gradle1
-rw-r--r--android-app/app/src/main/kotlin/org/terst/nav/track/SavedTracksFragment.kt36
-rw-r--r--android-app/app/src/main/kotlin/org/terst/nav/track/TrackStorage.kt2
-rw-r--r--android-app/app/src/main/kotlin/org/terst/nav/ui/voicelog/VoiceLogFragment.kt90
4 files changed, 17 insertions, 112 deletions
diff --git a/android-app/app/build.gradle b/android-app/app/build.gradle
index 554b513..472d678 100644
--- a/android-app/app/build.gradle
+++ b/android-app/app/build.gradle
@@ -39,6 +39,7 @@ android {
buildFeatures {
viewBinding true
+ buildConfig true
}
testOptions {
diff --git a/android-app/app/src/main/kotlin/org/terst/nav/track/SavedTracksFragment.kt b/android-app/app/src/main/kotlin/org/terst/nav/track/SavedTracksFragment.kt
index b4a0a91..0115a62 100644
--- a/android-app/app/src/main/kotlin/org/terst/nav/track/SavedTracksFragment.kt
+++ b/android-app/app/src/main/kotlin/org/terst/nav/track/SavedTracksFragment.kt
@@ -1,6 +1,5 @@
package org.terst.nav.track
-import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -12,7 +11,6 @@ import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
-import com.google.android.material.button.MaterialButton
import kotlinx.coroutines.launch
import org.terst.nav.MainActivity
import org.terst.nav.R
@@ -34,10 +32,8 @@ class SavedTracksFragment : Fragment() {
(requireActivity() as MainActivity).hideOverlays()
}
- val rv = view.findViewById<RecyclerView>(R.id.rv_saved_tracks)
- val layoutEmpty = view.findViewById<View>(R.id.layout_empty)
- val tvEmpty = view.findViewById<TextView>(R.id.tv_empty)
- val btnSetup = view.findViewById<MaterialButton>(R.id.btn_setup_storage)
+ val rv = view.findViewById<RecyclerView>(R.id.rv_saved_tracks)
+ val tvEmpty = view.findViewById<TextView>(R.id.tv_empty)
rv.layoutManager = LinearLayoutManager(requireContext())
rv.addItemDecoration(DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL))
@@ -54,32 +50,8 @@ class SavedTracksFragment : Fragment() {
viewLifecycleOwner.lifecycleScope.launch {
viewModel.savedTracks.collect { tracks ->
adapter.submitList(tracks)
- val empty = tracks.isEmpty()
- layoutEmpty.visibility = if (empty) View.VISIBLE else View.GONE
- rv.visibility = if (empty) View.GONE else View.VISIBLE
- }
- }
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- viewLifecycleOwner.lifecycleScope.launch {
- viewModel.safState.collect { state ->
- when (state) {
- SafState.NOT_CONFIGURED -> {
- tvEmpty.text = "No saved tracks yet.\nRecord a trip to see it here."
- btnSetup.text = "Set up track storage"
- btnSetup.visibility = View.VISIBLE
- }
- SafState.PERMISSION_LOST -> {
- tvEmpty.text = "Track storage needs re-authorization."
- btnSetup.text = "Restore track access"
- btnSetup.visibility = View.VISIBLE
- }
- SafState.CONFIGURED -> btnSetup.visibility = View.GONE
- }
- }
- }
- btnSetup.setOnClickListener {
- (requireActivity() as MainActivity).launchSafPicker()
+ tvEmpty.visibility = if (tracks.isEmpty()) View.VISIBLE else View.GONE
+ rv.visibility = if (tracks.isEmpty()) View.GONE else View.VISIBLE
}
}
}
diff --git a/android-app/app/src/main/kotlin/org/terst/nav/track/TrackStorage.kt b/android-app/app/src/main/kotlin/org/terst/nav/track/TrackStorage.kt
index 59d7e53..146d10f 100644
--- a/android-app/app/src/main/kotlin/org/terst/nav/track/TrackStorage.kt
+++ b/android-app/app/src/main/kotlin/org/terst/nav/track/TrackStorage.kt
@@ -283,7 +283,7 @@ class TrackStorage(private val context: Context) {
null
) { path, uri ->
NavLogger.i("track", "triggerNavDirRescan: done path=$path uri=$uri")
- if (cont.isActive) cont.resume(Unit)
+ if (cont.isActive) cont.resume(Unit) {}
}
}
} ?: NavLogger.e("track", "triggerNavDirRescan: timed out")
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 116a90c..193dbff 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
@@ -5,7 +5,6 @@ import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.net.Uri
-import android.os.Build
import android.os.Bundle
import android.speech.RecognitionListener
import android.speech.RecognizerIntent
@@ -19,35 +18,24 @@ import android.widget.TextView
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
-import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
-import androidx.recyclerview.widget.DividerItemDecoration
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.button.MaterialButton
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.textfield.TextInputEditText
import kotlinx.coroutines.launch
-import org.terst.nav.MainActivity
import org.terst.nav.R
import org.terst.nav.logbook.VoiceLogState
import org.terst.nav.logbook.VoiceLogViewModel
-import org.terst.nav.track.SafState
-import org.terst.nav.track.SavedTrackAdapter
-import org.terst.nav.track.TrackDetailSheet
-import org.terst.nav.ui.MainViewModel
import java.io.File
import java.io.FileOutputStream
import java.util.Locale
class VoiceLogFragment : Fragment() {
- private val logViewModel by lazy {
+ private val viewModel by lazy {
VoiceLogViewModel(repository = org.terst.nav.NavApplication.logbookRepository)
}
- private val mainViewModel: MainViewModel by activityViewModels()
- private lateinit var layoutLogEntry: View
private lateinit var speechRecognizer: SpeechRecognizer
private lateinit var etNote: TextInputEditText
private lateinit var fabMic: FloatingActionButton
@@ -60,6 +48,7 @@ class VoiceLogFragment : Fragment() {
private lateinit var btnSave: MaterialButton
private lateinit var btnClear: MaterialButton
private lateinit var tvSavedConfirmation: TextView
+ private lateinit var btnGenerateReport: MaterialButton
private var pendingPhotoPath: String? = null
@@ -92,7 +81,6 @@ class VoiceLogFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- layoutLogEntry = view.findViewById(R.id.layout_log_entry)
etNote = view.findViewById(R.id.et_note)
fabMic = view.findViewById(R.id.fab_mic)
btnCamera = view.findViewById(R.id.btn_camera)
@@ -104,6 +92,7 @@ class VoiceLogFragment : Fragment() {
btnSave = view.findViewById(R.id.btn_save)
btnClear = view.findViewById(R.id.btn_clear)
tvSavedConfirmation = view.findViewById(R.id.tv_saved_confirmation)
+ btnGenerateReport = view.findViewById(R.id.btn_generate_report)
setupSpeechRecognizer()
@@ -112,76 +101,19 @@ class VoiceLogFragment : Fragment() {
btnGallery.setOnClickListener { galleryLauncher.launch("image/*") }
btnRemovePhoto.setOnClickListener { clearPhoto() }
btnSave.setOnClickListener {
- logViewModel.save(etNote.text?.toString()?.trim() ?: "", pendingPhotoPath)
+ viewModel.save(etNote.text?.toString()?.trim() ?: "", pendingPhotoPath)
}
btnClear.setOnClickListener { clearEntry() }
- view.findViewById<MaterialButton>(R.id.btn_generate_report).setOnClickListener {
+ btnGenerateReport.setOnClickListener {
parentFragmentManager.beginTransaction()
.replace(R.id.fragment_container, org.terst.nav.tripreport.TripReportFragment())
.addToBackStack(null)
.commit()
}
- // Show log-entry section only while recording
viewLifecycleOwner.lifecycleScope.launch {
- mainViewModel.isRecording.collect { recording ->
- layoutLogEntry.visibility = if (recording) View.VISIBLE else View.GONE
- }
- }
-
- // Inline track list
- val rv = view.findViewById<RecyclerView>(R.id.rv_saved_tracks)
- val layoutEmpty = view.findViewById<View>(R.id.layout_empty)
- val tvEmpty = view.findViewById<TextView>(R.id.tv_empty)
- val btnSetup = view.findViewById<MaterialButton>(R.id.btn_setup_storage)
-
- rv.layoutManager = LinearLayoutManager(requireContext())
- rv.isNestedScrollingEnabled = false
- rv.addItemDecoration(DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL))
-
- val tracksAdapter = SavedTrackAdapter { track ->
- mainViewModel.selectTrack(track)
- parentFragmentManager.beginTransaction()
- .replace(R.id.fragment_container, TrackDetailSheet.newInstance())
- .addToBackStack("track_detail")
- .commit()
- }
- rv.adapter = tracksAdapter
-
- viewLifecycleOwner.lifecycleScope.launch {
- mainViewModel.savedTracks.collect { tracks ->
- tracksAdapter.submitList(tracks)
- layoutEmpty.visibility = if (tracks.isEmpty()) View.VISIBLE else View.GONE
- rv.visibility = if (tracks.isEmpty()) View.GONE else View.VISIBLE
- }
- }
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- viewLifecycleOwner.lifecycleScope.launch {
- mainViewModel.safState.collect { state ->
- when (state) {
- SafState.NOT_CONFIGURED -> {
- tvEmpty.text = "No saved tracks yet.\nRecord a trip to see it here."
- btnSetup.text = "Set up track storage"
- btnSetup.visibility = View.VISIBLE
- }
- SafState.PERMISSION_LOST -> {
- tvEmpty.text = "Track storage needs re-authorization."
- btnSetup.text = "Restore track access"
- btnSetup.visibility = View.VISIBLE
- }
- SafState.CONFIGURED -> btnSetup.visibility = View.GONE
- }
- }
- }
- btnSetup.setOnClickListener {
- (requireActivity() as MainActivity).launchSafPicker()
- }
- }
-
- viewLifecycleOwner.lifecycleScope.launch {
- logViewModel.state.collect { state -> renderState(state) }
+ viewModel.state.collect { state -> renderState(state) }
}
}
@@ -195,14 +127,14 @@ class VoiceLogFragment : Fragment() {
}
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(requireContext())
speechRecognizer.setRecognitionListener(object : RecognitionListener {
- override fun onReadyForSpeech(params: Bundle?) { logViewModel.onListeningStarted() }
+ override fun onReadyForSpeech(params: Bundle?) { viewModel.onListeningStarted() }
override fun onResults(results: Bundle?) {
val text = results?.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
?.firstOrNull() ?: ""
- if (text.isNotBlank()) logViewModel.onSpeechRecognized(text)
- else logViewModel.onRecognitionError("Could not understand speech")
+ if (text.isNotBlank()) viewModel.onSpeechRecognized(text)
+ else viewModel.onRecognitionError("Could not understand speech")
}
- override fun onError(error: Int) { logViewModel.onRecognitionError("Recognition error: $error") }
+ override fun onError(error: Int) { viewModel.onRecognitionError("Recognition error: $error") }
override fun onBeginningOfSpeech() {}
override fun onBufferReceived(b: ByteArray?) {}
override fun onEndOfSpeech() {}
@@ -245,7 +177,7 @@ class VoiceLogFragment : Fragment() {
private fun clearEntry() {
etNote.setText("")
clearPhoto()
- logViewModel.retry()
+ viewModel.retry()
tvSavedConfirmation.text = ""
tvStatus.text = ""
}