Add desktop mute toggle button in draft board

Add a setMute WebSocket action and a mute IconButton in the draft
board title bar. The button optimistically flips local state and
rolls back with a toast when the desktop is unreachable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Misaka
2026-06-17 22:12:29 +08:00
parent 2798b5a66a
commit 491513fc5e
3 changed files with 66 additions and 0 deletions

View File

@@ -134,6 +134,13 @@ class NativeConnectionApi {
return result ?? false;
}
Future<bool> sendMute(bool muted) async {
final result = await _methodChannel.invokeMethod<bool>('sendMute', {
'muted': muted,
});
return result ?? false;
}
Future<List<DiscoveredDevice>> startDiscovery() async {
try {
final result = await _methodChannel.invokeListMethod<dynamic>(
@@ -184,6 +191,7 @@ class _InputSyncPageState extends State<InputSyncPage>
bool headerExpanded = true;
bool inputFocused = false;
bool scanning = false;
bool desktopMuted = false;
@override
void initState() {
@@ -265,6 +273,7 @@ class _InputSyncPageState extends State<InputSyncPage>
}
if (!nextState.connected) {
sendButtonState = SendButtonState.idle;
desktopMuted = false;
}
});
@@ -423,6 +432,23 @@ class _InputSyncPageState extends State<InputSyncPage>
}
}
Future<void> _toggleMute() async {
if (!connection.connected) {
return;
}
final nextMuted = !desktopMuted;
setState(() {
desktopMuted = nextMuted;
});
final sent = await api.sendMute(nextMuted);
if (!sent && mounted) {
setState(() {
desktopMuted = !nextMuted;
});
_showToast('发送失败,连接已断开');
}
}
Future<void> _saveHistory(String text) async {
final trimmed = text.trim();
if (trimmed.isEmpty) {
@@ -904,6 +930,13 @@ class _InputSyncPageState extends State<InputSyncPage>
icon: const Icon(Icons.delete_outline),
),
),
IconButton(
tooltip: desktopMuted ? '取消静音' : '静音桌面',
onPressed: connection.connected ? _toggleMute : null,
icon: Icon(
desktopMuted ? Icons.volume_off : Icons.volume_up,
),
),
],
),
),