Sync full Android text after composition settles

This commit is contained in:
Misaka
2026-05-15 22:09:31 +08:00
parent 6b51fc5f99
commit 9dce49eb78

View File

@@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
@@ -42,7 +43,8 @@ class _InputSyncPageState extends State<InputSyncPage> {
final inputFocusNode = FocusNode();
WebSocketChannel? channel;
String lastText = '';
Timer? syncDebounce;
String lastSyncedText = '';
bool connected = false;
@override
@@ -54,6 +56,7 @@ class _InputSyncPageState extends State<InputSyncPage> {
@override
void dispose() {
syncDebounce?.cancel();
channel?.sink.close();
hostController.dispose();
portController.dispose();
@@ -85,10 +88,12 @@ class _InputSyncPageState extends State<InputSyncPage> {
setState(() {
connected = true;
});
_sendCurrentText(force: true);
inputFocusNode.requestFocus();
}
void _disconnect() {
syncDebounce?.cancel();
channel?.sink.close();
channel = null;
setState(() {
@@ -97,23 +102,40 @@ class _InputSyncPageState extends State<InputSyncPage> {
}
void _syncTextChange() {
final currentText = inputController.text;
if (!connected || channel == null || currentText == lastText) {
lastText = currentText;
if (!connected || channel == null) {
return;
}
if (currentText.length > lastText.length &&
currentText.startsWith(lastText)) {
_send('insertText', text: currentText.substring(lastText.length));
} else if (lastText.length == currentText.length + 1 &&
lastText.startsWith(currentText)) {
_send('backspace');
} else {
_send('insertText', text: currentText);
final value = inputController.value;
if (value.composing.isValid) {
return;
}
lastText = currentText;
final currentText = value.text;
if (currentText == lastSyncedText) {
return;
}
syncDebounce?.cancel();
syncDebounce = Timer(const Duration(milliseconds: 800), _sendCurrentText);
}
void _sendCurrentText({bool force = false}) {
if (!connected || channel == null) {
return;
}
final latestValue = inputController.value;
if (latestValue.composing.isValid) {
return;
}
if (!force && latestValue.text == lastSyncedText) {
return;
}
lastSyncedText = latestValue.text;
_send('replaceAll', text: latestValue.text);
}
void _send(String action, {String? text}) {