feat: can generate app with(out) router, l10n, analysis

This commit is contained in:
Hugo Pointcheval 2022-06-28 10:53:55 +02:00
parent 6f8b7ab7a1
commit 844b86d20f
Signed by: hugo
GPG Key ID: A9E8E9615379254F
14 changed files with 182 additions and 27 deletions

View File

@ -26,7 +26,7 @@ upgrade: clean ## Upgrades dependencies.
format: ## Formats the code.
@echo "• Formatting the code"
@dart format .
@dart format . --fix
lint: ## Lints the code.
@echo "• Verifying code..."

View File

@ -0,0 +1,5 @@
{
"@@locale": "fr_FR",
"counterAppBarTitle": "Compteur",
"goToCounter": "Aller au Compteur"
}

View File

@ -10,17 +10,17 @@ class App extends StatelessWidget {
Widget build(BuildContext context) {
// Data providers
// ...
return MultiRepositoryProvider(
providers: [
// Repositories
],
child: MultiBlocProvider(
providers: [
// Toplevel Blocs and Cubits
],
child: const WidgetTree(),
),
);
// return MultiRepositoryProvider(
// providers: [
// // Repositories
// ],
// child: MultiBlocProvider(
// providers: [
// // Toplevel Blocs and Cubits
// ],
// child: const WidgetTree(),
// ),
// );
return const WidgetTree();
}
}
}

View File

@ -0,0 +1,8 @@
import 'package:bloc/bloc.dart';
class CounterCubit extends Cubit<int> {
CounterCubit() : super(0);
void increment() => emit(state + 1);
void decrement() => emit(state - 1);
}

View File

@ -0,0 +1,40 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/logic/counter_cubit/counter_cubit.dart';
import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/shared/state_management/counter_state_management.dart';
{{#enable_l10n}}import 'package:{{project_name.snakeCase()}}/generated/l10n.dart';{{/enable_l10n}}
import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/presentation/pages/counter/widgets/counter_text.dart';
class CounterPage extends StatelessWidget {
const CounterPage({super.key});
@override
Widget build(BuildContext context) {
return CounterStateManagement(
builder: (BuildContext context, int state) {
return Scaffold(
{{#enable_l10n}}appBar: AppBar(title: Text(S.of(context).counterAppBarTitle)),{{/enable_l10n}}
{{^enable_l10n}}appBar: AppBar(title: Text('Counter')),{{/enable_l10n}}
body: const Center(child: CounterText()),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
FloatingActionButton(
heroTag: 'increment_tag',
onPressed: () => context.read<CounterCubit>().increment(),
child: const Icon(Icons.add),
),
const SizedBox(height: 8),
FloatingActionButton(
heroTag: 'decrement_tag',
onPressed: () => context.read<CounterCubit>().decrement(),
child: const Icon(Icons.remove),
),
],
),
);
}
);
}
}

View File

@ -0,0 +1,14 @@
import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/logic/counter_cubit/counter_cubit.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class CounterText extends StatelessWidget {
const CounterText({super.key});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final count = context.select((CounterCubit cubit) => cubit.state);
return Text('$count', style: theme.textTheme.headline1);
}
}

View File

@ -1,4 +1,8 @@
import 'package:flutter/material.dart';
{{#enable_router}}import 'package:go_router/go_router.dart';
import 'package:{{project_name.snakeCase()}}/resources/app_router.dart';{{/enable_router}}
{{^enable_router}}import 'package:{{project_name.snakeCase()}}/presentation/pages/counter/counter_page.dart';{{/enable_router}}
{{#enable_l10n}}import 'package:{{project_name.snakeCase()}}/generated/l10n.dart';{{/enable_l10n}}
class InitialPage extends StatelessWidget {
const InitialPage({super.key});
@ -6,8 +10,17 @@ class InitialPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('{{project_name.titleCase()}}')),
body: Column(
children: [
const Center(child: Text('{{project_name.titleCase()}}'),),
Center(child: ElevatedButton(
{{#enable_router}}onPressed: () => context.goNamed(AppRouter.counter),{{/enable_router}}
{{^enable_router}}onPressed: () => Navigator.of(context).push(MaterialPageRoute(builder: (context) => CounterPage())),{{/enable_router}}
{{#enable_l10n}}child: Text(S.of(context).goToCounter),{{/enable_l10n}}
{{^enable_l10n}}child: Text('Go to counter'),{{/enable_l10n}}
),)
],
),
);
}
}
}

View File

@ -0,0 +1,26 @@
import 'package:{{#snakeCase}}{{project_name}}{{/snakeCase}}/core/logic/counter_cubit/counter_cubit.dart';
import 'package:flutter/material.dart';
import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart';
class CounterStateManagement extends CubitScreen<CounterCubit, int> {
const CounterStateManagement({
super.key,
this.init,
required this.builder,
});
final void Function(CounterCubit cubit)? init;
final Widget Function(BuildContext context, int state) builder;
@override
CounterCubit create(BuildContext context) {
final cubit = CounterCubit();
init?.call(cubit);
return cubit;
}
@override
Widget onBuild(BuildContext context, int state) {
return builder.call(context, state);
}
}

View File

@ -0,0 +1,7 @@
import 'package:flutter/material.dart';
abstract class AppTheme {
static ThemeData defaultTheme = ThemeData(
primaryColor: Colors.blue
);
}

View File

@ -1,9 +1,11 @@
import 'package:{{project_name.snakeCase()}}/presentation/pages/initial/initial_page.dart';
import 'package:{{project_name.snakeCase()}}/presentation/pages/counter/counter_page.dart';
import 'package:go_router/go_router.dart';
import 'package:flutter/material.dart';
abstract class AppRouter {
static const String initial = 'initial';
static const String counter = 'counter';
static final List<GoRoute> routes = [
GoRoute(
@ -14,5 +16,13 @@ abstract class AppRouter {
child: const InitialPage(),
),
),
GoRoute(
path: '/counter',
name: counter,
pageBuilder: (context, state) => MaterialPage<void>(
key: state.pageKey,
child: const CounterPage(),
),
),
];
}
}

View File

@ -31,6 +31,7 @@ class WidgetTree extends StatelessWidget {
debugShowCheckedModeBanner: false,
title: '{{project_name.titleCase()}}',
routeInformationParser: _router.routeInformationParser,
routeInformationProvider: _router.routeInformationProvider,
routerDelegate: _router.routerDelegate,
theme: AppTheme.defaultTheme,
{{#enable_l10n}}localizationsDelegates: const [

View File

@ -26,14 +26,7 @@ dependencies:
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
ref: wyatt_form_bloc-v0.0.2
path: packages/wyatt_form_bloc
#{{/enable_forms}}{{#enable_bloc}} State management: BLoC
flutter_bloc: ^8.0.1
wyatt_bloc_helper:
git:
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
ref: wyatt_bloc_helper-v1.1.0
path: packages/wyatt_bloc_helper
#{{/enable_bloc}}{{#enable_freezed}} Freezed: model generation
#{{/enable_forms}}{{#enable_freezed}} Freezed: model generation
freezed_annotation: ^2.0.3
json_annotation: ^4.5.0
# {{/enable_freezed}}{{#enable_http}} Advanced HTTP Client
@ -46,9 +39,16 @@ dependencies:
go_router: ^4.1.0
# {{/enable_router}}
flutter_bloc: ^8.0.1
equatable: ^2.0.3
flutter_screenutil: ^5.5.3+2
gap: ^2.0.0
wyatt_bloc_helper:
git:
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
ref: wyatt_bloc_helper-v1.1.0
path: packages/wyatt_bloc_helper
dev_dependencies:
flutter_test:

View File

@ -0,0 +1,32 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'dart:io';
import 'package:mason/mason.dart';
Future<void> run(HookContext context) async {
final workingDirectory = '${Directory.current.path}';
final enablel10n = context.vars['enable_l10n'] as bool;
if (enablel10n) {
final processIntl = await Process.start(
'make',
['intl'],
workingDirectory: workingDirectory,
);
await processIntl.stdout.pipe(stdout);
}
}

View File

@ -37,5 +37,4 @@ void run(HookContext context) {
'enable_forms': features?.contains('forms') ?? false,
};
context.vars = {...context.vars, ...enabled_platforms, ...enabled_features};
context.logger.info(context.vars.toString());
}