diff --git a/packages/devtools_app/lib/src/framework/scaffold/status_line.dart b/packages/devtools_app/lib/src/framework/scaffold/status_line.dart index 54e78dc2954..9c362dad48e 100644 --- a/packages/devtools_app/lib/src/framework/scaffold/status_line.dart +++ b/packages/devtools_app/lib/src/framework/scaffold/status_line.dart @@ -90,7 +90,9 @@ class StatusLine extends StatelessWidget { final pageStatus = currentScreen.buildStatus(context); final widerThanXxs = screenWidth > MediaSize.xxs; final screenMetaData = ScreenMetaData.lookup(currentScreen.screenId); - final showVideoTutorial = screenMetaData?.tutorialVideoTimestamp != null; + final showVideoTutorial = + screenMetaData?.tutorialVideoTimestamp != null || + screenMetaData?.tutorialVideoUrl != null; return [ Row( mainAxisSize: MainAxisSize.min, @@ -237,12 +239,15 @@ class DocumentationLink extends StatelessWidget { /// A widget that links to the "Dive in to DevTools" YouTube video at the /// chapter for the given [screenMetaData]. class VideoTutorialLink extends StatelessWidget { - const VideoTutorialLink({ + VideoTutorialLink({ super.key, required this.screenMetaData, required this.screenWidth, required this.highlightForConnection, - }); + }) : assert( + screenMetaData.tutorialVideoTimestamp != null || + screenMetaData.tutorialVideoUrl != null, + ); final ScreenMetaData screenMetaData; @@ -262,6 +267,7 @@ class VideoTutorialLink extends StatelessWidget { link: GaLink( display: screenWidth <= MediaSize.xs ? 'Tutorial' : 'Watch tutorial', url: + screenMetaData.tutorialVideoUrl ?? '$_devToolsYouTubeVideoUrl${screenMetaData.tutorialVideoTimestamp}', gaScreenName: screenMetaData.id, gaSelectedItemDescription: diff --git a/packages/devtools_app/lib/src/shared/framework/screen.dart b/packages/devtools_app/lib/src/shared/framework/screen.dart index 6e090ff7bc0..32f3d21e4bb 100644 --- a/packages/devtools_app/lib/src/shared/framework/screen.dart +++ b/packages/devtools_app/lib/src/shared/framework/screen.dart @@ -27,6 +27,8 @@ const _kNetworkDisconnectExperience = bool.fromEnvironment( defaultValue: true, ); +const _deepLinksTutorialVideoUrl = 'https://youtu.be/d7sZL6h1Elw'; + enum ScreenMetaData { home( 'home', @@ -124,6 +126,7 @@ enum ScreenMetaData { requiresConnection: false, requiresDartVm: true, requiresFlutter: true, + tutorialVideoUrl: _deepLinksTutorialVideoUrl, ), vmTools( 'vm-tools', @@ -154,6 +157,7 @@ enum ScreenMetaData { this.worksWithOfflineData = false, this.requiresLibrary, this.tutorialVideoTimestamp, + this.tutorialVideoUrl, }) : assert( icon == null || iconAsset == null, 'Only one of icon or iconAsset may be specified.', @@ -179,6 +183,13 @@ enum ScreenMetaData { /// a particular chapter. final String? tutorialVideoTimestamp; + /// A custom video tutorial URL for a screen. + /// + /// If provided, this URL will be used instead of the default + /// "Dive in to DevTools" YouTube video timestamp. This is used for + /// screens that have their own dedicated video tutorials. + final String? tutorialVideoUrl; + /// Looks up the [ScreenMetaData] value for the screen [id]. static ScreenMetaData? lookup(String id) { return ScreenMetaData.values.firstWhereOrNull((screen) => screen.id == id);