fix(android): unblock mic permission startup

This commit is contained in:
Edison Jwa
2026-05-20 14:52:34 +09:00
parent 7254f81c65
commit 210a6a0e11
5 changed files with 168 additions and 78 deletions
+24 -3
View File
@@ -250,6 +250,7 @@ class _BetaHomeState extends State<_BetaHome> {
bool _inChannel = false;
rust.BridgeTransmitMode _transmitMode = rust.BridgeTransmitMode.ptt;
bool _hardMute = false;
bool _hardMuteByPermission = false;
int _releaseTailMs = 200;
BigInt? _currentVoiceChannelId;
BigInt? _pendingVoiceChannelId;
@@ -436,6 +437,7 @@ class _BetaHomeState extends State<_BetaHome> {
_inChannel = inChannel;
_transmitMode = transmitMode;
_hardMute = mute;
if (!mute) _hardMuteByPermission = false;
_releaseTailMs = releaseTailMs;
_audioStarted = inChannel;
_currentVoiceChannelId = currentChannelId;
@@ -687,7 +689,12 @@ class _BetaHomeState extends State<_BetaHome> {
// time via the Grant / Open Settings action.
try {
await rust.setHardMute(muted: true);
if (mounted) setState(() => _hardMute = true);
if (mounted) {
setState(() {
_hardMute = true;
_hardMuteByPermission = true;
});
}
} catch (_) {
// Best-effort clamp; if the bridge isn't ready we still
// proceed. The capture path also self-clamps on Android
@@ -696,6 +703,14 @@ class _BetaHomeState extends State<_BetaHome> {
// AtomicU8 clamp); this Dart setHardMute is the
// defence-in-depth path.
}
} else if (_hardMuteByPermission) {
await rust.setHardMute(muted: false);
if (mounted) {
setState(() {
_hardMute = false;
_hardMuteByPermission = false;
});
}
}
await rust.voiceJoin(channelId: ch.id, password: password ?? '');
if (!mounted) return;
@@ -787,7 +802,10 @@ class _BetaHomeState extends State<_BetaHome> {
await rust.setHardMute(muted: next);
await rust.setInputMuted(muted: next);
if (!mounted) return;
setState(() => _inputMuted = next);
setState(() {
_inputMuted = next;
_hardMuteByPermission = false;
});
} catch (e) {
if (!mounted) return;
setState(() => _error = e.toString());
@@ -2107,7 +2125,10 @@ class _SnapshotView extends StatelessWidget {
: () => onJoinChannel(ch),
),
selected: ch.id == currentVoiceChannelId,
onTap: hasJoinPending || !canJoinVoiceChannel || ch.id == currentVoiceChannelId
onTap:
hasJoinPending ||
!canJoinVoiceChannel ||
ch.id == currentVoiceChannelId
? null
: () => onJoinChannel(ch),
),