Unverified Commit bef97630 authored by Bruno Leroux's avatar Bruno Leroux Committed by GitHub

Add Share button to the SelectableRegion toolbar on Android (#141447)

## Description

This PR adds the share button to text selection toolbar buttons on Android ~~and iOS~~ for `SelectableRegion` (and therefore `SelectionArea`).

https://github.com/flutter/flutter/pull/139479 adds this button for `EditableText` (which is used by `TextField` and `SelectableText` but not by `SelectionArea`).

**Edit**: supporting this on iOS will need more work (see https://github.com/flutter/flutter/pull/141447#issuecomment-1889942622 and https://github.com/flutter/flutter/issues/141775).

## Related Issue

Follow up for https://github.com/flutter/flutter/issues/138728

## Tests

Adds 1 test.
parent 63018fe6
......@@ -152,6 +152,7 @@ class CupertinoAdaptiveTextSelectionToolbar extends StatelessWidget {
selectionGeometry: selectionGeometry,
onCopy: onCopy,
onSelectAll: onSelectAll,
onShare: null, // See https://github.com/flutter/flutter/issues/141775.
);
/// {@macro flutter.material.AdaptiveTextSelectionToolbar.anchors}
......
......@@ -150,6 +150,7 @@ class AdaptiveTextSelectionToolbar extends StatelessWidget {
super.key,
required VoidCallback onCopy,
required VoidCallback onSelectAll,
required VoidCallback? onShare,
required SelectionGeometry selectionGeometry,
required this.anchors,
}) : children = null,
......@@ -157,6 +158,7 @@ class AdaptiveTextSelectionToolbar extends StatelessWidget {
selectionGeometry: selectionGeometry,
onCopy: onCopy,
onSelectAll: onSelectAll,
onShare: onShare,
);
/// Create an instance of [AdaptiveTextSelectionToolbar] with the default
......
......@@ -267,9 +267,29 @@ class SelectableRegion extends StatefulWidget {
required final SelectionGeometry selectionGeometry,
required final VoidCallback onCopy,
required final VoidCallback onSelectAll,
required final VoidCallback? onShare,
}) {
final bool canCopy = selectionGeometry.status == SelectionStatus.uncollapsed;
final bool canSelectAll = selectionGeometry.hasContent;
final bool platformCanShare = switch (defaultTargetPlatform) {
TargetPlatform.android
=> selectionGeometry.status == SelectionStatus.uncollapsed,
TargetPlatform.macOS
|| TargetPlatform.fuchsia
|| TargetPlatform.linux
|| TargetPlatform.windows
=> false,
// TODO(bleroux): the share button should be shown on iOS but the share
// functionality requires some changes on the engine side because, on iPad,
// it needs an anchor for the popup.
// See: https://github.com/flutter/flutter/issues/141775.
TargetPlatform.iOS
=> false,
};
final bool canShare = onShare != null && platformCanShare;
// On Android, the share button is before the select all button.
final bool showShareBeforeSelectAll = defaultTargetPlatform == TargetPlatform.android;
// Determine which buttons will appear so that the order and total number is
// known. A button's position in the menu can slightly affect its
......@@ -280,11 +300,21 @@ class SelectableRegion extends StatefulWidget {
onPressed: onCopy,
type: ContextMenuButtonType.copy,
),
if (canShare && showShareBeforeSelectAll)
ContextMenuButtonItem(
onPressed: onShare,
type: ContextMenuButtonType.share,
),
if (canSelectAll)
ContextMenuButtonItem(
onPressed: onSelectAll,
type: ContextMenuButtonType.selectAll,
),
if (canShare && !showShareBeforeSelectAll)
ContextMenuButtonItem(
onPressed: onShare,
type: ContextMenuButtonType.share,
),
];
}
......@@ -1089,6 +1119,14 @@ class SelectableRegionState extends State<SelectableRegion> with TextSelectionDe
await Clipboard.setData(ClipboardData(text: data.plainText));
}
Future<void> _share() async {
final SelectedContent? data = _selectable?.getSelectedContent();
if (data == null) {
return;
}
await SystemChannels.platform.invokeMethod('Share.invoke', data.plainText);
}
/// {@macro flutter.widgets.EditableText.getAnchors}
///
/// See also:
......@@ -1191,7 +1229,7 @@ class SelectableRegionState extends State<SelectableRegion> with TextSelectionDe
onCopy: () {
_copy();
// In Android copy should clear the selection.
// On Android copy should clear the selection.
switch (defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
......@@ -1217,6 +1255,22 @@ class SelectableRegionState extends State<SelectableRegion> with TextSelectionDe
hideToolbar();
}
},
onShare: () {
_share();
// On Android, share should clear the selection.
switch (defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
_clearSelection();
case TargetPlatform.iOS:
hideToolbar(false);
case TargetPlatform.linux:
case TargetPlatform.macOS:
case TargetPlatform.windows:
hideToolbar();
}
},
)..addAll(_textProcessingActionButtonItems);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment