Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
- BREAKING: require flutter 3.27.0 or higher
- BREAKING: require dart 3.0.0 or higher
- BREAKING: rename autoFocus to autofocus to match `TextField`'s naming
- potentially BREAKING: remove `delayType` and `delay` fields from `LanguageToolController`
- potentially BREAKING: hide baseService and debouncing/throttling from Debouncing and Throttling LanguageService wrappers
- potentially BREAKING: rename `DebounceLanguageToolService` to `DebounceLanguageCheckService`
- potentially BREAKING: rename `ThrottleLanguageToolService` to `ThrottleLanguageCheckService`
- Allow overriding `languageCheckService`
- Add `isEnabled` to toggle spell check
- Add missing properties from flutter's `TextField`
- autofillHints
Expand Down
6 changes: 3 additions & 3 deletions lib/languagetool_textfield.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ export 'src/domain/highlight_style.dart';
export 'src/domain/language_check_service.dart';
export 'src/domain/mistake.dart';
export 'src/domain/writing_mistake.dart';
export 'src/implementations/debounce_lang_tool_service.dart';
export 'src/implementations/lang_tool_service.dart';
export 'src/implementations/throttling_lang_tool_service.dart';
export 'src/language_check_services/language_tool_service.dart';
export 'src/presentation/language_tool_text_field.dart';
export 'src/utils/mistake_popup.dart';
export 'src/utils/popup_overlay_renderer.dart';
export 'src/wrappers/debounce_language_check_service.dart';
export 'src/wrappers/throttling_language_check_service.dart';
72 changes: 36 additions & 36 deletions lib/src/core/controllers/language_tool_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,10 @@ import 'dart:math';
import 'package:collection/collection.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:languagetool_textfield/src/client/language_tool_client.dart';
import 'package:languagetool_textfield/src/core/enums/delay_type.dart';
import 'package:languagetool_textfield/languagetool_textfield.dart';
import 'package:languagetool_textfield/src/core/enums/mistake_type.dart';
import 'package:languagetool_textfield/src/domain/highlight_style.dart';
import 'package:languagetool_textfield/src/domain/language_check_service.dart';
import 'package:languagetool_textfield/src/domain/mistake.dart';
import 'package:languagetool_textfield/src/implementations/debounce_lang_tool_service.dart';
import 'package:languagetool_textfield/src/implementations/lang_tool_service.dart';
import 'package:languagetool_textfield/src/implementations/throttling_lang_tool_service.dart';
import 'package:languagetool_textfield/src/utils/closed_range.dart';
import 'package:languagetool_textfield/src/utils/keep_latest_response_service.dart';
import 'package:languagetool_textfield/src/utils/mistake_popup.dart';

/// A TextEditingController with overrides buildTextSpan for building
/// marked TextSpans with tap recognizer
Expand All @@ -24,23 +16,6 @@ class LanguageToolController extends TextEditingController {
/// Color scheme to highlight mistakes
final HighlightStyle highlightStyle;

/// Represents the type of delay for language checking.
///
/// [DelayType.debouncing] - Calls a function when a user hasn't carried out
/// the event in a specific amount of time.
///
/// [DelayType.throttling] - Calls a function at intervals of a specified
/// amount of time while the user is carrying out the event.
final DelayType delayType;

/// Represents the duration of the delay for language checking.
///
/// If the delay is [Duration.zero], no delaying is applied.
final Duration delay;

/// Create an instance of [LanguageToolClient] instance
final _languageToolClient = LanguageToolClient();

/// Create an instance of [KeepLatestResponseService]
/// to handle asynchronous operations
final _latestResponseService = KeepLatestResponseService();
Expand Down Expand Up @@ -69,10 +44,10 @@ class LanguageToolController extends TextEditingController {
///
/// A language code like en-US, de-DE, fr, or auto to guess
/// the language automatically.
String get language => _languageToolClient.language;
String get language => _languageCheckService?.language ?? 'auto';

set language(String language) {
_languageToolClient.language = language;
_languageCheckService?.language = language;
}

/// Indicates whether spell checking is enabled
Expand Down Expand Up @@ -108,26 +83,51 @@ class LanguageToolController extends TextEditingController {
super.value = newValue;
}

/// Controller constructor
/// Controller constructor.
///
/// [highlightStyle] - Color scheme to highlight mistakes.
///
/// [delayType] - Represents the type of delay for language checking.
/// [DelayType.debouncing] - Calls a function when a user hasn't carried out
/// the event in a specific amount of time.
/// [DelayType.throttling] - Calls a function at intervals of a specified
/// amount of time while the user is carrying out the event.
///
/// [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.
LanguageToolController({
bool isEnabled = true,
this.highlightStyle = const HighlightStyle(),
this.delay = Duration.zero,
this.delayType = DelayType.debouncing,
DelayType delayType = DelayType.debouncing,
Duration delay = Duration.zero,
LanguageCheckService? languageCheckService,
}) : _isEnabled = isEnabled {
_languageCheckService = _getLanguageCheckService();
_languageCheckService = languageCheckService ??
_getLanguageCheckService(
delayType: delayType,
delay: delay,
languageToolClient: LanguageToolClient(),
);
}

LanguageCheckService _getLanguageCheckService() {
final languageToolService = LangToolService(_languageToolClient);
static LanguageCheckService _getLanguageCheckService({
required DelayType delayType,
required Duration delay,
required LanguageToolClient languageToolClient,
}) {
final languageToolService = LanguageToolService(languageToolClient);

if (delay == Duration.zero) return languageToolService;

switch (delayType) {
case DelayType.debouncing:
return DebounceLangToolService(languageToolService, delay);
return DebounceLanguageCheckService(languageToolService, delay);
case DelayType.throttling:
return ThrottlingLangToolService(languageToolService, delay);
return ThrottlingLanguageCheckService(languageToolService, delay);
}
}

Expand Down
11 changes: 11 additions & 0 deletions lib/src/domain/language_check_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ import 'package:languagetool_textfield/src/utils/result.dart';

/// A base language check service.
abstract class LanguageCheckService {
/// Gets the current language code used for language checking.
///
/// Returns a string representing the language code (e.g., 'en-US', 'de-DE').
String get language;

/// Sets the language code to be used for language checking.
///
/// [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);

/// Creates a new instance of the [LanguageCheckService] class.
const LanguageCheckService();

Expand Down
30 changes: 0 additions & 30 deletions lib/src/implementations/debounce_lang_tool_service.dart

This file was deleted.

31 changes: 0 additions & 31 deletions lib/src/implementations/throttling_lang_tool_service.dart

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,20 @@ import 'package:languagetool_textfield/src/domain/writing_mistake.dart';
import 'package:languagetool_textfield/src/utils/result.dart';

/// An implementation of language check service with language tool service.
class LangToolService extends LanguageCheckService {
class LanguageToolService extends LanguageCheckService {
/// An instance of this class that is used to interact with LanguageTool API.
final LanguageToolClient languageTool;

/// Creates a new instance of the [LangToolService].
LangToolService(this.languageTool);
@override
String get language => languageTool.language;

@override
set language(String language) {
languageTool.language = language;
}

/// Creates a new instance of the [LanguageToolService].
LanguageToolService(this.languageTool);

@override
Future<Result<List<Mistake>>> findMistakes(String text) async {
Expand Down
40 changes: 40 additions & 0 deletions lib/src/wrappers/debounce_language_check_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import 'package:languagetool_textfield/src/domain/language_check_service.dart';
import 'package:languagetool_textfield/src/domain/mistake.dart';
import 'package:languagetool_textfield/src/utils/result.dart';
import 'package:throttling/throttling.dart';

/// A language check service with debouncing.
class DebounceLanguageCheckService extends LanguageCheckService {
/// A base language check service.
final LanguageCheckService _languageCheckService;

/// A debouncing used to debounce the API calls.
final Debouncing<Future<Result<List<Mistake>>?>> _debouncing;

@override
String get language => _languageCheckService.language;

@override
set language(String language) {
_languageCheckService.language = language;
}

/// Creates a new instance of the [DebounceLanguageCheckService] class.
DebounceLanguageCheckService(
this._languageCheckService,
Duration debouncingDuration,
) : _debouncing = Debouncing(duration: debouncingDuration);

@override
Future<Result<List<Mistake>>?> findMistakes(String text) async {
return await _debouncing
.debounce(() => _languageCheckService.findMistakes(text));
}

// ignore: proper_super_calls
@override
Future<void> dispose() async {
_debouncing.close();
await _languageCheckService.dispose();
}
}
41 changes: 41 additions & 0 deletions lib/src/wrappers/throttling_language_check_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import 'package:languagetool_textfield/src/domain/language_check_service.dart';
import 'package:languagetool_textfield/src/domain/mistake.dart';
import 'package:languagetool_textfield/src/utils/result.dart';
import 'package:throttling/throttling.dart';

/// A language check service with debouncing.
class ThrottlingLanguageCheckService extends LanguageCheckService {
/// A base language check service that is used to interact
/// with the language check API.
final LanguageCheckService _languageCheckService;

/// A throttling used to throttle the API calls.
final Throttling<Future<Result<List<Mistake>>?>> _throttling;

@override
String get language => _languageCheckService.language;

@override
set language(String language) {
_languageCheckService.language = language;
}

/// Creates a new instance of the [ThrottlingLanguageCheckService] class.
ThrottlingLanguageCheckService(
this._languageCheckService,
Duration throttlingDuration,
) : _throttling = Throttling(duration: throttlingDuration);

@override
Future<Result<List<Mistake>>?> findMistakes(String text) async {
return await _throttling
.throttle(() => _languageCheckService.findMistakes(text));
}

// ignore: proper_super_calls
@override
Future<void> dispose() async {
_throttling.close();
await _languageCheckService.dispose();
}
}