| // Copyright 2019 The Flutter team. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'package:flutter/gestures.dart'; |
| import 'package:flutter/material.dart'; |
| import 'package:url_launcher/url_launcher.dart'; |
| |
| import 'package:gallery/l10n/gallery_localizations.dart'; |
| |
| void showAboutDialog({ |
| @required BuildContext context, |
| }) { |
| assert(context != null); |
| showDialog<void>( |
| context: context, |
| builder: (context) { |
| return _AboutDialog(); |
| }, |
| ); |
| } |
| |
| class _AboutDialog extends StatelessWidget { |
| @override |
| Widget build(BuildContext context) { |
| final colorScheme = Theme.of(context).colorScheme; |
| final textTheme = Theme.of(context).textTheme; |
| final bodyTextStyle = textTheme.body2.apply(color: colorScheme.onPrimary); |
| |
| final name = 'Flutter Gallery'; // Don't need to localize. |
| final legalese = '© 2019 The Flutter team'; // Don't need to localize. |
| final samplesRepo = |
| GalleryLocalizations.of(context).aboutFlutterSamplesRepo; |
| // TODO: Determine why this doesn't work consistently. |
| // Certain versions of iOS/macOS aren't rendering the raw string correctly. |
| final seeSource = |
| GalleryLocalizations.of(context).aboutDialogDescription(samplesRepo); |
| final samplesRepoIndex = seeSource.indexOf(samplesRepo); |
| final samplesRepoIndexEnd = samplesRepoIndex + samplesRepo.length; |
| String seeSourceFirst; |
| String seeSourceSecond; |
| if (samplesRepoIndex > -1 && samplesRepoIndex > -1) { |
| seeSourceFirst = seeSource.substring(0, samplesRepoIndex); |
| seeSourceSecond = seeSource.substring(samplesRepoIndexEnd); |
| } else { |
| seeSourceFirst = 'To see the source code for this app, please visit the '; |
| seeSourceSecond = '.'; |
| } |
| |
| return AlertDialog( |
| backgroundColor: colorScheme.background, |
| shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), |
| content: Container( |
| constraints: BoxConstraints(maxWidth: 400), |
| child: Column( |
| crossAxisAlignment: CrossAxisAlignment.start, |
| mainAxisSize: MainAxisSize.min, |
| children: [ |
| Center( |
| child: Text( |
| '$name', |
| style: textTheme.display1.apply(color: colorScheme.onPrimary), |
| ), |
| ), |
| SizedBox(height: 24), |
| RichText( |
| text: TextSpan( |
| children: [ |
| TextSpan( |
| style: bodyTextStyle, |
| text: seeSourceFirst, |
| ), |
| TextSpan( |
| style: bodyTextStyle.copyWith( |
| color: colorScheme.primary, |
| ), |
| text: samplesRepo, |
| recognizer: TapGestureRecognizer() |
| ..onTap = () async { |
| final url = 'https://github.com/flutter/samples/'; |
| if (await canLaunch(url)) { |
| await launch( |
| url, |
| forceSafariVC: false, |
| ); |
| } |
| }, |
| ), |
| TextSpan( |
| style: bodyTextStyle, |
| text: seeSourceSecond, |
| ), |
| ], |
| ), |
| ), |
| SizedBox(height: 18), |
| Text( |
| legalese, |
| style: bodyTextStyle, |
| ), |
| ], |
| ), |
| ), |
| actions: [ |
| FlatButton( |
| textColor: colorScheme.primary, |
| child: Text( |
| MaterialLocalizations.of(context).viewLicensesButtonLabel, |
| ), |
| onPressed: () { |
| Navigator.of(context).push(MaterialPageRoute<void>( |
| builder: (context) => Theme( |
| data: Theme.of(context).copyWith( |
| textTheme: |
| Typography(platform: Theme.of(context).platform).black, |
| scaffoldBackgroundColor: Colors.white, |
| ), |
| child: LicensePage( |
| applicationName: name, |
| applicationLegalese: legalese, |
| ), |
| ), |
| )); |
| }, |
| ), |
| FlatButton( |
| textColor: colorScheme.primary, |
| child: Text(MaterialLocalizations.of(context).closeButtonLabel), |
| onPressed: () { |
| Navigator.pop(context); |
| }, |
| ), |
| ], |
| ); |
| } |
| } |