Skip to content

chore!: move spell checker to example #2145

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Aug 24, 2024
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
62 changes: 5 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ You can join our [Slack Group] for discussion.
- [🛠️ Using the embed blocks from `flutter_quill_extensions`](#️-using-the-embed-blocks-from-flutter_quill_extensions)
- [🔗 Links](#-links-2)
- [🔄 Conversion to HTML](#-conversion-to-html)
- [📝 Spelling checker](#-Spelling-checker)
- [📝 Spelling checker](#-spelling-checker)
- [🌐 Translation](#-translation)
- [🧪 Testing](#-testing)
- [👥 Contributors](#-contributors)
Expand Down Expand Up @@ -208,7 +208,7 @@ _controller.document = Document.fromJson(json);

## ⚙️ Configurations

The `QuillToolbar` and `QuillEditor` widgets let you customize a lot of things
The `QuillSimpleToolbar` and `QuillEditor` widgets are both customizable.
[Sample Page] provides sample code for advanced usage and configuration.

### 🔗 Links
Expand Down Expand Up @@ -285,63 +285,11 @@ The following packages can be used:

## 📝 Spelling checker

A spell checker is a software tool or feature integrated into various text processing applications that automatically identifies and corrects spelling errors in a written document. It works by comparing the words in the text against a built-in dictionary. If a word isn't found in the dictionary or doesn't match any known word patterns, the spell checker highlights it as a potential error.
While spell-checking is not a feature that's implemented into the project, it can be used using external dependencies.

#### Benefits of a spell checker include:
It's implemented using the package `simple_spell_checker` in the [Example](./example/).

* Improved Accuracy: It helps writers avoid common spelling mistakes, ensuring that the text is free of errors.
* Time-Saving: Automatically detecting errors reduces the time needed for manual proofreading.
* Enhanced Professionalism: Correctly spelled words contribute to the overall professionalism of documents, which is crucial in academic, business, and formal writing.
* Multilingual Support: Many spell checkers support multiple languages, making it easier for users to write accurately in different languages.

> [!IMPORTANT]
> The spell checker usually does not work as expected in most cases. **Many translations are not supported** such as: `Chinese`, `Japanese`, `Korean`, `Hebrew`, `Arabic`, `Russian`, etc. For now it is a purely **experimental** feature that may have **code that will be modified** in future versions.

#### The translations supported so far are:

* **German** - `de` (may contain errors or missing words)
* **English** - `en` (currently adding missing translations)
* **Spanish** - `es` (currently adding missing translations)
* **French** - `fr` (may contain errors or missing words)
* **Italian** - `it` (currently adding missing translations)
* **Norwegian** - `no` (may contain errors or missing words)
* **Portuguese** - `pt` (may contain errors or missing words)
* **Swedish** - `sv` (may contain errors or missing words)

_**Note**: If you have knowledge about any of these available languages or the unsupported ones, you can make a pull request to add support or add words that are not currently in [simple_spell_checker](https://github.com/CatHood0/simple_spell_checker)_.

In order to activate this functionality you can use the following code:

```dart
// you can use the language of your preference or directly select the language of the operating system
final language = 'en'; // or Localizations.localeOf(context).languageCode
FlutterQuillExtensions.useSpellCheckerService(language);
```

When you no longer need to have the Spell checker activated you can simply use `dispose()` of the `SpellCheckerServiceProvider` class:

```dart
// dispose all service and it cannot be used after this
SpellCheckerServiceProvider.dispose();
```

If what we want is to **close the StreamControllers** without deleting the values that are already stored in it, we can set `onlyPartial` to `true`.

```dart
// it can be still used by the editor
SpellCheckerServiceProvider.dispose(onlyPartial: true);
```

One use of this would be having the opportunity to **activate and deactivate** the service when we want, we can see this in the example that we have in this package, in which you can see that on each screen, we have a button that dynamically activates and deactivates the service. To do this is pretty simple:

```dart
SpellCheckerServiceProvider.toggleState();
// use isServiceActive to get the state of the service
SpellCheckerServiceProvider.isServiceActive();
setState(() {});
```

Open this [page](https://pub.dev/packages/simple_spell_checker) for more information.
Take a look at [Spelling Checker](./doc/spell_checker.md) page for more info.

## 🌐 Translation

Expand Down
79 changes: 79 additions & 0 deletions doc/spell_checker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# 📝 Spelling checker

A spell checker is a software tool or feature integrated into various text processing applications that automatically identifies and corrects spelling errors in a written document. It works by comparing the words in the text against a built-in dictionary. If a word isn't found in the dictionary or doesn't match any known word patterns, the spell checker highlights it as a potential error.

While spell-checking is not a feature that's implemented into the project, it can be used using external dependencies.

It's implemented using the package `simple_spell_checker` in the [Example](../example/).

> [!NOTE]
> [`simple_spell_checker`](https://pub.dev/packages/simple_spell_checker) is a client-side dependency that works without an internet connection, so, it could weigh more than expected due to each of the dictionaries. As mentioned below, it supports a very wide variety of languages which can have a file of up to 300.000 words (this being just one language).

### Benefits of a spell checker include:

* Improved Accuracy: It helps writers avoid common spelling mistakes, ensuring that the text is free of errors.
* Time-Saving: Automatically detecting errors reduces the time needed for manual proofreading.
* Enhanced Professionalism: Correctly spelled words contribute to the overall professionalism of documents, which is crucial in academic, business, and formal writing.
* Multilingual Support: Many spell checkers support multiple languages, making it easier for users to write accurately in different languages.

> [!IMPORTANT]
> The spell checker usually does not work as expected in most cases. For now it is a purely **experimental** feature that may have **code that will be modified** in future versions.

### The translations supported so far are:

* German - `de`, `de-ch`
* English - `en`, `en-gb`
* Spanish - `es`
* Catalan - `ca`
* Arabic - `ar`
* Danish - `da`
* French - `fr`
* Bulgarian - `bg`
* Dutch - `nl`
* Korean - `ko`
* Estonian - `et`
* Hebrew - `he`
* Slovak - `sk`
* Italian - `it`
* Norwegian - `no`
* Portuguese - `pt`
* Swedish - `sv`
* Russian - `ru`

_**Note**: If you have knowledge about any of these available languages or the unsupported ones, you can make a pull request to add support or add words that are not currently in [simple_spell_checker](https://github.com/CatHood0/simple_spell_checker)_.

In order to activate this functionality you can use the following code:

```dart
// you can use the language of your preference or directly select the language of the operating system
final language = 'en'; // or Localizations.localeOf(context).languageCode
SpellChecker.useSpellCheckerService(language);
```

> [!NOTE]
> The class `SpellChecker` is not available as part of the project API. Instead, you will have to implement it manually. Take a look at the example [Spell Checker](../example/lib/spell_checker/spell_checker.dart) class.

When you no longer need to have the Spell checker activated you can simply use `dispose()` of the `SpellCheckerServiceProvider` class:

```dart
// dispose all service and it cannot be used after this
SpellCheckerServiceProvider.dispose();
```

If what we want is to **close the StreamControllers** without deleting the values that are already stored in it, we can set `onlyPartial` to `true`.

```dart
// it can be still used by the editor
SpellCheckerServiceProvider.dispose(onlyPartial: true);
```

One use of this would be having the opportunity to **activate and deactivate** the service when we want, we can see this in the example that we have in this package, in which you can see that on each screen, we have a button that dynamically activates and deactivates the service. To do this is pretty simple:

```dart
SpellCheckerServiceProvider.toggleState();
// use isServiceActive to get the state of the service
SpellCheckerServiceProvider.isServiceActive();
setState(() {});
```

Open this [page](https://pub.dev/packages/simple_spell_checker) for more information.
11 changes: 4 additions & 7 deletions example/lib/screens/quill/quill_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,15 @@ import 'dart:convert' show jsonEncode;
import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart';
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'
show
FlutterQuillEmbeds,
FlutterQuillExtensions,
QuillSharedExtensionsConfigurations;
show FlutterQuillEmbeds, QuillSharedExtensionsConfigurations;
import 'package:share_plus/share_plus.dart' show Share;

import '../../extensions/scaffold_messenger.dart';
import '../../spell_checker/spell_checker.dart';
import '../shared/widgets/home_screen_button.dart';
import 'my_quill_editor.dart';
import 'my_quill_toolbar.dart';

var _isSpellcheckerActive = false;

@immutable
class QuillScreenArgs {
const QuillScreenArgs({required this.document});
Expand Down Expand Up @@ -43,6 +39,7 @@ class _QuillScreenState extends State<QuillScreen> {
final _editorFocusNode = FocusNode();
final _editorScrollController = ScrollController();
var _isReadOnly = false;
var _isSpellcheckerActive = false;

@override
void initState() {
Expand All @@ -63,7 +60,7 @@ class _QuillScreenState extends State<QuillScreen> {
_controller.readOnly = _isReadOnly;
if (!_isSpellcheckerActive) {
_isSpellcheckerActive = true;
FlutterQuillExtensions.useSpellCheckerService(
SpellChecker.useSpellCheckerService(
Localizations.localeOf(context).languageCode);
}
return Scaffold(
Expand Down
65 changes: 65 additions & 0 deletions example/lib/spell_checker/simple_spell_checker_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart';
import 'package:simple_spell_checker/simple_spell_checker.dart';

/// SimpleSpellChecker is a simple spell checker for get
/// all words divide on different objects if them are wrong or not
class SimpleSpellCheckerService
extends SpellCheckerService<LanguageIdentifier> {
SimpleSpellCheckerService({required super.language})
: checker = SimpleSpellChecker(
language: language,
safeDictionaryLoad: true,
);

/// [SimpleSpellChecker] comes from the package [simple_spell_checker]
/// that give us all necessary methods for get our spans with highlighting
/// where needed
final SimpleSpellChecker checker;

@override
List<TextSpan>? checkSpelling(
String text, {
LongPressGestureRecognizer Function(String word)?
customLongPressRecognizerOnWrongSpan,
}) {
return checker.check(
text,
customLongPressRecognizerOnWrongSpan:
customLongPressRecognizerOnWrongSpan,
);
}

@override
void toggleChecker() => checker.toggleChecker();

@override
bool isServiceActive() => checker.isCheckerActive();

@override
void dispose({bool onlyPartial = false}) {
if (onlyPartial) {
checker.disposeControllers();
return;
}
checker.dispose();
}

@override
void addCustomLanguage({required languageIdentifier}) {
checker
..registerLanguage(languageIdentifier.language)
..addCustomLanguage(languageIdentifier);
}

@override
void setNewLanguageState({required String language}) {
checker.setNewLanguageToState(language);
}

@override
void updateCustomLanguageIfExist({required languageIdentifier}) {
checker.updateCustomLanguageIfExist(languageIdentifier);
}
}
27 changes: 27 additions & 0 deletions example/lib/spell_checker/spell_checker.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'package:flutter_quill/flutter_quill.dart';

import 'simple_spell_checker_service.dart';

class SpellChecker {
SpellChecker._();

/// override the default implementation of [SpellCheckerServiceProvider]
/// to allow a `flutter quill` support a better check spelling
///
/// # !WARNING
/// To avoid memory leaks, ensure to use [dispose()] method to
/// close stream controllers that used by this custom implementation
/// when them no longer needed
///
/// Example:
///
///```dart
///// set partial true if you only need to close the controllers
///SpellCheckerServiceProvider.dispose(onlyPartial: false);
///```
static void useSpellCheckerService(String language) {
SpellCheckerServiceProvider.setNewCheckerService(
SimpleSpellCheckerService(language: language),
);
}
}
1 change: 1 addition & 0 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ dependencies:
equatable: ^2.0.5
cross_file: ^0.3.4
cached_network_image: ^3.3.1
simple_spell_checker: ^1.2.1

# Bloc libraries
bloc: ^8.1.4
Expand Down
31 changes: 12 additions & 19 deletions flutter_quill_extensions/lib/flutter_quill_extensions.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
library flutter_quill_extensions;

// ignore: implementation_imports
import 'package:flutter_quill/src/editor/spellchecker/spellchecker_service_provider.dart';
// ignore: implementation_imports
import 'package:flutter_quill/src/editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart';
import 'package:meta/meta.dart' show immutable;

import 'src/editor/spell_checker/simple_spell_checker_service.dart';
import 'src/editor_toolbar_controller_shared/clipboard/super_clipboard_service.dart';

export 'src/common/extensions/controller_ext.dart';
Expand All @@ -16,6 +13,7 @@ export 'src/editor/image/image_embed_types.dart';
export 'src/editor/image/image_web_embed.dart';
export 'src/editor/image/models/image_configurations.dart';
export 'src/editor/image/models/image_web_configurations.dart';
// TODO: Remove Simple Spell Checker Service
export 'src/editor/spell_checker/simple_spell_checker_service.dart';
export 'src/editor/table/table_cell_embed.dart';
export 'src/editor/table/table_embed.dart';
Expand Down Expand Up @@ -43,23 +41,18 @@ export 'src/toolbar/video/video_button.dart';
class FlutterQuillExtensions {
const FlutterQuillExtensions._();

/// override the default implementation of [SpellCheckerServiceProvider]
/// to allow a `flutter quill` support a better check spelling
///
/// # !WARNING
/// To avoid memory leaks, ensure to use [dispose()] method to
/// close stream controllers that used by this custom implementation
/// when them no longer needed
///
/// Example:
///
///```dart
///// set partial true if you only need to close the controllers
///SpellCheckerServiceProvider.dispose(onlyPartial: false);
///```
@Deprecated(
'''
Spell checker feature has been removed from the package to make it optional and
reduce bundle size. See issue https://github.com/singerdmx/flutter-quill/issues/2142
for more details.

Calling this function will no longer activate the feature.
''',
)
static void useSpellCheckerService(String language) {
SpellCheckerServiceProvider.setNewCheckerService(
SimpleSpellCheckerService(language: language));
// This feature has been removed from the package.
// See https://github.com/singerdmx/flutter-quill/issues/2142
}

/// Override default implementation of [ClipboardServiceProvider.instance]
Expand Down
Loading