diff --git a/packages/devtools_app/lib/src/extensions/embedded/view.dart b/packages/devtools_app/lib/src/extensions/embedded/view.dart index 51d64fe419c..e919785db87 100644 --- a/packages/devtools_app/lib/src/extensions/embedded/view.dart +++ b/packages/devtools_app/lib/src/extensions/embedded/view.dart @@ -8,7 +8,6 @@ import 'package:flutter/material.dart'; import '../../shared/analytics/analytics.dart' as ga; import '../../shared/analytics/constants.dart' as gac; import '../../shared/globals.dart'; -import '../../shared/utils.dart'; import '_view_desktop.dart' if (dart.library.js_interop) '_view_web.dart'; import 'controller.dart'; diff --git a/packages/devtools_app/lib/src/extensions/extension_screen.dart b/packages/devtools_app/lib/src/extensions/extension_screen.dart index ce412f985d5..22a3a464f99 100644 --- a/packages/devtools_app/lib/src/extensions/extension_screen.dart +++ b/packages/devtools_app/lib/src/extensions/extension_screen.dart @@ -12,7 +12,6 @@ import '../shared/analytics/constants.dart' as gac; import '../shared/common_widgets.dart'; import '../shared/globals.dart'; import '../shared/screen.dart'; -import '../shared/utils.dart'; import 'embedded/controller.dart'; import 'embedded/view.dart'; import 'extension_screen_controls.dart'; diff --git a/packages/devtools_app/lib/src/framework/disconnect_observer.dart b/packages/devtools_app/lib/src/framework/disconnect_observer.dart index bb4edb9cab9..9b2152e181d 100644 --- a/packages/devtools_app/lib/src/framework/disconnect_observer.dart +++ b/packages/devtools_app/lib/src/framework/disconnect_observer.dart @@ -16,7 +16,6 @@ import '../shared/connection_info.dart'; import '../shared/globals.dart'; import '../shared/query_parameters.dart'; import '../shared/routing.dart'; -import '../shared/utils.dart'; class DisconnectObserver extends StatefulWidget { const DisconnectObserver({ diff --git a/packages/devtools_app/lib/src/framework/release_notes/release_notes.dart b/packages/devtools_app/lib/src/framework/release_notes/release_notes.dart index 9b8a7166552..35f58be6515 100644 --- a/packages/devtools_app/lib/src/framework/release_notes/release_notes.dart +++ b/packages/devtools_app/lib/src/framework/release_notes/release_notes.dart @@ -5,6 +5,7 @@ import 'dart:async'; import 'dart:convert'; +import 'package:devtools_app_shared/ui.dart'; import 'package:devtools_app_shared/utils.dart'; import 'package:devtools_shared/devtools_shared.dart'; import 'package:flutter/material.dart'; diff --git a/packages/devtools_app/lib/src/framework/scaffold.dart b/packages/devtools_app/lib/src/framework/scaffold.dart index cd866e4be64..b9b7a2734e7 100644 --- a/packages/devtools_app/lib/src/framework/scaffold.dart +++ b/packages/devtools_app/lib/src/framework/scaffold.dart @@ -23,7 +23,6 @@ import '../shared/query_parameters.dart'; import '../shared/routing.dart'; import '../shared/screen.dart'; import '../shared/title.dart'; -import '../shared/utils.dart'; import 'about_dialog.dart'; import 'app_bar.dart'; import 'report_feedback_button.dart'; diff --git a/packages/devtools_app/lib/src/framework/settings_dialog.dart b/packages/devtools_app/lib/src/framework/settings_dialog.dart index a5f1e1c11c9..4d710e53620 100644 --- a/packages/devtools_app/lib/src/framework/settings_dialog.dart +++ b/packages/devtools_app/lib/src/framework/settings_dialog.dart @@ -5,17 +5,16 @@ import 'dart:async'; import 'package:devtools_app_shared/ui.dart'; +import 'package:devtools_app_shared/utils.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../shared/analytics/analytics_controller.dart'; import '../shared/analytics/constants.dart' as gac; import '../shared/common_widgets.dart'; -import '../shared/config_specific/copy_to_clipboard/copy_to_clipboard.dart'; import '../shared/globals.dart'; import '../shared/log_storage.dart'; import '../shared/server/server.dart'; -import '../shared/utils.dart'; class OpenSettingsAction extends ScaffoldAction { OpenSettingsAction({super.key, super.color}) @@ -113,7 +112,8 @@ class _VerboseLoggingSetting extends StatelessWidget { _minScreenWidthForTextBeforeScaling, onPressed: () async => await copyToClipboard( LogStorage.root.toString(), - 'Successfully copied logs', + onSuccess: () => + notificationService.push('Successfully copied logs'), ), ), const SizedBox(width: denseSpacing), diff --git a/packages/devtools_app/lib/src/screens/network/network_screen.dart b/packages/devtools_app/lib/src/screens/network/network_screen.dart index 12e0d3a97af..1a0a72e2baa 100644 --- a/packages/devtools_app/lib/src/screens/network/network_screen.dart +++ b/packages/devtools_app/lib/src/screens/network/network_screen.dart @@ -13,7 +13,6 @@ import 'package:provider/provider.dart'; import '../../shared/analytics/analytics.dart' as ga; import '../../shared/analytics/constants.dart' as gac; import '../../shared/common_widgets.dart'; -import '../../shared/config_specific/copy_to_clipboard/copy_to_clipboard.dart'; import '../../shared/globals.dart'; import '../../shared/http/curl_command.dart'; import '../../shared/http/http_request_data.dart'; @@ -437,7 +436,8 @@ class ActionsColumn extends ColumnData unawaited( copyToClipboard( data.uri, - 'Copied the URL to the clipboard', + onSuccess: () => + notificationService.push('Copied the URL to the clipboard'), ), ); }, @@ -448,7 +448,8 @@ class ActionsColumn extends ColumnData unawaited( copyToClipboard( CurlCommand.from(data).toString(), - 'Copied the cURL command to the clipboard', + onSuccess: () => notificationService + .push('Copied the cURL command to the clipboard'), ), ); }, diff --git a/packages/devtools_app/lib/src/shared/analytics/_analytics_web.dart b/packages/devtools_app/lib/src/shared/analytics/_analytics_web.dart index 244be3d70bb..4dba24e3488 100644 --- a/packages/devtools_app/lib/src/shared/analytics/_analytics_web.dart +++ b/packages/devtools_app/lib/src/shared/analytics/_analytics_web.dart @@ -10,6 +10,7 @@ library; import 'dart:async'; import 'dart:js_interop'; +import 'package:devtools_app_shared/ui.dart'; import 'package:flutter/foundation.dart'; import 'package:logging/logging.dart'; import 'package:unified_analytics/unified_analytics.dart' as ua; diff --git a/packages/devtools_app/lib/src/shared/common_widgets.dart b/packages/devtools_app/lib/src/shared/common_widgets.dart index bd79b497d2e..d2a50d92231 100644 --- a/packages/devtools_app/lib/src/shared/common_widgets.dart +++ b/packages/devtools_app/lib/src/shared/common_widgets.dart @@ -16,7 +16,6 @@ import 'package:vm_service/vm_service.dart'; import '../screens/debugger/debugger_controller.dart'; import 'analytics/analytics.dart' as ga; import 'analytics/constants.dart' as gac; -import 'config_specific/copy_to_clipboard/copy_to_clipboard.dart'; import 'console/widgets/expandable_variable.dart'; import 'diagnostics/dart_object_node.dart'; import 'diagnostics/tree_builder.dart'; @@ -1178,7 +1177,8 @@ class _JsonViewerState extends State .serviceManager.service!.fakeServiceCache .instanceToJson(copiedVariable.value as Instance), ), - 'JSON copied to clipboard', + onSuccess: () => + notificationService.push('JSON copied to clipboard'), ), ); }, @@ -1414,7 +1414,12 @@ class CopyToClipboardControl extends StatelessWidget { ga.select(gaScreen!, gaItem!); } unawaited( - copyToClipboard(dataProvider!() ?? '', successMessage), + copyToClipboard( + dataProvider!() ?? '', + onSuccess: successMessage != null + ? () => notificationService.push(successMessage!) + : null, + ), ); }; final size = this.size ?? defaultIconSize; diff --git a/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart b/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart index 26fa83f7499..7e0299e3c8b 100644 --- a/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart +++ b/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart @@ -13,6 +13,7 @@ import 'dart:developer'; import 'package:devtools_app_shared/service.dart'; import 'package:devtools_app_shared/service_extensions.dart'; +import 'package:devtools_app_shared/ui.dart'; import 'package:devtools_app_shared/utils.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; diff --git a/packages/devtools_app/lib/src/shared/dialogs.dart b/packages/devtools_app/lib/src/shared/dialogs.dart index c5a06070916..169d300460e 100644 --- a/packages/devtools_app/lib/src/shared/dialogs.dart +++ b/packages/devtools_app/lib/src/shared/dialogs.dart @@ -5,9 +5,9 @@ import 'dart:async'; import 'package:devtools_app_shared/ui.dart'; +import 'package:devtools_app_shared/utils.dart'; import 'package:flutter/material.dart'; -import 'config_specific/copy_to_clipboard/copy_to_clipboard.dart'; import 'globals.dart'; import 'utils.dart'; @@ -36,7 +36,8 @@ class UnexpectedErrorDialog extends StatelessWidget { onPressed: () => unawaited( copyToClipboard( additionalInfo, - 'Error details copied to clipboard', + onSuccess: () => + notificationService.push('Error details copied to clipboard'), ), ), ), diff --git a/packages/devtools_app/lib/src/shared/editable_list.dart b/packages/devtools_app/lib/src/shared/editable_list.dart index 42fc44d35f0..dbd8cc6c5b6 100644 --- a/packages/devtools_app/lib/src/shared/editable_list.dart +++ b/packages/devtools_app/lib/src/shared/editable_list.dart @@ -10,7 +10,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'common_widgets.dart'; -import 'config_specific/copy_to_clipboard/copy_to_clipboard.dart'; +import 'globals.dart'; /// A widget that displays the contents of [entries]. /// @@ -276,7 +276,12 @@ class EditableListCopyDirectoryButton extends StatelessWidget { icon: Icons.copy_outlined, outlined: false, onPressed: () { - unawaited(copyToClipboard(value, 'Copied to clipboard.')); + unawaited( + copyToClipboard( + value, + onSuccess: () => notificationService.push('Copied to clipboard.'), + ), + ); }, ); } diff --git a/packages/devtools_app/lib/src/shared/utils.dart b/packages/devtools_app/lib/src/shared/utils.dart index e833b474a77..541287f53f2 100644 --- a/packages/devtools_app/lib/src/shared/utils.dart +++ b/packages/devtools_app/lib/src/shared/utils.dart @@ -39,10 +39,6 @@ void debugLogger(String message) { ); } -/// Whether DevTools is in embedded mode, as determined by the [ideTheme] parsed -/// from query parameters. -bool isEmbedded() => ideTheme.embedded; - /// Whether DevTools is using a dark theme. /// /// When DevTools is in embedded mode, we first check if the [ideTheme] has diff --git a/packages/devtools_app_shared/CHANGELOG.md b/packages/devtools_app_shared/CHANGELOG.md index 2d4a683f5d8..5946e3a670b 100644 --- a/packages/devtools_app_shared/CHANGELOG.md +++ b/packages/devtools_app_shared/CHANGELOG.md @@ -6,6 +6,7 @@ can be disabled to prevent exceptions from being logged to console. * Add `caseInsensitiveFuzzyMatch` extension method on `String`. * Add common widgets `DevToolsClearableTextField`, `InputDecorationSuffixButton`, and `RoundedDropDownButton`. +* Add `copyToClipboard` and `isEmbedded` utility methods. * Deprecate `ServiceManager.hasConnection` in favor of `ServiceManager.connectedState.value.connected`. * Correct the dartdoc for the `ListValueNotifier` class. diff --git a/packages/devtools_app_shared/lib/src/ui/ui_utils.dart b/packages/devtools_app_shared/lib/src/ui/ui_utils.dart index cff4a29c74d..2e66d16487a 100644 --- a/packages/devtools_app_shared/lib/src/ui/ui_utils.dart +++ b/packages/devtools_app_shared/lib/src/ui/ui_utils.dart @@ -5,6 +5,10 @@ import '../utils/globals.dart'; import 'theme/ide_theme.dart'; +/// Whether DevTools is in embedded mode, as determined by the [ideTheme] parsed +/// from query parameters. +bool isEmbedded() => ideTheme.embedded; + IdeTheme get ideTheme { final theme = globals[IdeTheme]; if (theme == null) { diff --git a/packages/devtools_app/lib/src/shared/config_specific/copy_to_clipboard/_copy_to_clipboard_desktop.dart b/packages/devtools_app_shared/lib/src/utils/copy_to_clipboard/_copy_to_clipboard_desktop.dart similarity index 100% rename from packages/devtools_app/lib/src/shared/config_specific/copy_to_clipboard/_copy_to_clipboard_desktop.dart rename to packages/devtools_app_shared/lib/src/utils/copy_to_clipboard/_copy_to_clipboard_desktop.dart diff --git a/packages/devtools_app/lib/src/shared/config_specific/copy_to_clipboard/_copy_to_clipboard_web.dart b/packages/devtools_app_shared/lib/src/utils/copy_to_clipboard/_copy_to_clipboard_web.dart similarity index 100% rename from packages/devtools_app/lib/src/shared/config_specific/copy_to_clipboard/_copy_to_clipboard_web.dart rename to packages/devtools_app_shared/lib/src/utils/copy_to_clipboard/_copy_to_clipboard_web.dart diff --git a/packages/devtools_app/lib/src/shared/config_specific/copy_to_clipboard/copy_to_clipboard.dart b/packages/devtools_app_shared/lib/src/utils/copy_to_clipboard/copy_to_clipboard.dart similarity index 79% rename from packages/devtools_app/lib/src/shared/config_specific/copy_to_clipboard/copy_to_clipboard.dart rename to packages/devtools_app_shared/lib/src/utils/copy_to_clipboard/copy_to_clipboard.dart index 1b2a343f8f3..fc1835faa9a 100644 --- a/packages/devtools_app/lib/src/shared/config_specific/copy_to_clipboard/copy_to_clipboard.dart +++ b/packages/devtools_app_shared/lib/src/utils/copy_to_clipboard/copy_to_clipboard.dart @@ -5,8 +5,7 @@ import 'package:flutter/services.dart'; import 'package:logging/logging.dart'; -import '../../globals.dart'; -import '../../utils.dart'; +import '../../ui/ui_utils.dart'; import '_copy_to_clipboard_desktop.dart' if (dart.library.js_interop) '_copy_to_clipboard_web.dart'; @@ -19,24 +18,23 @@ final _log = Logger('copy_to_clipboard'); /// attempts to post the [data] to the parent frame where the parent frame will /// try to complete the copy (this fallback will only work in VSCode). Future copyToClipboard( - String data, - String? successMessage, -) async { + String data, { + void Function()? onSuccess, +}) async { try { await Clipboard.setData( ClipboardData( text: data, ), ); - - if (successMessage != null) notificationService.push(successMessage); + onSuccess?.call(); } catch (e) { if (isEmbedded()) { _log.warning( - 'DevTools copy failed. This may be as a result of a known bug in VSCode. ' + 'Copy failed. This may be as a result of a known bug in VS Code. ' 'See https://github.com/Dart-Code/Dart-Code/issues/4540 for more ' - 'information. DevTools will now attempt to use a fallback method of ' - 'copying the contents.', + 'information. Now attempting to use a fallback method of copying the ' + 'that is a workaround for VS Code only.', ); // Trying to use Clipboard.setData to copy in vscode will not work as a // result of a bug. So we should fallback to `copyToClipboardVSCode` which diff --git a/packages/devtools_app_shared/lib/utils.dart b/packages/devtools_app_shared/lib/utils.dart index f44804b7f82..6568b0e662a 100644 --- a/packages/devtools_app_shared/lib/utils.dart +++ b/packages/devtools_app_shared/lib/utils.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. export 'src/utils/auto_dispose.dart'; +export 'src/utils/copy_to_clipboard/copy_to_clipboard.dart'; export 'src/utils/globals.dart'; export 'src/utils/list.dart'; export 'src/utils/url/url.dart';