fix(ptt,ui): Continuous mode no longer self-disables after 30 s; rename PTT label to Mic
Issue 1: in Continuous transmit mode the talk indicator turned
gray-out / mic disabled after ~30 s and could only be revived by
toggling mic mute. Root cause: SAD-079 MissedKeyUpWatchdog
subscribed to AudioTransmitGate.transmit_active and force-cleared
it after 30 s of true. In PTT mode this is correct (stuck key =
bug). In Continuous mode transmit_active is *supposed* to stay
true indefinitely; the watchdog assumption doesn't hold.
Fix: the watchdog now subscribes to a new ptt_held watch on the
TransmitModeSelector (the raw key-state input, not the resolved
gate). In Continuous mode ptt_held is never set true, so the
watchdog never fires. In PTT mode it still fires on a stuck
key-down as before. The session owns the watchdog (was on the
engine) so it survives engine restarts; it's spawned lazily on the
first start_audio.
MissedKeyUpWatchdog gains spawn_on_signal(rx, on_timeout, timeout)
alongside the existing spawn(gate, timeout) — old shape preserved
for backwards compat. run_watchdog generalised to take any
watch::Receiver<bool> + Box<dyn Fn() + Send + Sync>.
Two new tests:
- watchdog_on_signal_does_not_fire_when_ptt_held_stays_false
(the Continuous-mode regression test)
- watchdog_on_signal_fires_when_signal_stays_true
(the stuck-key case still fires)
Issue 2: the Voice Bar stats line said 'PTT on/off' even when the
user was in Continuous mode where no PTT key is involved. Renamed
to 'Mic on/off' (mode-neutral) and l10n-ised the on/off literal:
- en: 'Mic on' / 'Mic off'
- zh: '麦克风 开启' / '麦克风 关闭'
cargo test --workspace --lib: 80 passed / 0 failed / 1 ignored
(was 78, +2 watchdog tests).
flutter analyze: clean (6 pre-existing Radio.groupValue infos).
This commit is contained in:
@@ -96,7 +96,7 @@
|
||||
"placeholders": { "reason": { "type": "String" } }
|
||||
},
|
||||
|
||||
"audioStatsLine": "TX {sent} frames • RX {received} frames • PTT {ptt}",
|
||||
"audioStatsLine": "TX {sent} frames • RX {received} frames • Mic {ptt}",
|
||||
"@audioStatsLine": {
|
||||
"placeholders": {
|
||||
"sent": { "type": "int" },
|
||||
@@ -126,5 +126,7 @@
|
||||
"voiceHardMuteLabel": "Mute microphone",
|
||||
"voiceOutputMuteLabel": "Mute speakers",
|
||||
"voiceSettingsTitle": "Voice settings",
|
||||
"voiceBindKeyAction": "Bind PTT key"
|
||||
"voiceBindKeyAction": "Bind PTT key",
|
||||
"voiceMicOn": "on",
|
||||
"voiceMicOff": "off"
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
"statusReconnecting": "正在重新连接……第 {attempt} 次尝试,{delay} 秒后",
|
||||
"statusConnectionLost": "连接已断开:{reason}",
|
||||
|
||||
"audioStatsLine": "发送 {sent} 帧 • 接收 {received} 帧 • PTT {ptt}",
|
||||
"audioStatsLine": "发送 {sent} 帧 • 接收 {received} 帧 • 麦克风 {ptt}",
|
||||
|
||||
"channelsHeading": "频道",
|
||||
"clientsHeading": "在线用户",
|
||||
@@ -83,5 +83,7 @@
|
||||
"voiceHardMuteLabel": "麦克风静音",
|
||||
"voiceOutputMuteLabel": "扬声器静音",
|
||||
"voiceSettingsTitle": "语音设置",
|
||||
"voiceBindKeyAction": "绑定 PTT 按键"
|
||||
"voiceBindKeyAction": "绑定 PTT 按键",
|
||||
"voiceMicOn": "开启",
|
||||
"voiceMicOff": "关闭"
|
||||
}
|
||||
|
||||
@@ -454,7 +454,7 @@ abstract class AppL10n {
|
||||
/// No description provided for @audioStatsLine.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'TX {sent} frames • RX {received} frames • PTT {ptt}'**
|
||||
/// **'TX {sent} frames • RX {received} frames • Mic {ptt}'**
|
||||
String audioStatsLine(int sent, int received, String ptt);
|
||||
|
||||
/// No description provided for @channelsHeading.
|
||||
@@ -546,6 +546,18 @@ abstract class AppL10n {
|
||||
/// In en, this message translates to:
|
||||
/// **'Bind PTT key'**
|
||||
String get voiceBindKeyAction;
|
||||
|
||||
/// No description provided for @voiceMicOn.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'on'**
|
||||
String get voiceMicOn;
|
||||
|
||||
/// No description provided for @voiceMicOff.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'off'**
|
||||
String get voiceMicOff;
|
||||
}
|
||||
|
||||
class _AppL10nDelegate extends LocalizationsDelegate<AppL10n> {
|
||||
|
||||
@@ -216,7 +216,7 @@ class AppL10nEn extends AppL10n {
|
||||
|
||||
@override
|
||||
String audioStatsLine(int sent, int received, String ptt) {
|
||||
return 'TX $sent frames • RX $received frames • PTT $ptt';
|
||||
return 'TX $sent frames • RX $received frames • Mic $ptt';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -265,4 +265,10 @@ class AppL10nEn extends AppL10n {
|
||||
|
||||
@override
|
||||
String get voiceBindKeyAction => 'Bind PTT key';
|
||||
|
||||
@override
|
||||
String get voiceMicOn => 'on';
|
||||
|
||||
@override
|
||||
String get voiceMicOff => 'off';
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ class AppL10nZh extends AppL10n {
|
||||
|
||||
@override
|
||||
String audioStatsLine(int sent, int received, String ptt) {
|
||||
return '发送 $sent 帧 • 接收 $received 帧 • PTT $ptt';
|
||||
return '发送 $sent 帧 • 接收 $received 帧 • 麦克风 $ptt';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -259,4 +259,10 @@ class AppL10nZh extends AppL10n {
|
||||
|
||||
@override
|
||||
String get voiceBindKeyAction => '绑定 PTT 按键';
|
||||
|
||||
@override
|
||||
String get voiceMicOn => '开启';
|
||||
|
||||
@override
|
||||
String get voiceMicOff => '关闭';
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ class VoiceBar extends StatelessWidget {
|
||||
l10n.audioStatsLine(
|
||||
stats.framesSent,
|
||||
stats.framesReceived,
|
||||
stats.pttActive ? 'on' : 'off',
|
||||
stats.pttActive ? l10n.voiceMicOn : l10n.voiceMicOff,
|
||||
),
|
||||
style: theme.textTheme.bodySmall,
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user