fix(app): smooth the fluxer.com migration and expired re-login (#3019)

This commit is contained in:
Hampus authored and GitHub committed 2026-09-28 18:11:18 +02:00
1 parent a728be4062
commit c9ae5b6ee8
75 files changed
+3284 -2368

No files matched your search

@@ -15,6 +15,7 @@ type DeviceListener = (state: VoiceDeviceState) => void;
class VoiceDevicePermissionState {
deviceState: VoiceDeviceState = voiceDeviceManager.getState();
private deviceListeners = new Set<DeviceListener>();
private deviceStateReconcilers = new Set<DeviceListener>();
private permissionRequestsInFlight = new Map<'audio' | 'video', Promise<boolean>>();
constructor() {
@@ -23,6 +24,13 @@ class VoiceDevicePermissionState {
private handleDeviceStateChange(state: VoiceDeviceState): void {
this.deviceState = state;
this.deviceStateReconcilers.forEach((reconciler) => {
try {
reconciler(state);
} catch (error) {
logger.error('Voice device state reconciler threw', {error});
}
});
this.deviceListeners.forEach((listener) => {
try {
listener(state);
@@ -44,6 +52,11 @@ class VoiceDevicePermissionState {
};
}
addDeviceStateReconciler(reconciler: DeviceListener): void {
this.deviceStateReconcilers.add(reconciler);
reconciler(this.deviceState);
}
async ensureDevices(options: EnsureVoiceDevicesOptions = {}): Promise<VoiceDeviceState> {
const state = await voiceDeviceManager.ensureDevices(options);
if (this.deviceState !== state) {
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {isPendingMigratedDeviceId} from '@app/features/app/domain_migration/DomainMigrationDeviceRemap';
import {Logger} from '@app/features/platform/utils/AppLogger';
import {VoiceTrackKind} from '@app/features/voice/engine/VoiceTrackSource';
import VoiceSettings from '@app/features/voice/state/VoiceSettings';
@@ -83,12 +84,19 @@ async function resolveAvailableOutputDeviceId(deviceId: string): Promise<string>
return deviceId;
}
const state = await voiceDeviceManager.ensureDevices({requestPermissions: false});
const currentDeviceId = VoiceSettings.getOutputDeviceId();
if (currentDeviceId !== deviceId) {
return currentDeviceId;
}
if (state.outputDevices.length === 0) {
return deviceId;
}
if (state.outputDevices.some((device) => device.deviceId === deviceId)) {
return deviceId;
}
if (isPendingMigratedDeviceId(deviceId)) {
return 'default';
}
logger.warn('Selected audio output device no longer available; falling back to default', {deviceId});
VoiceSettings.updateSettings({outputDeviceId: 'default'});
return 'default';
@@ -106,7 +114,9 @@ async function applyOutputDeviceToWebAudioMixer(room: Room, deviceId: string): P
if (isDeviceMissingError(error)) {
logger.warn('Web Audio mixer sink no longer available', {deviceId});
if (deviceId !== 'default') {
VoiceSettings.updateSettings({outputDeviceId: 'default'});
if (VoiceSettings.getOutputDeviceId() === deviceId && !isPendingMigratedDeviceId(deviceId)) {
VoiceSettings.updateSettings({outputDeviceId: 'default'});
}
try {
await audioContext.setSinkId('');
} catch (fallbackError) {