Android: route trim UI + RouteTrimmer (epic #992) #995

Closed
opened 2026-08-07 03:50:53 +00:00 by spikerj · 1 comment
Owner

Part of epic #992.

  • core/tracking/RouteTrimmer.kt mirroring iOS exactly (apply + suggest, TrackStats.haversineKm).
  • TrimRecordedRouteRequest + @POST("recorded-routes/{id}/trim") in SpikerSoftApi (first used download-shaped call — exercises detail DTO mapping).
  • RouteRepository.replacePoints(routeId, points) — rebuild stats via TrackStats.statsFor, dao.upsert (REPLACE strategy).
  • RouteTrimScreen.kt + Hilt RouteTrimViewModel: Material3 RangeSlider, suggest, confirm; unsynced → local apply + replacePoints; synced → API trim then replacePoints from response — never re-enqueue RouteSyncWorker (server dup).
  • TrackerMapController.showTrimPreview/clearTrimPreview; tracker_style.json trim-dimmed + trim-handles.
  • Nav route tracker/trim/{routeId} + Trim button in RouteDetailScreen (reload on return).
  • RouteTrimmerTest.kt with the shared fixture.
Part of epic #992. - `core/tracking/RouteTrimmer.kt` mirroring iOS exactly (apply + suggest, `TrackStats.haversineKm`). - `TrimRecordedRouteRequest` + `@POST("recorded-routes/{id}/trim")` in `SpikerSoftApi` (first *used* download-shaped call — exercises detail DTO mapping). - `RouteRepository.replacePoints(routeId, points)` — rebuild stats via `TrackStats.statsFor`, `dao.upsert` (REPLACE strategy). - `RouteTrimScreen.kt` + Hilt `RouteTrimViewModel`: Material3 `RangeSlider`, suggest, confirm; unsynced → local apply + replacePoints; synced → API trim then replacePoints from response — never re-enqueue `RouteSyncWorker` (server dup). - `TrackerMapController.showTrimPreview/clearTrimPreview`; `tracker_style.json` `trim-dimmed` + `trim-handles`. - Nav route `tracker/trim/{routeId}` + Trim button in `RouteDetailScreen` (reload on return). - `RouteTrimmerTest.kt` with the shared fixture.
Author
Owner

Verified complete 2026-08-07 — closing.

  • Code: spikersoft-android@4aa6100 (PR #10, feat/route-trim-995, commit bcc59e0) — every bullet in the body is present on main:
    • core/tracking/RouteTrimmer.kt + core/tracking/RouteTrimmerTest.kt (shared fixture)
    • core/network/SpikerSoftApi.kt:83-84 → @POST("recorded-routes/{id}/trim") suspend fun trimRecordedRoute(...)
    • core/tracking/RouteRepository.kt:86 → suspend fun replacePoints(routeId, points)
    • features/tracker/RouteTrimScreen.kt (+ :128 routes.replacePoints, :217 controller.showTrimPreview) and TrackerMapView.kt:72 showTrimPreview
    • assets-tracker/tracker_style.json:72,79,145,172 → trim-dimmed + trim-handles sources and layers
    • Nav wiring in features/home/SpikerSoftNavHost.kt:130,134 → tracker/trim/{routeId} plus the Trim entry from RouteDetailScreen
  • Live: nothing runtime-observable from this box (native app). Its server dependency is live: POST https://api.spikersoft.com/api/recorded-routes/{id}/trim → 401 (deployed) vs 404 for a bogus sibling path.
  • Shipped by: android PR #10.

Not migrated: nothing left to do.

— Opus 5 Agent

Verified complete 2026-08-07 — closing. - **Code:** `spikersoft-android@4aa6100` (PR #10, `feat/route-trim-995`, commit `bcc59e0`) — every bullet in the body is present on main: - `core/tracking/RouteTrimmer.kt` + `core/tracking/RouteTrimmerTest.kt` (shared fixture) - `core/network/SpikerSoftApi.kt:83-84` → `@POST("recorded-routes/{id}/trim") suspend fun trimRecordedRoute(...)` - `core/tracking/RouteRepository.kt:86` → `suspend fun replacePoints(routeId, points)` - `features/tracker/RouteTrimScreen.kt` (+ `:128` `routes.replacePoints`, `:217` `controller.showTrimPreview`) and `TrackerMapView.kt:72` `showTrimPreview` - `assets-tracker/tracker_style.json:72,79,145,172` → `trim-dimmed` + `trim-handles` sources and layers - Nav wiring in `features/home/SpikerSoftNavHost.kt:130,134` → `tracker/trim/{routeId}` plus the Trim entry from `RouteDetailScreen` - **Live:** nothing runtime-observable from this box (native app). Its server dependency is live: `POST https://api.spikersoft.com/api/recorded-routes/{id}/trim` → 401 (deployed) vs 404 for a bogus sibling path. - **Shipped by:** android PR #10. Not migrated: nothing left to do. — Opus 5 Agent
Sign in to join this conversation.