From 372a4484825a624050ca8981be164652a9c7477f Mon Sep 17 00:00:00 2001 From: d-rooX Date: Wed, 24 May 2023 19:46:21 +0300 Subject: [PATCH] added wide-selection editing and paste support --- .../colored_text_editing_controller.dart | 32 ++++++++++--------- lib/domain/language_check_service.dart | 3 +- .../debounce_lang_tool_service.dart | 4 +-- pubspec.yaml | 1 + 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/lib/core/controllers/colored_text_editing_controller.dart b/lib/core/controllers/colored_text_editing_controller.dart index e6ef79d..af85e47 100644 --- a/lib/core/controllers/colored_text_editing_controller.dart +++ b/lib/core/controllers/colored_text_editing_controller.dart @@ -1,3 +1,4 @@ +import 'package:collection_ext/ranges.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:languagetool_textfield/core/enums/mistake_type.dart'; @@ -55,8 +56,8 @@ class ColoredTextEditingController extends TextEditingController { /// Replaces mistake with given replacement void replaceMistake(Mistake mistake, String replacement) { - text = text.replaceRange(mistake.offset, mistake.endOffset, replacement); _mistakes.remove(mistake); + text = text.replaceRange(mistake.offset, mistake.endOffset, replacement); selection = TextSelection.fromPosition( TextPosition(offset: mistake.offset + replacement.length), ); @@ -69,23 +70,26 @@ class ColoredTextEditingController extends TextEditingController { ///so this check avoid cleaning Mistake list when text wasn't really changed if (newText == text) return; + // do not display mistake that was changed during text input + final selectionRange = IntRange(selection.start, selection.end).toSet(); + _mistakes.removeWhere((mistake) { + final mistakeRange = IntRange( + mistake.offset, + mistake.endOffset, + ).toSet(); + + return selectionRange.intersection(mistakeRange).isNotEmpty; + }); + // list containing mistakes with updated offset final List newMistakes = []; + final lengthDifference = newText.length - text.length; for (final mistake in _mistakes) { - // do not display mistake that was changed during text input - final bool _mistakeTextChanged = selection.start >= mistake.offset && - selection.start <= mistake.endOffset; - if (_mistakeTextChanged) { - continue; - } - int newOffset = mistake.offset; // move mistake if it located by the right side of cursor if (selection.start <= mistake.offset) { - final bool _isTextExtended = newText.length > text.length; - _isTextExtended ? newOffset += 1 : newOffset -= 1; + newOffset += lengthDifference; } - newMistakes.add( Mistake( message: mistake.message, @@ -95,13 +99,11 @@ class ColoredTextEditingController extends TextEditingController { ), ); } - // update current mistakes list with the moved one _mistakes = newMistakes; final mistakes = await languageCheckService.findMistakes(newText); - // findMistakes() future returns empty list if debouncing - // so in that case we don't need to update it - if (mistakes.isNotEmpty) { + // null is returned in case of debouncing when API isn't truly queried + if (mistakes != null) { _mistakes = mistakes; } diff --git a/lib/domain/language_check_service.dart b/lib/domain/language_check_service.dart index 16843d9..6841122 100644 --- a/lib/domain/language_check_service.dart +++ b/lib/domain/language_check_service.dart @@ -6,5 +6,6 @@ abstract class LanguageCheckService { const LanguageCheckService(); /// Returns found mistakes in the given [text]. - Future> findMistakes(String text); + /// Returns null if API wasn't queried, i.e when using debouncing + Future?> findMistakes(String text); } diff --git a/lib/implementations/debounce_lang_tool_service.dart b/lib/implementations/debounce_lang_tool_service.dart index 7aabc2d..143e218 100644 --- a/lib/implementations/debounce_lang_tool_service.dart +++ b/lib/implementations/debounce_lang_tool_service.dart @@ -17,11 +17,11 @@ class DebounceLangToolService extends LanguageCheckService { ) : debouncing = Debouncing(duration: debouncingDuration); @override - Future> findMistakes(String text) async { + Future?> findMistakes(String text) async { final value = await debouncing.debounce(() { return baseService.findMistakes(text); }) as List?; - return value ?? []; + return value; } } diff --git a/pubspec.yaml b/pubspec.yaml index ce683b8..7ddd3c9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,6 +7,7 @@ environment: flutter: ">=1.17.0" dependencies: + collection_ext: ^1.0.0 flutter: sdk: flutter language_tool: ^2.1.1