From 8e73c73f4bfa533958fd704bc4cb8734fcfda3bf Mon Sep 17 00:00:00 2001 From: Abdullah Deshmukh <abdullahzakir99@gmail.com> Date: Wed, 14 Jul 2021 03:01:14 +0530 Subject: [PATCH] [linting_tool] Add Adaptive Layout with Theming (#852) --- experimental/linting_tool/lib/app.dart | 40 +++ .../linting_tool/lib/layout/adaptive.dart | 23 ++ experimental/linting_tool/lib/main.dart | 63 +--- .../lib/pages/default_lints_page.dart | 15 + .../linting_tool/lib/pages/home_page.dart | 15 + .../lib/pages/saved_lints_page.dart | 15 + experimental/linting_tool/lib/routes.dart | 6 + .../linting_tool/lib/theme/app_theme.dart | 208 +++++++++++ .../linting_tool/lib/theme/colors.dart | 42 +++ .../lib/widgets/adaptive_nav.dart | 334 ++++++++++++++++++ .../macos/Flutter/Flutter-Debug.xcconfig | 1 + .../macos/Flutter/Flutter-Release.xcconfig | 1 + .../Flutter/GeneratedPluginRegistrant.swift | 2 + experimental/linting_tool/macos/Podfile | 40 +++ experimental/linting_tool/macos/Podfile.lock | 22 ++ .../macos/Runner.xcodeproj/project.pbxproj | 62 +++- .../contents.xcworkspacedata | 3 + .../macos/Runner/DebugProfile.entitlements | 2 + .../linting_tool/macos/Runner/Info.plist | 2 +- experimental/linting_tool/pubspec.lock | 129 ++++++- experimental/linting_tool/pubspec.yaml | 3 +- .../linting_tool/test/widget_test.dart | 33 +- tool/flutter_ci_script_beta.sh | 1 + tool/flutter_ci_script_dev.sh | 1 + tool/flutter_ci_script_stable.sh | 1 + 25 files changed, 984 insertions(+), 80 deletions(-) create mode 100644 experimental/linting_tool/lib/app.dart create mode 100644 experimental/linting_tool/lib/layout/adaptive.dart create mode 100644 experimental/linting_tool/lib/pages/default_lints_page.dart create mode 100644 experimental/linting_tool/lib/pages/home_page.dart create mode 100644 experimental/linting_tool/lib/pages/saved_lints_page.dart create mode 100644 experimental/linting_tool/lib/routes.dart create mode 100644 experimental/linting_tool/lib/theme/app_theme.dart create mode 100644 experimental/linting_tool/lib/theme/colors.dart create mode 100644 experimental/linting_tool/lib/widgets/adaptive_nav.dart create mode 100644 experimental/linting_tool/macos/Podfile create mode 100644 experimental/linting_tool/macos/Podfile.lock diff --git a/experimental/linting_tool/lib/app.dart b/experimental/linting_tool/lib/app.dart new file mode 100644 index 000000000..b2e24ddcb --- /dev/null +++ b/experimental/linting_tool/lib/app.dart @@ -0,0 +1,40 @@ +// Copyright 2021 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/material.dart'; +import 'package:linting_tool/theme/app_theme.dart'; +import 'package:linting_tool/widgets/adaptive_nav.dart'; +import 'package:linting_tool/routes.dart' as routes; + +class LintingTool extends StatefulWidget { + const LintingTool({Key? key}) : super(key: key); + + static const String homeRoute = routes.homeRoute; + + @override + _LintingToolState createState() => _LintingToolState(); +} + +class _LintingToolState extends State<LintingTool> { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Linting Tool', + theme: AppTheme.buildReplyLightTheme(context), + darkTheme: AppTheme.buildReplyDarkTheme(context), + themeMode: ThemeMode.light, + initialRoute: LintingTool.homeRoute, + onGenerateRoute: (settings) { + switch (settings.name) { + case LintingTool.homeRoute: + return MaterialPageRoute<void>( + builder: (context) => const AdaptiveNav(), + settings: settings, + ); + } + return null; + }, + ); + } +} diff --git a/experimental/linting_tool/lib/layout/adaptive.dart b/experimental/linting_tool/lib/layout/adaptive.dart new file mode 100644 index 000000000..c0d14dbff --- /dev/null +++ b/experimental/linting_tool/lib/layout/adaptive.dart @@ -0,0 +1,23 @@ +// Copyright 2021 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:adaptive_breakpoints/adaptive_breakpoints.dart'; +import 'package:flutter/material.dart'; + +/// Returns a boolean value whether the window is considered medium or large size. +/// Used to build adaptive and responsive layouts. +bool isDisplayLarge(BuildContext context) => + getWindowType(context) >= AdaptiveWindowType.medium; + +/// Returns boolean value whether the window is considered medium size. +/// Used to build adaptive and responsive layouts. +bool isDisplayMedium(BuildContext context) { + return getWindowType(context) == AdaptiveWindowType.medium; +} + +/// Returns boolean value whether the window is considered small size. +/// Used to build adaptive and responsive layouts. +bool isDisplaySmall(BuildContext context) { + return getWindowType(context) <= AdaptiveWindowType.small; +} diff --git a/experimental/linting_tool/lib/main.dart b/experimental/linting_tool/lib/main.dart index e22de4739..84c7024e2 100644 --- a/experimental/linting_tool/lib/main.dart +++ b/experimental/linting_tool/lib/main.dart @@ -3,67 +3,8 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; +import 'package:linting_tool/app.dart'; void main() { - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Linting Tool', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: const MyHomePage(title: 'Flutter Linting Tool'), - ); - } -} - -class MyHomePage extends StatefulWidget { - const MyHomePage({Key? key, required this.title}) : super(key: key); - - final String title; - - @override - _MyHomePageState createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State<MyHomePage> { - int _counter = 0; - - void _incrementCounter() { - setState(() { - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: <Widget>[ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headline4, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), - ); - } + runApp(const LintingTool()); } diff --git a/experimental/linting_tool/lib/pages/default_lints_page.dart b/experimental/linting_tool/lib/pages/default_lints_page.dart new file mode 100644 index 000000000..28d890330 --- /dev/null +++ b/experimental/linting_tool/lib/pages/default_lints_page.dart @@ -0,0 +1,15 @@ +// Copyright 2021 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/material.dart'; + +class DefaultLintsPage extends StatelessWidget { + const DefaultLintsPage({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + // TODO(abd99): Implement DefaultLintsPage, showing a list of default lint rules. + return const Text('Default Profiles'); + } +} diff --git a/experimental/linting_tool/lib/pages/home_page.dart b/experimental/linting_tool/lib/pages/home_page.dart new file mode 100644 index 000000000..45b05ddd9 --- /dev/null +++ b/experimental/linting_tool/lib/pages/home_page.dart @@ -0,0 +1,15 @@ +// Copyright 2021 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/material.dart'; + +class HomePage extends StatelessWidget { + const HomePage({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + // TODO(abd99): Implement HomePage, showing a list of supported lint rules. + return const Text('Home'); + } +} diff --git a/experimental/linting_tool/lib/pages/saved_lints_page.dart b/experimental/linting_tool/lib/pages/saved_lints_page.dart new file mode 100644 index 000000000..dd1d93ea5 --- /dev/null +++ b/experimental/linting_tool/lib/pages/saved_lints_page.dart @@ -0,0 +1,15 @@ +// Copyright 2021 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/material.dart'; + +class SavedLintsPage extends StatelessWidget { + const SavedLintsPage({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + // TODO(abd99): Implement SavedLintsPage, showing a list of saved lint rules profiles. + return const Text('Saved Profiles'); + } +} diff --git a/experimental/linting_tool/lib/routes.dart b/experimental/linting_tool/lib/routes.dart new file mode 100644 index 000000000..184c9a694 --- /dev/null +++ b/experimental/linting_tool/lib/routes.dart @@ -0,0 +1,6 @@ +// Copyright 2021 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. + +const String homeRoute = '/home'; +// TODO(abd99): Add new routes. diff --git a/experimental/linting_tool/lib/theme/app_theme.dart b/experimental/linting_tool/lib/theme/app_theme.dart new file mode 100644 index 000000000..34051bf0c --- /dev/null +++ b/experimental/linting_tool/lib/theme/app_theme.dart @@ -0,0 +1,208 @@ +// Copyright 2021 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/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:linting_tool/theme/colors.dart'; + +class AppTheme { + static ThemeData buildReplyLightTheme(BuildContext context) { + final base = ThemeData.light(); + return base.copyWith( + bottomAppBarColor: AppColors.blue700, + bottomSheetTheme: BottomSheetThemeData( + backgroundColor: AppColors.blue700, + modalBackgroundColor: Colors.white.withOpacity(0.7), + ), + navigationRailTheme: NavigationRailThemeData( + backgroundColor: AppColors.blue700, + selectedIconTheme: const IconThemeData(color: AppColors.orange500), + selectedLabelTextStyle: + GoogleFonts.workSansTextTheme().headline5!.copyWith( + color: AppColors.orange500, + ), + unselectedIconTheme: const IconThemeData(color: AppColors.blue200), + unselectedLabelTextStyle: + GoogleFonts.workSansTextTheme().headline5!.copyWith( + color: AppColors.blue200, + ), + ), + canvasColor: AppColors.white50, + cardColor: AppColors.white50, + chipTheme: _buildChipTheme( + AppColors.blue700, + AppColors.lightChipBackground, + Brightness.light, + ), + colorScheme: ColorScheme.fromSwatch(primarySwatch: Colors.blueGrey), + textTheme: _buildReplyLightTextTheme(base.textTheme), + scaffoldBackgroundColor: AppColors.blue50, + ); + } + + static ThemeData buildReplyDarkTheme(BuildContext context) { + final base = ThemeData.dark(); + return base.copyWith( + bottomAppBarColor: AppColors.darkBottomAppBarBackground, + bottomSheetTheme: BottomSheetThemeData( + backgroundColor: AppColors.darkDrawerBackground, + modalBackgroundColor: Colors.black.withOpacity(0.7), + ), + navigationRailTheme: NavigationRailThemeData( + backgroundColor: AppColors.darkBottomAppBarBackground, + selectedIconTheme: const IconThemeData(color: AppColors.orange300), + selectedLabelTextStyle: + GoogleFonts.workSansTextTheme().headline5!.copyWith( + color: AppColors.orange300, + ), + unselectedIconTheme: const IconThemeData(color: AppColors.greyLabel), + unselectedLabelTextStyle: + GoogleFonts.workSansTextTheme().headline5!.copyWith( + color: AppColors.greyLabel, + ), + ), + canvasColor: AppColors.black900, + cardColor: AppColors.darkCardBackground, + chipTheme: _buildChipTheme( + AppColors.blue200, + AppColors.darkChipBackground, + Brightness.dark, + ), + colorScheme: const ColorScheme.dark( + primary: AppColors.blue200, + primaryVariant: AppColors.blue300, + secondary: AppColors.orange300, + secondaryVariant: AppColors.orange300, + surface: AppColors.black800, + error: AppColors.red200, + onPrimary: AppColors.black900, + onSecondary: AppColors.black900, + onBackground: AppColors.white50, + onSurface: AppColors.white50, + onError: AppColors.black900, + background: AppColors.black900Alpha087, + ), + textTheme: _buildReplyDarkTextTheme(base.textTheme), + scaffoldBackgroundColor: AppColors.black900, + ); + } + + static ChipThemeData _buildChipTheme( + Color primaryColor, + Color chipBackground, + Brightness brightness, + ) { + return ChipThemeData( + backgroundColor: primaryColor.withOpacity(0.12), + disabledColor: primaryColor.withOpacity(0.87), + selectedColor: primaryColor.withOpacity(0.05), + secondarySelectedColor: chipBackground, + padding: const EdgeInsets.all(4), + shape: const StadiumBorder(), + labelStyle: GoogleFonts.workSansTextTheme().bodyText2!.copyWith( + color: brightness == Brightness.dark + ? AppColors.white50 + : AppColors.black900, + ), + secondaryLabelStyle: GoogleFonts.workSansTextTheme().bodyText2!, + brightness: brightness, + ); + } + + static TextTheme _buildReplyLightTextTheme(TextTheme base) { + return base.copyWith( + headline4: GoogleFonts.workSans( + fontWeight: FontWeight.w600, + fontSize: 34, + letterSpacing: 0.4, + height: 0.9, + color: AppColors.black900, + ), + headline5: GoogleFonts.workSans( + fontWeight: FontWeight.bold, + fontSize: 24, + letterSpacing: 0.27, + color: AppColors.black900, + ), + headline6: GoogleFonts.workSans( + fontWeight: FontWeight.w600, + fontSize: 20, + letterSpacing: 0.18, + color: AppColors.black900, + ), + subtitle2: GoogleFonts.workSans( + fontWeight: FontWeight.w600, + fontSize: 14, + letterSpacing: -0.04, + color: AppColors.black900, + ), + bodyText1: GoogleFonts.workSans( + fontWeight: FontWeight.normal, + fontSize: 18, + letterSpacing: 0.2, + color: AppColors.black900, + ), + bodyText2: GoogleFonts.workSans( + fontWeight: FontWeight.normal, + fontSize: 14, + letterSpacing: -0.05, + color: AppColors.black900, + ), + caption: GoogleFonts.workSans( + fontWeight: FontWeight.normal, + fontSize: 12, + letterSpacing: 0.2, + color: AppColors.black900, + ), + ); + } + + static TextTheme _buildReplyDarkTextTheme(TextTheme base) { + return base.copyWith( + headline4: GoogleFonts.workSans( + fontWeight: FontWeight.w600, + fontSize: 34, + letterSpacing: 0.4, + height: 0.9, + color: AppColors.white50, + ), + headline5: GoogleFonts.workSans( + fontWeight: FontWeight.bold, + fontSize: 24, + letterSpacing: 0.27, + color: AppColors.white50, + ), + headline6: GoogleFonts.workSans( + fontWeight: FontWeight.w600, + fontSize: 20, + letterSpacing: 0.18, + color: AppColors.white50, + ), + subtitle2: GoogleFonts.workSans( + fontWeight: FontWeight.w600, + fontSize: 14, + letterSpacing: -0.04, + color: AppColors.white50, + ), + bodyText1: GoogleFonts.workSans( + fontWeight: FontWeight.normal, + fontSize: 18, + letterSpacing: 0.2, + color: AppColors.white50, + ), + bodyText2: GoogleFonts.workSans( + fontWeight: FontWeight.normal, + fontSize: 14, + letterSpacing: -0.05, + color: AppColors.white50, + ), + caption: GoogleFonts.workSans( + fontWeight: FontWeight.normal, + fontSize: 12, + letterSpacing: 0.2, + color: AppColors.white50, + ), + ); + } +} diff --git a/experimental/linting_tool/lib/theme/colors.dart b/experimental/linting_tool/lib/theme/colors.dart new file mode 100644 index 000000000..9ffebb8e5 --- /dev/null +++ b/experimental/linting_tool/lib/theme/colors.dart @@ -0,0 +1,42 @@ +// Copyright 2021 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/material.dart'; + +class AppColors { + static const Color white50 = Color(0xFFFFFFFF); + + static const Color black800 = Color(0xFF121212); + static const Color black900 = Color(0xFF000000); + + static const Color blue50 = Color(0xFFEEF0F2); + static const Color blue100 = Color(0xFFD2DBE0); + static const Color blue200 = Color(0xFFADBBC4); + static const Color blue300 = Color(0xFF8CA2AE); + static const Color blue600 = Color(0xFF4A6572); + static const Color blue700 = Color(0xFF344955); + static const Color blue800 = Color(0xFF232F34); + + static const Color orange300 = Color(0xFFFBD790); + static const Color orange400 = Color(0xFFF9BE64); + static const Color orange500 = Color(0xFFF9AA33); + + static const Color red200 = Color(0xFFCF7779); + static const Color red400 = Color(0xFFFF4C5D); + + static const Color white50Alpha060 = Color(0x99FFFFFF); + + static const Color blue50Alpha060 = Color(0x99EEF0F2); + + static const Color black900Alpha020 = Color(0x33000000); + static const Color black900Alpha087 = Color(0xDE000000); + static const Color black900Alpha060 = Color(0x99000000); + + static const Color greyLabel = Color(0xFFAEAEAE); + static const Color darkBottomAppBarBackground = Color(0xFF2D2D2D); + static const Color darkDrawerBackground = Color(0xFF353535); + static const Color darkCardBackground = Color(0xFF1E1E1E); + static const Color darkChipBackground = Color(0xFF2A2A2A); + static const Color lightChipBackground = Color(0xFFE5E5E5); +} diff --git a/experimental/linting_tool/lib/widgets/adaptive_nav.dart b/experimental/linting_tool/lib/widgets/adaptive_nav.dart new file mode 100644 index 000000000..a143030e0 --- /dev/null +++ b/experimental/linting_tool/lib/widgets/adaptive_nav.dart @@ -0,0 +1,334 @@ +// Copyright 2021 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 'dart:math' as math; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:linting_tool/pages/default_lints_page.dart'; +import 'package:linting_tool/pages/home_page.dart'; +import 'package:linting_tool/pages/saved_lints_page.dart'; +import 'package:linting_tool/layout/adaptive.dart'; +import 'package:linting_tool/theme/colors.dart'; + +final navKey = GlobalKey<NavigatorState>(); + +class AdaptiveNav extends StatefulWidget { + const AdaptiveNav({Key? key}) : super(key: key); + + @override + _AdaptiveNavState createState() => _AdaptiveNavState(); +} + +class _AdaptiveNavState extends State<AdaptiveNav> { + @override + Widget build(BuildContext context) { + final isDesktop = isDisplayLarge(context); + const _navigationDestinations = <_Destination>[ + _Destination( + textLabel: 'Home', + icon: Icons.home_outlined, + selectedIcon: Icons.home, + destination: HomePage(), + ), + _Destination( + textLabel: 'Saved Profiles', + icon: Icons.save_outlined, + selectedIcon: Icons.save, + destination: SavedLintsPage(), + ), + _Destination( + textLabel: 'Default Profiles', + icon: Icons.featured_play_list_outlined, + selectedIcon: Icons.featured_play_list, + destination: DefaultLintsPage(), + ), + ]; + + final _trailing = <String, IconData>{ + 'About': Icons.info_outline, + }; + + return _NavView( + extended: isDesktop, + destinations: _navigationDestinations, + trailing: _trailing, + ); + } +} + +class _NavView extends StatefulWidget { + const _NavView({ + Key? key, + required this.extended, + required this.destinations, + this.trailing, + }) : super(key: key); + + final bool extended; + final List<_Destination> destinations; + final Map<String, IconData>? trailing; + + @override + _NavViewState createState() => _NavViewState(); +} + +class _NavViewState extends State<_NavView> { + late ValueNotifier<bool?> _isExtended; + var _selectedIndex = 0; + + @override + void initState() { + super.initState(); + _isExtended = ValueNotifier<bool?>(widget.extended); + } + + void _onDestinationSelected(int index) { + setState(() { + _selectedIndex = index; + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Row( + children: [ + LayoutBuilder( + builder: (context, constraints) { + return SingleChildScrollView( + clipBehavior: Clip.antiAlias, + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: constraints.maxHeight, + ), + child: IntrinsicHeight( + child: ValueListenableBuilder<bool?>( + valueListenable: _isExtended, + builder: (context, value, child) { + var isSmallDisplay = isDisplaySmall(context); + return NavigationRail( + destinations: [ + for (var destination in widget.destinations) + NavigationRailDestination( + icon: Icon(destination.icon), + selectedIcon: destination.selectedIcon != null + ? Icon(destination.selectedIcon) + : null, + label: Text(destination.textLabel), + ), + ], + extended: _isExtended.value! && !isSmallDisplay, + labelType: NavigationRailLabelType.none, + leading: _NavigationRailHeader( + extended: _isExtended, + ), + trailing: _NavigationRailTrailingSection( + trailingDestinations: widget.trailing!, + ), + selectedIndex: _selectedIndex, + onDestinationSelected: _onDestinationSelected, + ); + }, + ), + ), + ), + ); + }, + ), + const VerticalDivider(thickness: 1, width: 1), + Expanded( + child: Center( + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 1340), + child: AnimatedSwitcher( + duration: const Duration(milliseconds: 300), + switchOutCurve: Curves.easeOut, + switchInCurve: Curves.easeIn, + child: widget.destinations[_selectedIndex].destination, + ), + ), + ), + ), + ], + ), + ); + } +} + +class _NavigationRailHeader extends StatelessWidget { + const _NavigationRailHeader({ + required this.extended, + }); + + final ValueNotifier<bool?> extended; + + @override + Widget build(BuildContext context) { + final textTheme = Theme.of(context).textTheme; + final animation = NavigationRail.extendedAnimation(context); + + return AnimatedBuilder( + animation: animation, + builder: (context, child) { + return Align( + alignment: AlignmentDirectional.centerStart, + widthFactor: animation.value, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 56, + child: Row( + children: [ + const SizedBox(width: 6), + InkWell( + key: const ValueKey('ReplyLogo'), + borderRadius: const BorderRadius.all(Radius.circular(16)), + onTap: () { + extended.value = !extended.value!; + }, + child: Row( + children: [ + Transform.rotate( + angle: animation.value * math.pi, + child: const Icon( + Icons.arrow_left, + color: AppColors.white50, + size: 16, + ), + ), + const FlutterLogo(), + const SizedBox(width: 10), + Align( + alignment: AlignmentDirectional.centerStart, + widthFactor: animation.value, + child: Opacity( + opacity: animation.value, + child: Text( + 'Linting Tool', + style: textTheme.bodyText1!.copyWith( + color: AppColors.white50, + ), + ), + ), + ), + SizedBox(width: 18 * animation.value), + ], + ), + ), + ], + ), + ), + const SizedBox(height: 8), + ], + ), + ); + }, + ); + } +} + +class _NavigationRailTrailingSection extends StatelessWidget { + const _NavigationRailTrailingSection({ + required this.trailingDestinations, + }); + + final Map<String, IconData> trailingDestinations; + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + final textTheme = theme.textTheme; + final navigationRailTheme = theme.navigationRailTheme; + final animation = NavigationRail.extendedAnimation(context); + + return AnimatedBuilder( + animation: animation, + builder: (context, child) { + return Visibility( + maintainAnimation: true, + maintainState: true, + visible: animation.value > 0, + child: Opacity( + opacity: animation.value, + child: Align( + widthFactor: animation.value, + alignment: AlignmentDirectional.centerStart, + child: SizedBox( + height: 485, + width: 256, + child: ListView( + padding: const EdgeInsets.all(12), + physics: const NeverScrollableScrollPhysics(), + children: [ + const Divider( + color: AppColors.blue200, + thickness: 0.4, + indent: 14, + endIndent: 16, + ), + const SizedBox(height: 8), + for (var item in trailingDestinations.keys) + InkWell( + borderRadius: const BorderRadius.all( + Radius.circular(36), + ), + onTap: () => _onTapped(context, item), + child: Column( + children: [ + Row( + children: [ + const SizedBox(width: 12), + Icon( + trailingDestinations[item], + color: AppColors.blue300, + ), + const SizedBox(width: 24), + Text( + item, + style: textTheme.bodyText1!.copyWith( + color: navigationRailTheme + .unselectedLabelTextStyle!.color, + ), + ), + const SizedBox(height: 72), + ], + ), + ], + ), + ), + ], + ), + ), + ), + ), + ); + }, + ); + } + + void _onTapped(BuildContext context, String key) { + switch (key) { + case 'About': + showAboutDialog(context: context); + break; + default: + break; + } + } +} + +class _Destination { + const _Destination({ + required this.destination, + required this.textLabel, + required this.icon, + this.selectedIcon, + }); + + final String textLabel; + final IconData icon; + final IconData? selectedIcon; + final Widget destination; +} diff --git a/experimental/linting_tool/macos/Flutter/Flutter-Debug.xcconfig b/experimental/linting_tool/macos/Flutter/Flutter-Debug.xcconfig index c2efd0b60..4b81f9b2d 100644 --- a/experimental/linting_tool/macos/Flutter/Flutter-Debug.xcconfig +++ b/experimental/linting_tool/macos/Flutter/Flutter-Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/experimental/linting_tool/macos/Flutter/Flutter-Release.xcconfig b/experimental/linting_tool/macos/Flutter/Flutter-Release.xcconfig index c2efd0b60..5caa9d157 100644 --- a/experimental/linting_tool/macos/Flutter/Flutter-Release.xcconfig +++ b/experimental/linting_tool/macos/Flutter/Flutter-Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/experimental/linting_tool/macos/Flutter/GeneratedPluginRegistrant.swift b/experimental/linting_tool/macos/Flutter/GeneratedPluginRegistrant.swift index cccf817a5..0d56f519c 100644 --- a/experimental/linting_tool/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/experimental/linting_tool/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,6 +5,8 @@ import FlutterMacOS import Foundation +import path_provider_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) } diff --git a/experimental/linting_tool/macos/Podfile b/experimental/linting_tool/macos/Podfile new file mode 100644 index 000000000..dade8dfad --- /dev/null +++ b/experimental/linting_tool/macos/Podfile @@ -0,0 +1,40 @@ +platform :osx, '10.11' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_macos_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end diff --git a/experimental/linting_tool/macos/Podfile.lock b/experimental/linting_tool/macos/Podfile.lock new file mode 100644 index 000000000..328ddd1ae --- /dev/null +++ b/experimental/linting_tool/macos/Podfile.lock @@ -0,0 +1,22 @@ +PODS: + - FlutterMacOS (1.0.0) + - path_provider_macos (0.0.1): + - FlutterMacOS + +DEPENDENCIES: + - FlutterMacOS (from `Flutter/ephemeral`) + - path_provider_macos (from `Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos`) + +EXTERNAL SOURCES: + FlutterMacOS: + :path: Flutter/ephemeral + path_provider_macos: + :path: Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos + +SPEC CHECKSUMS: + FlutterMacOS: 57701585bf7de1b3fc2bb61f6378d73bbdea8424 + path_provider_macos: a0a3fd666cb7cd0448e936fb4abad4052961002b + +PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c + +COCOAPODS: 1.10.1 diff --git a/experimental/linting_tool/macos/Runner.xcodeproj/project.pbxproj b/experimental/linting_tool/macos/Runner.xcodeproj/project.pbxproj index 7ec458b9a..5eac5b098 100644 --- a/experimental/linting_tool/macos/Runner.xcodeproj/project.pbxproj +++ b/experimental/linting_tool/macos/Runner.xcodeproj/project.pbxproj @@ -21,6 +21,7 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 263EC21EDDA79B90E36D3AF2 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BA99C65F70358A600BD0DB9 /* Pods_Runner.framework */; }; 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; @@ -52,9 +53,10 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 1FF9829B1C25BAA5E9CFD6F7 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; }; 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; }; - 33CC10ED2044A3C60003C045 /* linting_tool.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "linting_tool.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* linting_tool.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = linting_tool.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; }; @@ -66,7 +68,10 @@ 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; }; 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; }; + 4BA99C65F70358A600BD0DB9 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 66D130ED505BEFC4C780F92C /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; }; + 7E301E068432A8A69757147C /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; }; /* End PBXFileReference section */ @@ -75,6 +80,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 263EC21EDDA79B90E36D3AF2 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -99,6 +105,7 @@ 33CEB47122A05771004F2AC0 /* Flutter */, 33CC10EE2044A3C60003C045 /* Products */, D73912EC22F37F3D000D13A0 /* Frameworks */, + 51EE2FAB634AFBA8448DB770 /* Pods */, ); sourceTree = "<group>"; }; @@ -145,9 +152,21 @@ path = Runner; sourceTree = "<group>"; }; + 51EE2FAB634AFBA8448DB770 /* Pods */ = { + isa = PBXGroup; + children = ( + 66D130ED505BEFC4C780F92C /* Pods-Runner.debug.xcconfig */, + 1FF9829B1C25BAA5E9CFD6F7 /* Pods-Runner.release.xcconfig */, + 7E301E068432A8A69757147C /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = "<group>"; + }; D73912EC22F37F3D000D13A0 /* Frameworks */ = { isa = PBXGroup; children = ( + 4BA99C65F70358A600BD0DB9 /* Pods_Runner.framework */, ); name = Frameworks; sourceTree = "<group>"; @@ -159,11 +178,13 @@ isa = PBXNativeTarget; buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + FA1FF96E71045A62F03992DA /* [CP] Check Pods Manifest.lock */, 33CC10E92044A3C60003C045 /* Sources */, 33CC10EA2044A3C60003C045 /* Frameworks */, 33CC10EB2044A3C60003C045 /* Resources */, 33CC110E2044A8840003C045 /* Bundle Framework */, 3399D490228B24CF009A79C7 /* ShellScript */, + A7CF0EFBD867541ADB9884D5 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -270,6 +291,45 @@ shellPath = /bin/sh; shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; }; + A7CF0EFBD867541ADB9884D5 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + FA1FF96E71045A62F03992DA /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ diff --git a/experimental/linting_tool/macos/Runner.xcworkspace/contents.xcworkspacedata b/experimental/linting_tool/macos/Runner.xcworkspace/contents.xcworkspacedata index 1d526a16e..21a3cc14c 100644 --- a/experimental/linting_tool/macos/Runner.xcworkspace/contents.xcworkspacedata +++ b/experimental/linting_tool/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ <FileRef location = "group:Runner.xcodeproj"> </FileRef> + <FileRef + location = "group:Pods/Pods.xcodeproj"> + </FileRef> </Workspace> diff --git a/experimental/linting_tool/macos/Runner/DebugProfile.entitlements b/experimental/linting_tool/macos/Runner/DebugProfile.entitlements index dddb8a30c..3ba6c1266 100644 --- a/experimental/linting_tool/macos/Runner/DebugProfile.entitlements +++ b/experimental/linting_tool/macos/Runner/DebugProfile.entitlements @@ -6,6 +6,8 @@ <true/> <key>com.apple.security.cs.allow-jit</key> <true/> + <key>com.apple.security.network.client</key> + <true/> <key>com.apple.security.network.server</key> <true/> </dict> diff --git a/experimental/linting_tool/macos/Runner/Info.plist b/experimental/linting_tool/macos/Runner/Info.plist index 4789daa6a..485f6f479 100644 --- a/experimental/linting_tool/macos/Runner/Info.plist +++ b/experimental/linting_tool/macos/Runner/Info.plist @@ -13,7 +13,7 @@ <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> - <string>$(PRODUCT_NAME)</string> + <string>Flutter Linting Tool</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> diff --git a/experimental/linting_tool/pubspec.lock b/experimental/linting_tool/pubspec.lock index 29526b6b5..9b9d9436a 100644 --- a/experimental/linting_tool/pubspec.lock +++ b/experimental/linting_tool/pubspec.lock @@ -1,6 +1,13 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + adaptive_breakpoints: + dependency: "direct main" + description: + name: adaptive_breakpoints + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4" async: dependency: transitive description: @@ -43,6 +50,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.15.0" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" cupertino_icons: dependency: "direct main" description: @@ -57,6 +71,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.2" flutter: dependency: "direct main" description: flutter @@ -74,6 +102,27 @@ packages: description: flutter source: sdk version: "0.0.0" + google_fonts: + dependency: "direct main" + description: + name: google_fonts + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.3" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" lints: dependency: transitive description: @@ -102,6 +151,69 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.0" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.11.1" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.1" sky_engine: dependency: transitive description: flutter @@ -163,5 +275,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.5" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0" sdks: - dart: ">=2.12.0 <3.0.0" + dart: ">=2.13.0 <3.0.0" + flutter: ">=1.20.0" diff --git a/experimental/linting_tool/pubspec.yaml b/experimental/linting_tool/pubspec.yaml index a78b1c825..e2d777bd3 100644 --- a/experimental/linting_tool/pubspec.yaml +++ b/experimental/linting_tool/pubspec.yaml @@ -9,8 +9,9 @@ environment: dependencies: flutter: sdk: flutter - + adaptive_breakpoints: ^0.0.4 cupertino_icons: ^1.0.2 + google_fonts: ^2.1.0 dev_dependencies: flutter_test: diff --git a/experimental/linting_tool/test/widget_test.dart b/experimental/linting_tool/test/widget_test.dart index b8f99f38d..ca2c76550 100644 --- a/experimental/linting_tool/test/widget_test.dart +++ b/experimental/linting_tool/test/widget_test.dart @@ -5,26 +5,29 @@ // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. -import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; - -import 'package:linting_tool/main.dart'; +import 'package:linting_tool/app.dart'; +import 'package:linting_tool/pages/default_lints_page.dart'; +import 'package:linting_tool/pages/home_page.dart'; +import 'package:linting_tool/pages/saved_lints_page.dart'; void main() { - testWidgets('Counter increments smoke test', (tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); + testWidgets('NavigationRail smoke test', (tester) async { + await tester.pumpWidget(const LintingTool()); - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); + expect(find.byType(SavedLintsPage), findsNothing); + await tester.tap(find.text('Saved Profiles')); + await tester.pumpAndSettle(); + expect(find.byType(SavedLintsPage), findsOneWidget); - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); + expect(find.byType(DefaultLintsPage), findsNothing); + await tester.tap(find.text('Default Profiles')); + await tester.pumpAndSettle(); + expect(find.byType(DefaultLintsPage), findsOneWidget); - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); + expect(find.byType(HomePage), findsNothing); + await tester.tap(find.text('Home')); + await tester.pumpAndSettle(); + expect(find.byType(HomePage), findsOneWidget); }); } diff --git a/tool/flutter_ci_script_beta.sh b/tool/flutter_ci_script_beta.sh index 43591cc6e..3160b6e2d 100755 --- a/tool/flutter_ci_script_beta.sh +++ b/tool/flutter_ci_script_beta.sh @@ -22,6 +22,7 @@ declare -ar PROJECT_NAMES=( "experimental/federated_plugin/federated_plugin" # TODO(redbrogdon): Restore during next beta branch merge. # "experimental/web_dashboard" + "experimental/linting_tool" "flutter_maps_firestore" "infinite_list" "ios_app_clip" diff --git a/tool/flutter_ci_script_dev.sh b/tool/flutter_ci_script_dev.sh index 8fcc9fcb6..0546ec22a 100755 --- a/tool/flutter_ci_script_dev.sh +++ b/tool/flutter_ci_script_dev.sh @@ -22,6 +22,7 @@ declare -ar PROJECT_NAMES=( "experimental/federated_plugin/federated_plugin" # TODO(redbrogdon): Restore during next beta branch merge. # "experimental/web_dashboard" + "experimental/linting_tool" "flutter_maps_firestore" "infinite_list" "ios_app_clip" diff --git a/tool/flutter_ci_script_stable.sh b/tool/flutter_ci_script_stable.sh index b6db4f4cc..3a3a54e32 100755 --- a/tool/flutter_ci_script_stable.sh +++ b/tool/flutter_ci_script_stable.sh @@ -17,6 +17,7 @@ declare -ar PROJECT_NAMES=( "experimental/desktop_photo_search" "experimental/federated_plugin/federated_plugin" "experimental/web_dashboard" + "experimental/linting_tool" "flutter_maps_firestore" "infinite_list" "ios_app_clip"