mirror of
https://github.com/flutter/samples.git
synced 2025-11-08 22:09:06 +00:00
[linting_tool] Add Adaptive Layout with Theming (#852)
This commit is contained in:
committed by
GitHub
parent
35f1670098
commit
8e73c73f4b
40
experimental/linting_tool/lib/app.dart
Normal file
40
experimental/linting_tool/lib/app.dart
Normal file
@@ -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;
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
23
experimental/linting_tool/lib/layout/adaptive.dart
Normal file
23
experimental/linting_tool/lib/layout/adaptive.dart
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
15
experimental/linting_tool/lib/pages/default_lints_page.dart
Normal file
15
experimental/linting_tool/lib/pages/default_lints_page.dart
Normal file
@@ -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');
|
||||
}
|
||||
}
|
||||
15
experimental/linting_tool/lib/pages/home_page.dart
Normal file
15
experimental/linting_tool/lib/pages/home_page.dart
Normal file
@@ -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');
|
||||
}
|
||||
}
|
||||
15
experimental/linting_tool/lib/pages/saved_lints_page.dart
Normal file
15
experimental/linting_tool/lib/pages/saved_lints_page.dart
Normal file
@@ -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');
|
||||
}
|
||||
}
|
||||
6
experimental/linting_tool/lib/routes.dart
Normal file
6
experimental/linting_tool/lib/routes.dart
Normal file
@@ -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.
|
||||
208
experimental/linting_tool/lib/theme/app_theme.dart
Normal file
208
experimental/linting_tool/lib/theme/app_theme.dart
Normal file
@@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
42
experimental/linting_tool/lib/theme/colors.dart
Normal file
42
experimental/linting_tool/lib/theme/colors.dart
Normal file
@@ -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);
|
||||
}
|
||||
334
experimental/linting_tool/lib/widgets/adaptive_nav.dart
Normal file
334
experimental/linting_tool/lib/widgets/adaptive_nav.dart
Normal file
@@ -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;
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import path_provider_macos
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
}
|
||||
|
||||
40
experimental/linting_tool/macos/Podfile
Normal file
40
experimental/linting_tool/macos/Podfile
Normal file
@@ -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
|
||||
22
experimental/linting_tool/macos/Podfile.lock
Normal file
22
experimental/linting_tool/macos/Podfile.lock
Normal file
@@ -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
|
||||
@@ -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 */
|
||||
|
||||
@@ -4,4 +4,7 @@
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user