@@ -9,9 +9,11 @@ import 'package:devtools_app_shared/utils.dart';
99import 'package:dtd/dtd.dart' ;
1010import 'package:flutter/material.dart' ;
1111
12+ import '../../../framework/scaffold/report_feedback_button.dart' ;
1213import '../../../shared/analytics/analytics.dart' as ga;
1314import '../../../shared/analytics/constants.dart' as gac;
1415import '../../../shared/editor/editor_client.dart' ;
16+ import '../../../shared/primitives/query_parameters.dart' ;
1517import '../../../shared/ui/common_widgets.dart' ;
1618import 'property_editor_controller.dart' ;
1719import 'property_editor_view.dart' ;
@@ -80,6 +82,8 @@ class _PropertyEditorPanelState extends State<PropertyEditorPanel> {
8082class _PropertyEditorConnectedPanel extends StatefulWidget {
8183 const _PropertyEditorConnectedPanel (this .editor, {required this .controller});
8284
85+ static const footerHeight = 25.0 ;
86+
8387 final EditorClient editor;
8488 final PropertyEditorController controller;
8589
@@ -115,22 +119,29 @@ class _PropertyEditorConnectedPanelState
115119 Scrollbar (
116120 controller: scrollController,
117121 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,
126- ),
127- child: Column (
128- crossAxisAlignment: CrossAxisAlignment .start,
129- children: [
130- PropertyEditorView (controller: widget.controller),
131- ],
122+ child: Column (
123+ children: [
124+ Expanded (
125+ child: SingleChildScrollView (
126+ controller: scrollController,
127+ child: Padding (
128+ padding: const EdgeInsets .fromLTRB (
129+ denseSpacing,
130+ defaultSpacing,
131+ defaultSpacing, // Additional right padding for scroll bar.
132+ defaultSpacing,
133+ ),
134+ child: Column (
135+ crossAxisAlignment: CrossAxisAlignment .start,
136+ children: [
137+ PropertyEditorView (controller: widget.controller),
138+ ],
139+ ),
140+ ),
141+ ),
132142 ),
133- ),
143+ const _PropertyEditorFooter (),
144+ ],
134145 ),
135146 ),
136147 if (shouldReconnect) const ReconnectingOverlay (),
@@ -140,3 +151,59 @@ class _PropertyEditorConnectedPanelState
140151 );
141152 }
142153}
154+
155+ class _PropertyEditorFooter extends StatelessWidget {
156+ const _PropertyEditorFooter ();
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+ color: colorScheme.secondary,
165+ height: _PropertyEditorConnectedPanel .footerHeight,
166+ padding: const EdgeInsets .symmetric (vertical: densePadding),
167+ alignment: Alignment .center,
168+ child: Row (
169+ children: [
170+ if (documentationLink != null )
171+ _DocsLink (documentationLink: documentationLink),
172+ const Spacer (),
173+ ReportFeedbackButton (color: colorScheme.onSecondary),
174+ ],
175+ ),
176+ );
177+ }
178+
179+ String ? _documentationLink () {
180+ final queryParams = DevToolsQueryParams .load ();
181+ final isEmbedded = queryParams.embedMode.embedded;
182+ if (! isEmbedded) return null ;
183+ const uriPrefix = 'https://docs.flutter.dev/tools/' ;
184+ const uriHash = '#property-editor' ;
185+ return '$uriPrefix ${queryParams .ide == 'VSCode' ? 'vs-code' : 'android-studio' }$uriHash ' ;
186+ }
187+ }
188+
189+ class _DocsLink extends StatelessWidget {
190+ const _DocsLink ({required this .documentationLink});
191+
192+ final String documentationLink;
193+
194+ @override
195+ Widget build (BuildContext context) {
196+ return RichText (
197+ text: GaLinkTextSpan (
198+ link: GaLink (
199+ display: 'documentation' ,
200+ url: documentationLink,
201+ gaScreenName: gac.PropertyEditorSidebar .id,
202+ gaSelectedItemDescription:
203+ gac.PropertyEditorSidebar .documentationLink,
204+ ),
205+ context: context,
206+ ),
207+ );
208+ }
209+ }
0 commit comments