Skip to content

Add a physical output safety ceiling, a live orbit preview, and the Spanish locale - #370

Merged
ultraelectronica merged 8 commits into
mainfrom
versionF
Nov 9, 2026
Merged

ultraelectronica merged 8 commits into
mainfrom
versionF

Conversation

@ultraelectronica

Copy link
Copy Markdown
Member

Summary

  • Expose the existing Latin American Spanish draft translation as a selectable locale, with a draft notice, regional es fallback, search keywords, and no Baybayin toggle for Spanish.
  • Show a live, non-playing orbit preview in Orbit settings, including the library header boundary, a collapse/fullscreen control, and a pinned preview above the scrolling settings body.
  • Explain that the orbit stops at the library header, and fix narrow-language overflows in the detail header and player layout sheet.
  • Detect wired and USB physical outputs on Android and apply a one-time 25% safety ceiling before system/software-tier playback, preserving exact mute and never raising the user's level.
  • Keep that ceiling intact across direct-USB handoffs, crossfade player swaps, ducking, ReplayGain, bit-perfect changes, and route changes; pause playback and block Play if the safety write fails until retry succeeds.
  • Share one volume value between the Android crossfade's outgoing and incoming players so ramp ticks cannot bypass the ceiling, and prevent a paused or cancelled crossfade from starting full-scale audio.

Spanish locale

  • Adds es to the supported locales and language picker, resolves es_MX/es_419/es_ES to it, and persists the selection.
  • The translation itself was already present in the base revision; this change registers it and adds the English draft-review notice.

Orbit preview

  • OrbitPreview renders the real OrbitScroll with live preferences, using the library's first 40 songs when there are at least five, otherwise localized demo cards.
  • Browsing only moves a local selection; it never starts playback, queues songs, or changes favorites.
  • The preview is expanded by default on screens at least 620dp high, supports collapse and a fullscreen route, and follows the selected portrait/landscape profile.

Physical output safety

  • Android now reports whether a physical output is attached, plus a stable connection identity that survives managed route-id changes and duplicate device callbacks.
  • On a new physical connection, non-direct-USB software/system tiers are capped at 25% once; removal clears the guard so reconnecting reapplies it.
  • Direct-USB hardware authority keeps its verified restore path, but software attenuation and mute transfer across the handoff instead of restoring a remembered higher DAC volume.

Tests

  • Adds coverage for Spanish selection, regional resolution, persistence, draft copy, and search keywords.
  • Adds orbit preview tests for live preferences, demo/library sources, collapse, fullscreen sizing, landscape axis, short windows, and 1.5x text.
  • Adds physical-output guard tests for wired/USB identity, one-time capping, reapplication, mute, direct-USB handoffs, failed writes, Play blocking/retry, and route changes.
  • Adds crossfade volume tests for both player slots, every ramp tick, mute across pause/resume, cancellation, and failed preparation.

Related issue

none

Checklist

  • flutter analyze passes
  • flutter test passes
  • Rust changes: cargo test --manifest-path rust/Cargo.toml passes
  • Built and ran the app if the change touches a playback path (flutter run --flavor full)
  • Generated code regenerated and committed if bridge/drift/freezed models changed
  • CHANGELOG.md updated for user-facing changes
  • No secrets, keys, tokens, or machine-local files committed
  • One change per PR; no unrelated reformatting in the same diff
  • Hardware tested if the Rust audio engine or USB/DAC output changed

Add app_es.arb with generated localizations and a review guide
noting the translation is unverified. The language picker marks
Spanish as a draft pending native-speaker review, matching the
Taglish notice; system Spanish locales resolve to this `es` copy.

Resource parity, arguments and language-switch behavior are covered
by automated tests. Native-speaker approval and on-device checks
remain unverified.
Wrap the player layout sheet title and action labels so long
translations can't overflow, and add Spanish search keywords.

Document the orbit header boundary setting and pin a live orbit
preview to the top of the Orbit settings screen.
Wire the draft LatAm Spanish locale into the language picker and
extend SettingsScaffold with an optional pinned header that stays
above the scrollable body.
Render a browse-only miniature of the library header and orbit that
tracks the settings below, with expand/collapse and a fullscreen view.
Tapping cards only moves the preview focus; playback and the queue are
untouched.

Also wrap the detail header's lossless label in Flexible so long
translations don't overflow, and cover the preview and Spanish search
keywords with widget tests.
Register Latin American Spanish as a supported locale with a draft
notice in the language picker, and localize the orbit header boundary
and browse-only preview copy.

Cover Spanish selection, persistence, regional resolution, and the
language picker with widget and unit tests; a new es resource file is
generated from app_es.arb.
Extend the playback device info with physical output type, id,
connection id, and label, preferring wired/analog outputs and falling
back to an attached UAC2 device when Android has not exposed a route.

Notify the Dart side of device additions and removals via
onPlaybackDevicesChanged so physical connection events are not missed.
Cover device info parsing, crossfade safety gain during volume
changes, and the player service guard that lowers volume once per
physical output connection, survives engine handoff, and keeps
failed safety writes paused and retried.
Route framework volume changes through a single engine-level gain
setter so the safety ceiling survives crossfade ramp ticks and player
swaps, and let the secondary crossfade player be provided externally.

Defer crossfade preparation when playback is paused, track ramp and
generation state so a safety pause is not undone mid-preparation, and
restore USB DAC volume on attach.

Apply the physical output safety ceiling once per connection key on the
non-direct-USB paths, blocking manual volume changes until the guard
settles and resetting software-volume state on device change.
@ultraelectronica ultraelectronica self-assigned this Nov 9, 2026
@ultraelectronica
ultraelectronica merged commit 487e3a4 into main Nov 9, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant