fix(ios-audio): activate session before voice joins (#38)
* fix(ios-audio): add voice join session coordinator * fix(ios-audio): activate session before voice joins * docs(ios-audio): align activation lifecycle comments * fix(ios-audio): keep session active when already-in-channel The 'already in channel' server response (code 0x0302) is treated as a successful join by _onJoinChannel: the user stays in the channel and local state is updated to reflect the joined target. But the underlying voiceJoin call still raises BridgeError_ServerRejected, which the joinVoiceChannelWithIosAudioSession helper used to interpret as a join failure and deactivate the iOS audio session. Result: the UI shows the user as joined while the audio session is dead and capture/playback remain silent. Add an isJoinSuccess predicate to the ordering helper. When the predicate matches, the helper rethrows (so the caller can still run its success-on-already-joined branch) without deactivating the session. Wire _onJoinChannel to pass _isAlreadyInChannel as the predicate so the 0x0302 path keeps the session active. Adds two regression tests covering the success-on-rethrow and the predicate-false-still-deactivates paths. * docs(security): regenerate license inventories Cargo inventory: pick up chanora_resolver bump from 0.1.0 to 0.2.0-beta.1 so it matches the workspace; also adds a trailing newline so 'cargo about generate' is idempotent in CI license-drift checks. Flutter inventory: pick up flutter_local_notifications (+ platform interfaces) and timezone pulled in by the prior notification permission work.
This commit is contained in:
@@ -34,6 +34,7 @@ import 'services/prefetch_debouncer.dart';
|
||||
import 'services/snapshot_state_mapper.dart';
|
||||
import 'services/ts3_server_link.dart';
|
||||
import 'services/ui_preferences_service.dart';
|
||||
import 'services/voice_join_ordering.dart';
|
||||
import 'src/rust/api.dart' as rust;
|
||||
import 'src/rust/frb_generated.dart';
|
||||
import 'src/rust/lib.dart' as rust_err;
|
||||
@@ -1301,7 +1302,18 @@ class _BetaHomeState extends State<_BetaHome> with WidgetsBindingObserver {
|
||||
});
|
||||
}
|
||||
}
|
||||
await rust.voiceJoin(channelId: ch.id, password: password ?? '');
|
||||
await joinVoiceChannelWithIosAudioSession(
|
||||
channelId: ch.id,
|
||||
password: password ?? '',
|
||||
voiceJoin: rust.voiceJoin,
|
||||
activateIosAudioSession: iosAudioSessionController.activate,
|
||||
deactivateIosAudioSession: iosAudioSessionController.deactivate,
|
||||
// Server says we are already in the target channel: the user is
|
||||
// still joined to a voice channel, so the iOS audio session must
|
||||
// stay active. The catch below converts this rethrow into the
|
||||
// success-on-already-joined branch.
|
||||
isJoinSuccess: _isAlreadyInChannel,
|
||||
);
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_currentVoiceChannelId = ch.id;
|
||||
|
||||
Reference in New Issue
Block a user