blob: b823f3f9fbb8f825b7b650d3d3727b40ec721ef8 [file] [log] [blame] [edit]
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'system_channels.dart';
/// A data structure describing text processing actions.
@immutable
class ProcessTextAction {
/// Creates text processing actions based on those returned by the engine.
const ProcessTextAction(this.id, this.label);
/// The action unique id.
final String id;
/// The action localized label.
final String label;
@override
bool operator ==(Object other) {
if (identical(this, other)) {
return true;
}
return other is ProcessTextAction &&
other.id == id &&
other.label == label;
}
@override
int get hashCode => Object.hash(id, label);
}
/// Determines how to interact with the text processing feature.
abstract class ProcessTextService {
/// Returns a [Future] that resolves to a [List] of [ProcessTextAction]s
/// containing all text processing actions available.
///
/// If there are no actions available, an empty list will be returned.
Future<List<ProcessTextAction>> queryTextActions();
/// Returns a [Future] that resolves to a [String] when the text action
/// returns a transformed text or null when the text action did not return
/// a transformed text.
///
/// The `id` parameter is the text action unique identifier returned by
/// [queryTextActions].
///
/// The `text` parameter is the text to be processed.
///
/// The `readOnly` parameter indicates that the transformed text, if it exists,
/// will be used as read-only.
Future<String?> processTextAction(String id, String text, bool readOnly);
}
/// The service used by default for the text processing feature.
///
/// Any widget may use this service to get a list of text processing actions
/// and send requests to activate these text actions.
///
/// This is currently only supported by Android.
///
/// See also:
///
/// * [ProcessTextService], the service that this implements.
class DefaultProcessTextService implements ProcessTextService {
/// Creates the default service to interact with the platform text processing
/// feature via communication over the text processing [MethodChannel].
DefaultProcessTextService() {
_processTextChannel = SystemChannels.processText;
}
/// The channel used to communicate with the engine side.
late MethodChannel _processTextChannel;
/// Set the [MethodChannel] used to communicate with the engine text processing
/// feature.
///
/// This is only meant for testing within the Flutter SDK.
@visibleForTesting
void setChannel(MethodChannel newChannel) {
assert(() {
_processTextChannel = newChannel;
return true;
}());
}
@override
Future<List<ProcessTextAction>> queryTextActions() async {
final List<ProcessTextAction> textActions = <ProcessTextAction>[];
final Map<Object?, Object?>? rawResults;
try {
rawResults = await _processTextChannel.invokeMethod(
'ProcessText.queryTextActions',
) as Map<Object?, Object?>;
} catch (e) {
return textActions;
}
for (final Object? id in rawResults.keys) {
textActions.add(ProcessTextAction(id! as String, rawResults[id]! as String));
}
return textActions;
}
@override
/// On Android, the readOnly parameter might be used by the targeted activity, see:
/// https://developer.android.com/reference/android/content/Intent#EXTRA_PROCESS_TEXT_READONLY.
Future<String?> processTextAction(String id, String text, bool readOnly) async {
final String? processedText = await _processTextChannel.invokeMethod(
'ProcessText.processTextAction',
<dynamic>[id, text, readOnly],
) as String?;
return processedText;
}
}