From 03886745daf4d007a29e772a5115ce49b200b7ac Mon Sep 17 00:00:00 2001 From: Kateryna Kalinchenko Date: Wed, 7 Jun 2023 18:40:26 +0300 Subject: [PATCH 01/11] Removed language tool package and added the implementation with the api call --- example/ios/Runner.xcodeproj/project.pbxproj | 1 + lib/beans/category.dart | 26 ++++++ lib/beans/context.dart | 33 +++++++ lib/beans/language_tool_answer_raw.dart | 32 +++++++ lib/beans/match.dart | 90 ++++++++++++++++++++ lib/beans/replacement.dart | 20 +++++ lib/beans/rule.dart | 46 ++++++++++ lib/beans/type.dart | 20 +++++ lib/beans/warnings.dart | 20 +++++ lib/core/network/language_tool.dart | 81 ++++++++++++++++++ lib/domain/writing_mistake.dart | 66 ++++++++++++++ lib/implementations/lang_tool_service.dart | 17 ++-- lib/languagetool_textfield.dart | 12 ++- pubspec.yaml | 2 +- 14 files changed, 456 insertions(+), 10 deletions(-) create mode 100644 lib/beans/category.dart create mode 100644 lib/beans/context.dart create mode 100644 lib/beans/language_tool_answer_raw.dart create mode 100644 lib/beans/match.dart create mode 100644 lib/beans/replacement.dart create mode 100644 lib/beans/rule.dart create mode 100644 lib/beans/type.dart create mode 100644 lib/beans/warnings.dart create mode 100644 lib/core/network/language_tool.dart create mode 100644 lib/domain/writing_mistake.dart diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 48a7e6f..dc96e20 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -176,6 +176,7 @@ files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); name = "Thin Binary"; outputPaths = ( diff --git a/lib/beans/category.dart b/lib/beans/category.dart new file mode 100644 index 0000000..327fc70 --- /dev/null +++ b/lib/beans/category.dart @@ -0,0 +1,26 @@ +/// Category of the rule. +class Category { + /// Id field. + String id; + + /// Name field. + String name; + + /// Constructor for [Category] + Category({ + required this.id, + required this.name, + }); + + /// Parse [Category] from json. + factory Category.fromJson(Map json) => Category( + id: json['id'] as String, + name: json['name'] as String, + ); + + /// Get json from [Category]. + Map toJson() => { + 'id': id, + 'name': name, + }; +} diff --git a/lib/beans/context.dart b/lib/beans/context.dart new file mode 100644 index 0000000..bac3984 --- /dev/null +++ b/lib/beans/context.dart @@ -0,0 +1,33 @@ +/// Context of the error, +/// i.e. the error and some text to the left and to the left. +class Context { + /// Text. + String text; + + /// Offset to the text. + int offset; + + /// Length of the sentence. + int length; + + /// + Context({ + required this.text, + required this.offset, + required this.length, + }); + + /// + factory Context.fromJson(Map json) => Context( + text: json['text'] as String, + offset: json['offset'] as int, + length: json['length'] as int, + ); + + /// + Map toJson() => { + 'text': text, + 'offset': offset, + 'length': length, + }; +} diff --git a/lib/beans/language_tool_answer_raw.dart b/lib/beans/language_tool_answer_raw.dart new file mode 100644 index 0000000..947f6b0 --- /dev/null +++ b/lib/beans/language_tool_answer_raw.dart @@ -0,0 +1,32 @@ +import 'package:languagetool_textfield/languagetool_textfield.dart'; + +/// +class LanguageToolAnswerRaw { + /// + List matches; + + /// + Warnings warnings; + + /// + LanguageToolAnswerRaw({ + required this.matches, + required this.warnings, + }); + + /// + factory LanguageToolAnswerRaw.fromJson(Map json) => + LanguageToolAnswerRaw( + matches: (json['matches'] as Iterable) + .map( + (e) => Match.fromJson(e as Map), + ) + .toList(), + warnings: Warnings.fromJson(json['warnings'] as Map), + ); + + /// + Map toJson() => { + 'matches': List.from(matches.map((x) => x.toJson())), + }; +} diff --git a/lib/beans/match.dart b/lib/beans/match.dart new file mode 100644 index 0000000..84899b2 --- /dev/null +++ b/lib/beans/match.dart @@ -0,0 +1,90 @@ +import 'package:languagetool_textfield/beans/context.dart'; +import 'package:languagetool_textfield/beans/replacement.dart'; +import 'package:languagetool_textfield/beans/rule.dart'; +import 'package:languagetool_textfield/beans/type.dart'; + +/// +class Match { + /// + String message; + + /// Shortened message (may be empty). + String shortMessage; + + /// List of possible replacements + List replacements; + + /// + int offset; + + /// + int length; + + /// + Context context; + + /// + String sentence; + + /// + Type type; + + /// + Rule rule; + + /// + bool ignoreForIncompleteSentence; + + /// + int contextForSureMatch; + + /// + Match({ + required this.message, + required this.shortMessage, + required this.replacements, + required this.offset, + required this.length, + required this.context, + required this.sentence, + required this.type, + required this.rule, + required this.ignoreForIncompleteSentence, + required this.contextForSureMatch, + }); + + /// + factory Match.fromJson(Map json) => Match( + message: json['message'] as String, + shortMessage: json['shortMessage'] as String, + replacements: (json['replacements'] as Iterable) + .map( + (e) => Replacement.fromJson(e as Map), + ) + .toList(), + offset: json['offset'] as int, + length: json['length'] as int, + context: Context.fromJson(json['context'] as Map), + sentence: json['sentence'] as String, + type: Type.fromJson(json['type'] as Map), + rule: Rule.fromJson(json['rule'] as Map), + ignoreForIncompleteSentence: + json['ignoreForIncompleteSentence'] as bool, + contextForSureMatch: json['contextForSureMatch'] as int, + ); + + /// + Map toJson() => { + 'message': message, + 'shortMessage': shortMessage, + 'replacements': List.from(replacements.map((x) => x.toJson())), + 'offset': offset, + 'length': length, + 'context': context.toJson(), + 'sentence': sentence, + 'type': type.toJson(), + 'rule': rule.toJson(), + 'ignoreForIncompleteSentence': ignoreForIncompleteSentence, + 'contextForSureMatch': contextForSureMatch, + }; +} diff --git a/lib/beans/replacement.dart b/lib/beans/replacement.dart new file mode 100644 index 0000000..9ec4b89 --- /dev/null +++ b/lib/beans/replacement.dart @@ -0,0 +1,20 @@ +/// Possible replacement. +class Replacement { + /// + String value; + + /// + Replacement({ + required this.value, + }); + + /// + factory Replacement.fromJson(Map json) => Replacement( + value: json['value'] as String, + ); + + /// + Map toJson() => { + 'value': value, + }; +} diff --git a/lib/beans/rule.dart b/lib/beans/rule.dart new file mode 100644 index 0000000..b5f23d3 --- /dev/null +++ b/lib/beans/rule.dart @@ -0,0 +1,46 @@ +import 'package:languagetool_textfield/beans/category.dart'; + +/// The rule description. +class Rule { + /// Id (i.e.UPPERCASE_SENTENCE_START). + String id; + + /// The description in the set language. + String description; + + /// The type of the error (spelling, typographical, etc). + String issueType; + + /// The category of the rule. + Category category; + + /// The subscription status of the rule. + bool isPremium; + + /// + Rule({ + required this.id, + required this.description, + required this.issueType, + required this.category, + required this.isPremium, + }); + + /// + factory Rule.fromJson(Map json) => Rule( + id: json['id'] as String, + description: json['description'] as String, + issueType: json['issueType'] as String, + category: Category.fromJson(json['category'] as Map), + isPremium: json['isPremium'] as bool, + ); + + /// + Map toJson() => { + 'id': id, + 'description': description, + 'issueType': issueType, + 'category': category.toJson(), + 'isPremium': isPremium, + }; +} diff --git a/lib/beans/type.dart b/lib/beans/type.dart new file mode 100644 index 0000000..c31ed1c --- /dev/null +++ b/lib/beans/type.dart @@ -0,0 +1,20 @@ +/// Type of the mistake. +class Type { + /// + String typeName; + + /// + Type({ + required this.typeName, + }); + + /// + factory Type.fromJson(Map json) => Type( + typeName: json['typeName'] as String, + ); + + /// + Map toJson() => { + 'typeName': typeName, + }; +} diff --git a/lib/beans/warnings.dart b/lib/beans/warnings.dart new file mode 100644 index 0000000..e69aea5 --- /dev/null +++ b/lib/beans/warnings.dart @@ -0,0 +1,20 @@ +/// Checks if the results are incomplete. +class Warnings { + /// + bool incompleteResults; + + /// + Warnings({ + required this.incompleteResults, + }); + + /// + factory Warnings.fromJson(Map json) => Warnings( + incompleteResults: json['incompleteResults'] as bool, + ); + + /// + Map toJson() => { + 'incompleteResults': incompleteResults, + }; +} diff --git a/lib/core/network/language_tool.dart b/lib/core/network/language_tool.dart new file mode 100644 index 0000000..96713af --- /dev/null +++ b/lib/core/network/language_tool.dart @@ -0,0 +1,81 @@ +import 'dart:convert'; + +import 'package:http/http.dart' as http; +import 'package:languagetool_textfield/beans/language_tool_answer_raw.dart'; +import 'package:languagetool_textfield/domain/writing_mistake.dart'; + +/// Class to interact with the LanguageTool API. +/// +/// Read more @ https://languagetool.org/http-api/swagger-ui/#/ +class LanguageTool { + /// Url of LanguageTool API. + static const _url = 'api.languagetoolplus.com'; + + /// Headers for request. + static const _headers = { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Accept': 'application/json', + }; + + /// A language code. + final String language; + + /// Constructor for [LanguageTool]. + LanguageTool({ + this.language = 'auto', + }); + + /// Checks the errors in text. + Future> check(String text) => http + .post( + Uri.https(_url, 'v2/check'), + headers: _headers, + body: _getBodyForCheckRequest(text), + ) + .then( + (value) { + final languageToolAnswer = LanguageToolAnswerRaw.fromJson( + json.decode(utf8.decode(value.bodyBytes)) as Map, + ); + + return _parseRawAnswer(languageToolAnswer); + }, + ).onError( + (error, stackTrace) => throw Exception(error), + ); + + /// Converts a [LanguageToolAnswerRaw] in a [WritingMistake]. + List _parseRawAnswer( + LanguageToolAnswerRaw languageToolAnswer, + ) { + final result = []; + for (final match in languageToolAnswer.matches) { + final replacements = []; + for (final item in match.replacements) { + replacements.add(item.value); + } + + result.add( + WritingMistake( + issueDescription: match.rule.description, + issueType: match.rule.issueType, + length: match.length, + offset: match.offset, + replacements: replacements, + message: match.message, + context: match.context, + shortMessage: match.shortMessage, + ), + ); + } + + return result; + } + + /// Get the body of the request. + String _getBodyForCheckRequest(String uncheckedText) { + final text = uncheckedText.replaceAll(' ', '%20'); + + return 'text=$text&language=$language&enabledOnly=false&level=default'; + } +} diff --git a/lib/domain/writing_mistake.dart b/lib/domain/writing_mistake.dart new file mode 100644 index 0000000..59119bb --- /dev/null +++ b/lib/domain/writing_mistake.dart @@ -0,0 +1,66 @@ +import 'package:languagetool_textfield/beans/context.dart'; + +/// Object that stores information about a single writing mistake. +class WritingMistake { + /// Position of the beginning of the mistake. + final int offset; + + /// Length of the mistake after the offset. + final int length; + + /// The type of mistake. + final String issueType; + + /// Description of the [issueType]. + final String issueDescription; + + /// A brief description of the mistake. + final String message; + + /// A list of suggestions for replacing the mistake. + /// + /// Sorted by probability. + final List replacements; + + /// An optional shorter version of 'message'. , + final String shortMessage; + + /// Context of the error, + /// i.e. the error and some text to the left and to the left. + final Context context; + + /// Object that stores information about a single writing mistake. + WritingMistake({ + required this.message, + required this.offset, + required this.length, + required this.issueType, + required this.issueDescription, + required this.replacements, + required this.shortMessage, + required this.context, + }); + + /// Copies the object with the specified values changed. + WritingMistake copyWith({ + required int offset, + required int length, + required String issueType, + required String issueDescription, + required String message, + required List replacements, + required String shortMessage, + required Context context, + }) { + return WritingMistake( + offset: offset, + length: length, + issueType: issueType, + issueDescription: issueDescription, + message: message, + replacements: replacements, + context: context, + shortMessage: shortMessage, + ); + } +} diff --git a/lib/implementations/lang_tool_service.dart b/lib/implementations/lang_tool_service.dart index 69e56c9..f30cbe5 100644 --- a/lib/implementations/lang_tool_service.dart +++ b/lib/implementations/lang_tool_service.dart @@ -1,7 +1,8 @@ -import 'package:language_tool/language_tool.dart'; import 'package:languagetool_textfield/core/enums/mistake_type.dart'; +import 'package:languagetool_textfield/core/network/language_tool.dart'; import 'package:languagetool_textfield/domain/language_check_service.dart'; import 'package:languagetool_textfield/domain/mistake.dart'; +import 'package:languagetool_textfield/domain/writing_mistake.dart'; import 'package:languagetool_textfield/utils/result.dart'; /// An implementation of language check service with language tool service. @@ -20,9 +21,10 @@ class LangToolService extends LanguageCheckService { .catchError(Result>.error); final mistakesWrapper = writingMistakesWrapper.map( - (mistakes) => mistakes - .map( - (m) => Mistake( + (mistakes) { + return mistakes.map( + (m) { + return Mistake( message: m.message, type: _stringToMistakeType( m.issueType, @@ -30,9 +32,10 @@ class LangToolService extends LanguageCheckService { offset: m.offset, length: m.length, replacements: m.replacements, - ), - ) - .toList(growable: false), + ); + }, + ).toList(growable: false); + }, ); return mistakesWrapper; diff --git a/lib/languagetool_textfield.dart b/lib/languagetool_textfield.dart index 46d764d..42aa1ab 100644 --- a/lib/languagetool_textfield.dart +++ b/lib/languagetool_textfield.dart @@ -1,11 +1,19 @@ library languagetool_textfield; -export 'package:language_tool/language_tool.dart'; - +export 'beans/category.dart'; +export 'beans/context.dart'; +export 'beans/language_tool_answer_raw.dart'; +export 'beans/match.dart'; +export 'beans/replacement.dart'; +export 'beans/rule.dart'; +export 'beans/type.dart'; +export 'beans/warnings.dart'; export 'core/controllers/colored_text_editing_controller.dart'; +export 'core/network/language_tool.dart'; export 'domain/highlight_style.dart'; export 'domain/language_check_service.dart'; export 'domain/mistake.dart'; +export 'domain/writing_mistake.dart'; export 'implementations/debounce_lang_tool_service.dart'; export 'implementations/lang_tool_service.dart'; export 'implementations/throttling_lang_tool_service.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index ce683b8..9c2412f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -9,7 +9,7 @@ environment: dependencies: flutter: sdk: flutter - language_tool: ^2.1.1 + http: 1.0.0 throttling: ^1.0.0 dev_dependencies: From 8077217a8f2c2cc22c1d9cc23756116c7e93061b Mon Sep 17 00:00:00 2001 From: Kateryna Kalinchenko Date: Thu, 8 Jun 2023 09:50:32 +0300 Subject: [PATCH 02/11] Added documentation --- lib/beans/category.dart | 2 +- lib/beans/context.dart | 8 +++---- ...answer_raw.dart => language_tool_raw.dart} | 23 ++++++++---------- lib/beans/match.dart | 24 +++++++++---------- lib/beans/replacement.dart | 8 +++---- lib/beans/rule.dart | 6 ++--- lib/beans/type.dart | 8 +++---- lib/beans/warnings.dart | 20 ---------------- lib/core/network/language_tool.dart | 8 +++---- lib/domain/writing_mistake.dart | 2 +- lib/languagetool_textfield.dart | 3 +-- 11 files changed, 44 insertions(+), 68 deletions(-) rename lib/beans/{language_tool_answer_raw.dart => language_tool_raw.dart} (50%) delete mode 100644 lib/beans/warnings.dart diff --git a/lib/beans/category.dart b/lib/beans/category.dart index 327fc70..5990608 100644 --- a/lib/beans/category.dart +++ b/lib/beans/category.dart @@ -6,7 +6,7 @@ class Category { /// Name field. String name; - /// Constructor for [Category] + /// Creates a new instance of the [Category] class. Category({ required this.id, required this.name, diff --git a/lib/beans/context.dart b/lib/beans/context.dart index bac3984..cb28f36 100644 --- a/lib/beans/context.dart +++ b/lib/beans/context.dart @@ -1,4 +1,4 @@ -/// Context of the error, +/// A data model class that stores context of the error, /// i.e. the error and some text to the left and to the left. class Context { /// Text. @@ -10,21 +10,21 @@ class Context { /// Length of the sentence. int length; - /// + /// Creates a new instance of the [Context] class. Context({ required this.text, required this.offset, required this.length, }); - /// + /// Parse [Context] from json. factory Context.fromJson(Map json) => Context( text: json['text'] as String, offset: json['offset'] as int, length: json['length'] as int, ); - /// + /// Get json from [Context]. Map toJson() => { 'text': text, 'offset': offset, diff --git a/lib/beans/language_tool_answer_raw.dart b/lib/beans/language_tool_raw.dart similarity index 50% rename from lib/beans/language_tool_answer_raw.dart rename to lib/beans/language_tool_raw.dart index 947f6b0..42578b9 100644 --- a/lib/beans/language_tool_answer_raw.dart +++ b/lib/beans/language_tool_raw.dart @@ -1,31 +1,28 @@ import 'package:languagetool_textfield/languagetool_textfield.dart'; +/// The raw bean that is returned from the API call. /// -class LanguageToolAnswerRaw { - /// +/// It's possible to add software, language and warning information. +class LanguageToolRaw { + /// The matched mistakes. List matches; - /// - Warnings warnings; - - /// - LanguageToolAnswerRaw({ + /// Creates a new instance of the [LanguageToolRaw] class. + LanguageToolRaw({ required this.matches, - required this.warnings, }); - /// - factory LanguageToolAnswerRaw.fromJson(Map json) => - LanguageToolAnswerRaw( + /// Parse [LanguageToolRaw] from json. + factory LanguageToolRaw.fromJson(Map json) => + LanguageToolRaw( matches: (json['matches'] as Iterable) .map( (e) => Match.fromJson(e as Map), ) .toList(), - warnings: Warnings.fromJson(json['warnings'] as Map), ); - /// + /// Get json from [LanguageToolRaw]. Map toJson() => { 'matches': List.from(matches.map((x) => x.toJson())), }; diff --git a/lib/beans/match.dart b/lib/beans/match.dart index 84899b2..70c8bc8 100644 --- a/lib/beans/match.dart +++ b/lib/beans/match.dart @@ -5,7 +5,7 @@ import 'package:languagetool_textfield/beans/type.dart'; /// class Match { - /// + /// The message about the error. String message; /// Shortened message (may be empty). @@ -14,31 +14,31 @@ class Match { /// List of possible replacements List replacements; - /// + /// Offset to the word. int offset; - /// + /// Length of the word. int length; - /// + /// Context of the mistake. Context context; - /// + /// The whole sentence. String sentence; - /// + /// The type of the mistake. Type type; - /// + /// The mistake's rule. Rule rule; - /// + /// Flag that indicates if the mistake is because sentence is incomplete. bool ignoreForIncompleteSentence; - /// + /// Context for sure match (i.e. -1, 0, 1, etc). int contextForSureMatch; - /// + /// Creates a new instance of the [Match] class. Match({ required this.message, required this.shortMessage, @@ -53,7 +53,7 @@ class Match { required this.contextForSureMatch, }); - /// + /// Parse [Match] from json. factory Match.fromJson(Map json) => Match( message: json['message'] as String, shortMessage: json['shortMessage'] as String, @@ -73,7 +73,7 @@ class Match { contextForSureMatch: json['contextForSureMatch'] as int, ); - /// + /// Get json from [Match]. Map toJson() => { 'message': message, 'shortMessage': shortMessage, diff --git a/lib/beans/replacement.dart b/lib/beans/replacement.dart index 9ec4b89..e919640 100644 --- a/lib/beans/replacement.dart +++ b/lib/beans/replacement.dart @@ -1,19 +1,19 @@ /// Possible replacement. class Replacement { - /// + /// The replacement word. String value; - /// + /// Creates a new instance of the [Replacement] class. Replacement({ required this.value, }); - /// + /// Parse [Replacement] from json. factory Replacement.fromJson(Map json) => Replacement( value: json['value'] as String, ); - /// + /// Get json from [Replacement]. Map toJson() => { 'value': value, }; diff --git a/lib/beans/rule.dart b/lib/beans/rule.dart index b5f23d3..5cd82a5 100644 --- a/lib/beans/rule.dart +++ b/lib/beans/rule.dart @@ -17,7 +17,7 @@ class Rule { /// The subscription status of the rule. bool isPremium; - /// + /// Creates a new instance of the [Rule] class. Rule({ required this.id, required this.description, @@ -26,7 +26,7 @@ class Rule { required this.isPremium, }); - /// + /// Parse [Rule] from json. factory Rule.fromJson(Map json) => Rule( id: json['id'] as String, description: json['description'] as String, @@ -35,7 +35,7 @@ class Rule { isPremium: json['isPremium'] as bool, ); - /// + /// Get json from [Rule]. Map toJson() => { 'id': id, 'description': description, diff --git a/lib/beans/type.dart b/lib/beans/type.dart index c31ed1c..53591db 100644 --- a/lib/beans/type.dart +++ b/lib/beans/type.dart @@ -1,19 +1,19 @@ /// Type of the mistake. class Type { - /// + /// Indicates the mistake type (i.e. UnknownWord). String typeName; - /// + /// Creates a new instance of the [Type] class. Type({ required this.typeName, }); - /// + /// Parse [Type] from json. factory Type.fromJson(Map json) => Type( typeName: json['typeName'] as String, ); - /// + /// Get json from [Type]. Map toJson() => { 'typeName': typeName, }; diff --git a/lib/beans/warnings.dart b/lib/beans/warnings.dart deleted file mode 100644 index e69aea5..0000000 --- a/lib/beans/warnings.dart +++ /dev/null @@ -1,20 +0,0 @@ -/// Checks if the results are incomplete. -class Warnings { - /// - bool incompleteResults; - - /// - Warnings({ - required this.incompleteResults, - }); - - /// - factory Warnings.fromJson(Map json) => Warnings( - incompleteResults: json['incompleteResults'] as bool, - ); - - /// - Map toJson() => { - 'incompleteResults': incompleteResults, - }; -} diff --git a/lib/core/network/language_tool.dart b/lib/core/network/language_tool.dart index 96713af..97bf461 100644 --- a/lib/core/network/language_tool.dart +++ b/lib/core/network/language_tool.dart @@ -1,7 +1,7 @@ import 'dart:convert'; import 'package:http/http.dart' as http; -import 'package:languagetool_textfield/beans/language_tool_answer_raw.dart'; +import 'package:languagetool_textfield/beans/language_tool_raw.dart'; import 'package:languagetool_textfield/domain/writing_mistake.dart'; /// Class to interact with the LanguageTool API. @@ -34,7 +34,7 @@ class LanguageTool { ) .then( (value) { - final languageToolAnswer = LanguageToolAnswerRaw.fromJson( + final languageToolAnswer = LanguageToolRaw.fromJson( json.decode(utf8.decode(value.bodyBytes)) as Map, ); @@ -44,9 +44,9 @@ class LanguageTool { (error, stackTrace) => throw Exception(error), ); - /// Converts a [LanguageToolAnswerRaw] in a [WritingMistake]. + /// Converts a [LanguageToolRaw] in a [WritingMistake]. List _parseRawAnswer( - LanguageToolAnswerRaw languageToolAnswer, + LanguageToolRaw languageToolAnswer, ) { final result = []; for (final match in languageToolAnswer.matches) { diff --git a/lib/domain/writing_mistake.dart b/lib/domain/writing_mistake.dart index 59119bb..606f2eb 100644 --- a/lib/domain/writing_mistake.dart +++ b/lib/domain/writing_mistake.dart @@ -29,7 +29,7 @@ class WritingMistake { /// i.e. the error and some text to the left and to the left. final Context context; - /// Object that stores information about a single writing mistake. + /// Constructor for [WritingMistake]. WritingMistake({ required this.message, required this.offset, diff --git a/lib/languagetool_textfield.dart b/lib/languagetool_textfield.dart index 42aa1ab..7edc2f6 100644 --- a/lib/languagetool_textfield.dart +++ b/lib/languagetool_textfield.dart @@ -2,12 +2,11 @@ library languagetool_textfield; export 'beans/category.dart'; export 'beans/context.dart'; -export 'beans/language_tool_answer_raw.dart'; +export 'beans/language_tool_raw.dart'; export 'beans/match.dart'; export 'beans/replacement.dart'; export 'beans/rule.dart'; export 'beans/type.dart'; -export 'beans/warnings.dart'; export 'core/controllers/colored_text_editing_controller.dart'; export 'core/network/language_tool.dart'; export 'domain/highlight_style.dart'; From 471d1a428b9e7d85204443e3580a8c9f915b468c Mon Sep 17 00:00:00 2001 From: Kateryna Kalinchenko Date: Thu, 8 Jun 2023 10:06:51 +0300 Subject: [PATCH 03/11] Code refactoring --- lib/beans/category.dart | 2 +- lib/beans/context.dart | 2 +- lib/beans/match.dart | 2 +- lib/beans/replacement.dart | 2 +- lib/beans/rule.dart | 2 +- lib/beans/type.dart | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/beans/category.dart b/lib/beans/category.dart index 5990608..843d15d 100644 --- a/lib/beans/category.dart +++ b/lib/beans/category.dart @@ -1,4 +1,4 @@ -/// Category of the rule. +/// Object that stores information about category of the rule. class Category { /// Id field. String id; diff --git a/lib/beans/context.dart b/lib/beans/context.dart index cb28f36..96ae245 100644 --- a/lib/beans/context.dart +++ b/lib/beans/context.dart @@ -1,4 +1,4 @@ -/// A data model class that stores context of the error, +/// A data model class that stores context of the error, /// i.e. the error and some text to the left and to the left. class Context { /// Text. diff --git a/lib/beans/match.dart b/lib/beans/match.dart index 70c8bc8..dfb4e69 100644 --- a/lib/beans/match.dart +++ b/lib/beans/match.dart @@ -3,7 +3,7 @@ import 'package:languagetool_textfield/beans/replacement.dart'; import 'package:languagetool_textfield/beans/rule.dart'; import 'package:languagetool_textfield/beans/type.dart'; -/// +/// Object that stores information about matched mistakes. class Match { /// The message about the error. String message; diff --git a/lib/beans/replacement.dart b/lib/beans/replacement.dart index e919640..b413c34 100644 --- a/lib/beans/replacement.dart +++ b/lib/beans/replacement.dart @@ -1,4 +1,4 @@ -/// Possible replacement. +/// Object that stores information about possible replacement. class Replacement { /// The replacement word. String value; diff --git a/lib/beans/rule.dart b/lib/beans/rule.dart index 5cd82a5..4d6cb5a 100644 --- a/lib/beans/rule.dart +++ b/lib/beans/rule.dart @@ -1,6 +1,6 @@ import 'package:languagetool_textfield/beans/category.dart'; -/// The rule description. +/// Object that stores information about the rule (description, type, etc). class Rule { /// Id (i.e.UPPERCASE_SENTENCE_START). String id; diff --git a/lib/beans/type.dart b/lib/beans/type.dart index 53591db..677a50f 100644 --- a/lib/beans/type.dart +++ b/lib/beans/type.dart @@ -1,4 +1,4 @@ -/// Type of the mistake. +/// Object that stores information about the type of the mistake. class Type { /// Indicates the mistake type (i.e. UnknownWord). String typeName; From 5fb2bcb490c9cc0681e598fe3e1bb49a0e85068b Mon Sep 17 00:00:00 2001 From: Kateryna Kalinchenko Date: Thu, 8 Jun 2023 12:54:59 +0300 Subject: [PATCH 04/11] Refactored language tool client --- example/lib/app.dart | 2 +- .../language_tool_client.dart} | 34 ++++++++----------- lib/implementations/lang_tool_service.dart | 4 +-- lib/languagetool_textfield.dart | 2 +- 4 files changed, 19 insertions(+), 23 deletions(-) rename lib/{core/network/language_tool.dart => client/language_tool_client.dart} (73%) diff --git a/example/lib/app.dart b/example/lib/app.dart index fa7dcba..ce85c71 100644 --- a/example/lib/app.dart +++ b/example/lib/app.dart @@ -12,7 +12,7 @@ class App extends StatefulWidget { class _AppState extends State { /// Initialize LanguageTool - static final LanguageTool _languageTool = LanguageTool(); + static final LanguageToolClient _languageTool = LanguageToolClient(); /// Initialize DebounceLangToolService static final DebounceLangToolService _debouncedLangService = diff --git a/lib/core/network/language_tool.dart b/lib/client/language_tool_client.dart similarity index 73% rename from lib/core/network/language_tool.dart rename to lib/client/language_tool_client.dart index 97bf461..455cb2c 100644 --- a/lib/core/network/language_tool.dart +++ b/lib/client/language_tool_client.dart @@ -7,7 +7,7 @@ import 'package:languagetool_textfield/domain/writing_mistake.dart'; /// Class to interact with the LanguageTool API. /// /// Read more @ https://languagetool.org/http-api/swagger-ui/#/ -class LanguageTool { +class LanguageToolClient { /// Url of LanguageTool API. static const _url = 'api.languagetoolplus.com'; @@ -20,29 +20,25 @@ class LanguageTool { /// A language code. final String language; - /// Constructor for [LanguageTool]. - LanguageTool({ + /// Constructor for [LanguageToolClient]. + LanguageToolClient({ this.language = 'auto', }); /// Checks the errors in text. - Future> check(String text) => http - .post( - Uri.https(_url, 'v2/check'), - headers: _headers, - body: _getBodyForCheckRequest(text), - ) - .then( - (value) { - final languageToolAnswer = LanguageToolRaw.fromJson( - json.decode(utf8.decode(value.bodyBytes)) as Map, - ); + Future> check(String text) async { + final result = await http.post( + Uri.https(_url, 'v2/check'), + headers: _headers, + body: _getBodyForCheckRequest(text), + ); - return _parseRawAnswer(languageToolAnswer); - }, - ).onError( - (error, stackTrace) => throw Exception(error), - ); + final languageToolAnswer = LanguageToolRaw.fromJson( + json.decode(utf8.decode(result.bodyBytes)) as Map, + ); + + return _parseRawAnswer(languageToolAnswer); + } /// Converts a [LanguageToolRaw] in a [WritingMistake]. List _parseRawAnswer( diff --git a/lib/implementations/lang_tool_service.dart b/lib/implementations/lang_tool_service.dart index f30cbe5..d7940b5 100644 --- a/lib/implementations/lang_tool_service.dart +++ b/lib/implementations/lang_tool_service.dart @@ -1,5 +1,5 @@ import 'package:languagetool_textfield/core/enums/mistake_type.dart'; -import 'package:languagetool_textfield/core/network/language_tool.dart'; +import 'package:languagetool_textfield/client/language_tool_client.dart'; import 'package:languagetool_textfield/domain/language_check_service.dart'; import 'package:languagetool_textfield/domain/mistake.dart'; import 'package:languagetool_textfield/domain/writing_mistake.dart'; @@ -8,7 +8,7 @@ import 'package:languagetool_textfield/utils/result.dart'; /// An implementation of language check service with language tool service. class LangToolService extends LanguageCheckService { /// An instance of this class that is used to interact with LanguageTool API. - final LanguageTool languageTool; + final LanguageToolClient languageTool; /// Creates a new instance of the [LangToolService]. const LangToolService(this.languageTool); diff --git a/lib/languagetool_textfield.dart b/lib/languagetool_textfield.dart index 7edc2f6..4cf59a0 100644 --- a/lib/languagetool_textfield.dart +++ b/lib/languagetool_textfield.dart @@ -7,8 +7,8 @@ export 'beans/match.dart'; export 'beans/replacement.dart'; export 'beans/rule.dart'; export 'beans/type.dart'; +export 'client/language_tool_client.dart'; export 'core/controllers/colored_text_editing_controller.dart'; -export 'core/network/language_tool.dart'; export 'domain/highlight_style.dart'; export 'domain/language_check_service.dart'; export 'domain/mistake.dart'; From d34febd7908dfeb75f837d910da4e45b09d86550 Mon Sep 17 00:00:00 2001 From: Kateryna Kalinchenko Date: Thu, 8 Jun 2023 12:56:55 +0300 Subject: [PATCH 05/11] Made all fields final --- lib/beans/category.dart | 4 ++-- lib/beans/context.dart | 6 +++--- lib/beans/language_tool_raw.dart | 2 +- lib/beans/match.dart | 22 +++++++++++----------- lib/beans/replacement.dart | 2 +- lib/beans/rule.dart | 10 +++++----- lib/beans/type.dart | 2 +- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/beans/category.dart b/lib/beans/category.dart index 843d15d..766d928 100644 --- a/lib/beans/category.dart +++ b/lib/beans/category.dart @@ -1,10 +1,10 @@ /// Object that stores information about category of the rule. class Category { /// Id field. - String id; + final String id; /// Name field. - String name; + final String name; /// Creates a new instance of the [Category] class. Category({ diff --git a/lib/beans/context.dart b/lib/beans/context.dart index 96ae245..4d2d467 100644 --- a/lib/beans/context.dart +++ b/lib/beans/context.dart @@ -2,13 +2,13 @@ /// i.e. the error and some text to the left and to the left. class Context { /// Text. - String text; + final String text; /// Offset to the text. - int offset; + final int offset; /// Length of the sentence. - int length; + final int length; /// Creates a new instance of the [Context] class. Context({ diff --git a/lib/beans/language_tool_raw.dart b/lib/beans/language_tool_raw.dart index 42578b9..203b796 100644 --- a/lib/beans/language_tool_raw.dart +++ b/lib/beans/language_tool_raw.dart @@ -5,7 +5,7 @@ import 'package:languagetool_textfield/languagetool_textfield.dart'; /// It's possible to add software, language and warning information. class LanguageToolRaw { /// The matched mistakes. - List matches; + final List matches; /// Creates a new instance of the [LanguageToolRaw] class. LanguageToolRaw({ diff --git a/lib/beans/match.dart b/lib/beans/match.dart index dfb4e69..0b86d77 100644 --- a/lib/beans/match.dart +++ b/lib/beans/match.dart @@ -6,37 +6,37 @@ import 'package:languagetool_textfield/beans/type.dart'; /// Object that stores information about matched mistakes. class Match { /// The message about the error. - String message; + final String message; /// Shortened message (may be empty). - String shortMessage; + final String shortMessage; /// List of possible replacements - List replacements; + final List replacements; /// Offset to the word. - int offset; + final int offset; /// Length of the word. - int length; + final int length; /// Context of the mistake. - Context context; + final Context context; /// The whole sentence. - String sentence; + final String sentence; /// The type of the mistake. - Type type; + final Type type; /// The mistake's rule. - Rule rule; + final Rule rule; /// Flag that indicates if the mistake is because sentence is incomplete. - bool ignoreForIncompleteSentence; + final bool ignoreForIncompleteSentence; /// Context for sure match (i.e. -1, 0, 1, etc). - int contextForSureMatch; + final int contextForSureMatch; /// Creates a new instance of the [Match] class. Match({ diff --git a/lib/beans/replacement.dart b/lib/beans/replacement.dart index b413c34..fb96b41 100644 --- a/lib/beans/replacement.dart +++ b/lib/beans/replacement.dart @@ -1,7 +1,7 @@ /// Object that stores information about possible replacement. class Replacement { /// The replacement word. - String value; + final String value; /// Creates a new instance of the [Replacement] class. Replacement({ diff --git a/lib/beans/rule.dart b/lib/beans/rule.dart index 4d6cb5a..16fc443 100644 --- a/lib/beans/rule.dart +++ b/lib/beans/rule.dart @@ -3,19 +3,19 @@ import 'package:languagetool_textfield/beans/category.dart'; /// Object that stores information about the rule (description, type, etc). class Rule { /// Id (i.e.UPPERCASE_SENTENCE_START). - String id; + final String id; /// The description in the set language. - String description; + final String description; /// The type of the error (spelling, typographical, etc). - String issueType; + final String issueType; /// The category of the rule. - Category category; + final Category category; /// The subscription status of the rule. - bool isPremium; + final bool isPremium; /// Creates a new instance of the [Rule] class. Rule({ diff --git a/lib/beans/type.dart b/lib/beans/type.dart index 677a50f..7a53745 100644 --- a/lib/beans/type.dart +++ b/lib/beans/type.dart @@ -1,7 +1,7 @@ /// Object that stores information about the type of the mistake. class Type { /// Indicates the mistake type (i.e. UnknownWord). - String typeName; + final String typeName; /// Creates a new instance of the [Type] class. Type({ From 667e1ae6f3ee903a1541d8ed019c1570fbfbcc0a Mon Sep 17 00:00:00 2001 From: Kateryna Kalinchenko Date: Thu, 8 Jun 2023 13:11:41 +0300 Subject: [PATCH 06/11] Code refactoring --- lib/beans/match.dart | 6 +++--- lib/beans/{type.dart => mistake_type.dart} | 12 ++++++------ lib/client/language_tool_client.dart | 22 +++++++--------------- lib/implementations/lang_tool_service.dart | 2 +- lib/languagetool_textfield.dart | 2 +- 5 files changed, 18 insertions(+), 26 deletions(-) rename lib/beans/{type.dart => mistake_type.dart} (56%) diff --git a/lib/beans/match.dart b/lib/beans/match.dart index 0b86d77..357ee86 100644 --- a/lib/beans/match.dart +++ b/lib/beans/match.dart @@ -1,7 +1,7 @@ import 'package:languagetool_textfield/beans/context.dart'; +import 'package:languagetool_textfield/beans/mistake_type.dart'; import 'package:languagetool_textfield/beans/replacement.dart'; import 'package:languagetool_textfield/beans/rule.dart'; -import 'package:languagetool_textfield/beans/type.dart'; /// Object that stores information about matched mistakes. class Match { @@ -27,7 +27,7 @@ class Match { final String sentence; /// The type of the mistake. - final Type type; + final MistakeType type; /// The mistake's rule. final Rule rule; @@ -66,7 +66,7 @@ class Match { length: json['length'] as int, context: Context.fromJson(json['context'] as Map), sentence: json['sentence'] as String, - type: Type.fromJson(json['type'] as Map), + type: MistakeType.fromJson(json['type'] as Map), rule: Rule.fromJson(json['rule'] as Map), ignoreForIncompleteSentence: json['ignoreForIncompleteSentence'] as bool, diff --git a/lib/beans/type.dart b/lib/beans/mistake_type.dart similarity index 56% rename from lib/beans/type.dart rename to lib/beans/mistake_type.dart index 7a53745..1d7c78f 100644 --- a/lib/beans/type.dart +++ b/lib/beans/mistake_type.dart @@ -1,19 +1,19 @@ /// Object that stores information about the type of the mistake. -class Type { +class MistakeType { /// Indicates the mistake type (i.e. UnknownWord). final String typeName; - /// Creates a new instance of the [Type] class. - Type({ + /// Creates a new instance of the [MistakeType] class. + MistakeType({ required this.typeName, }); - /// Parse [Type] from json. - factory Type.fromJson(Map json) => Type( + /// Parse [MistakeType] from json. + factory MistakeType.fromJson(Map json) => MistakeType( typeName: json['typeName'] as String, ); - /// Get json from [Type]. + /// Get json from [MistakeType]. Map toJson() => { 'typeName': typeName, }; diff --git a/lib/client/language_tool_client.dart b/lib/client/language_tool_client.dart index 455cb2c..c63ecd8 100644 --- a/lib/client/language_tool_client.dart +++ b/lib/client/language_tool_client.dart @@ -17,20 +17,19 @@ class LanguageToolClient { 'Accept': 'application/json', }; - /// A language code. - final String language; - /// Constructor for [LanguageToolClient]. - LanguageToolClient({ - this.language = 'auto', - }); + LanguageToolClient(); /// Checks the errors in text. - Future> check(String text) async { + Future> check( + String text, { + String language = 'auto', + }) async { final result = await http.post( Uri.https(_url, 'v2/check'), headers: _headers, - body: _getBodyForCheckRequest(text), + body: 'text=${text.replaceAll(' ', '%20')}&language=$language&' + 'enabledOnly=false&level=default', ); final languageToolAnswer = LanguageToolRaw.fromJson( @@ -67,11 +66,4 @@ class LanguageToolClient { return result; } - - /// Get the body of the request. - String _getBodyForCheckRequest(String uncheckedText) { - final text = uncheckedText.replaceAll(' ', '%20'); - - return 'text=$text&language=$language&enabledOnly=false&level=default'; - } } diff --git a/lib/implementations/lang_tool_service.dart b/lib/implementations/lang_tool_service.dart index d7940b5..edff5a6 100644 --- a/lib/implementations/lang_tool_service.dart +++ b/lib/implementations/lang_tool_service.dart @@ -1,5 +1,5 @@ -import 'package:languagetool_textfield/core/enums/mistake_type.dart'; import 'package:languagetool_textfield/client/language_tool_client.dart'; +import 'package:languagetool_textfield/core/enums/mistake_type.dart'; import 'package:languagetool_textfield/domain/language_check_service.dart'; import 'package:languagetool_textfield/domain/mistake.dart'; import 'package:languagetool_textfield/domain/writing_mistake.dart'; diff --git a/lib/languagetool_textfield.dart b/lib/languagetool_textfield.dart index 4cf59a0..f6273ca 100644 --- a/lib/languagetool_textfield.dart +++ b/lib/languagetool_textfield.dart @@ -4,9 +4,9 @@ export 'beans/category.dart'; export 'beans/context.dart'; export 'beans/language_tool_raw.dart'; export 'beans/match.dart'; +export 'beans/mistake_type.dart'; export 'beans/replacement.dart'; export 'beans/rule.dart'; -export 'beans/type.dart'; export 'client/language_tool_client.dart'; export 'core/controllers/colored_text_editing_controller.dart'; export 'domain/highlight_style.dart'; From 3af0bcbf7759cd94ce228576bf8148d77a0cdbe1 Mon Sep 17 00:00:00 2001 From: Kateryna Kalinchenko Date: Thu, 8 Jun 2023 14:39:28 +0300 Subject: [PATCH 07/11] Added enums and removed some repeating data classes --- lib/beans/language_tool_raw.dart | 5 ----- lib/beans/match.dart | 21 ------------------- lib/beans/mistake_type.dart | 20 ------------------ lib/beans/rule.dart | 14 +++---------- lib/core/enums/mistake_type.dart | 22 +++++++++++++++++++- lib/domain/writing_mistake.dart | 5 +++-- lib/implementations/lang_tool_service.dart | 24 +--------------------- lib/languagetool_textfield.dart | 1 - 8 files changed, 28 insertions(+), 84 deletions(-) delete mode 100644 lib/beans/mistake_type.dart diff --git a/lib/beans/language_tool_raw.dart b/lib/beans/language_tool_raw.dart index 203b796..250ea44 100644 --- a/lib/beans/language_tool_raw.dart +++ b/lib/beans/language_tool_raw.dart @@ -21,9 +21,4 @@ class LanguageToolRaw { ) .toList(), ); - - /// Get json from [LanguageToolRaw]. - Map toJson() => { - 'matches': List.from(matches.map((x) => x.toJson())), - }; } diff --git a/lib/beans/match.dart b/lib/beans/match.dart index 357ee86..4c8bfc2 100644 --- a/lib/beans/match.dart +++ b/lib/beans/match.dart @@ -1,5 +1,4 @@ import 'package:languagetool_textfield/beans/context.dart'; -import 'package:languagetool_textfield/beans/mistake_type.dart'; import 'package:languagetool_textfield/beans/replacement.dart'; import 'package:languagetool_textfield/beans/rule.dart'; @@ -26,9 +25,6 @@ class Match { /// The whole sentence. final String sentence; - /// The type of the mistake. - final MistakeType type; - /// The mistake's rule. final Rule rule; @@ -47,7 +43,6 @@ class Match { required this.length, required this.context, required this.sentence, - required this.type, required this.rule, required this.ignoreForIncompleteSentence, required this.contextForSureMatch, @@ -66,25 +61,9 @@ class Match { length: json['length'] as int, context: Context.fromJson(json['context'] as Map), sentence: json['sentence'] as String, - type: MistakeType.fromJson(json['type'] as Map), rule: Rule.fromJson(json['rule'] as Map), ignoreForIncompleteSentence: json['ignoreForIncompleteSentence'] as bool, contextForSureMatch: json['contextForSureMatch'] as int, ); - - /// Get json from [Match]. - Map toJson() => { - 'message': message, - 'shortMessage': shortMessage, - 'replacements': List.from(replacements.map((x) => x.toJson())), - 'offset': offset, - 'length': length, - 'context': context.toJson(), - 'sentence': sentence, - 'type': type.toJson(), - 'rule': rule.toJson(), - 'ignoreForIncompleteSentence': ignoreForIncompleteSentence, - 'contextForSureMatch': contextForSureMatch, - }; } diff --git a/lib/beans/mistake_type.dart b/lib/beans/mistake_type.dart deleted file mode 100644 index 1d7c78f..0000000 --- a/lib/beans/mistake_type.dart +++ /dev/null @@ -1,20 +0,0 @@ -/// Object that stores information about the type of the mistake. -class MistakeType { - /// Indicates the mistake type (i.e. UnknownWord). - final String typeName; - - /// Creates a new instance of the [MistakeType] class. - MistakeType({ - required this.typeName, - }); - - /// Parse [MistakeType] from json. - factory MistakeType.fromJson(Map json) => MistakeType( - typeName: json['typeName'] as String, - ); - - /// Get json from [MistakeType]. - Map toJson() => { - 'typeName': typeName, - }; -} diff --git a/lib/beans/rule.dart b/lib/beans/rule.dart index 16fc443..980205c 100644 --- a/lib/beans/rule.dart +++ b/lib/beans/rule.dart @@ -1,4 +1,5 @@ import 'package:languagetool_textfield/beans/category.dart'; +import 'package:languagetool_textfield/core/enums/mistake_type.dart'; /// Object that stores information about the rule (description, type, etc). class Rule { @@ -9,7 +10,7 @@ class Rule { final String description; /// The type of the error (spelling, typographical, etc). - final String issueType; + final MistakeType issueType; /// The category of the rule. final Category category; @@ -30,17 +31,8 @@ class Rule { factory Rule.fromJson(Map json) => Rule( id: json['id'] as String, description: json['description'] as String, - issueType: json['issueType'] as String, + issueType: MistakeType.fromString(json['issueType'] as String), category: Category.fromJson(json['category'] as Map), isPremium: json['isPremium'] as bool, ); - - /// Get json from [Rule]. - Map toJson() => { - 'id': id, - 'description': description, - 'issueType': issueType, - 'category': category.toJson(), - 'isPremium': isPremium, - }; } diff --git a/lib/core/enums/mistake_type.dart b/lib/core/enums/mistake_type.dart index 513304c..d721ccc 100644 --- a/lib/core/enums/mistake_type.dart +++ b/lib/core/enums/mistake_type.dart @@ -19,5 +19,25 @@ enum MistakeType { style, /// Any other mistake type - other, + other; + + /// Getting the [MistakeType] from String. + static MistakeType fromString(String value) { + switch (value.toLowerCase()) { + case 'misspelling': + return MistakeType.misspelling; + case 'typographical': + return MistakeType.typographical; + case 'grammar': + return MistakeType.grammar; + case 'uncategorized': + return MistakeType.uncategorized; + case 'non-conformance': + return MistakeType.nonConformance; + case 'style': + return MistakeType.style; + default: + return MistakeType.other; + } + } } diff --git a/lib/domain/writing_mistake.dart b/lib/domain/writing_mistake.dart index 606f2eb..c603646 100644 --- a/lib/domain/writing_mistake.dart +++ b/lib/domain/writing_mistake.dart @@ -1,4 +1,5 @@ import 'package:languagetool_textfield/beans/context.dart'; +import 'package:languagetool_textfield/core/enums/mistake_type.dart'; /// Object that stores information about a single writing mistake. class WritingMistake { @@ -9,7 +10,7 @@ class WritingMistake { final int length; /// The type of mistake. - final String issueType; + final MistakeType issueType; /// Description of the [issueType]. final String issueDescription; @@ -45,7 +46,7 @@ class WritingMistake { WritingMistake copyWith({ required int offset, required int length, - required String issueType, + required MistakeType issueType, required String issueDescription, required String message, required List replacements, diff --git a/lib/implementations/lang_tool_service.dart b/lib/implementations/lang_tool_service.dart index edff5a6..a64e3e8 100644 --- a/lib/implementations/lang_tool_service.dart +++ b/lib/implementations/lang_tool_service.dart @@ -1,5 +1,4 @@ import 'package:languagetool_textfield/client/language_tool_client.dart'; -import 'package:languagetool_textfield/core/enums/mistake_type.dart'; import 'package:languagetool_textfield/domain/language_check_service.dart'; import 'package:languagetool_textfield/domain/mistake.dart'; import 'package:languagetool_textfield/domain/writing_mistake.dart'; @@ -26,9 +25,7 @@ class LangToolService extends LanguageCheckService { (m) { return Mistake( message: m.message, - type: _stringToMistakeType( - m.issueType, - ), + type: m.issueType, offset: m.offset, length: m.length, replacements: m.replacements, @@ -40,23 +37,4 @@ class LangToolService extends LanguageCheckService { return mistakesWrapper; } - - MistakeType _stringToMistakeType(String issueType) { - switch (issueType.toLowerCase()) { - case 'misspelling': - return MistakeType.misspelling; - case 'typographical': - return MistakeType.typographical; - case 'grammar': - return MistakeType.grammar; - case 'uncategorized': - return MistakeType.uncategorized; - case 'non-conformance': - return MistakeType.nonConformance; - case 'style': - return MistakeType.style; - default: - return MistakeType.other; - } - } } diff --git a/lib/languagetool_textfield.dart b/lib/languagetool_textfield.dart index f6273ca..0220502 100644 --- a/lib/languagetool_textfield.dart +++ b/lib/languagetool_textfield.dart @@ -4,7 +4,6 @@ export 'beans/category.dart'; export 'beans/context.dart'; export 'beans/language_tool_raw.dart'; export 'beans/match.dart'; -export 'beans/mistake_type.dart'; export 'beans/replacement.dart'; export 'beans/rule.dart'; export 'client/language_tool_client.dart'; From da36e5859209982418f2f93227e038f8b0f50618 Mon Sep 17 00:00:00 2001 From: Kateryna Kalinchenko Date: Thu, 8 Jun 2023 14:41:33 +0300 Subject: [PATCH 08/11] Code refactoring --- example/lib/app.dart | 2 +- lib/beans/category.dart | 6 ------ lib/beans/context.dart | 7 ------- lib/beans/replacement.dart | 5 ----- 4 files changed, 1 insertion(+), 19 deletions(-) diff --git a/example/lib/app.dart b/example/lib/app.dart index ce85c71..4478732 100644 --- a/example/lib/app.dart +++ b/example/lib/app.dart @@ -11,7 +11,7 @@ class App extends StatefulWidget { } class _AppState extends State { - /// Initialize LanguageTool + /// Initialize LanguageToolClient static final LanguageToolClient _languageTool = LanguageToolClient(); /// Initialize DebounceLangToolService diff --git a/lib/beans/category.dart b/lib/beans/category.dart index 766d928..fcacac0 100644 --- a/lib/beans/category.dart +++ b/lib/beans/category.dart @@ -17,10 +17,4 @@ class Category { id: json['id'] as String, name: json['name'] as String, ); - - /// Get json from [Category]. - Map toJson() => { - 'id': id, - 'name': name, - }; } diff --git a/lib/beans/context.dart b/lib/beans/context.dart index 4d2d467..e98a143 100644 --- a/lib/beans/context.dart +++ b/lib/beans/context.dart @@ -23,11 +23,4 @@ class Context { offset: json['offset'] as int, length: json['length'] as int, ); - - /// Get json from [Context]. - Map toJson() => { - 'text': text, - 'offset': offset, - 'length': length, - }; } diff --git a/lib/beans/replacement.dart b/lib/beans/replacement.dart index fb96b41..b734ab8 100644 --- a/lib/beans/replacement.dart +++ b/lib/beans/replacement.dart @@ -12,9 +12,4 @@ class Replacement { factory Replacement.fromJson(Map json) => Replacement( value: json['value'] as String, ); - - /// Get json from [Replacement]. - Map toJson() => { - 'value': value, - }; } From fe9c997fa86e1fa15909253cffc26807c942f834 Mon Sep 17 00:00:00 2001 From: solid-danylokhvan Date: Tue, 27 Jun 2023 20:17:22 +0300 Subject: [PATCH 09/11] Refactor after review --- lib/beans/match.dart | 7 +++--- .../{context.dart => mistake_context.dart} | 10 ++++----- lib/client/language_tool_client.dart | 14 ++++++++---- lib/core/enums/mistake_type.dart | 22 +++++-------------- lib/domain/writing_mistake.dart | 6 ++--- lib/languagetool_textfield.dart | 2 +- 6 files changed, 29 insertions(+), 32 deletions(-) rename lib/beans/{context.dart => mistake_context.dart} (67%) diff --git a/lib/beans/match.dart b/lib/beans/match.dart index 4c8bfc2..3af9f53 100644 --- a/lib/beans/match.dart +++ b/lib/beans/match.dart @@ -1,4 +1,4 @@ -import 'package:languagetool_textfield/beans/context.dart'; +import 'package:languagetool_textfield/beans/mistake_context.dart'; import 'package:languagetool_textfield/beans/replacement.dart'; import 'package:languagetool_textfield/beans/rule.dart'; @@ -20,7 +20,7 @@ class Match { final int length; /// Context of the mistake. - final Context context; + final MistakeContext context; /// The whole sentence. final String sentence; @@ -59,7 +59,8 @@ class Match { .toList(), offset: json['offset'] as int, length: json['length'] as int, - context: Context.fromJson(json['context'] as Map), + context: + MistakeContext.fromJson(json['context'] as Map), sentence: json['sentence'] as String, rule: Rule.fromJson(json['rule'] as Map), ignoreForIncompleteSentence: diff --git a/lib/beans/context.dart b/lib/beans/mistake_context.dart similarity index 67% rename from lib/beans/context.dart rename to lib/beans/mistake_context.dart index e98a143..894a984 100644 --- a/lib/beans/context.dart +++ b/lib/beans/mistake_context.dart @@ -1,6 +1,6 @@ /// A data model class that stores context of the error, /// i.e. the error and some text to the left and to the left. -class Context { +class MistakeContext { /// Text. final String text; @@ -10,15 +10,15 @@ class Context { /// Length of the sentence. final int length; - /// Creates a new instance of the [Context] class. - Context({ + /// Creates a new instance of the [MistakeContext] class. + MistakeContext({ required this.text, required this.offset, required this.length, }); - /// Parse [Context] from json. - factory Context.fromJson(Map json) => Context( + /// Parse [MistakeContext] from json. + factory MistakeContext.fromJson(Map json) => MistakeContext( text: json['text'] as String, offset: json['offset'] as int, length: json['length'] as int, diff --git a/lib/client/language_tool_client.dart b/lib/client/language_tool_client.dart index c63ecd8..3987442 100644 --- a/lib/client/language_tool_client.dart +++ b/lib/client/language_tool_client.dart @@ -25,15 +25,21 @@ class LanguageToolClient { String text, { String language = 'auto', }) async { + final encodedText = Uri.encodeQueryComponent(text); + final encodedLanguage = Uri.encodeQueryComponent(language); + final result = await http.post( - Uri.https(_url, 'v2/check'), + Uri.https(_url, 'v2/check', { + 'text': encodedText, + 'language': encodedLanguage, + 'enabledOnly': 'false', + 'level': 'default', + }), headers: _headers, - body: 'text=${text.replaceAll(' ', '%20')}&language=$language&' - 'enabledOnly=false&level=default', ); final languageToolAnswer = LanguageToolRaw.fromJson( - json.decode(utf8.decode(result.bodyBytes)) as Map, + json.decode(result.body) as Map, ); return _parseRawAnswer(languageToolAnswer); diff --git a/lib/core/enums/mistake_type.dart b/lib/core/enums/mistake_type.dart index d721ccc..26db860 100644 --- a/lib/core/enums/mistake_type.dart +++ b/lib/core/enums/mistake_type.dart @@ -23,21 +23,11 @@ enum MistakeType { /// Getting the [MistakeType] from String. static MistakeType fromString(String value) { - switch (value.toLowerCase()) { - case 'misspelling': - return MistakeType.misspelling; - case 'typographical': - return MistakeType.typographical; - case 'grammar': - return MistakeType.grammar; - case 'uncategorized': - return MistakeType.uncategorized; - case 'non-conformance': - return MistakeType.nonConformance; - case 'style': - return MistakeType.style; - default: - return MistakeType.other; - } + final lowercasedValue = value.toLowerCase(); + + return MistakeType.values.firstWhere( + (type) => type.toString().split('.').last == lowercasedValue, + orElse: () => MistakeType.other, + ); } } diff --git a/lib/domain/writing_mistake.dart b/lib/domain/writing_mistake.dart index c603646..0b27d49 100644 --- a/lib/domain/writing_mistake.dart +++ b/lib/domain/writing_mistake.dart @@ -1,4 +1,4 @@ -import 'package:languagetool_textfield/beans/context.dart'; +import 'package:languagetool_textfield/beans/mistake_context.dart'; import 'package:languagetool_textfield/core/enums/mistake_type.dart'; /// Object that stores information about a single writing mistake. @@ -28,7 +28,7 @@ class WritingMistake { /// Context of the error, /// i.e. the error and some text to the left and to the left. - final Context context; + final MistakeContext context; /// Constructor for [WritingMistake]. WritingMistake({ @@ -51,7 +51,7 @@ class WritingMistake { required String message, required List replacements, required String shortMessage, - required Context context, + required MistakeContext context, }) { return WritingMistake( offset: offset, diff --git a/lib/languagetool_textfield.dart b/lib/languagetool_textfield.dart index 0220502..69b5b6f 100644 --- a/lib/languagetool_textfield.dart +++ b/lib/languagetool_textfield.dart @@ -1,7 +1,7 @@ library languagetool_textfield; export 'beans/category.dart'; -export 'beans/context.dart'; +export 'beans/mistake_context.dart'; export 'beans/language_tool_raw.dart'; export 'beans/match.dart'; export 'beans/replacement.dart'; From 3424f6503ecbd1b39fbb38a05fb4477ba76b82de Mon Sep 17 00:00:00 2001 From: solid-danylokhvan Date: Tue, 4 Jul 2023 16:46:35 +0300 Subject: [PATCH 10/11] Refactor after review --- lib/beans/mistake_context.dart | 26 ------------------- lib/client/language_tool_client.dart | 3 +-- lib/core/enums/mistake_type.dart | 21 +++++++++------ lib/{beans => core/model}/category.dart | 0 .../model}/language_tool_raw.dart | 0 lib/{beans => core/model}/match.dart | 11 ++------ lib/{beans => core/model}/replacement.dart | 0 lib/{beans => core/model}/rule.dart | 2 +- lib/domain/writing_mistake.dart | 8 ------ lib/languagetool_textfield.dart | 11 ++++---- 10 files changed, 22 insertions(+), 60 deletions(-) delete mode 100644 lib/beans/mistake_context.dart rename lib/{beans => core/model}/category.dart (100%) rename lib/{beans => core/model}/language_tool_raw.dart (100%) rename lib/{beans => core/model}/match.dart (82%) rename lib/{beans => core/model}/replacement.dart (100%) rename lib/{beans => core/model}/rule.dart (94%) diff --git a/lib/beans/mistake_context.dart b/lib/beans/mistake_context.dart deleted file mode 100644 index 894a984..0000000 --- a/lib/beans/mistake_context.dart +++ /dev/null @@ -1,26 +0,0 @@ -/// A data model class that stores context of the error, -/// i.e. the error and some text to the left and to the left. -class MistakeContext { - /// Text. - final String text; - - /// Offset to the text. - final int offset; - - /// Length of the sentence. - final int length; - - /// Creates a new instance of the [MistakeContext] class. - MistakeContext({ - required this.text, - required this.offset, - required this.length, - }); - - /// Parse [MistakeContext] from json. - factory MistakeContext.fromJson(Map json) => MistakeContext( - text: json['text'] as String, - offset: json['offset'] as int, - length: json['length'] as int, - ); -} diff --git a/lib/client/language_tool_client.dart b/lib/client/language_tool_client.dart index 3987442..d2f3797 100644 --- a/lib/client/language_tool_client.dart +++ b/lib/client/language_tool_client.dart @@ -1,7 +1,7 @@ import 'dart:convert'; import 'package:http/http.dart' as http; -import 'package:languagetool_textfield/beans/language_tool_raw.dart'; +import 'package:languagetool_textfield/core/model/language_tool_raw.dart'; import 'package:languagetool_textfield/domain/writing_mistake.dart'; /// Class to interact with the LanguageTool API. @@ -64,7 +64,6 @@ class LanguageToolClient { offset: match.offset, replacements: replacements, message: match.message, - context: match.context, shortMessage: match.shortMessage, ), ); diff --git a/lib/core/enums/mistake_type.dart b/lib/core/enums/mistake_type.dart index 26db860..e5f1de1 100644 --- a/lib/core/enums/mistake_type.dart +++ b/lib/core/enums/mistake_type.dart @@ -1,32 +1,37 @@ ///Enumerate several mistake types enum MistakeType { /// Misspelling mistake type - misspelling, + misspelling('misspelling'), /// Typographical mistake type - typographical, + typographical('typographical'), /// Grammar mistake type - grammar, + grammar('grammar'), /// Uncategorized mistake type - uncategorized, + uncategorized('uncategorized'), /// NonConformance mistake type - nonConformance, + nonConformance('nonconformance'), /// Style mistake type - style, + style('style'), /// Any other mistake type - other; + other('other'); + + /// The string value associated with the MistakeType variant + final String value; + + const MistakeType(this.value); /// Getting the [MistakeType] from String. static MistakeType fromString(String value) { final lowercasedValue = value.toLowerCase(); return MistakeType.values.firstWhere( - (type) => type.toString().split('.').last == lowercasedValue, + (type) => type.value == lowercasedValue, orElse: () => MistakeType.other, ); } diff --git a/lib/beans/category.dart b/lib/core/model/category.dart similarity index 100% rename from lib/beans/category.dart rename to lib/core/model/category.dart diff --git a/lib/beans/language_tool_raw.dart b/lib/core/model/language_tool_raw.dart similarity index 100% rename from lib/beans/language_tool_raw.dart rename to lib/core/model/language_tool_raw.dart diff --git a/lib/beans/match.dart b/lib/core/model/match.dart similarity index 82% rename from lib/beans/match.dart rename to lib/core/model/match.dart index 3af9f53..5af21bf 100644 --- a/lib/beans/match.dart +++ b/lib/core/model/match.dart @@ -1,6 +1,5 @@ -import 'package:languagetool_textfield/beans/mistake_context.dart'; -import 'package:languagetool_textfield/beans/replacement.dart'; -import 'package:languagetool_textfield/beans/rule.dart'; +import 'package:languagetool_textfield/core/model/replacement.dart'; +import 'package:languagetool_textfield/core/model/rule.dart'; /// Object that stores information about matched mistakes. class Match { @@ -19,9 +18,6 @@ class Match { /// Length of the word. final int length; - /// Context of the mistake. - final MistakeContext context; - /// The whole sentence. final String sentence; @@ -41,7 +37,6 @@ class Match { required this.replacements, required this.offset, required this.length, - required this.context, required this.sentence, required this.rule, required this.ignoreForIncompleteSentence, @@ -59,8 +54,6 @@ class Match { .toList(), offset: json['offset'] as int, length: json['length'] as int, - context: - MistakeContext.fromJson(json['context'] as Map), sentence: json['sentence'] as String, rule: Rule.fromJson(json['rule'] as Map), ignoreForIncompleteSentence: diff --git a/lib/beans/replacement.dart b/lib/core/model/replacement.dart similarity index 100% rename from lib/beans/replacement.dart rename to lib/core/model/replacement.dart diff --git a/lib/beans/rule.dart b/lib/core/model/rule.dart similarity index 94% rename from lib/beans/rule.dart rename to lib/core/model/rule.dart index 980205c..7a4bdd5 100644 --- a/lib/beans/rule.dart +++ b/lib/core/model/rule.dart @@ -1,5 +1,5 @@ -import 'package:languagetool_textfield/beans/category.dart'; import 'package:languagetool_textfield/core/enums/mistake_type.dart'; +import 'package:languagetool_textfield/core/model/category.dart'; /// Object that stores information about the rule (description, type, etc). class Rule { diff --git a/lib/domain/writing_mistake.dart b/lib/domain/writing_mistake.dart index 0b27d49..abee140 100644 --- a/lib/domain/writing_mistake.dart +++ b/lib/domain/writing_mistake.dart @@ -1,4 +1,3 @@ -import 'package:languagetool_textfield/beans/mistake_context.dart'; import 'package:languagetool_textfield/core/enums/mistake_type.dart'; /// Object that stores information about a single writing mistake. @@ -26,10 +25,6 @@ class WritingMistake { /// An optional shorter version of 'message'. , final String shortMessage; - /// Context of the error, - /// i.e. the error and some text to the left and to the left. - final MistakeContext context; - /// Constructor for [WritingMistake]. WritingMistake({ required this.message, @@ -39,7 +34,6 @@ class WritingMistake { required this.issueDescription, required this.replacements, required this.shortMessage, - required this.context, }); /// Copies the object with the specified values changed. @@ -51,7 +45,6 @@ class WritingMistake { required String message, required List replacements, required String shortMessage, - required MistakeContext context, }) { return WritingMistake( offset: offset, @@ -60,7 +53,6 @@ class WritingMistake { issueDescription: issueDescription, message: message, replacements: replacements, - context: context, shortMessage: shortMessage, ); } diff --git a/lib/languagetool_textfield.dart b/lib/languagetool_textfield.dart index 69b5b6f..c95bb13 100644 --- a/lib/languagetool_textfield.dart +++ b/lib/languagetool_textfield.dart @@ -1,13 +1,12 @@ library languagetool_textfield; -export 'beans/category.dart'; -export 'beans/mistake_context.dart'; -export 'beans/language_tool_raw.dart'; -export 'beans/match.dart'; -export 'beans/replacement.dart'; -export 'beans/rule.dart'; export 'client/language_tool_client.dart'; export 'core/controllers/colored_text_editing_controller.dart'; +export 'core/model/category.dart'; +export 'core/model/language_tool_raw.dart'; +export 'core/model/match.dart'; +export 'core/model/replacement.dart'; +export 'core/model/rule.dart'; export 'domain/highlight_style.dart'; export 'domain/language_check_service.dart'; export 'domain/mistake.dart'; From dc134c41accf8cb5aaeb5b8d05651a1acc4470f2 Mon Sep 17 00:00:00 2001 From: solid-danylokhvan Date: Tue, 4 Jul 2023 20:40:00 +0300 Subject: [PATCH 11/11] rm unnecessary copyWith --- lib/domain/writing_mistake.dart | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/lib/domain/writing_mistake.dart b/lib/domain/writing_mistake.dart index abee140..fd55829 100644 --- a/lib/domain/writing_mistake.dart +++ b/lib/domain/writing_mistake.dart @@ -35,25 +35,4 @@ class WritingMistake { required this.replacements, required this.shortMessage, }); - - /// Copies the object with the specified values changed. - WritingMistake copyWith({ - required int offset, - required int length, - required MistakeType issueType, - required String issueDescription, - required String message, - required List replacements, - required String shortMessage, - }) { - return WritingMistake( - offset: offset, - length: length, - issueType: issueType, - issueDescription: issueDescription, - message: message, - replacements: replacements, - shortMessage: shortMessage, - ); - } }