minor fixes [skip ci]

Omar committed Jul 14, 2026 at 04:56 UTC 5423484c91f0b1d14c38550dbf0462a0e6406827
5 files changed +35 -4
lib/new-ui/widgets/send_page/send_address_input.dart
+2
@@ -88,6 +88,8 @@ class _NewSendAddressInputState extends State<NewSendAddressInput> {
88 children: [
89 TextField(
90 focusNode: widget.focusNode,
91 + autocorrect: false,
92 + enableSuggestions: false,
93 onSubmitted: (val) => FocusScope.of(context).unfocus(),
94 onChanged: state.didChange,
95 onEditingComplete: () {
lib/new-ui/widgets/send_page/send_amount_input.dart
+7 -1
@@ -71,6 +71,8 @@ class _NewSendAmountInputState extends State<NewSendAmountInput> {
71 signed: false,
72 decimal: widget.maxDecimals > 0,
73 ),
74 + autocorrect: false,
75 + enableSuggestions: false,
76 inputFormatters: <TextInputFormatter>[
77 DecimalInputFormatter(maxDecimals: widget.maxDecimals),
78 ],
@@ -87,7 +89,11 @@ class _NewSendAmountInputState extends State<NewSendAmountInput> {
89 onPressed: () async {
90 final data = await Clipboard.getData(Clipboard.kTextPlain);
91 if (data != null && data.text != null) {
90 - widget.amountController.text = data.text!;
92 + final text = data.text!;
93 + widget.amountController.value = TextEditingValue(
94 + text: text,
95 + selection: TextSelection.collapsed(offset: text.length),
96 + );
97 }
98 }),
99 ],
lib/src/screens/connect_device/connect_device_page.dart
+2 -2
@@ -149,8 +149,8 @@ class ConnectDevicePageBodyState extends State<ConnectDevicePageBody> {
149 bleDevices.add(device);
150 if (longWait) longWait = false;
151 }))
152 - ..onError((e) {
153 - throw e.toString();
152 + ..onError((Object e) {
153 + printV(e);
154 });
155 _bleRefreshTimer?.cancel();
156 _bleRefreshTimer = null;
lib/utils/decimal_input_formatter.dart
+6 -1
@@ -11,7 +11,12 @@ class DecimalInputFormatter extends TextInputFormatter {
11 final text = newValue.text;
12 if (text.isEmpty) return newValue;
13
14 - if (S.current.all.startsWith(text)) return TextEditingValue(text: "");
14 + if (S.current.all.startsWith(text)) {
15 + return const TextEditingValue(
16 + text: "",
17 + selection: TextSelection.collapsed(offset: 0),
18 + );
19 + }
20
21 final regex = maxDecimals == 0 ? RegExp(r'^\d*$') : RegExp('^\\d*([.,]\\d{0,$maxDecimals})?\$');
22 return regex.hasMatch(text) ? newValue.copyWith(text: text.replaceAll(',', '.')) : oldValue;
lib/utils/exception_handler.dart
+18
@@ -277,6 +277,7 @@ class ExceptionHandler {
277 "invalid signature",
278 "invalid password",
279 "NetworkImage._loadAsync",
280 + "Invalid image data",
281 "SSLV3_ALERT_BAD_RECORD_MAC",
282 "PlatformException(already_active, File picker is already active",
283 // SVG-related errors
@@ -296,6 +297,10 @@ class ExceptionHandler {
297 "Wrong Device Status: 0x5515 (UNKNOWN)",
298 "Command handling failed. With error: hostUnreachable",
299
300 + // Android IME/Gboard occasionally reports a caret offset past the end of
301 + // the text on the platform text-input channel while typing. Non-fatal
302 + // framework<->platform desync; the app keeps working.
303 + "invalid selection start",
304 "FocusScopeNode was used after being disposed",
305 "_getDismissibleFlushbar",
306 "_QueuedFuture.execute (package:universal_ble/src/queue.dart:65)",
@@ -456,6 +461,19 @@ class ExceptionHandler {
461 }
462 }
463
464 + if (errorDetails.exception.toString().contains("Cannot add event after closing")) {
465 + // grpc-dart teardown race (e.g. the MWEB channel on litecoin): a buffered outgoing
466 + // frame is delivered to the http2 stream's sink after the call/channel was
467 + // terminated. The message alone is too generic to ignore, so require the exact
468 + // shape of grpc's forwarding chain: .map().map().handleError().listen(sink.add).
469 + final stack = errorDetails.stack.toString();
470 + if (stack.contains("_StreamSinkWrapper.add") &&
471 + stack.contains("_MapStream._handleData") &&
472 + stack.contains("_HandleErrorStream._handleData")) {
473 + return true;
474 + }
475 + }
476 +
477 return false;
478 }
479 }