summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-07-02fix+feat: track layer cleanup, notification, log redesign, color consistencymainPeter Stone
- Fix track events persisting on main map: clear selectedTrack and pop track_detail back stack in hideOverlays() so speed segments and tack circles are removed when navigating to Map via bottom nav - Notification: dual channels (recording=DEFAULT, background=MIN); shows app name + "Recording journey · Xh Ym · X.X nm"; updates live from trackStats collector; invisible when not recording - Log tab: unified reverse-chronological ship's log merging saved tracks + standalone notes (no photo-only rows); form hidden when not recording with "New Note" button → AlertDialog (with camera/gallery); combine() flow keeps list reactive to both tracks and log entries - Sheet border: bottom nav + fragment container now use colorSurfaceContainerHigh matching the instrument card's elevated surface color; card elevation set to 0dp with explicit background to avoid double-tinting Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02fix+feat: layer cards, ocean floor, notifications, units, log, photosPeter Stone
Layer picker: - Fix blank cards: app:layout_columnWeight → android:layout_columnWeight (GridLayout children require android: namespace for weight attributes) - Add Distance unit chips (nm/km/mi) to UNITS section Map layers: - Fix ocean floor: use addLayerAbove(lastFillLayer) instead of addLayerAt(0) so base rasters appear above OFM water/land fills but below roads+labels - CardView elevation 16dp→4dp to eliminate visible shadow border Notifications: - Add POST_NOTIFICATIONS to manifest - Request it alongside location permissions on Android 13+ (TIRAMISU+) Conditions sheet: - showOverlay() now always hides bottom sheet (STATE_HIDDEN) so it can't leak onto non-map pages; bottom padding (80dp) added to Safety+Log panes Log entries: - Log entry form visible always (was only shown while recording) - Photo-only events filtered from track timeline; photos appear only when paired with real text in a log entry Anchor watch: - Inputs and output radius now use configured depth unit (ft/m) with label updates and ft→m conversion before calculation Photos: - Tap thumbnail in track event log → fullscreen dialog viewer Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02fix(ui): quit X icon, FAB visibility, sheet border, blank map layersPeter Stone
- Remove ic_close icon from Quit App button (fragment_safety.xml) - fab_fishing now hides/shows in showOverlay/showTrackDetail/hideOverlays so fishing+record FABs always move together and disappear on non-map pages - Add strokeWidth=0dp to instrument bottom sheet card to remove gray border - Fix blank map: split addToStyleBuilder into addSourcesToStyleBuilder (builder time) + addBaseLayersToStyle (inserts at index 0, below OFM vector layers) + addOverlayLayersToStyle (appends above OFM labels). Previously withLayer() appended rasters after OFM layers so the opaque Ocean base covered all labels/roads. - Add Log.d tracing throughout style load + layer insertion for debugging Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02fix(ui): layer previews, fishing pole icon, button alignment, safety page ↵Peter Stone
cleanup - Layer picker: change android:src→android:background on preview ImageViews; shape drawables have no intrinsic size so centerCrop renders blank — background fills correctly - Replace ic_fish with ic_fishing_pole (rod + reel + line + hook vector) - Move fab_fishing to CoordinatorLayout with layout_anchor on instrument_bottom_sheet top|start, matching fab_record_track positioning so both FABs sit level at sheet top - Raise fishing_overlay marginBottom 140dp→200dp to clear the realigned FAB - Safety: remove HELP button + DocFragment import from SafetyFragment; rename Quit→Quit App Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02fix(ui): remove night mode FAB, fix fishing FAB occlusion, cap Ocean tiles ↵Peter Stone
at zoom 13 - Remove fab_night_mode from layout and all MainActivity code (nightModePrefs, isNightMode, fabNightMode field, onCreate theme apply, click handler, applyScreenBrightness) - Raise fab_fishing marginBottom 80dp→136dp so it clears the instrument sheet peek (120dp) - Set maxZoom=13 on Esri Ocean Base TileSet; tiles stop at z13, MapLibre overzooms rather than fetching blank 404 tiles at higher zoom levels Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01fix(tests): resolve 17 pre-existing JVM test failuresPeter Stone
- build.gradle: add kxml2 for XmlPullFactory in JVM tests (fixes GpxRoundTripTest x6) - MainViewModel: make trackRepository an injectable constructor param (was NavApplication static); move _pastTracks/_savedTracks before init block to prevent NPE under UnconfinedTestDispatcher (fixes MainViewModelTest x8) - MainViewModelTest: pass mockk<TrackRepository>(relaxed) to makeVm() - PreTripReportGenerator: lower windFactor for <5kt wind (0.30→0.24) — 36ft boat in 3kt gives ~1.64kt, below 2.0kt assertion threshold (fixes PreTripReportGeneratorTest) - TripReportGeneratorTest: update photo marker assertion to match emoji output (📷 not [photo]) - TackDetectorGpxTest: update assertion to >=6 tacks; XML parsing now works so algorithm runs; rewritten TackDetector detects more maneuvers on real track Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01docs(agent): update code-map for layer redesign (OCEAN, ATON, TSS, new picker)Peter Stone
Updated Last updated field to 2026-07-01. Added ui/aton/ subsection with AtonData and AtonRepository entries. Updated MapLayerManager to describe MapBasePreset values (OCEAN/SATELLITE/CHARTS/HYBRID) and ATON/TSS prefs. Updated LayerPickerSheet to describe Windy-style card layout and 13-param constructor. Updated MapHandler with ATON/TSS layer methods. Added AtonDataTest to testing guide. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01feat(main): wire ATON repository + TSS into MainActivity layer sheetPeter Stone
2026-07-01feat(ui): rewrite LayerPickerSheet — Windy-style cards, full-height, ATON/TSSPeter Stone
2026-07-01feat(ui): Windy-style layer picker layout with base map cards and overlay ↵Peter Stone
sections Replaces ScrollView + flat switch list with NestedScrollView + GridLayout card sections: BASE MAP (2x2 preview cards), NAVIGATION, OCEAN DATA, WEATHER, MY DATA (toggle cards with 48dp previews), and UNITS (unchanged). Stubs out old chip_group_base wiring in LayerPickerSheet.kt pending Task 7 rewrite. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01fix(layers): TSS string constants + close openRawResource streamPeter Stone
2026-07-01feat(layers): ATON CircleLayer + TSS FillLayer in MapHandlerPeter Stone
2026-07-01feat(ui): gradient preview drawables for layer picker cardsPeter Stone
2026-07-01feat(layers): bundled Pacific TSS GeoJSON asset (placeholder coordinates)Peter Stone
2026-07-01docs(layers): update KDoc layer order, mark ATON/TSS setters as Task 6-8 stubsPeter Stone
2026-07-01feat(layers): OCEAN base preset (Esri), ATON/TSS pref keys, all defaults falsePeter Stone
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01fix(aton): switch to org.json, add stale-cache fallbackPeter Stone
Replace Gson dependency in AtonData with org.json.JSONObject (Android SDK built-in) and add testImplementation for org.json to support unit tests. AtonRepository now falls back to stale cache data when the network is unavailable rather than returning an empty list.
2026-07-01feat(aton): AtonData model + AtonRepository with 24h cachePeter Stone
Implements AtonData (color mapping + Gson-based JSON parsing for NOAA AtoN station data) and AtonRepository (disk-cached HTTP fetcher). Uses Gson instead of org.json so unit tests run on the JVM classpath. 7/7 AtonDataTest assertions pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30docs(agent): update code-map + worklog; add additional map sources planPeter Stone
Code map updated for all 2026-06-30 changes: ui/fishing/ package, FadData, MapLayerManager (SST/depth/ATON), SafetyFragment collapsible, PreTripReport auto-generate, LogEntry.trackId, idle timer, NightVision vs dark mode. New 5-task plan: NOAA chart tiles, ATON vector layer, TSS overlay. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30fix: restore dark mode, fix depth tile source, show FADs by defaultPeter Stone
- Remove MODE_NIGHT_NO from NavApplication — system dark mode now respected; NightVision toggle (red-on-black) is separate and unaffected - Depth layer: swap empty OpenSeaMap depth tiles for NOAA CoastWatch ETOPO180 WMS which has full Pacific/Hawaii coverage - FADs default to visible (was off) since Hawaii DAR data is loaded at startup Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30chore: update worklog with fishing mode implementationPeter Stone
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30feat(fishing): dashed bearing line on map for fishing targetPeter Stone
Adds setupFishingLayer() and updateFishingBearing() to MapHandler with destinationPoint() haversine helper. Draws dashed orange line from boat toward the computed fishing target bearing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30feat(fishing): wire fishing mode FAB and overlay in MainActivityPeter Stone
Adds FishingOverlayView + fab_fishing to layout, initializes FishingModeManager, and wires FAB click to toggle fishing mode with SST layer and target overlay. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30feat(fishing): FishingOverlayView card UI and ic_fish vector drawablePeter Stone
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30feat(fishing): FishingModeManager with target zone computationPeter Stone
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30feat(fishing): SST raster layer from NOAA CoastWatchPeter Stone
Adds SST source/layer to MapLayerManager, SST toggle to LayerPickerSheet UI and wires it up in MainActivity. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30feat(fishing): FishingTarget + RigAdvisor logicPeter Stone
Also fix pre-existing test compile errors in WeatherApiServiceTest (nullable list access) and add missing metresToFeet/formatFt helpers to InstrumentHandler. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30feat: UX improvements + HAW FAD data + fishing mode planPeter Stone
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 <noreply@anthropic.com>
2026-06-30feat: add ocean layers — depth contours, seamarks toggle, FADsPeter Stone
- MapLayerManager: depth contour tiles (OpenSeaMap), seamarks made toggleable (was always visible), FAD pref; layer order is now satellite → charts → wind → depth → seamarks - MapHandler: FAD GeoJSON layer (orange circles + zoom-10 labels), setupFadLayer / setFadLayerVisible / updateFadLayer helpers - LayerPickerSheet: wire seamarks, depth, FAD switches; fix chip binding direction bug (DepthUnit.METERS side was swapped) - layout_layer_picker_sheet: add OCEAN LAYERS section with three toggles (seamarks/nav aids, depth contours, FADs) - MainActivity: call setupFadLayer on style load; wire all three ocean layer callbacks in buildLayerPickerSheet Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05Fix wind grid deserialization: make forecast-only fields nullableClaude
The batch wind-grid endpoint only requests windspeed_10m and winddirection_10m, so temperature_2m, precipitation_probability, and weathercode are absent from its response. Moshi required these fields and threw, causing fetchWindGrid to silently fail. Made those three fields nullable with null defaults in WeatherHourly. Updated the two call sites in WeatherRepository that access them via the full forecast endpoint to use safe-call syntax. https://claude.ai/code/session_017TwkSjhzhmTcHKmVG5MWUa
2026-06-05Merge claude/location-retention-regression-AOycc: fix background location ↵Claude
retention - Stop GPS updates entirely when backgrounded and idle (was: drop to 5s ECONOMY) - Add PowerMode.NONE, ACTION_STOP_UPDATES; guard startLocationUpdatesInternal against NONE - Fix _currentPowerMode initial value FULL→NONE for accurate state tracking - Fix code-map GPS section (DeviceGpsProvider dead code, no No-GPS banner, replay=1 caveat) - Add review-intent-reality.md audit prompt + Living Documentation mandates to config.md https://claude.ai/code/session_0126zvB69ccVoFtx2o96oaE2
2026-06-05docs(agent): fix code-map GPS section; add intent-reality audit processClaude
code-map.md: - Correct the GPS gotcha section: DeviceGpsProvider uses LocationManager (not FusedLocationProviderClient) and is dead code — never instantiated - Remove the false claim that MainViewModel shows a "No GPS" banner - Document locationFlow replay=1 staleness behaviour accurately - Document ACTION_STOP_UPDATES background-idle behaviour added in this session config.md: - Add review-intent-reality.md to the directory table - Add two Living Documentation mandates: code-map accuracy obligation and intent-reality audit cadence review-intent-reality.md (new): - Structured audit prompt covering 6 categories: code-map vs implementation, dead code with documented intent, lying comments, architectural invariants, design-doc vs shipped code, worklog vs current state - Standardised finding format (doc claim / code reality / severity / fix) - Post-review commit convention https://claude.ai/code/session_0126zvB69ccVoFtx2o96oaE2
2026-06-04Fix location-retention regression: stop GPS when backgrounded and idleClaude
The previous fix (48ae3b0) dropped to ECONOMY (5 s interval) on app pause, but never stopped location requests. The fusedLocationClient continued polling indefinitely in the background even with nothing recording or anchor-watching — accessing location without any need. Fix: - Add PowerMode.NONE to represent "no updates in flight" - Add ACTION_STOP_UPDATES to LocationService: calls stopLocationUpdatesInternal() and parks _currentPowerMode at NONE - Guard startLocationUpdatesInternal() against PowerMode.NONE so a stray setPowerMode(NONE) call can never request zero-interval updates - Change _currentPowerMode initial value from FULL to NONE (accurate: no updates are running at process start) - throttleLocationIfIdle() now sends ACTION_STOP_UPDATES instead of ACTION_START_ECONOMY; the existing restoreLocationMode() on onResume already sends ACTION_START_ECONOMY which transitions NONE→ECONOMY correctly since NONE != ECONOMY bypasses the no-op guard Tracking and anchor-watch paths are unchanged: throttleLocationIfIdle() skips the stop if either is active, and onResume sends ACTION_START_FULL when recording is still in progress. https://claude.ai/code/session_0126zvB69ccVoFtx2o96oaE2
2026-06-04Fix wind particles never appearingClaude
Two bugs prevented wind particles from rendering: 1. Retrofit URL-encoded commas in the batch lat/lon query strings (%2C instead of ,), so Open-Meteo rejected every grid fetch silently. Fixed with encoded=true on the @Query annotations. 2. loadWindGrid() was only called from onCameraIdleListener, so particles never started unless the user manually panned. Added an eager trigger on the first GPS fix using the map's current visible region. Also added a log warning when fetchWindGrid fails so future failures are visible in logcat. https://claude.ai/code/session_017TwkSjhzhmTcHKmVG5MWUa
2026-06-04Merge claude/wind-particles-movement-eNrTx: spatial wind particlesClaude
https://claude.ai/code/session_017TwkSjhzhmTcHKmVG5MWUa
2026-06-04Spatial wind particles: grid interpolation, fast projection, density/opacityClaude
- Particles now use bilinear interpolation of the 4×5 wind grid so speed and direction vary by position, swirling around weather systems. Particles are hidden until the first grid arrives (no stale fallback). - Replace 150–300 per-particle toScreenLocation() JNI calls with a single 3-point affine transform computed once per frame. Rendering stays smooth during map panning. - Per-particle tail direction is now derived from the local (u,v) wind vector rotated into screen space by the map bearing. - Density: N 300→600, activeN range [150,600] (was [60,300]). - Opacity: max alpha 200→110, min 15→8; stroke 3.5→2.5 px. Wire setWindGrid() in MainActivity windGrid.collect alongside the existing updateWindGridLayer() call. https://claude.ai/code/session_017TwkSjhzhmTcHKmVG5MWUa
2026-06-04Merge claude/wind-particles-movement-eNrTx: fix wind particles not movingClaude
https://claude.ai/code/session_017TwkSjhzhmTcHKmVG5MWUa
2026-06-04Fix wind particles not visibly movingClaude
Two bugs caused particles to appear stationary: 1. Speed constant was 0.03 (particles moved ~7 px/s at 10 kt — barely perceptible). Changed to 0.1 so a 10-kt particle crosses the full viewport in MAX_AGE seconds (~24 px/s), producing clear streaming. 2. Individual respawn assigned a random age in [0, MAX_AGE). Half of all newly spawned particles were born old and faded out almost immediately without traversing visible distance, giving a "static noise" look rather than flowing motion. Respawn now starts near age 0 (with a 0–2 s jitter to desynchronise simultaneous respawn bursts). https://claude.ai/code/session_017TwkSjhzhmTcHKmVG5MWUa
2026-06-03Merge claude/code-map-context-tips-4AiHY: add code-map.mdClaude
https://claude.ai/code/session_015p2yh5CaTdjWWJatAz5NBY
2026-06-03Add code-map.md: package topology, key classes, gotchas, testing guideClaude
Comprehensive bootstrap doc for future agent sessions: full package/file table for every domain, architectural invariants (SAF source-of-truth, NavLogger, MOB always-on-top, etc.), testing commands, CI/merge workflow, and a gotchas section covering known tricky spots. Updated config.md directory table and worklog. https://claude.ai/code/session_015p2yh5CaTdjWWJatAz5NBY
2026-06-03Add PMIM-1 hardware assembly guideClaude
Physical layout, parts list with costs, step-by-step wiring, RF chain, BMP280 pressure vent, pre-close checklist, first power-on sequence, and troubleshooting table. Complete pin summary at the end. https://claude.ai/code/session_01KXYBuAHZkvv63DeUG6XaZD
2026-06-03PMIM-1 hardware support: UDP, IIXDR, inclinometerClaude
Transport: - NmeaStreamManager supports TCP and UDP modes - NmeaConnectionPrefs replaces hardcoded 192.168.1.1:10110; defaults to UDP/10110 matching PMIM-1 spec (ESP32 AP at 192.168.4.1) - LocationService reads prefs via startNmeaFromPrefs() Parsing: - NmeaParser.parseXdr() handles $IIXDR attitude (HEEL/PTCH in degrees) and baro (pressure in bar → hPa, air temp °C) - New AttitudeData and NmeaBaroData sensor types UI: - Heel + pitch row in instrument sheet (hidden until data arrives) - InclinometerView: canvas circle with rotating waterline (heel) and displaced dot (pitch), colorPrimary-tinted, respects night mode - Inclinometer overlay top-left of map, appears on first attitude packet - NMEA baro overrides device sensor reading when available https://claude.ai/code/session_01KXYBuAHZkvv63DeUG6XaZD
2026-06-03Add night vision mode toggleClaude
Single-tap moon FAB (stacked below layers FAB) toggles red-on-black night vision mode. NightVision theme now has a full M3 color palette (surface, surfaceVariant, outline, secondary, error) all in dark red tones. Screen brightness is set to 30% in night mode and restored to system default on exit. State persists across sessions; recreate() applies the theme switch cleanly. https://claude.ai/code/session_01KXYBuAHZkvv63DeUG6XaZD
2026-06-03Update worklog: tech debt sweep + trip report redesign (2026-06-03)Claude
https://claude.ai/code/session_01KXYBuAHZkvv63DeUG6XaZD
2026-05-30Trip report: map, photos, structured layout, preferred unitsClaude
Replaces monospace text block with: - Full-bleed MapLibre track map (260dp) at the top - Structured stats row (distance / avg speed / max speed) - Conditions row (wave height, temp) in user-preferred units - Log entries with full-width photo thumbnails - Pirate mode Easter egg preserved via long-press title - Speed, temp, and depth formatted with UnitPrefs https://claude.ai/code/session_01KXYBuAHZkvv63DeUG6XaZD
2026-05-30Redesign trip report: structured layout, remove generate button, fix photo ↵Claude
entries Layout: - Stats displayed as three large-number columns (distance / avg kt / max kt) - Date and time range as a clean header above stats - Conditions row (seas + temp) conditionally shown - Log entries rendered as a proper list with HH:mm timestamps - No GENERATE REPORT button — report auto-generates on open; RETRY shown only on error - Pirate mode (long-press title) still renders monospace narrative as before Generator: - Time format changed from 4-digit HHmm to HH:mm - "(photo only)" entries display as 📷 instead of literal "(photo only) [photo]" https://claude.ai/code/session_01KXYBuAHZkvv63DeUG6XaZD
2026-05-30Remove Generate Trip Report button from Log tabClaude
Each track row already has a REPORT button; the standalone button was redundant. https://claude.ai/code/session_01KXYBuAHZkvv63DeUG6XaZD
2026-05-30Fix VoiceLogFragment: pass onReport to SavedTrackAdapter (CI compile error)Claude
SavedTrackAdapter gained an onReport callback when the REPORT button was added to the track list. VoiceLogFragment was still using the old single-lambda form. https://claude.ai/code/session_01KXYBuAHZkvv63DeUG6XaZD
2026-05-28Tech debt: Room list fast-path, delete AnchorWatchHandler orphan, ↵Claude
LogbookRepository thread safety 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
2026-05-28Merge claude/whats-next-0XCO3: tech debt items 1, 2, 5Claude
- Deleted com.example.androidapp ghost package (18 stale source files) - Fixed tide model package declarations and HarmonicTideCalculator imports - Symlinked test-runner TackDetector to android-app canonical source - Fixed forecast to use current wall-clock hour slot instead of app-start hour https://claude.ai/code/session_01KXYBuAHZkvv63DeUG6XaZD