Skip to content

Commit

Permalink
Add enable suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
Amir-P committed Jun 9, 2024
1 parent 178d2bb commit c75abff
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 32 deletions.
28 changes: 28 additions & 0 deletions packages/fleather/lib/src/widgets/editor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,15 @@ class FleatherEditor extends StatefulWidget {
/// Defaults to `true`.
final bool autocorrect;

/// Whether to show input suggestions as the user types.
///
/// This flag only affects Android. On iOS, suggestions are tied directly to
/// [autocorrect], so that suggestions are only shown when [autocorrect] is
/// true. On Android autocorrection and suggestion are controlled separately.
///
/// Defaults to true.
final bool enableSuggestions;

/// Whether to enable user interface affordances for changing the
/// text selection.
///
Expand Down Expand Up @@ -289,6 +298,7 @@ class FleatherEditor extends StatefulWidget {
this.showCursor = true,
this.readOnly = false,
this.autocorrect = true,
this.enableSuggestions = true,
this.enableInteractiveSelection = true,
this.minHeight,
this.maxHeight,
Expand Down Expand Up @@ -460,6 +470,7 @@ class _FleatherEditorState extends State<FleatherEditor>
autocorrect: widget.autocorrect,
showCursor: widget.showCursor,
readOnly: widget.readOnly,
enableSuggestions: widget.enableSuggestions,
enableInteractiveSelection: widget.enableInteractiveSelection,
minHeight: widget.minHeight,
maxHeight: widget.maxHeight,
Expand Down Expand Up @@ -559,6 +570,7 @@ class RawEditor extends StatefulWidget {
bool? showCursor,
this.readOnly = false,
this.autocorrect = true,
this.enableSuggestions = true,
this.enableInteractiveSelection = true,
this.minHeight,
this.maxHeight,
Expand Down Expand Up @@ -615,6 +627,15 @@ class RawEditor extends StatefulWidget {
/// Defaults to `true`.
final bool autocorrect;

/// Whether to show input suggestions as the user types.
///
/// This flag only affects Android. On iOS, suggestions are tied directly to
/// [autocorrect], so that suggestions are only shown when [autocorrect] is
/// true. On Android autocorrection and suggestion are controlled separately.
///
/// Defaults to true.
final bool enableSuggestions;

/// Callback which is triggered when the user wants to open a URL from
/// a link in the document.
final ValueChanged<String?>? onLaunchUrl;
Expand Down Expand Up @@ -1405,6 +1426,13 @@ class RawEditorState extends EditorState
} else {
if (oldWidget.readOnly && _hasFocus) {
openConnectionIfNeeded();
} else if (oldWidget.autocorrect != widget.autocorrect ||
oldWidget.enableSuggestions != widget.enableSuggestions ||
oldWidget.keyboardAppearance != widget.keyboardAppearance ||
oldWidget.textCapitalization != widget.textCapitalization ||
oldWidget.enableInteractiveSelection !=
widget.enableInteractiveSelection) {
updateConnectionConfig();
}
}
}
Expand Down
33 changes: 20 additions & 13 deletions packages/fleather/lib/src/widgets/editor_input_client_mixin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,26 +51,33 @@ mixin RawEditorStateTextInputClientMixin on EditorState

if (!hasConnection) {
_lastKnownRemoteTextEditingValue = textEditingValue;
_textInputConnection = TextInput.attach(
this,
TextInputConfiguration(
inputType: TextInputType.multiline,
readOnly: widget.readOnly,
obscureText: false,
autocorrect: widget.autocorrect,
enableDeltaModel: true,
inputAction: TextInputAction.newline,
keyboardAppearance: widget.keyboardAppearance,
textCapitalization: widget.textCapitalization,
),
);
_textInputConnection = TextInput.attach(this, _configuration);

_updateSizeAndTransform();
_textInputConnection!.setEditingState(_lastKnownRemoteTextEditingValue!);
}
_textInputConnection!.show();
}

void updateConnectionConfig() {
if (hasConnection) {
_textInputConnection!.updateConfig(_configuration);
}
}

TextInputConfiguration get _configuration => TextInputConfiguration(
inputType: TextInputType.multiline,
readOnly: widget.readOnly,
obscureText: false,
enableDeltaModel: true,
autocorrect: widget.autocorrect,
enableSuggestions: widget.enableSuggestions,
inputAction: TextInputAction.newline,
enableInteractiveSelection: widget.enableInteractiveSelection,
keyboardAppearance: widget.keyboardAppearance,
textCapitalization: widget.textCapitalization,
);

/// Closes input connection if it's currently open. Otherwise does nothing.
void closeConnectionIfNeeded() {
if (hasConnection) {
Expand Down
11 changes: 11 additions & 0 deletions packages/fleather/lib/src/widgets/field.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ class FleatherField extends StatefulWidget {
/// Defaults to `true`.
final bool autocorrect;

/// Whether to show input suggestions as the user types.
///
/// This flag only affects Android. On iOS, suggestions are tied directly to
/// [autocorrect], so that suggestions are only shown when [autocorrect] is
/// true. On Android autocorrection and suggestion are controlled separately.
///
/// Defaults to true.
final bool enableSuggestions;

/// Whether to enable user interface affordances for changing the
/// text selection.
///
Expand Down Expand Up @@ -181,6 +190,7 @@ class FleatherField extends StatefulWidget {
this.showCursor = true,
this.readOnly = false,
this.autocorrect = true,
this.enableSuggestions = true,
this.enableInteractiveSelection = true,
this.minHeight,
this.maxHeight,
Expand Down Expand Up @@ -252,6 +262,7 @@ class _FleatherFieldState extends State<FleatherField> {
showCursor: widget.showCursor,
readOnly: widget.readOnly,
autocorrect: widget.autocorrect,
enableSuggestions: widget.enableSuggestions,
enableInteractiveSelection: widget.enableInteractiveSelection,
minHeight: widget.minHeight,
maxHeight: widget.maxHeight,
Expand Down
60 changes: 41 additions & 19 deletions packages/fleather/test/widgets/editor_input_client_mixin_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -299,28 +299,50 @@ void main() {
});
});

group('send editor options to TextInputConnection', () {
testWidgets('send autocorrect option', (tester) async {
Map<String, dynamic>? textInputClientProperties;
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(
SystemChannels.textInput, (MethodCall methodCall) async {
if (methodCall.method == 'TextInput.setClient') {
textInputClientProperties = methodCall.arguments[1];
}
return null;
});
testWidgets('send editor options to TextInputConnection', (tester) async {
Map<String, dynamic>? textInputSetClientProperties;
Map<String, dynamic>? textInputUpdateConfigProperties;
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(
SystemChannels.textInput, (MethodCall methodCall) async {
if (methodCall.method == 'TextInput.setClient') {
textInputSetClientProperties = methodCall.arguments[1];
} else if (methodCall.method == 'TextInput.updateConfig') {
textInputUpdateConfigProperties = methodCall.arguments;
}
return null;
});

final editor =
EditorSandBox(tester: tester, document: ParchmentDocument());
await editor.pump();
await editor.tap();
final controller = FleatherController();
Future<void> pumpEditor(bool enable) async {
final editor = MaterialApp(
home: FleatherField(
controller: controller,
enableSuggestions: enable,
autocorrect: enable,
));
await tester.pumpWidget(editor);
await tester.tapAt(tester.getCenter(find.byType(RawEditor)));
tester.binding.scheduleWarmUpFrame();
await tester.pumpAndSettle();
}

expect(
textInputClientProperties?['autocorrect'],
true,
);
});
await pumpEditor(true);
expect(textInputSetClientProperties?['autocorrect'], true);
expect(textInputSetClientProperties?['enableSuggestions'], true);
expect(textInputUpdateConfigProperties, isNull);

await tester.pumpWidget(const SizedBox());
await tester.pumpAndSettle();

await pumpEditor(false);
expect(textInputSetClientProperties?['autocorrect'], false);
expect(textInputSetClientProperties?['enableSuggestions'], false);
expect(textInputUpdateConfigProperties, isNull);

textInputSetClientProperties = null;
await pumpEditor(true);
expect(textInputUpdateConfigProperties?['autocorrect'], true);
expect(textInputUpdateConfigProperties?['enableSuggestions'], true);
expect(textInputSetClientProperties, isNull);
});
}

0 comments on commit c75abff

Please sign in to comment.