Skip to content

Commit e071617

Browse files
feat(call): show banner when preferred device reconnects and is restored
When a device disconnects, auto-fallback switches to another device and shows a banner. Now when the original device comes back and the system switches back to it, a recovery banner ("reconnected — switched back") is shown for situational awareness. Applies to camera, mic, and speaker. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 47c7640 commit e071617

1 file changed

Lines changed: 19 additions & 0 deletions

File tree

client/src/call/hooks/useDeviceAlignment.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ export function useDeviceAlignment(
215215
console.log(`Setting ${deviceType} via ${matchType} match`, {
216216
preferredId, preferredLabel, targetId, targetLabel: targetDevice.device.label, matchType,
217217
});
218+
// Check if this is a recovery (we previously fell back for this device)
219+
const isRecovery = loggedUnavailableRef.current === preferredId;
218220
// eslint-disable-next-line no-param-reassign
219221
loggedUnavailableRef.current = null;
220222
// eslint-disable-next-line no-param-reassign
@@ -227,6 +229,14 @@ export function useDeviceAlignment(
227229
}
228230
// Clear any stale fallback banner for this device
229231
if (clearBannersForDevice) clearBannersForDevice(deviceType);
232+
// Show recovery banner so the user knows we switched back
233+
if (isRecovery && addDeviceBanner) {
234+
const deviceName = targetDevice.device.label || preferredLabel || preferredId;
235+
addDeviceBanner({
236+
deviceType,
237+
message: `"${deviceName}" reconnected — switched back`,
238+
});
239+
}
230240
}
231241
} catch (err) {
232242
console.error(`Failed to set ${deviceType} via ${matchType} match`, err);
@@ -350,6 +360,7 @@ export function useDeviceAlignment(
350360
preferredSpeakerId, preferredSpeakerLabel,
351361
targetId, targetLabel: targetSpeaker.device.label, matchType,
352362
});
363+
const isSpeakerRecovery = loggedUnavailableSpeakerRef.current === preferredSpeakerId;
353364
loggedUnavailableSpeakerRef.current = null;
354365
updatingSpeakerRef.current = true;
355366
try {
@@ -360,6 +371,14 @@ export function useDeviceAlignment(
360371
}
361372
// Clear any stale fallback banner for speaker
362373
if (clearBannersForDevice) clearBannersForDevice("speaker");
374+
// Show recovery banner so the user knows we switched back
375+
if (isSpeakerRecovery && addDeviceBanner) {
376+
const deviceName = targetSpeaker.device.label || preferredSpeakerLabel || preferredSpeakerId;
377+
addDeviceBanner({
378+
deviceType: "speaker",
379+
message: `"${deviceName}" reconnected — switched back`,
380+
});
381+
}
363382
setPendingGestureOperations((prev) => ({ ...prev, speaker: false }));
364383
setPendingOperationDetails((prev) => ({ ...prev, speaker: null }));
365384
}

0 commit comments

Comments
 (0)