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:
@@ -291,6 +291,34 @@ class ConnectionService : Service() {
|
||||
return sendAction(socket, "enter", null)
|
||||
}
|
||||
|
||||
fun sendMute(muted: Boolean): Boolean {
|
||||
Log.d("WTS", "ConnectionService.sendMute muted=$muted connected=${state.connected}")
|
||||
val socket = currentSocket ?: return false
|
||||
if (!state.connected) {
|
||||
return false
|
||||
}
|
||||
|
||||
return sendMuteAction(socket, muted)
|
||||
}
|
||||
|
||||
private fun sendMuteAction(socket: WebSocket, muted: Boolean): Boolean {
|
||||
val payload = JSONObject()
|
||||
.put("action", "setMute")
|
||||
.put("muted", muted)
|
||||
.toString()
|
||||
val sent = socket.send(payload)
|
||||
if (!sent && currentSocket == socket) {
|
||||
currentSocket = null
|
||||
updateState(
|
||||
connected = false,
|
||||
connecting = false,
|
||||
lastError = "连接已断开"
|
||||
)
|
||||
}
|
||||
|
||||
return sent
|
||||
}
|
||||
|
||||
private fun sendAction(socket: WebSocket, action: String, text: String?): Boolean {
|
||||
val payload = JSONObject()
|
||||
.put("action", action)
|
||||
|
||||
@@ -44,6 +44,11 @@ class MainActivity : FlutterActivity() {
|
||||
Log.d(tag, "MethodChannel sendEnter")
|
||||
result.success(ConnectionService.sendEnter())
|
||||
}
|
||||
"sendMute" -> {
|
||||
val muted = call.argument<Boolean>("muted") ?: false
|
||||
Log.d(tag, "MethodChannel sendMute muted=$muted")
|
||||
result.success(ConnectionService.sendMute(muted))
|
||||
}
|
||||
"getState" -> {
|
||||
Log.d(tag, "MethodChannel getState")
|
||||
result.success(ConnectionService.stateMap())
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user