|
| 1 | +import 'package:device_info_plus/device_info_plus.dart'; |
| 2 | +import 'package:flutter/material.dart'; |
| 3 | +import 'package:flutter/services.dart'; |
| 4 | + |
| 5 | +/// Copies [data] to the clipboard and shows a popup on success. |
| 6 | +/// |
| 7 | +/// Must have a [Scaffold] ancestor. |
| 8 | +/// |
| 9 | +/// On newer Android the popup is defined and shown by the platform. On older |
| 10 | +/// Android and on iOS, shows a [Snackbar] with [successContent]. |
| 11 | +/// |
| 12 | +/// In English, the text in [successContent] should be short, should start with |
| 13 | +/// a capital letter, and should have no ending punctuation: "{noun} copied". |
| 14 | +void copyWithPopup({ |
| 15 | + required BuildContext context, |
| 16 | + required ClipboardData data, |
| 17 | + required Widget successContent, |
| 18 | +}) async { |
| 19 | + await Clipboard.setData(data); |
| 20 | + final deviceInfo = await DeviceInfoPlugin().deviceInfo; |
| 21 | + |
| 22 | + // Early return on !mounted would be better, but: |
| 23 | + // https://github.com/dart-lang/linter/issues/4007 |
| 24 | + if (context.mounted) { |
| 25 | + final bool shouldShowSnackbar; |
| 26 | + switch (deviceInfo) { |
| 27 | + case AndroidDeviceInfo(:var version): |
| 28 | + // Android 13+ shows its own popup on copying to the clipboard, |
| 29 | + // so we suppress ours, following the advice at: |
| 30 | + // https://developer.android.com/develop/ui/views/touch-and-input/copy-paste#duplicate-notifications |
| 31 | + // TODO(android-sdk-33): Simplify this and dartdoc |
| 32 | + shouldShowSnackbar = version.sdkInt <= 32; |
| 33 | + default: |
| 34 | + shouldShowSnackbar = true; |
| 35 | + } |
| 36 | + |
| 37 | + if (shouldShowSnackbar) { |
| 38 | + ScaffoldMessenger.of(context).showSnackBar( |
| 39 | + SnackBar(behavior: SnackBarBehavior.floating, content: successContent)); |
| 40 | + } |
| 41 | + } |
| 42 | +} |
0 commit comments