Skip to content

Commit d2d7962

Browse files
authored
[Property Editor] Add a footer for opening documentation / reporting errors (#9099)
1 parent 09c4072 commit d2d7962

File tree

2 files changed

+93
-15
lines changed

2 files changed

+93
-15
lines changed

packages/devtools_app/lib/src/shared/analytics/constants/_property_editor_sidebar_constants.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ class PropertyEditorSidebar {
99
/// Analytics id to track events that come from the DTD editor sidebar.
1010
static String get id => 'propertyEditorSidebar';
1111

12+
/// Analytics id for opening the documentation.
13+
static String get documentationLink => 'propertyEditorDocumentation';
14+
1215
/// Analytics event that is sent when the property editor is updated with new
1316
/// properties.
1417
static String widgetPropertiesUpdate({String? name}) =>

packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_panel.dart

Lines changed: 90 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ import 'package:devtools_app_shared/utils.dart';
99
import 'package:dtd/dtd.dart';
1010
import 'package:flutter/material.dart';
1111

12+
import '../../../framework/scaffold/report_feedback_button.dart';
1213
import '../../../shared/analytics/analytics.dart' as ga;
1314
import '../../../shared/analytics/constants.dart' as gac;
1415
import '../../../shared/editor/editor_client.dart';
16+
import '../../../shared/primitives/query_parameters.dart';
1517
import '../../../shared/ui/common_widgets.dart';
1618
import 'property_editor_controller.dart';
1719
import 'property_editor_view.dart';
@@ -115,22 +117,29 @@ class _PropertyEditorConnectedPanelState
115117
Scrollbar(
116118
controller: scrollController,
117119
thumbVisibility: true,
118-
child: SingleChildScrollView(
119-
controller: scrollController,
120-
child: Padding(
121-
padding: const EdgeInsets.fromLTRB(
122-
denseSpacing,
123-
defaultSpacing,
124-
defaultSpacing, // Additional right padding for scroll bar.
125-
defaultSpacing,
120+
child: Column(
121+
children: [
122+
Expanded(
123+
child: SingleChildScrollView(
124+
controller: scrollController,
125+
child: Padding(
126+
padding: const EdgeInsets.fromLTRB(
127+
denseSpacing,
128+
defaultSpacing,
129+
defaultSpacing, // Additional right padding for scroll bar.
130+
defaultSpacing,
131+
),
132+
child: Column(
133+
crossAxisAlignment: CrossAxisAlignment.start,
134+
children: [
135+
PropertyEditorView(controller: widget.controller),
136+
],
137+
),
138+
),
139+
),
126140
),
127-
child: Column(
128-
crossAxisAlignment: CrossAxisAlignment.start,
129-
children: [
130-
PropertyEditorView(controller: widget.controller),
131-
],
132-
),
133-
),
141+
const _PropertyEditorFooter(),
142+
],
134143
),
135144
),
136145
if (shouldReconnect) const ReconnectingOverlay(),
@@ -140,3 +149,69 @@ class _PropertyEditorConnectedPanelState
140149
);
141150
}
142151
}
152+
153+
class _PropertyEditorFooter extends StatelessWidget {
154+
const _PropertyEditorFooter();
155+
156+
static const _footerHeight = 25.0;
157+
158+
@override
159+
Widget build(BuildContext context) {
160+
final theme = Theme.of(context);
161+
final colorScheme = theme.colorScheme;
162+
final documentationLink = _documentationLink();
163+
return Container(
164+
decoration: BoxDecoration(
165+
color: colorScheme.surface,
166+
border: Border(top: BorderSide(color: Theme.of(context).focusColor)),
167+
),
168+
height: _footerHeight,
169+
padding: const EdgeInsets.symmetric(vertical: densePadding),
170+
child: Row(
171+
crossAxisAlignment: CrossAxisAlignment.end,
172+
children: [
173+
if (documentationLink != null)
174+
Padding(
175+
padding: const EdgeInsets.only(left: denseSpacing),
176+
child: _DocsLink(
177+
documentationLink: documentationLink,
178+
color: colorScheme.onSurface,
179+
),
180+
),
181+
const Spacer(),
182+
ReportFeedbackButton(color: colorScheme.onSurface),
183+
],
184+
),
185+
);
186+
}
187+
188+
String? _documentationLink() {
189+
final queryParams = DevToolsQueryParams.load();
190+
final isEmbedded = queryParams.embedMode.embedded;
191+
if (!isEmbedded) return null;
192+
const uriPrefix = 'https://docs.flutter.dev/tools/';
193+
const uriHash = '#property-editor';
194+
return '$uriPrefix${queryParams.ide == 'VSCode' ? 'vs-code' : 'android-studio'}$uriHash';
195+
}
196+
}
197+
198+
class _DocsLink extends StatelessWidget {
199+
const _DocsLink({required this.documentationLink, required this.color});
200+
201+
final Color color;
202+
final String documentationLink;
203+
204+
@override
205+
Widget build(BuildContext context) {
206+
return LinkIconLabel(
207+
icon: Icons.library_books_outlined,
208+
link: GaLink(
209+
display: 'Docs',
210+
url: documentationLink,
211+
gaScreenName: gac.PropertyEditorSidebar.id,
212+
gaSelectedItemDescription: gac.PropertyEditorSidebar.documentationLink,
213+
),
214+
color: color,
215+
);
216+
}
217+
}

0 commit comments

Comments
 (0)