Skip to content

Commit e7c9b30

Browse files
fix(call): always clear stale banners in alignment early-return paths
When the current device already matches the target, unconditionally clear any stale fallback banner before optionally showing a recovery banner. This handles the case where the user manually switched back via the picker (which resets loggedUnavailableRef to null), leaving a stale banner visible. clearBannersForDevice now bails out with the same state reference when nothing matches, so the unconditional call is safe and loop-free. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 1612835 commit e7c9b30

1 file changed

Lines changed: 8 additions & 5 deletions

File tree

client/src/call/hooks/useDeviceAlignment.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,10 @@ export function useDeviceAlignment(
210210

211211
// Skip if we're already using this device
212212
if (currentDeviceId === targetId) {
213-
// If we previously fell back, show recovery banner.
214-
// addDeviceBanner internally clears existing banners for this device
215-
// type first, so no separate clearBannersForDevice call is needed.
213+
// Always clear any stale fallback banner — safe because clearBannersForDevice
214+
// bails out (returns prev) when nothing matches, so no unnecessary re-render.
215+
if (clearBannersForDevice) clearBannersForDevice(deviceType);
216+
// If this was an auto-fallback recovery, show a recovery banner.
216217
if (loggedUnavailableRef.current === preferredId) {
217218
// eslint-disable-next-line no-param-reassign
218219
loggedUnavailableRef.current = null;
@@ -384,8 +385,10 @@ export function useDeviceAlignment(
384385
}
385386

386387
if (devices?.currentSpeaker?.device?.deviceId === targetId) {
387-
// If we previously fell back, show recovery banner.
388-
// addDeviceBanner internally clears existing banners for speaker first.
388+
// Always clear any stale fallback banner — safe because clearBannersForDevice
389+
// bails out (returns prev) when nothing matches, so no unnecessary re-render.
390+
if (clearBannersForDevice) clearBannersForDevice("speaker");
391+
// If this was an auto-fallback recovery, show a recovery banner.
389392
if (loggedUnavailableSpeakerRef.current === preferredSpeakerId) {
390393
loggedUnavailableSpeakerRef.current = null;
391394
const deviceName = targetSpeaker.device.label || preferredSpeakerLabel || preferredSpeakerId;

0 commit comments

Comments
 (0)