diff --git a/CHANGELOG.md b/CHANGELOG.md index c345970..84cc605 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.1 + +- Fix: recheck text on changing language + ## 1.0.0 - BREAKING: require flutter 3.27.0 or higher @@ -64,7 +68,7 @@ - Moved implementation into the `src` directory - Updated dependencies - Add some properties (cursorColor, onTextChange, focusNode, onTextSubmitted, ...) for TextField - Credits: @dab246 + Credits: @dab246 - Replace deprecated MaterialStateMouseCursor ## 0.0.6 diff --git a/example/lib/main.dart b/example/lib/main.dart index 968adf1..2e65dab 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -10,7 +10,7 @@ void main() { } /// Example App main page -// ignore: prefer_match_file_name +// ignore: prefer_match_file_name, prefer-match-file-name class App extends StatefulWidget { /// Example app constructor const App({super.key}); diff --git a/lib/src/core/controllers/language_tool_controller.dart b/lib/src/core/controllers/language_tool_controller.dart index 40867a4..0e7e999 100644 --- a/lib/src/core/controllers/language_tool_controller.dart +++ b/lib/src/core/controllers/language_tool_controller.dart @@ -47,7 +47,12 @@ class LanguageToolController extends TextEditingController { String get language => _languageCheckService?.language ?? 'auto'; set language(String language) { + if (this.language == language) return; _languageCheckService?.language = language; + + if (!_isEnabled) return; + + _handleTextChange(text, spellCheckSameText: true); } /// Indicates whether spell checking is enabled @@ -96,9 +101,9 @@ class LanguageToolController extends TextEditingController { /// [delay] - Represents the duration of the delay for language checking. /// If the delay is [Duration.zero], no delaying is applied. /// - /// You can optionally provide a custom [languageCheckService] to fully control - /// how text is analyzed and processed. When provided, [delayType] and [delay] - /// are ignored. + /// You can optionally provide a custom [languageCheckService] to + /// fully control how text is analyzed and processed. + /// When provided, [delayType] and [delay] are ignored. LanguageToolController({ bool isEnabled = true, this.highlightStyle = const HighlightStyle(), @@ -121,6 +126,8 @@ class LanguageToolController extends TextEditingController { }) { final languageToolService = LanguageToolService(languageToolClient); + // false positive, the same variable is used beyond the return statement + // ignore: avoid_unnecessary_return_variable if (delay == Duration.zero) return languageToolService; switch (delayType) { diff --git a/lib/src/domain/language_check_service.dart b/lib/src/domain/language_check_service.dart index 1ccd56f..4fb2421 100644 --- a/lib/src/domain/language_check_service.dart +++ b/lib/src/domain/language_check_service.dart @@ -10,7 +10,8 @@ abstract class LanguageCheckService { /// Sets the language code to be used for language checking. /// - /// [language] A string representing the language code (e.g., 'en-US', 'de-DE'). + /// [language] A string representing the language code + /// (e.g., 'en-US', 'de-DE'). /// This determines which language rules will be applied during text analysis. set language(String language); diff --git a/lib/src/language_check_services/language_tool_service.dart b/lib/src/language_check_services/language_tool_service.dart index 344a8fd..0b885aa 100644 --- a/lib/src/language_check_services/language_tool_service.dart +++ b/lib/src/language_check_services/language_tool_service.dart @@ -27,7 +27,7 @@ class LanguageToolService extends LanguageCheckService { .then(Result.success) .catchError(Result>.error); - final mistakesWrapper = writingMistakesWrapper.map( + return writingMistakesWrapper.map( (mistakes) { return mistakes.map( (m) { @@ -42,7 +42,5 @@ class LanguageToolService extends LanguageCheckService { ).toList(growable: false); }, ); - - return mistakesWrapper; } } diff --git a/lib/src/utils/mistake_popup.dart b/lib/src/utils/mistake_popup.dart index 89463b1..14a1f92 100644 --- a/lib/src/utils/mistake_popup.dart +++ b/lib/src/utils/mistake_popup.dart @@ -86,7 +86,6 @@ class LanguageToolMistakePopup extends StatelessWidget { /// [LanguageToolMistakePopup] constructor const LanguageToolMistakePopup({ - super.key, required this.popupRenderer, required this.mistake, required this.controller, @@ -96,18 +95,19 @@ class LanguageToolMistakePopup extends StatelessWidget { this.horizontalMargin = _defaultHorizontalMargin, this.verticalMargin = _defaultVerticalMargin, this.mistakeStyle, + super.key, }); @override Widget build(BuildContext context) { - const _borderRadius = 10.0; - const _mistakeNameFontSize = 11.0; - const _mistakeMessageFontSize = 13.0; - const _replacementButtonsSpacing = 4.0; - const _replacementButtonsSpacingMobile = -6.0; - const _paddingBetweenTitle = 14.0; - const _titleLetterSpacing = 0.56; - const _dismissSplashRadius = 2.0; + const borderRadius = 10.0; + const mistakeNameFontSize = 11.0; + const mistakeMessageFontSize = 13.0; + const replacementButtonsSpacing = 4.0; + const replacementButtonsSpacingMobile = -6.0; + const paddingBetweenTitle = 14.0; + const titleLetterSpacing = 0.56; + const dismissSplashRadius = 2.0; const padding = 10.0; @@ -128,7 +128,7 @@ class LanguageToolMistakePopup extends StatelessWidget { ), decoration: BoxDecoration( color: colorScheme.surface.withValues(alpha: 0.9), - borderRadius: BorderRadius.circular(_borderRadius), + borderRadius: BorderRadius.circular(borderRadius), boxShadow: [ BoxShadow( color: colorScheme.onSurface.withValues(alpha: 0.5), @@ -174,7 +174,7 @@ class LanguageToolMistakePopup extends StatelessWidget { ), constraints: const BoxConstraints(), padding: EdgeInsets.zero, - splashRadius: _dismissSplashRadius, + splashRadius: dismissSplashRadius, onPressed: () { _dismissDialog(); controller.onClosePopup(); @@ -188,7 +188,7 @@ class LanguageToolMistakePopup extends StatelessWidget { padding: const EdgeInsets.all(padding), decoration: BoxDecoration( color: colorScheme.surface, - borderRadius: BorderRadius.circular(_borderRadius), + borderRadius: BorderRadius.circular(borderRadius), ), child: SingleChildScrollView( child: Column( @@ -196,16 +196,16 @@ class LanguageToolMistakePopup extends StatelessWidget { children: [ Padding( padding: const EdgeInsets.only( - bottom: _paddingBetweenTitle, + bottom: paddingBetweenTitle, ), child: Text( mistake.type.name.capitalize(), style: TextStyle( color: colorScheme.onSurface.withValues(alpha: 0.7), - fontSize: _mistakeNameFontSize, + fontSize: mistakeNameFontSize, fontWeight: FontWeight.w600, - letterSpacing: _titleLetterSpacing, + letterSpacing: titleLetterSpacing, ), ), ), @@ -214,15 +214,15 @@ class LanguageToolMistakePopup extends StatelessWidget { child: Text( mistake.message, style: const TextStyle( - fontSize: _mistakeMessageFontSize, + fontSize: mistakeMessageFontSize, ), ), ), Wrap( - spacing: _replacementButtonsSpacing, + spacing: replacementButtonsSpacing, runSpacing: kIsWeb - ? _replacementButtonsSpacing - : _replacementButtonsSpacingMobile, + ? replacementButtonsSpacing + : replacementButtonsSpacingMobile, children: mistake.replacements .map( (replacement) => ElevatedButton( diff --git a/lib/src/utils/popup_overlay_renderer.dart b/lib/src/utils/popup_overlay_renderer.dart index ead45d3..aaafdce 100644 --- a/lib/src/utils/popup_overlay_renderer.dart +++ b/lib/src/utils/popup_overlay_renderer.dart @@ -12,17 +12,16 @@ class PopupOverlayRenderer { /// Render overlay entry on the screen with dismiss logic OverlayEntry render( BuildContext context, { - ValueChanged? onClose, required Offset position, required WidgetBuilder popupBuilder, + ValueChanged? onClose, }) { - final _createdEntry = OverlayEntry( + final createdEntry = OverlayEntry( builder: (context) => GestureDetector( behavior: HitTestBehavior.opaque, onTapDown: onClose, child: Material( color: Colors.transparent, - type: MaterialType.canvas, child: Stack( children: [ CustomSingleChildLayout( @@ -38,10 +37,10 @@ class PopupOverlayRenderer { ), ); - Overlay.of(context).insert(_createdEntry); - _overlayEntry = _createdEntry; + Overlay.of(context).insert(createdEntry); + _overlayEntry = createdEntry; - return _createdEntry; + return createdEntry; } /// Remove popup @@ -65,12 +64,12 @@ class PopupOverlayLayoutDelegate extends SingleChildLayoutDelegate { } Offset _calculatePosition(Size size, Offset position, Size childSize) { - final _popupRect = Rect.fromCenter( + final popupRect = Rect.fromCenter( center: position, width: childSize.width, height: childSize.height, ); - double dx = _popupRect.left; + double dx = popupRect.left; // limiting X offset dx = max(0, dx); final rightBorderPosition = dx + childSize.width;