现象
QA 浮窗按 Option 开始录音后,浮窗内部完全没有音量电平反馈。用户说话时浮窗里没有任何视觉提示在变化(除了顶部 status bar 里的"录音中"小红点 pulse)——用户不知道麦克风是否真的在收音,也不知道音量是否合适。
对比:主听写胶囊(capsule)录音时有完整的 AudioBars 电平条会随声音起伏,体验差异明显。
复现
- 选段文字,Cmd+Shift+; 弹浮窗
- 按 Option 开始录音
- 对着麦克风说话
- 观察:浮窗内部除了 status bar 的小红点,没有任何视觉反馈显示音量。胶囊(如果还显示)能看到电平变化,但浮窗自己看不到。
根因
coordinator.rs:1743 在录音过程中**每帧(~33ms 节流)**通过 app.emit_to(\"qa\", \"qa:level\", { level }) 推一帧电平给 QA 浮窗:
```rust
let _ = app.emit_to(
"qa",
"qa:level",
serde_json::json!({ "level": level }),
);
```
但 QaPanel.tsx:46 只 listen qa:state 和 qa:dismiss,完全没 listen qa:level:
```tsx
// QaPanel.tsx 当前的 listener 注册
const stateHandle = await listen('qa:state', event => {...});
const dismissHandle = await listen('qa:dismiss', () => {...});
// ⚠️ 缺:listen('qa:level', ...) 完全没有
```
后端推的 level 帧成了"广播给空气"。
影响
- 三平台所有 QA 录音都没有电平视觉反馈
- 用户不知道麦克风状态(设备静音/音量过低/被别的 app 抢占都看不出)
- 已有的后端节流逻辑(每 33ms 一帧 + Recording 状态守卫)是浪费
建议 fix
QaPanel 加一个 `level` state + listener,把 level 渲染成跟 Capsule 一样的 AudioBars(或简化成顶部 progress 条),跟着 recording 状态淡入淡出:
```tsx
const [level, setLevel] = useState(0);
useEffect(() => {
if (!isTauri) return;
let unlisten: (() => void) | undefined;
(async () => {
const { listen } = await import('@tauri-apps/api/event');
unlisten = await listen<{level: number}>('qa:level', e => {
setLevel(e.payload.level);
});
})();
return () => unlisten?.();
}, []);
// 渲染:录音中显示 level 条
{status === 'recording' && }
```
或者简单点:复用 Capsule 的 `AudioBars` 组件直接 import 进来用。
现象
QA 浮窗按 Option 开始录音后,浮窗内部完全没有音量电平反馈。用户说话时浮窗里没有任何视觉提示在变化(除了顶部 status bar 里的"录音中"小红点 pulse)——用户不知道麦克风是否真的在收音,也不知道音量是否合适。
对比:主听写胶囊(capsule)录音时有完整的 AudioBars 电平条会随声音起伏,体验差异明显。
复现
根因
coordinator.rs:1743在录音过程中**每帧(~33ms 节流)**通过app.emit_to(\"qa\", \"qa:level\", { level })推一帧电平给 QA 浮窗:```rust
let _ = app.emit_to(
"qa",
"qa:level",
serde_json::json!({ "level": level }),
);
```
但
QaPanel.tsx:46只 listenqa:state和qa:dismiss,完全没 listenqa:level:```tsx⚠️ 缺:listen('qa:level', ...) 完全没有
// QaPanel.tsx 当前的 listener 注册
const stateHandle = await listen('qa:state', event => {...});
const dismissHandle = await listen('qa:dismiss', () => {...});
//
```
后端推的 level 帧成了"广播给空气"。
影响
建议 fix
QaPanel 加一个 `level` state + listener,把 level 渲染成跟 Capsule 一样的 AudioBars(或简化成顶部 progress 条),跟着 recording 状态淡入淡出:
```tsx
const [level, setLevel] = useState(0);
useEffect(() => {
if (!isTauri) return;
let unlisten: (() => void) | undefined;
(async () => {
const { listen } = await import('@tauri-apps/api/event');
unlisten = await listen<{level: number}>('qa:level', e => {
setLevel(e.payload.level);
});
})();
return () => unlisten?.();
}, []);
// 渲染:录音中显示 level 条
{status === 'recording' && }
```
或者简单点:复用 Capsule 的 `AudioBars` 组件直接 import 进来用。