summaryrefslogtreecommitdiff
path: root/android-app/app/src/main/res
AgeCommit message (Collapse)Author
2026-04-03feat(instruments): add forecast wind, wave, swell and current from Open-MeteoPeter Stone
- Add swell params to MarineApiService request - Add swell fields to MarineHourly model - Add MarineConditions snapshot model - Add WeatherRepository.fetchCurrentConditions() (first forecast hour) - Add MainViewModel.loadConditions() + marineConditions StateFlow - Add Forecast section to instrument sheet: Curr / Wave / Swell - Populate TWS from forecast wind speed on first GPS fix - Trigger loadConditions() once on first GPS position received Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03feat(instruments): replace simulation with real GPS and barometer dataPeter Stone
- Drop VMG, Polar %, and PolarDiagramView — no NMEA source on boat - Shrink grid to 3×2 (AWS/HDG/BSP / TWS/COG/SOG) - Move Depth + Baro to expanded section side by side - Initialize all instruments to "—" on startup - Wire LocationService.locationFlow → SOG + COG display (real GPS) - Wire LocationService.barometerStatus → Baro display (device sensor) - Delete startInstrumentSimulation() fake loop entirely Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02feat(map): interactive map with auto-follow, recenter button, and UI ↵Peter Stone
immersive mode (#2) * docs: add map interaction design spec Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: add map interaction implementation plan Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(map): add isFollowing state and gesture-driven manual mode to MapHandler * feat(ui): add fab_recenter pill button to map layout * feat(map): wire UI fade-out and recenter button to MapHandler.isFollowing * fix(map): prevent fadeIn flash on cold start; consolidate fab_mob listener * fix(map): preserve user zoom level on recenter Capture the current camera zoom when the user gestures (entering manual mode) and pass it back to centerOnLocation in recenter(), so tapping Recenter returns to the user's chosen zoom rather than always snapping to the default 14. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(map): capture lastZoom on camera idle, not gesture start OnCameraMoveStartedListener fires before the gesture completes, so it captured the pre-gesture zoom. OnCameraIdleListener fires after the camera settles, giving the user's final intended zoom level. Only update lastZoom while in manual mode (isFollowing=false). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(map): guard recenter against null island and add KDoc - Skip recenter() if no GPS fix received (lastLat/lastLon still 0.0) to avoid animating to 0°N, 0°E - Add KDoc comment to recenter() consistent with other public methods Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03fix(ui): raise FAB elevation above CardView sheet to fix z-orderPeter Stone
The instrument sheet CardView has cardElevation=16dp which was rendering on top of the FABs (default ~6dp elevation). Set app:elevation=20dp on both FABs so they always appear above the sheet. Also reverts oversized marginBottom back to standard 16dp all-round now that elevation stacking is correct. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03fix(ui): raise both FABs fully above instrument sheet top edgePeter Stone
anchorGravity=top centers the FAB on the sheet edge, leaving half the button occluded. Increase marginBottom to 44dp (28dp to clear the FAB radius + 16dp gap) so both buttons sit fully above the sheet. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02fix(ui): anchor both FABs to instrument sheet (squash merge recovery)Peter Stone
Both fab_mob and fab_record_track now anchor to instrument_bottom_sheet so they sit above the sheet peek zone rather than being occluded by the sheet's 16dp elevation. Resolves stash conflict in settings.local.json. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25feat(track): implement GPS track recording with map overlayPeter Stone
- TrackRepository + TrackPoint wired into MainViewModel: isRecording/trackPoints StateFlows, startTrack/stopTrack/addGpsPoint - MapHandler.updateTrackLayer(): lazily initialises a red LineLayer and updates GeoJSON polyline from List<TrackPoint> - fab_record_track FAB in activity_main.xml (top|end of bottom nav); icon toggles between ic_track_record and ic_close while recording - MainActivity feeds every GPS fix into viewModel.addGpsPoint() and observes trackPoints to redraw the polyline in real time - ic_track_record.xml vector drawable (red record dot) - 8 TrackRepositoryTest tests all GREEN Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25feat: add AnchorWatchHandler UI with Depth/Rode Out inputs and suggested radiusAgent
- Add AnchorWatchState with calculateRecommendedWatchCircleRadius, which uses ScopeCalculator.watchCircleRadius (Pythagorean scope formula) and falls back to rode length when geometry is invalid - Add AnchorWatchHandler Fragment with EditText inputs for Depth (m) and Rode Out (m); updates suggested watch circle radius live via TextWatcher - Add fragment_anchor_watch.xml layout - Wire AnchorWatchHandler into bottom navigation (MainActivity + menu) - Add AnchorWatchStateTest covering valid geometry, short-rode fallback Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25feat: offline GRIB staleness checker, ViewModel integration, and UI badgeClaudomator Agent
- Add GribRegion, GribFile data models and GribFileManager interface - Add InMemoryGribFileManager for testing and default use - Add GribStalenessChecker with FreshnessResult sealed class (Fresh/Stale/NoData) - Integrate weatherStaleness StateFlow into MainViewModel (checked after loadWeather) - Add yellow staleness banner TextView to fragment_map.xml - Wire staleness banner in MapFragment (shown on Stale, hidden on Fresh/NoData) - Add GribStalenessCheckerTest (4 TDD tests) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25fix: add missing layout_width/height to instruments sheet include tagPeter Stone
Caused a fatal InflateException crash on app launch. Android requires layout_width and layout_height on <include> tags explicitly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25fix: add layout_width/height to instrument text stylesPeter Stone
InstrumentLabel and InstrumentPrimaryValue were missing layout dimension attributes, causing InflateException crash on startup. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23fix: resolve Kotlin compilation errors from UI refactorPeter Stone
- Make InstrumentHandler.labelTrend and barometerTrendView nullable - Remove anchorWatchHandler init block referencing non-existent view IDs - Fix state.radiusM -> state.watchCircleRadiusMeters - Add bottom_nav_weather_menu.xml with nav_forecast; point WeatherActivity at it Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23feat: refactor UI to BottomNavigationView with Safety and Doc fragmentsPeter Stone
Replace FAB-based navigation with a 4-tab BottomNavigationView (Map, Instruments, Log, Safety). Instruments use a collapsible bottom sheet; Log and Safety display as full-screen overlay fragments. - Add SafetyFragment with MOB and Anchor Watch controls - Add DocFragment for in-app markdown help (Markwon: core, tables, images) - Add layout_instruments_sheet with 3x3 instrument grid and PolarDiagramView - Add fragment_safety and fragment_doc layouts - Add vector drawables: ic_map, ic_instruments, ic_log, ic_safety, ic_close - Update activity_main.xml to CoordinatorLayout with bottom sheet + overlay - Fix: set isHideable=true before STATE_HIDDEN to avoid silent no-op from behavior_hideable=false default; restore false on Map/Instruments tabs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15feat: integrate AIS into ViewModel and MapFragment with vessel symbol layerClaudomator Agent
- MainViewModel: add _aisTargets StateFlow, processAisSentence(), refreshAisFromInternet() - AisRepository: add ingestVessel() for internet-sourced vessels - MapFragment: add AIS vessel SymbolLayer with heading-based rotation and zoom-gated labels - MainActivity: add startAisHardwareFeed() TCP stub, wire viewModel - ic_ship_arrow.xml: new vector drawable for AIS target icons - MainViewModelTest: 3 new AIS tests (processAisSentence happy path, dedup, non-AIS sentence) - JVM test harness: /tmp/ais-vm-test-runner/ — 3 tests GREEN Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15merge: integrate weather/forecast feature from local remotePeter Stone
Merges wind/current overlay and weather forecast implementation: - Weather feature: WeatherRepository, MainViewModel, MapFragment, ForecastFragment, ForecastAdapter - Data models: WindArrow, ForecastItem, WeatherResponse, MarineResponse - API services: WeatherApiService, MarineApiService (Open-Meteo, no key required) - Layouts: activity_weather.xml, fragment_map.xml, fragment_forecast.xml, item_forecast.xml - Resources: merged colors (wind_slow/medium/strong), strings, themes (Theme.NavApp added) - Manifest: added ACCESS_COARSE_LOCATION - build.gradle: merged deps — kept Firebase+MapLibre 11.5.1, added kotlin-kapt, retrofit, moshi, turbine - Fix: re-packaged com.example.androidapp → org.terst.nav; weather MainActivity uses ActivityWeatherBinding Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15feat: add voice log UI with FAB, fragment container, and logbook domain modelsPeter Stone
- 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 <noreply@anthropic.com>
2026-03-14fix: correct ConstraintLayout attribute typo in activity_main.xmlPeter Stone
layout_bottom_toTopOf → layout_constraintBottom_toTopOf on fab_tidal. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14Implement barometric pressure trend monitoring and visualizationClaudomator Agent
2026-03-14Implement tidal current overlay on the chart with toggle FABClaudomator Agent
2026-03-13refactor: rename app from AndroidApp to navPeter Stone
2026-03-13fix: resolve MapLibre 11.x migration issues and layout/resource errorsPeter Stone
2026-03-13fix: resolve XML syntax and resource formatting errorsPeter Stone
2026-03-13refactor: update package name to org.terst.nav and setup CI/CD with Firebase ↵Peter Stone
App Distribution
2026-03-13Implement polar performance diagram visualizationClaudomator Agent
2026-03-13feat: Implement MOB (Man Overboard) alarm functionalityClaudomator Agent
This commit introduces the core functionality for the Man Overboard (MOB) alarm. Key changes include: - Added a persistent, high-contrast red MOB Floating Action Button to the UI. - Implemented dynamic location permission requests and initialization of LocationService. - Created a MobWaypoint data class to store MOB location and timestamp. - Developed the activateMob() function to: - Capture current GPS coordinates. - Set the active MOB waypoint and mark MOB as activated. - Switch to a dedicated MOB navigation view, hiding other UI elements. - Start a continuous, looping audible alarm (assumes R.raw.mob_alarm exists). - Log the MOB event to the console (placeholder for future logbook integration). - Implemented a MOB navigation view (ConstraintLayout) with real-time distance to MOB and elapsed time display. - Added a recoverMob() function, triggered by a 'Recovered' button, to: - Deactivate MOB mode. - Stop and release the audible alarm. - Restore the main UI visibility. - Location updates are observed to continuously update the MOB navigation display. - Ensured MediaPlayer resources are properly released on activity destruction. Future enhancements (not part of this commit) include: - Implementing a bearing arrow in the MOB navigation view. - Integrating with a persistent logbook system.
2026-03-13feat: add wind/current map overlay and weather forecast on startupClaudomator Agent
Implements the wind/current map overlay and 7-day weather forecast display that loads on application launch: Data layer: - Open-Meteo API (free, no key): WeatherApiService + MarineApiService - Moshi-annotated response models (WeatherResponse, MarineResponse) - WeatherRepository: parallel async fetch, Result<T> error propagation - Domain models: WindArrow (with beaufortScale/isCalm) + ForecastItem (with weatherDescription/isRainy via WMO weather codes) Presentation layer: - MainViewModel: StateFlow<UiState> (Loading/Success/Error), windArrow and forecast streams - MainActivity: runtime location permission, FusedLocationProvider GPS fetch on startup, falls back to SF Bay default - MapFragment: MapLibre GL map with wind-arrow SymbolLayer; icon rotated by wind direction, size scaled by speed in knots - ForecastFragment + ForecastAdapter: RecyclerView ListAdapter showing 7-day hourly forecast (time, description, wind, temp, precip) Resources: - ic_wind_arrow.xml vector drawable (north-pointing, rotated by MapLibre) - BottomNavigationView: Map / Forecast tabs - ViewBinding enabled throughout Tests (TDD — written before implementation): - WindArrowTest: calm detection, direction normalisation, Beaufort scale - ForecastItemTest: weatherDescription, isRainy for WMO codes - WeatherApiServiceTest: MockWebServer request params + response parsing - WeatherRepositoryTest: MockK service mocks, data mapping, error paths - MainViewModelTest: Turbine StateFlow assertions for all state transitions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13Implement basic instrument displayClaudomator Agent
2026-03-13feat: Implement initial chart display setup with MapLibre GL NativeClaudomator Agent
2026-03-13Implement GPS navigation with position, SOG, and COGClaudomator Agent