# Proposal: Android Auto Local Music — On-Demand Paging + Friendly Folder Name Fast-follow polish to the archived `android-auto-local-music` Phase 1 (`archive/2026-07-19-android-auto-local-music/`). NOT Phase 2/3. ## Intent Phase 1 capped each local-music folder at `_maxItemsCarpetaLocal = 50` and silently truncated the rest alphabetically — items past 50 are unreachable. The user rejects silent data loss and wants on-demand incremental loading, with an explicit memory goal: do NOT eagerly build full `MediaItem`s (art, title) for items beyond the page actually shown. Also fold in an archived verify SUGGESTION: settings shows the raw SAF content URI instead of a human-friendly folder name. ## Scope ### In Scope - Replace silent truncation in `itemsLocales` with 50-per-page on-demand paging for local-music folders, via a synthetic browsable non-playable "Más…" trailing item (established `MediaBrowserService` workaround — the car UI has no native "load more" signal). - Memory efficiency: hold only the cheap full `NodoLocal` list per browsed level; construct `MediaItem`s (art/title) ONLY for the requested page. Verified by unit test. - Friendly folder-name display in settings `_SeccionMusicaLocal` instead of the raw `content://…/tree/…` URI. - Update ALL 13 `app_*.arb` locale files for any new string (the "Más…" label) — Phase 1's verify caught an en/es-only omission; do not repeat. ### Out of Scope - Phase 2 (metadata/sort/filter/embedded art) and Phase 3 (subfolder scoping/shuffle) — remain deferred. - Radio-station folders (`_maxItemsPorCarpeta = 50`) keep cap-and-truncate; paging is NOT generalized to radio (user raised local music only; no architectural need forces sharing now). - Native Kotlin paging: `listAudioChildren` already returns the full level; no native offset/limit added. ## Capabilities ### New Capabilities None. ### Modified Capabilities - `android-auto-media`: local-music folder browse replaces silent 50-item truncation with on-demand "Más…" paging. (sdd-spec: confirm exact requirement location; the settings friendly-name fix is phone-UI and may need only a light or no spec delta.) ## Approach Pure-Dart, additive on existing seams. `itemsLocales(nodos, pagina)` sorts the full (cheap) `NodoLocal` list deterministically, then `.skip(pagina*50).take(50).map(_itemLocal)` — so only the page's items are built — and appends a "Más…" item when more remain. The "Más…" media-id encodes `(documentId, siguientePagina)` (new prefix, e.g. `carpeta_local_pag:`); tapping it re-invokes `getChildren`, which re-enumerates that one folder (native already returns the whole level) and returns the next slice. Nothing is cached between taps → minimal memory; deterministic sort keeps page boundaries stable across re-queries. Friendly name via pure-Dart `nombreCarpetaDesdeUri(treeUri)` (decode the tree documentId's trailing path segment; fall back to the raw URI when empty) — zero native surface, fully unit-testable. ## Affected Areas | Area | Impact | Description | |------|--------|-------------| | `lib/servicios/navegacion_auto.dart` | Modified | `itemsLocales` gains page param + "Más…" item; paged media-id predicate/parse; `hijosMusicaLocal` routes paged ids | | `lib/servicios/servicio_audio.dart` | Modified | `getChildren` branch for the paged "Más…" media-id | | `lib/servicios/musica_local_auto.dart` | Modified | Add `nombreCarpetaDesdeUri` helper (pure Dart) | | `lib/pantallas/pantalla_ajustes.dart` | Modified | `_SeccionMusicaLocal` renders friendly name (line ~361) | | `lib/l10n/app_{ar,bn,de,en,es,fr,hi,id,it,ja,pt,ru,zh}.arb` | Modified | New "Más…" label across all 13 locales | | `MainActivity.kt` / `pubspec.yaml` | Unchanged | No native/dep change | ## Risks | Risk | Likelihood | Mitigation | |------|------------|------------| | Re-enumerating the folder on each "Más…" tap repeats one SAF query | Med | Acceptable per-tap cost; deterministic sort keeps pages stable; no cache = minimal memory | | Pure-Dart friendly-name derivation brittle for exotic SAF providers | Med | Fallback to raw URI; native `DocumentFile.getName` left as a design fallback | | Very deep folders still hold full `NodoLocal` list per level | Low | DTOs are tiny; only paged `MediaItem` build is bounded | | l10n omission regresses (missing locales) | Med | Scope all 13 arb files into tasks from the start | ## Rollback Plan Behavioral/additive. Revert = restore `.take(_maxItemsCarpetaLocal)` truncation, drop the paged media-id + "Más…" item, revert the settings subtitle to the raw URI, remove the new arb key. Stations untouched. ## Dependencies None (no new packages, no native changes). ## Success Criteria - [ ] A folder with >50 items exposes every item via "Más…" paging; none silently dropped. - [ ] Only the requested page's `MediaItem`s are constructed — proven by a unit test (page N+1 items not built until page N+1 is requested). - [ ] Settings shows a human-friendly folder name, not the raw content URI. - [ ] All 13 `app_*.arb` files carry the new label. - [ ] No station browse/play regression; pure-Dart fully unit-tested; native unchanged.