# GPS2Audio v2.0.1 — Direct Reorder UI ## Artifacts - Signed APK: `/home/user/workspace/GPS2Audio_v2_0_1_direct_reorder_signed.apk` - Source ZIP (no secrets): `/home/user/workspace/GPS2Audio_v2_0_1_direct_reorder_source.zip` - This handoff: `/home/user/workspace/GPS2Audio_v2_0_1_direct_reorder_handoff.md` ## Version / signing - `applicationId`: `de.waypointaudio` - `versionName`: `2.0.1` - `versionCode`: `29` (was 28) - Signed with the existing release keystore (`GPS2Audio_release_keystore.jks`, alias `gps2audio_release`). - Signing certificate (verified with `apksigner verify --print-certs`): - DN: `CN=GPS2Audio, OU=NesoHub, O=GPS2Audio, L=Germany, C=DE` - SHA-256: `7B:0E:A4:D5:52:86:05:17:3D:29:9D:7B:26:8E:7A:B8:76:8D:D5:04:EC:15:B6:6A:52:D4:7B:42:57:B3:BB:46` - SHA-1: `EB:92:2A:83:39:09:ED:6B:2D:CB:62:52:F0:CF:42:5F:26:DF:25:AD` - `aapt dump badging` confirmed: `package: name='de.waypointaudio' versionCode='29' versionName='2.0.1'`. - `gradle :app:assembleRelease` → BUILD SUCCESSFUL (only pre-existing deprecation warnings — `launchWhenStarted`, OSMDroid setters, `Modifier.menuAnchor()`). ## UI changes (precise) All changes are in `app/src/main/kotlin/de/waypointaudio/ui/WaypointListScreen.kt` and `app/src/main/res/values/strings.xml`. ### 1. Prominent `Reihenfolge bearbeiten` row removed - The `SortModeBar` composable and the associated full-width row that used to sit between the tour tabs and the Tour-Zähler card are **deleted**. - The `sortMode`/`sortBlocked` toggle state was removed from the screen state. Tab clicks no longer have to check `if (!sortMode)`. - The `TourReorderList` panel that expanded under that bar is replaced by a compact dialog (see section 3). ### 2. Direct waypoint reordering on each card `WaypointCard` now exposes a small two-arrow column on the left edge of every card. The arrows are always rendered, so the user can re-order waypoints with one tap (no mode to enter first): - Up arrow → `viewModel.moveWaypoint(index, index - 1)` - Down arrow → `viewModel.moveWaypoint(index, index + 1)` The arrows are disabled (greyed out) when: - The waypoint is at the top/bottom of the current tour's list (`canMoveUp`/`canMoveDown`). - The GPS service is running OR a track recording is active (`reorderBlocked = serviceRunning || isRecording`). In that case both arrows are non-interactive and the new short hint `Sortieren während GPS/Aufzeichnung deaktiviert` (string `reorder_blocked_hint_short`) is shown to the right of the `Wegpunkt-Tracks` heading. German accessibility labels are attached to both arrows via `contentDescription` (updated `sort_move_up`/`sort_move_down` to `Nach oben verschieben` / `Nach unten verschieben`). Icons are `Icons.Filled.KeyboardArrowUp` / `KeyboardArrowDown` for a clean look. The `Switch` for `isActive` no longer disables itself during reorder (there is no reorder mode anymore); it stays freely tappable whenever the card is visible. Persistence is unchanged: `WaypointViewModel.moveWaypoint` continues to delegate to `WaypointStore.moveWaypointInTour` and persists immediately. ### 3. Compact tour reordering — `Touren ordnen` dialog - New overflow-menu item `Touren ordnen` (`menu_tour_reorder`) sits in the existing ⋮ menu just above `Display aktiv halten`. It is disabled whenever fewer than two tours exist or when GPS/recording is active. - Tapping it opens an `AlertDialog` titled `Touren ordnen` listing every tour with up/down arrows, calling `viewModel.moveTour(from, to)`. The dialog closes with the existing `Fertig` button. - No large always-visible bar remains in the main screen — tour reordering is reachable in two taps (overflow → Touren ordnen) and consumes zero vertical space until invoked. ### 4. Start-screen vertical density - Removed the full-width `SortModeBar` row (≈40 dp tall). - Removed the expandable `Touren-Reihenfolge` panel that grew under it. - The waypoint cards are now slightly more compact: padding tightened from `start=12 / vertical=10` to `start=8 / vertical=8` to compensate for the always-on arrow column without making the card taller. Section ordering on the start screen is preserved (top → bottom): ScrollableTabRow (Touren) → Tour-Zähler-Karte → Live/PTT → Atmo (Begleitmusik mini player) → Manual Player Bar → "Wegpunkt-Tracks" heading (with optional GPS-blocked hint) → waypoint cards. The whole content is still wrapped in a `verticalScroll` and the dual FAB stack is unchanged. ## How to reorder now (user-facing) - **Waypoints inside a tour**: tap the small ▲ or ▼ button on the left edge of any waypoint card. Order is saved immediately. - **Tours (tab order)**: tap ⋮ → `Touren ordnen`. In the dialog use the ▲▼ buttons next to each tour. Close with `Fertig`. - **While GPS service or track recording is active**: both controls are disabled. The card arrows render greyed-out; the overflow item is disabled; a short hint `Sortieren während GPS/Aufzeichnung deaktiviert` appears next to the `Wegpunkt-Tracks` heading. Stop the service / recording to re-enable. ## Preserved features (regression checklist) - `applicationId = de.waypointaudio`, signed with the v2.0.0 release keystore → in-place upgrade over v2.0.0 works. - v2.0.0 features: - Wake Lock settings dialog accessible via overflow. - Atmo (`BegleitmusikMiniPlayer`) is placed above the waypoint list, with autostart / resume preserved (`AtmoResumeManager`, `BackgroundMusicManager` untouched). - Compact TopBar with launcher icon, app title, and Play/Map/ Track-Editor/⋮ actions — unchanged. - Map provider selection — untouched. - Track-Editor / drafts (`TrackDraftListScreen`, `TrackDraftEditorScreen`) — unchanged, including thick route line, marking handles and "Import marked points". - Backup export/import (`BackupDialog`, `BackupImportDialog`) — wiring unchanged. - Map search everywhere (`PlaceSearchDialog` usage in `MapScreen`, `TrackDraftEditorScreen`) — unchanged. - Audio-library playlist (`BegleitmusikDialog`) — unchanged. - PTT pauses/resumes Atmo (`LivePttCard` + `LivePttManager` + `BackgroundMusicPlayer.duck/pauseForPtt`) — unchanged. - OSM attribution layout in `MapScreen` — unchanged. - ScrollableTabRow identity-key fix (`key(tabs.joinToString("|"))`) — retained. - About dialog incl. PayPal link / version notice — unchanged. - `viewModel.moveWaypoint` / `moveTour` semantics — unchanged; this patch only changes how the user reaches them. ## Regression checklist (suggested manual test plan) 1. Fresh install: tab bar shows existing tours; no "Reihenfolge bearbeiten" row appears above Tour-Zähler. 2. With two or more waypoints, tap ▲▼ on a card: list re-orders immediately and persists across app restart. 3. Tap ▲ on the first card and ▼ on the last: visually disabled, no action. 4. Start GPS service: card arrows grey out, hint `Sortieren während GPS/Aufzeichnung deaktiviert` shown next to "Wegpunkt-Tracks". Overflow `Touren ordnen` is disabled. Stop service → controls re-enabled. 5. Start track recording (same expectations). 6. Open ⋮ → `Touren ordnen`: dialog lists every tour; ▲▼ reorder, tabs reflect new order after closing with `Fertig`. 7. Verify ScrollableTabRow does not throw IndexOutOfBounds when tours are reordered, renamed, or deleted (identity-key fix retained). 8. Verify Atmo, Live/PTT, Manual Player, Tour-Zähler still appear in their v2.0.0 order and are scrollable. 9. Backup export/import still completes round-trip. 10. Install over v2.0.0 (same keystore) — no signature conflict. ## Build & verification commands used ``` gradle :app:assembleRelease # BUILD SUCCESSFUL apksigner verify --print-certs app-release.apk aapt dump badging app-release.apk ``` Both confirm the signing cert SHA-256 `7B0EA4D5...B3BB46` and package `de.waypointaudio versionCode='29' versionName='2.0.1'`. ## Source-tree hygiene - The signed build was produced with a local `keystore.properties` at the project root pointing to `/home/user/workspace/GPS2Audio_release_keystore.jks` and using the passwords from `/home/user/workspace/GPS2Audio_release_keystore_credentials.txt`. - `GPS2Audio_v2_0_1_direct_reorder_source.zip` **does not** contain `keystore.properties`, the `.jks`, or the credentials file. Only the unchanged `keystore.properties.example` is shipped. The Gradle config still reads either `keystore.properties` or the `GPS2AUDIO_RELEASE_*` env vars, so future builds work with the same mechanism v2.0.0 used.