mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 02:44:02 +00:00
Trim the Radio Next/Previous change to the HAL-722 scope
- Selections take the playback fallback as a `playFallback` option and set it after releasing a stale stream, instead of callers arming state that the release then had to save and restore. - Move the tuner `station-unavailable` release and the Pause label while a stream connects out of this branch: both were wrong on main already and go in a separate change. - Share the Radio layer test setup in src/testSupport/radioLayerHarness.mjs and fold overlapping Next/Previous tests (13 to 7). - One-line comments and a two-line changelog entry.
This commit is contained in:
1 parent
fa840ae3c3
commit
a55450e2e7
10 files changed
+172
-340
No files matched your search
@@ -345,18 +345,16 @@ export function createPlayback({ state: layerState, services, parts, source }) {
|
||||
if (!parts.interaction.radioPresentationAllowed())
|
||||
return Promise.resolve(false);
|
||||
if (layerState._selectedId) {
|
||||
// An explicit Play owns its attempt; a fallback left by an earlier step
|
||||
// (a cancelled voice handoff) belongs to a playback that never started.
|
||||
// Drop a fallback left by a voice step whose playback never started.
|
||||
layerState._playFallbackId = null;
|
||||
layerState._playFallbackFocus = null;
|
||||
} else {
|
||||
const ranked = parts.queries.rankedVisibleStations();
|
||||
if (!ranked.length) return Promise.resolve(false);
|
||||
layerState._playFallbackId = ranked[1]?.id || null;
|
||||
layerState._playFallbackFocus = false;
|
||||
parts.selection.selectRadioStation(ranked[0].id, {
|
||||
autoplay: false,
|
||||
focus: false,
|
||||
playFallback: { id: ranked[1]?.id || null, focus: false },
|
||||
});
|
||||
}
|
||||
return playSelectedRadio({ origin });
|
||||
|
||||
@@ -73,22 +73,14 @@ export function createSelection({
|
||||
return { filter: layerState._filter, volume: layerState._userVolume };
|
||||
}
|
||||
|
||||
// Selecting another station without playing retires a paused or failed
|
||||
// stream, so no control can resume or report a broadcaster that is no longer
|
||||
// the selection. Stop clears fallbacks; the caller may have armed one for
|
||||
// this selection, so it survives.
|
||||
// A paused or failed stream of another station would outlive its selection.
|
||||
function releaseStaleRadioStream(stationId) {
|
||||
if (
|
||||
!layerState._audioStationId ||
|
||||
layerState._audioStationId === stationId ||
|
||||
!['paused', 'error'].includes(layerState._audioState)
|
||||
layerState._audioStationId &&
|
||||
layerState._audioStationId !== stationId &&
|
||||
['paused', 'error'].includes(layerState._audioState)
|
||||
)
|
||||
return;
|
||||
const fallbackId = layerState._playFallbackId;
|
||||
const fallbackFocus = layerState._playFallbackFocus;
|
||||
parts.playback.stopRadioPlayback();
|
||||
layerState._playFallbackId = fallbackId;
|
||||
layerState._playFallbackFocus = fallbackFocus;
|
||||
parts.playback.stopRadioPlayback();
|
||||
}
|
||||
|
||||
/** Select a station. Playback occurs only when autoplay is explicitly true. */
|
||||
@@ -101,12 +93,18 @@ export function createSelection({
|
||||
origin = 'programmatic',
|
||||
attemptId = null,
|
||||
cameraNavigation = null,
|
||||
playFallback = null,
|
||||
} = {},
|
||||
) {
|
||||
if (!parts.interaction.radioPresentationAllowed()) return false;
|
||||
const station = layerState._stationById.get(String(id));
|
||||
if (!station) return false;
|
||||
if (!autoplay) releaseStaleRadioStream(station.id);
|
||||
// Set after the release, which clears fallbacks.
|
||||
if (playFallback) {
|
||||
layerState._playFallbackId = playFallback.id;
|
||||
layerState._playFallbackFocus = playFallback.focus;
|
||||
}
|
||||
layerState._tuningUnavailableStationId = null;
|
||||
if (
|
||||
!parts.navigation.radioCameraNavigationOwnsSelection(
|
||||
@@ -184,7 +182,7 @@ export function createSelection({
|
||||
? 0
|
||||
: (current + (direction < 0 ? -1 : 1) + ranked.length) % ranked.length;
|
||||
// Voice defers playback, so its silent step needs a fallback; UI steps do not.
|
||||
layerState._playFallbackId =
|
||||
const fallbackId =
|
||||
fallback && ranked.length > 1
|
||||
? ranked[(nextIndex + 1) % ranked.length].id
|
||||
: null;
|
||||
@@ -194,7 +192,7 @@ export function createSelection({
|
||||
const rotationNavigation = rotate
|
||||
? parts.navigation.beginRadioCameraNavigation(rotationCameraState)
|
||||
: null;
|
||||
layerState._playFallbackFocus =
|
||||
const fallbackFocus =
|
||||
fallback && rotate
|
||||
? (fallbackStation) => {
|
||||
parts.navigation.rotateRadioStationIntoView(
|
||||
@@ -219,6 +217,7 @@ export function createSelection({
|
||||
focus: false,
|
||||
origin,
|
||||
cameraNavigation: rotationNavigation,
|
||||
playFallback: { id: fallbackId, focus: fallbackFocus },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -245,9 +244,12 @@ export function createSelection({
|
||||
},
|
||||
);
|
||||
if (!ranked.length) return null;
|
||||
layerState._playFallbackId = ranked[1]?.id || null;
|
||||
layerState._playFallbackFocus = false;
|
||||
selectRadioStation(ranked[0].id, { autoplay, focus: false, origin });
|
||||
selectRadioStation(ranked[0].id, {
|
||||
autoplay,
|
||||
focus: false,
|
||||
origin,
|
||||
playFallback: { id: ranked[1]?.id || null, focus: false },
|
||||
});
|
||||
return ranked[0];
|
||||
}
|
||||
|
||||
|
||||
@@ -179,10 +179,7 @@ export function createTuning({ state: layerState, services, parts, source }) {
|
||||
layerState._selectionGeneration += 1;
|
||||
parts.tuningNoise.clearRadioTuningNoise({ emit: false });
|
||||
layerState._tuningUnavailableStationId = stationId;
|
||||
// The drag paused the previous stream; with no selection left, Resume
|
||||
// could only start the nearest station, so release it. Stop publishes
|
||||
// the state, and as the user's gesture it cancels a voice handoff.
|
||||
parts.playback.stopRadioPlayback({ origin });
|
||||
parts.presentation.emitState();
|
||||
return Object.freeze({
|
||||
ok: false,
|
||||
reason: 'station-unavailable',
|
||||
|
||||
Reference in new issue
Block a user