Compare commits

..

No commits in common. "25cf9518f9761d450245538dd7e2f5e539d8f1cb" and "d098d9a6bf518a5a23208f30914a9b2f5e42bba0" have entirely different histories.

160 changed files with 506 additions and 479 deletions

View File

@ -24,17 +24,13 @@ scripts:
melos exec -c 1 -- flutter analyze --fatal-infos melos exec -c 1 -- flutter analyze --fatal-infos
description: Run `flutter analyze` for all packages. description: Run `flutter analyze` for all packages.
fix:
run: melos exec dart fix . --apply
description: Run `dart fix` for all packages.
format: format:
run: melos exec dart format . run: melos exec flutter format . --fix
description: Run `dart format` for all packages. description: Run `flutter format` for all packages.
format-check: format-check:
run: melos exec dart fix . --set-exit-if-changed run: melos exec flutter format . --set-exit-if-changed
description: Run `dart fix` checks for all packages. description: Run `flutter format` checks for all packages.
clean:deep: clean:deep:
run: git clean -x -d -f -q run: git clean -x -d -f -q

View File

@ -15,6 +15,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:architecture_example/data/models/photo_model.dart'; import 'package:architecture_example/data/models/photo_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';

View File

@ -24,6 +24,7 @@ import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart';
class PhotoRepositoryImpl extends PhotoRepository { class PhotoRepositoryImpl extends PhotoRepository {
PhotoRepositoryImpl( PhotoRepositoryImpl(
this._photoRemoteDataSource, this._photoRemoteDataSource,
this._albumRemoteDataSource, this._albumRemoteDataSource,

View File

@ -21,6 +21,7 @@ import 'package:architecture_example/domain/repositories/photo_repository.dart';
import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_architecture/wyatt_architecture.dart';
class AddPhotoToFavorites extends AsyncUseCase<Photo, List<Photo>> { class AddPhotoToFavorites extends AsyncUseCase<Photo, List<Photo>> {
AddPhotoToFavorites(this._photoRepository); AddPhotoToFavorites(this._photoRepository);
final PhotoRepository _photoRepository; final PhotoRepository _photoRepository;

View File

@ -20,6 +20,7 @@ import 'package:architecture_example/domain/repositories/photo_repository.dart';
import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_architecture/wyatt_architecture.dart';
class CheckIfPhotoIsInFavorites extends AsyncUseCase<int, bool> { class CheckIfPhotoIsInFavorites extends AsyncUseCase<int, bool> {
CheckIfPhotoIsInFavorites(this._photoRepository); CheckIfPhotoIsInFavorites(this._photoRepository);
final PhotoRepository _photoRepository; final PhotoRepository _photoRepository;

View File

@ -19,6 +19,7 @@ import 'package:architecture_example/domain/repositories/photo_repository.dart';
import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_architecture/wyatt_architecture.dart';
class DisplayFavorites extends AsyncUseCase<NoParam, List<Photo>> { class DisplayFavorites extends AsyncUseCase<NoParam, List<Photo>> {
DisplayFavorites(this._photoRepository); DisplayFavorites(this._photoRepository);
final PhotoRepository _photoRepository; final PhotoRepository _photoRepository;

View File

@ -21,6 +21,7 @@ import 'package:architecture_example/domain/repositories/photo_repository.dart';
import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_architecture/wyatt_architecture.dart';
class DisplayPhoto extends AsyncUseCase<int, Photo> { class DisplayPhoto extends AsyncUseCase<int, Photo> {
DisplayPhoto(this._photoRepository); DisplayPhoto(this._photoRepository);
final PhotoRepository _photoRepository; final PhotoRepository _photoRepository;

View File

@ -22,6 +22,7 @@ import 'package:architecture_example/domain/usecases/photos/params/query_paramet
import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_architecture/wyatt_architecture.dart';
class OpenAlbum extends AsyncUseCase<QueryParameters, List<Photo>> { class OpenAlbum extends AsyncUseCase<QueryParameters, List<Photo>> {
OpenAlbum(this._photoRepository); OpenAlbum(this._photoRepository);
final PhotoRepository _photoRepository; final PhotoRepository _photoRepository;

View File

@ -15,6 +15,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
class QueryParameters { class QueryParameters {
QueryParameters(this.start, this.limit, {this.albumId = -1}); QueryParameters(this.start, this.limit, {this.albumId = -1});
final int albumId; final int albumId;
final int? start; final int? start;

View File

@ -21,6 +21,7 @@ import 'package:architecture_example/domain/repositories/photo_repository.dart';
import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_architecture/wyatt_architecture.dart';
class RemovePhotoFromFavorites extends AsyncUseCase<int, List<Photo>> { class RemovePhotoFromFavorites extends AsyncUseCase<int, List<Photo>> {
RemovePhotoFromFavorites(this._photoRepository); RemovePhotoFromFavorites(this._photoRepository);
final PhotoRepository _photoRepository; final PhotoRepository _photoRepository;

View File

@ -22,6 +22,7 @@ import 'package:architecture_example/domain/usecases/photos/params/query_paramet
import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_architecture/wyatt_architecture.dart';
class RetrieveAllAlbums extends AsyncUseCase<QueryParameters, List<Album>> { class RetrieveAllAlbums extends AsyncUseCase<QueryParameters, List<Album>> {
RetrieveAllAlbums(this._photoRepository); RetrieveAllAlbums(this._photoRepository);
final PhotoRepository _photoRepository; final PhotoRepository _photoRepository;

View File

@ -33,6 +33,7 @@ EventTransformer<E> throttleDroppable<E>(Duration duration) =>
(events, mapper) => droppable<E>().call(events.throttle(duration), mapper); (events, mapper) => droppable<E>().call(events.throttle(duration), mapper);
class AlbumBloc extends Bloc<AlbumEvent, AlbumState> { class AlbumBloc extends Bloc<AlbumEvent, AlbumState> {
AlbumBloc(this._retrieveAllAlbums) : super(const AlbumState()) { AlbumBloc(this._retrieveAllAlbums) : super(const AlbumState()) {
on<AlbumFetched>( on<AlbumFetched>(
_onAlbumFetched, _onAlbumFetched,

View File

@ -35,7 +35,7 @@ class AlbumsScreen extends BlocScreen<AlbumBloc, AlbumEvent, AlbumState> {
bloc..add(AlbumFetched()); bloc..add(AlbumFetched());
@override @override
Widget parent(BuildContext context, Widget child) => AlbumsWrapperWidget( Widget onWrap(BuildContext context, Widget child) => AlbumsWrapperWidget(
child: child, child: child,
); );

View File

@ -22,11 +22,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
class AlbumsList extends StatefulWidget { class AlbumsList extends StatefulWidget {
const AlbumsList({ const AlbumsList(
required this.albums, {required this.albums, required this.hasReachedMax, super.key,});
required this.hasReachedMax,
super.key,
});
final List<Album> albums; final List<Album> albums;
final bool hasReachedMax; final bool hasReachedMax;

View File

@ -26,6 +26,7 @@ abstract class PhotoDetailsState extends Equatable {
class PhotoDetailsInitial extends PhotoDetailsState {} class PhotoDetailsInitial extends PhotoDetailsState {}
class PhotoDetailsSuccess extends PhotoDetailsState { class PhotoDetailsSuccess extends PhotoDetailsState {
const PhotoDetailsSuccess(this.photo, {required this.isFavorite}); const PhotoDetailsSuccess(this.photo, {required this.isFavorite});
final Photo photo; final Photo photo;
final bool isFavorite; final bool isFavorite;
@ -35,6 +36,7 @@ class PhotoDetailsSuccess extends PhotoDetailsState {
} }
class PhotoDetailsFailure extends PhotoDetailsState { class PhotoDetailsFailure extends PhotoDetailsState {
const PhotoDetailsFailure(this.error); const PhotoDetailsFailure(this.error);
final String error; final String error;

View File

@ -43,7 +43,7 @@ class PhotoDetailsScreen
bloc..load(photoId); bloc..load(photoId);
@override @override
Widget parent(BuildContext context, Widget child) => Widget onWrap(BuildContext context, Widget child) =>
PhotoDetailsWrapperWidget(child: child); PhotoDetailsWrapperWidget(child: child);
@override @override

View File

@ -23,6 +23,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
part 'favorite_checker_state.dart'; part 'favorite_checker_state.dart';
class FavoriteCheckerCubit extends Cubit<FavoriteCheckerState> { class FavoriteCheckerCubit extends Cubit<FavoriteCheckerState> {
FavoriteCheckerCubit(this._checkIfPhotoIsInFavorites) FavoriteCheckerCubit(this._checkIfPhotoIsInFavorites)
: super(FavoriteCheckerInitial()); : super(FavoriteCheckerInitial());
final CheckIfPhotoIsInFavorites _checkIfPhotoIsInFavorites; final CheckIfPhotoIsInFavorites _checkIfPhotoIsInFavorites;

View File

@ -10,6 +10,7 @@ abstract class FavoriteCheckerState extends Equatable {
class FavoriteCheckerInitial extends FavoriteCheckerState {} class FavoriteCheckerInitial extends FavoriteCheckerState {}
class FavoriteCheckerSuccess extends FavoriteCheckerState { class FavoriteCheckerSuccess extends FavoriteCheckerState {
const FavoriteCheckerSuccess(this.photoId, {required this.isFavorite}); const FavoriteCheckerSuccess(this.photoId, {required this.isFavorite});
final int photoId; final int photoId;
final bool isFavorite; final bool isFavorite;
@ -19,6 +20,7 @@ class FavoriteCheckerSuccess extends FavoriteCheckerState {
} }
class FavoriteCheckerFailure extends FavoriteCheckerState { class FavoriteCheckerFailure extends FavoriteCheckerState {
const FavoriteCheckerFailure(this.error); const FavoriteCheckerFailure(this.error);
final String error; final String error;

View File

@ -33,6 +33,7 @@ EventTransformer<E> throttleDroppable<E>(Duration duration) =>
(events, mapper) => droppable<E>().call(events.throttle(duration), mapper); (events, mapper) => droppable<E>().call(events.throttle(duration), mapper);
class PhotoBloc extends Bloc<PhotoEvent, PhotoState> { class PhotoBloc extends Bloc<PhotoEvent, PhotoState> {
PhotoBloc(this._openAlbum) : super(const PhotoState()) { PhotoBloc(this._openAlbum) : super(const PhotoState()) {
on<PhotoFetched>( on<PhotoFetched>(
_onPhotoFetched, _onPhotoFetched,

View File

@ -24,6 +24,7 @@ abstract class PhotoEvent extends Equatable {
} }
class PhotoFetched extends PhotoEvent { class PhotoFetched extends PhotoEvent {
const PhotoFetched(this.albumId); const PhotoFetched(this.albumId);
final int albumId; final int albumId;
} }

View File

@ -37,7 +37,7 @@ class PhotosScreen extends BlocScreen<PhotoBloc, PhotoEvent, PhotoState> {
bloc..add(PhotoFetched(albumId)); bloc..add(PhotoFetched(albumId));
@override @override
Widget parent(BuildContext context, Widget child) => PhotosWrapperWidget( Widget onWrap(BuildContext context, Widget child) => PhotosWrapperWidget(
child: child, child: child,
); );

View File

@ -55,10 +55,7 @@ class PhotosGridThumbnail
), ),
if (state is FavoriteCheckerSuccess && state.isFavorite) ...[ if (state is FavoriteCheckerSuccess && state.isFavorite) ...[
const Positioned( const Positioned(
bottom: 10, bottom: 10, right: 10, child: Icon(Icons.favorite),)
right: 10,
child: Icon(Icons.favorite),
)
] ]
], ],
), ),

View File

@ -17,6 +17,7 @@
import 'package:wyatt_type_utils/wyatt_type_utils.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart';
abstract class AppException implements Exception { abstract class AppException implements Exception {
AppException([this.message]); AppException([this.message]);
final String? message; final String? message;

View File

@ -35,7 +35,7 @@ class EditProfileCubit extends FormDataCubitImpl {
status: FormStatus.submissionInProgress, status: FormStatus.submissionInProgress,
), ),
); );
// final user = (await authenticationRepository.getAccount()).ok; final user = (await authenticationRepository.getAccount()).ok;
final form = state.form; final form = state.form;
final email = form.valueOf<String?>(AuthFormField.email); final email = form.valueOf<String?>(AuthFormField.email);

View File

@ -25,8 +25,8 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
class MockAuthenticationRepository extends Mock class MockAuthenticationRepository extends Mock
implements AuthenticationRepository<int> {} implements AuthenticationRepository<int> {}
class MockAuthenticationCubit extends Mock class MockAuthenticationCubit extends Mock implements AuthenticationCubit<int> {
implements AuthenticationCubit<int> {} }
class MockAccount extends Mock implements Account {} class MockAccount extends Mock implements Account {}

View File

@ -25,8 +25,8 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
class MockAuthenticationRepository extends Mock class MockAuthenticationRepository extends Mock
implements AuthenticationRepository<int> {} implements AuthenticationRepository<int> {}
class MockAuthenticationCubit extends Mock class MockAuthenticationCubit extends Mock implements AuthenticationCubit<int> {
implements AuthenticationCubit<int> {} }
class MockAccount extends Mock implements Account {} class MockAccount extends Mock implements Account {}

View File

@ -25,8 +25,8 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
class MockAuthenticationRepository extends Mock class MockAuthenticationRepository extends Mock
implements AuthenticationRepository<int> {} implements AuthenticationRepository<int> {}
class MockAuthenticationCubit extends Mock class MockAuthenticationCubit extends Mock implements AuthenticationCubit<int> {
implements AuthenticationCubit<int> {} }
class MockAccount extends Mock implements Account {} class MockAccount extends Mock implements Account {}

View File

@ -25,8 +25,8 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
class MockAuthenticationRepository extends Mock class MockAuthenticationRepository extends Mock
implements AuthenticationRepository<int> {} implements AuthenticationRepository<int> {}
class MockAuthenticationCubit extends Mock class MockAuthenticationCubit extends Mock implements AuthenticationCubit<int> {
implements AuthenticationCubit<int> {} }
class MockAccount extends Mock implements Account {} class MockAccount extends Mock implements Account {}

View File

@ -25,6 +25,7 @@ class CounterBloc extends Bloc<CounterEvent, CounterState> {
final CounterRepository counterRepository; final CounterRepository counterRepository;
CounterBloc(this.counterRepository) : super(const CounterInitial()) { CounterBloc(this.counterRepository) : super(const CounterInitial()) {
on<CounterIncrement>((event, emit) { on<CounterIncrement>((event, emit) {
emit(CounterModified(counterRepository.increment(state.count))); emit(CounterModified(counterRepository.increment(state.count)));
}); });

View File

@ -32,3 +32,4 @@ class CounterInitial extends CounterState {
class CounterModified extends CounterState { class CounterModified extends CounterState {
const CounterModified(super.count); const CounterModified(super.count);
} }

View File

@ -24,16 +24,14 @@ class CounterBlocPage
const CounterBlocPage({super.key}); const CounterBlocPage({super.key});
@override @override
CounterBloc create(BuildContext context) => CounterBloc create(BuildContext context) => CounterBloc(repo<CounterRepository>(context));
CounterBloc(repo<CounterRepository>(context));
@override @override
Widget onBuild(BuildContext context, CounterState state) { Widget onBuild(BuildContext context, CounterState state) {
final textTheme = Theme.of(context).textTheme; final textTheme = Theme.of(context).textTheme;
return Scaffold( return Scaffold(
appBar: AppBar(title: const Text('Counter with Bloc')), appBar: AppBar(title: const Text('Counter with Bloc')),
body: body: Center(child: Text('${state.count}', style: textTheme.headline2)),
Center(child: Text('${state.count}', style: textTheme.displayMedium)),
floatingActionButton: Column( floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,

View File

@ -28,8 +28,7 @@ class CounterConsumerPage
final textTheme = Theme.of(context).textTheme; final textTheme = Theme.of(context).textTheme;
return Scaffold( return Scaffold(
appBar: AppBar(title: const Text('Counter with Consumer')), appBar: AppBar(title: const Text('Counter with Consumer')),
body: body: Center(child: Text('${state.count}', style: textTheme.headline2)),
Center(child: Text('${state.count}', style: textTheme.displayMedium)),
floatingActionButton: Column( floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,

View File

@ -19,20 +19,19 @@ import 'package:bloc_helper_example/counter/repository/counter_repository.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart'; import 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart';
class CounterCubitPage extends CubitScreen<CounterCubit, CounterState> { class CounterCubitPage
extends CubitScreen<CounterCubit, CounterState> {
const CounterCubitPage({super.key}); const CounterCubitPage({super.key});
@override @override
CounterCubit create(BuildContext context) => CounterCubit create(BuildContext context) => CounterCubit(repo<CounterRepository>(context));
CounterCubit(repo<CounterRepository>(context));
@override @override
Widget onBuild(BuildContext context, CounterState state) { Widget onBuild(BuildContext context, CounterState state) {
final textTheme = Theme.of(context).textTheme; final textTheme = Theme.of(context).textTheme;
return Scaffold( return Scaffold(
appBar: AppBar(title: const Text('Counter with Cubit')), appBar: AppBar(title: const Text('Counter with Cubit')),
body: body: Center(child: Text('${state.count}', style: textTheme.headline2)),
Center(child: Text('${state.count}', style: textTheme.displayMedium)),
floatingActionButton: Column( floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,

View File

@ -35,7 +35,7 @@ class CounterProviderPage
appBar: AppBar(title: const Text('Counter with Provider')), appBar: AppBar(title: const Text('Counter with Provider')),
body: Center(child: BlocBuilder<CounterBloc, CounterState>( body: Center(child: BlocBuilder<CounterBloc, CounterState>(
builder: (context, state) { builder: (context, state) {
return Text('${state.count}', style: textTheme.displayMedium); return Text('${state.count}', style: textTheme.headline2);
}, },
)), )),
floatingActionButton: Column( floatingActionButton: Column(

View File

@ -32,3 +32,4 @@ class CounterInitial extends CounterState {
class CounterModified extends CounterState { class CounterModified extends CounterState {
const CounterModified(super.count); const CounterModified(super.count);
} }

View File

@ -20,6 +20,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
void main() { void main() {
Bloc.observer = CounterObserver(); BlocOverrides.runZoned(() => runApp(const CounterRepositoryProviderPage()),
runApp(const CounterRepositoryProviderPage()); blocObserver: CounterObserver());
} }

View File

@ -56,8 +56,7 @@ class MainPage extends StatelessWidget {
onPressed: () => Navigator.of(context) onPressed: () => Navigator.of(context)
.push(MaterialPageRoute(builder: (context) { .push(MaterialPageRoute(builder: (context) {
return BlocProvider<CounterCubit>( return BlocProvider<CounterCubit>(
create: (context) => create: (context) => CounterCubit(context.read<CounterRepository>()),
CounterCubit(context.read<CounterRepository>()),
child: const CounterConsumerPage(), child: const CounterConsumerPage(),
); );
})), })),

View File

@ -1,4 +1,4 @@
# Copyright (C) 2023 WYATT GROUP # Copyright (C) 2022 WYATT GROUP
# Please see the AUTHORS file for details. # Please see the AUTHORS file for details.
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
@ -14,4 +14,6 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
include: package:wyatt_analysis/analysis_options.flutter.yaml
include: package:wyatt_analysis/analysis_options.flutter.experimental.yaml

View File

@ -7,33 +7,31 @@ class ExampleCubit extends Cubit<CrudState> {
FutureOr<void> run() async { FutureOr<void> run() async {
while (true) { while (true) {
await Future<void>.delayed(const Duration(seconds: 1)); await Future.delayed(const Duration(seconds: 1));
emit(CrudLoading()); emit(CrudLoading());
await Future<void>.delayed(const Duration(seconds: 1)); await Future.delayed(const Duration(seconds: 1));
emit(const CrudError('Cubit Error')); emit(CrudError('Cubit Error'));
await Future<void>.delayed(const Duration(seconds: 1)); await Future.delayed(const Duration(seconds: 1));
emit(const CrudLoaded<String>('DATA LOADED')); emit(CrudLoaded<String>('DATA LOADED'));
await Future<void>.delayed(const Duration(seconds: 1)); await Future.delayed(const Duration(seconds: 1));
emit(CrudInitial()); emit(CrudInitial());
} }
} }
FutureOr<void> runList() async { FutureOr<void> runList() async {
while (true) { while (true) {
await Future<void>.delayed(const Duration(seconds: 1)); await Future.delayed(const Duration(seconds: 1));
emit(CrudLoading()); emit(CrudLoading());
await Future<void>.delayed(const Duration(seconds: 1)); await Future.delayed(const Duration(seconds: 1));
emit(const CrudError('Cubit Error')); emit(CrudError('Cubit Error'));
await Future<void>.delayed(const Duration(seconds: 1)); await Future.delayed(const Duration(seconds: 1));
emit( emit(CrudListLoaded<String>([
const CrudListLoaded<String>([
'DATA LOADED 1', 'DATA LOADED 1',
'DATA LOADED 2', 'DATA LOADED 2',
'DATA LOADED 3', 'DATA LOADED 3',
'DATA LOADED 4' 'DATA LOADED 4'
]), ]));
); await Future.delayed(const Duration(seconds: 1));
await Future<void>.delayed(const Duration(seconds: 1));
emit(CrudInitial()); emit(CrudInitial());
} }
} }

View File

@ -7,7 +7,7 @@ part 'custom_app_bar.g.dart';
@ComponentCopyWithExtension() @ComponentCopyWithExtension()
class CustomAppBar extends TopAppBarComponent with $CustomAppBarCWMixin { class CustomAppBar extends TopAppBarComponent with $CustomAppBarCWMixin {
const CustomAppBar({super.key, super.title}); const CustomAppBar({super.title});
@override @override
Widget build(BuildContext context) => AppBar( Widget build(BuildContext context) => AppBar(
title: Text(title?.data ?? 'Title'), title: Text(title?.data ?? 'Title'),

View File

@ -7,23 +7,19 @@ part 'custom_bottom_bar.g.dart';
@ComponentCopyWithExtension() @ComponentCopyWithExtension()
class CustomBottomBar extends BottomNavigationBarComponent class CustomBottomBar extends BottomNavigationBarComponent
with $CustomBottomBarCWMixin { with $CustomBottomBarCWMixin {
const CustomBottomBar({super.key});
@override @override
Widget build(BuildContext context) => BottomNavigationBar( Widget build(BuildContext context) => BottomNavigationBar(
items: const [ items: [
BottomNavigationBarItem( BottomNavigationBarItem(
icon: Icon( icon: Icon(
Icons.e_mobiledata, Icons.e_mobiledata,
), ),
label: 'Icon 1', label: 'Icon 1'),
),
BottomNavigationBarItem( BottomNavigationBarItem(
icon: Icon( icon: Icon(
Icons.do_not_disturb_off, Icons.do_not_disturb_off,
), ),
label: 'Icon 2', label: 'Icon 2'),
),
], ],
backgroundColor: Colors.blue, backgroundColor: Colors.blue,
); );

View File

@ -7,7 +7,7 @@ part 'custom_error_widget.g.dart';
@ComponentCopyWithExtension() @ComponentCopyWithExtension()
class CustomErrorWidget extends ErrorWidgetComponent class CustomErrorWidget extends ErrorWidgetComponent
with $CustomErrorWidgetCWMixin { with $CustomErrorWidgetCWMixin {
CustomErrorWidget({super.key, super.error}); CustomErrorWidget({super.error});
@override @override
Widget build(BuildContext context) => ColoredBox( Widget build(BuildContext context) => ColoredBox(

View File

@ -7,7 +7,7 @@ part 'custom_loading_widget.g.dart';
@ComponentCopyWithExtension() @ComponentCopyWithExtension()
class CustomLoadingWidget extends LoadingWidgetComponent class CustomLoadingWidget extends LoadingWidgetComponent
with $CustomLoadingWidgetCWMixin { with $CustomLoadingWidgetCWMixin {
CustomLoadingWidget({super.key, super.color}); CustomLoadingWidget({super.color});
@override @override
Widget build(BuildContext context) => Widget build(BuildContext context) =>

View File

@ -6,8 +6,8 @@ import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';
class AppThemeComponent { class AppThemeComponent {
static ComponentThemeData get components => ComponentThemeData.raw( static ComponentThemeData get components => ComponentThemeData.raw(
appBar: const CustomAppBar(), appBar: CustomAppBar(),
bottomNavigationBar: const CustomBottomBar(), bottomNavigationBar: CustomBottomBar(),
loadingWidget: CustomLoadingWidget(), loadingWidget: CustomLoadingWidget(),
errorWidget: CustomErrorWidget(), errorWidget: CustomErrorWidget(),
); );

View File

@ -28,7 +28,8 @@ class MyApp extends StatelessWidget {
// This widget is the root of your application. // This widget is the root of your application.
@override @override
Widget build(BuildContext context) => ComponentTheme( Widget build(BuildContext context) {
return ComponentTheme(
componentThemeWidget: AppThemeComponent.components, componentThemeWidget: AppThemeComponent.components,
child: MaterialApp( child: MaterialApp(
title: 'Bloc Layout Example', title: 'Bloc Layout Example',
@ -44,13 +45,13 @@ class MyApp extends StatelessWidget {
Expanded( Expanded(
child: BlocProvider( child: BlocProvider(
create: (_) => ExampleCubit()..run(), create: (_) => ExampleCubit()..run(),
child: const ExampleCrudStateManagement(), child: ExampleCrudStateManagement(),
), ),
), ),
Expanded( Expanded(
child: BlocProvider( child: BlocProvider(
create: (_) => ExampleCubit()..runList(), create: (_) => ExampleCubit()..runList(),
child: const ExampleListCrudStateManagement(), child: ExampleListCrudStateManagement(),
), ),
), ),
], ],
@ -62,14 +63,12 @@ class MyApp extends StatelessWidget {
Expanded( Expanded(
child: BlocProvider( child: BlocProvider(
create: (_) => ExampleCubit()..run(), create: (_) => ExampleCubit()..run(),
child: const ExampleFrameLayoutCrudConsumer(), child: ExampleFrameLayoutCrudConsumer()),
),
), ),
Expanded( Expanded(
child: BlocProvider( child: BlocProvider(
create: (_) => ExampleCubit()..runList(), create: (_) => ExampleCubit()..runList(),
child: const ExampleFrameLayoutCrudListConsumer(), child: ExampleFrameLayoutCrudListConsumer()),
),
), ),
], ],
), ),
@ -80,11 +79,10 @@ class MyApp extends StatelessWidget {
), ),
); );
} }
}
class ExampleCrudStateManagement class ExampleCrudStateManagement
extends CrudCubitConsumerScreen<ExampleCubit, String> { extends CrudCubitConsumerScreen<ExampleCubit, String> {
const ExampleCrudStateManagement({super.key});
@override @override
Widget initialBuilder(BuildContext context, CrudInitial state) => Widget initialBuilder(BuildContext context, CrudInitial state) =>
Container(color: Colors.yellow); Container(color: Colors.yellow);
@ -95,8 +93,6 @@ class ExampleCrudStateManagement
class ExampleListCrudStateManagement class ExampleListCrudStateManagement
extends CrudListCubitConsumerScreen<ExampleCubit, String> { extends CrudListCubitConsumerScreen<ExampleCubit, String> {
const ExampleListCrudStateManagement({super.key});
@override @override
Widget initialBuilder(BuildContext context, CrudInitial state) => Widget initialBuilder(BuildContext context, CrudInitial state) =>
Container(color: Colors.green); Container(color: Colors.green);
@ -110,7 +106,7 @@ class ExampleListCrudStateManagement
class ExampleFrameLayoutCrudConsumer class ExampleFrameLayoutCrudConsumer
extends FrameLayoutCrudCubitConsumerScreen<ExampleCubit, String> { extends FrameLayoutCrudCubitConsumerScreen<ExampleCubit, String> {
const ExampleFrameLayoutCrudConsumer({super.key}) const ExampleFrameLayoutCrudConsumer()
: super( : super(
title: 'Example Title', title: 'Example Title',
currentIndex: 0, currentIndex: 0,
@ -123,7 +119,7 @@ class ExampleFrameLayoutCrudConsumer
class ExampleFrameLayoutCrudListConsumer class ExampleFrameLayoutCrudListConsumer
extends FrameLayoutCrudListCubitConsumerScreen<ExampleCubit, String> { extends FrameLayoutCrudListCubitConsumerScreen<ExampleCubit, String> {
const ExampleFrameLayoutCrudListConsumer({super.key}) const ExampleFrameLayoutCrudListConsumer()
: super( : super(
title: 'Example Title', title: 'Example Title',
currentIndex: 0, currentIndex: 0,

View File

@ -20,7 +20,7 @@ import 'package:flutter_bloc/flutter_bloc.dart' as bloc_base;
import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart'; import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart';
import 'package:wyatt_ui_components/wyatt_wyatt_ui_components.dart'; import 'package:wyatt_ui_components/wyatt_wyatt_ui_components.dart';
mixin CrudMixin<Cubit extends bloc_base.Cubit<dynamic>, mixin CrudMixin<Cubit extends bloc_base.Cubit,
SuccessState extends CrudSuccess> { SuccessState extends CrudSuccess> {
Widget errorBuilder(BuildContext context, CrudError state) => Widget errorBuilder(BuildContext context, CrudError state) =>
context.components.errorWidget?.copyWith(error: state.message.wrap()) ?? context.components.errorWidget?.copyWith(error: state.message.wrap()) ??

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/widgets.dart'; import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_bloc/flutter_bloc.dart' as bloc_base; import 'package:flutter_bloc/flutter_bloc.dart' as bloc_base;
import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart'; import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';

View File

@ -16,5 +16,5 @@
export './app_bar_layout_crud_cubit_consumer_screen.dart'; export './app_bar_layout_crud_cubit_consumer_screen.dart';
export './bottom_bar_layout_crud_cubit_consumer_screen.dart'; export './bottom_bar_layout_crud_cubit_consumer_screen.dart';
export './crud_cubit_consumer_screen.dart';
export './frame_layout_crud_cubit_consumer_screen.dart'; export './frame_layout_crud_cubit_consumer_screen.dart';
export './crud_cubit_consumer_screen.dart';

View File

@ -15,8 +15,8 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart' as bloc_base;
import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart'; import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';
import 'package:flutter_bloc/flutter_bloc.dart' as bloc_base;
abstract class CrudCubitConsumerScreen<Cubit extends bloc_base.Cubit<CrudState>, abstract class CrudCubitConsumerScreen<Cubit extends bloc_base.Cubit<CrudState>,
T extends Object?> extends CubitConsumerScreen<Cubit, CrudState> T extends Object?> extends CubitConsumerScreen<Cubit, CrudState>

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
export './crud_cubit_screen.dart';
export 'app_bar_layout_crud_cubit_screen.dart'; export 'app_bar_layout_crud_cubit_screen.dart';
export 'bottom_bar_layout_crud_cubit_screen.dart'; export 'bottom_bar_layout_crud_cubit_screen.dart';
export 'frame_layout_crud_cubit_screen.dart'; export 'frame_layout_crud_cubit_screen.dart';
export './crud_cubit_screen.dart';

View File

@ -15,8 +15,8 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart' as bloc_base;
import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart'; import 'package:wyatt_bloc_layout/wyatt_bloc_layout.dart';
import 'package:flutter_bloc/flutter_bloc.dart' as bloc_base;
abstract class CrudCubitScreen<Cubit extends bloc_base.Cubit<CrudState>, abstract class CrudCubitScreen<Cubit extends bloc_base.Cubit<CrudState>,
T extends Object?> extends CubitScreen<Cubit, CrudState> T extends Object?> extends CubitScreen<Cubit, CrudState>

View File

@ -14,11 +14,11 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
export 'package:flutter_bloc/flutter_bloc.dart';
export 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart';
export 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart';
export 'package:wyatt_ui_components/wyatt_wyatt_ui_components.dart';
export 'package:wyatt_ui_layout/wyatt_wyatt_ui_layout.dart';
export 'core/core.dart';
export 'presentation/presentation.dart'; export 'presentation/presentation.dart';
export 'core/core.dart';
export 'package:flutter_bloc/flutter_bloc.dart';
export 'package:wyatt_ui_components/wyatt_wyatt_ui_components.dart';
export 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart';
export 'package:wyatt_ui_layout/wyatt_wyatt_ui_layout.dart';
export 'package:wyatt_bloc_helper/wyatt_bloc_helper.dart';

View File

@ -3,17 +3,14 @@ description: Layouts based on bloc helper library
repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_bloc_layout repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_bloc_layout
version: 0.0.1 version: 0.0.1
publish_to: "none"
environment: environment:
sdk: ">=2.17.0 <3.0.0" sdk: '>=2.17.0 <3.0.0'
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
flutter_bloc: ^8.1.2
wyatt_bloc_helper: wyatt_bloc_helper:
git: git:
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
@ -35,9 +32,11 @@ dependencies:
path: packages/wyatt_ui_components path: packages/wyatt_ui_components
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
wyatt_analysis: wyatt_analysis:
git: git:
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages

View File

@ -1 +1,7 @@
include: package:wyatt_analysis/analysis_options.yaml include: package:wyatt_analysis/analysis_options.yaml

View File

@ -3,8 +3,6 @@ description: Generator for copywith method for components.
repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/component_copy_with_gen repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/component_copy_with_gen
version: 1.0.0 version: 1.0.0
publish_to: "none"
environment: environment:
sdk: ">=2.19.0 <3.0.0" sdk: ">=2.19.0 <3.0.0"

View File

@ -92,6 +92,7 @@ class MyHomePage extends StatelessWidget {
); );
}, },
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {
@ -120,7 +121,9 @@ class MyHomePage extends StatelessWidget {
), ),
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {
context.read<UserCubit>().query([LimitQuery(2)]); context
.read<UserCubit>()
.query([LimitQuery(2)]);
}, },
child: const Text("Query"), child: const Text("Query"),
), ),

View File

@ -24,6 +24,7 @@ import 'package:wyatt_crud_bloc/src/domain/entities/query.dart';
class CrudInMemoryDataSourceImpl<Model extends ObjectModel> class CrudInMemoryDataSourceImpl<Model extends ObjectModel>
extends CrudDataSource<Model> { extends CrudDataSource<Model> {
CrudInMemoryDataSourceImpl({required this.toMap, Map<String, Model>? data}) CrudInMemoryDataSourceImpl({required this.toMap, Map<String, Model>? data})
: _data = data ?? {}; : _data = data ?? {};
final Map<String, Model> _data; final Map<String, Model> _data;

View File

@ -22,6 +22,7 @@ import 'package:wyatt_crud_bloc/src/domain/entities/query.dart';
class CrudFirestoreDataSourceImpl<Model extends ObjectModel, Entity> class CrudFirestoreDataSourceImpl<Model extends ObjectModel, Entity>
extends CrudDataSource<Model> { extends CrudDataSource<Model> {
CrudFirestoreDataSourceImpl( CrudFirestoreDataSourceImpl(
String collection, { String collection, {
required Model Function( required Model Function(

View File

@ -23,6 +23,7 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
class CrudRepositoryImpl<Model extends ObjectModel> class CrudRepositoryImpl<Model extends ObjectModel>
extends CrudRepository<Model> { extends CrudRepository<Model> {
CrudRepositoryImpl({ CrudRepositoryImpl({
required CrudDataSource<Model> crudDataSource, required CrudDataSource<Model> crudDataSource,
}) : _crudDataSource = crudDataSource; }) : _crudDataSource = crudDataSource;

View File

@ -25,6 +25,7 @@ abstract class QueryParser<Q> {
abstract class QueryInterface extends Entity {} abstract class QueryInterface extends Entity {}
class WhereQuery<Value> extends QueryInterface { class WhereQuery<Value> extends QueryInterface {
WhereQuery(this.type, this.field, this.value); WhereQuery(this.type, this.field, this.value);
final WhereQueryType type; final WhereQueryType type;
final String field; final String field;
@ -32,11 +33,13 @@ class WhereQuery<Value> extends QueryInterface {
} }
class LimitQuery extends QueryInterface { class LimitQuery extends QueryInterface {
LimitQuery(this.limit); LimitQuery(this.limit);
final int limit; final int limit;
} }
class OrderByQuery extends QueryInterface { class OrderByQuery extends QueryInterface {
OrderByQuery(this.field, {this.ascending = true}); OrderByQuery(this.field, {this.ascending = true});
final String field; final String field;
final bool ascending; final bool ascending;

View File

@ -21,6 +21,7 @@ import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart';
import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart';
class Delete<Model extends ObjectModel> extends AsyncUseCase<String, void> { class Delete<Model extends ObjectModel> extends AsyncUseCase<String, void> {
Delete(this._crudRepository); Delete(this._crudRepository);
final CrudRepository<Model> _crudRepository; final CrudRepository<Model> _crudRepository;

View File

@ -19,6 +19,7 @@ import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart';
import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart';
class DeleteAll<Model extends ObjectModel> extends AsyncUseCase<void, void> { class DeleteAll<Model extends ObjectModel> extends AsyncUseCase<void, void> {
DeleteAll(this._crudRepository); DeleteAll(this._crudRepository);
final CrudRepository<Model> _crudRepository; final CrudRepository<Model> _crudRepository;

View File

@ -21,6 +21,7 @@ import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart';
import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart'; import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart';
class Get<Model extends ObjectModel> extends AsyncUseCase<String, Model?> { class Get<Model extends ObjectModel> extends AsyncUseCase<String, Model?> {
Get(this._crudRepository); Get(this._crudRepository);
final CrudRepository<Model> _crudRepository; final CrudRepository<Model> _crudRepository;

View File

@ -20,6 +20,7 @@ import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart';
class GetAll<Model extends ObjectModel> class GetAll<Model extends ObjectModel>
extends AsyncUseCase<void, List<Model?>> { extends AsyncUseCase<void, List<Model?>> {
GetAll(this._crudRepository); GetAll(this._crudRepository);
final CrudRepository<Model> _crudRepository; final CrudRepository<Model> _crudRepository;

View File

@ -23,6 +23,7 @@ import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart';
class Query<Model extends ObjectModel> class Query<Model extends ObjectModel>
extends AsyncUseCase<List<QueryInterface>, List<Model?>> { extends AsyncUseCase<List<QueryInterface>, List<Model?>> {
Query(this._crudRepository); Query(this._crudRepository);
final CrudRepository<Model> _crudRepository; final CrudRepository<Model> _crudRepository;

View File

@ -14,8 +14,9 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
// class Stream<Model extends ObjectModel> extends UseCase<StreamParameters,
//List<Model?>> {
// class Stream<Model extends ObjectModel> extends UseCase<StreamParameters, List<Model?>> {
// final CrudRepository<Model> _crudRepository; // final CrudRepository<Model> _crudRepository;
// Stream(this._crudRepository); // Stream(this._crudRepository);
@ -39,6 +40,5 @@
// } // }
// @override // @override
// FutureOrResult<Stream<List<Model?>>> call(StreamParameters? params) => // FutureOrResult<Stream<List<Model?>>> call(StreamParameters? params) => _crudRepository.stream();
// _crudRepository.stream();
// } // }

View File

@ -23,6 +23,7 @@ import 'package:wyatt_crud_bloc/src/domain/usecases/params/update_parameters.dar
class Update<Model extends ObjectModel> class Update<Model extends ObjectModel>
extends AsyncUseCase<UpdateParameters<Model>, void> { extends AsyncUseCase<UpdateParameters<Model>, void> {
Update(this._crudRepository); Update(this._crudRepository);
final CrudRepository<Model> _crudRepository; final CrudRepository<Model> _crudRepository;

View File

@ -22,6 +22,7 @@ import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart';
class UpdateAll<Model extends ObjectModel> class UpdateAll<Model extends ObjectModel>
extends AsyncUseCase<Map<String, Object?>, void> { extends AsyncUseCase<Map<String, Object?>, void> {
UpdateAll(this._crudRepository); UpdateAll(this._crudRepository);
final CrudRepository<Model> _crudRepository; final CrudRepository<Model> _crudRepository;

View File

@ -35,6 +35,7 @@ import 'package:wyatt_crud_bloc/src/domain/usecases/update_all.dart';
part 'crud_state.dart'; part 'crud_state.dart';
abstract class CrudCubit<Model extends ObjectModel> extends Cubit<CrudState> { abstract class CrudCubit<Model extends ObjectModel> extends Cubit<CrudState> {
CrudCubit() : super(CrudInitial()); CrudCubit() : super(CrudInitial());
Create<Model>? get crudCreate; Create<Model>? get crudCreate;
DeleteAll<Model>? get crudDeleteAll; DeleteAll<Model>? get crudDeleteAll;

View File

@ -36,6 +36,7 @@ class CrudOkReturn extends CrudState {
} }
class CrudError extends CrudState { class CrudError extends CrudState {
const CrudError(this.message); const CrudError(this.message);
final String? message; final String? message;
@ -44,6 +45,7 @@ class CrudError extends CrudState {
} }
class CrudLoaded<T> extends CrudSuccess { class CrudLoaded<T> extends CrudSuccess {
const CrudLoaded(this.data); const CrudLoaded(this.data);
final T? data; final T? data;
@ -52,6 +54,7 @@ class CrudLoaded<T> extends CrudSuccess {
} }
class CrudListLoaded<T> extends CrudSuccess { class CrudListLoaded<T> extends CrudSuccess {
const CrudListLoaded(this.data); const CrudListLoaded(this.data);
final List<T?> data; final List<T?> data;

View File

@ -35,9 +35,7 @@ class App extends StatelessWidget {
FormInput(formFieldEmail, const Email.pure(), FormInput(formFieldEmail, const Email.pure(),
metadata: const FormInputMetadata<Metadata>(extra: blue)), metadata: const FormInputMetadata<Metadata>(extra: blue)),
FormInput( FormInput(
formFieldList, formFieldList, const ListOption<String>.pure(choices: ['c1', 'c2', 'c3'],defaultValue: 'c3')),
const ListOption<String>.pure(
choices: ['c1', 'c2', 'c3'], defaultValue: 'c3')),
FormInput(formFieldRadio, const TextString.pure()), FormInput(formFieldRadio, const TextString.pure()),
FormInput(formFieldPro, const Boolean.pure(), FormInput(formFieldPro, const Boolean.pure(),
metadata: const FormInputMetadata<Metadata>(name: 'business')), metadata: const FormInputMetadata<Metadata>(name: 'business')),

View File

@ -15,7 +15,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
enum Category { perso, business } enum Category {
perso,
business
}
class Metadata { class Metadata {
final Category category; final Category category;

View File

@ -21,6 +21,10 @@ import 'package:form_bloc_example/app/bloc_observer.dart';
Future<void> main() async { Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
Bloc.observer = AppBlocObserver(); BlocOverrides.runZoned(
runApp(const App()); () => runApp(
const App(),
),
blocObserver: AppBlocObserver(),
);
} }

View File

@ -38,7 +38,8 @@ class _NameInput extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return InputBuilderTextController<SimpleCustomFormCubit, String?, Metadata>( return InputBuilderTextController<SimpleCustomFormCubit, String?, Metadata>(
field: formFieldName, field: formFieldName,
builder: (context, cubit, state, field, input, controller, metadata) { builder:
(context, cubit, state, field, input, controller, metadata) {
final meta = state.form.metadataOf<Metadata>(field).extra; final meta = state.form.metadataOf<Metadata>(field).extra;
final color = computeColor(meta); final color = computeColor(meta);
return Row( return Row(

View File

@ -33,7 +33,7 @@ enum SetOperation {
/// Add new elements to set. /// Add new elements to set.
union(FormUnion()); union(FormUnion());
const SetOperation(this.operation);
final FormOperation operation; final FormOperation operation;
const SetOperation(this.operation);
} }

View File

@ -26,6 +26,7 @@ import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator
// ignore: must_be_immutable // ignore: must_be_immutable
class WyattFormImpl extends WyattForm { class WyattFormImpl extends WyattForm {
WyattFormImpl( WyattFormImpl(
this._inputs, { this._inputs, {
required String name, required String name,

View File

@ -22,7 +22,8 @@ import 'package:wyatt_form_bloc/src/domain/input_validators/form_input_validator
/// {@endtemplate} /// {@endtemplate}
class Boolean extends NullableValidator<bool, ValidationStandardError> { class Boolean extends NullableValidator<bool, ValidationStandardError> {
/// {@macro boolean} /// {@macro boolean}
const Boolean.pure({bool defaultValue = false}) : super.pure(defaultValue); const Boolean.pure({bool defaultValue = false})
: super.pure(defaultValue);
/// {@macro boolean} /// {@macro boolean}
const Boolean.dirty({bool? value}) : super.dirty(value); const Boolean.dirty({bool? value}) : super.dirty(value);
@ -33,4 +34,5 @@ class Boolean extends NullableValidator<bool, ValidationStandardError> {
@override @override
ValidationStandardError? validator(bool? value) => ValidationStandardError? validator(bool? value) =>
value != null ? null : onNull; value != null ? null : onNull;
} }

View File

@ -21,7 +21,8 @@ class EnumOption<T> extends AnyValidator<T, List<T>, ValidationError> {
const EnumOption.pure({this.enums = const [], T? defaultValue}) const EnumOption.pure({this.enums = const [], T? defaultValue})
: super.pure(defaultValue); : super.pure(defaultValue);
const EnumOption.dirty({required this.enums, T? value}) : super.dirty(value); const EnumOption.dirty({required this.enums, T? value})
: super.dirty(value);
final List<T> enums; final List<T> enums;

View File

@ -61,5 +61,6 @@ class FormInput<
List<Object?> get props => [key, validator, metadata]; List<Object?> get props => [key, validator, metadata];
@override @override
String toString() => 'FormInput(name: $name, $validator)'; String toString() =>
'FormInput(name: $name, $validator)';
} }

View File

@ -17,12 +17,12 @@
part of 'form_data_cubit.dart'; part of 'form_data_cubit.dart';
abstract class FormDataState extends Equatable { abstract class FormDataState extends Equatable {
const FormDataState({ const FormDataState({
required this.form, required this.form,
this.status = FormStatus.pure, this.status = FormStatus.pure,
this.errorMessage, this.errorMessage,
}); });
/// Global status of a form. /// Global status of a form.
final FormStatus status; final FormStatus status;

View File

@ -27,6 +27,7 @@ import 'package:wyatt_form_bloc/src/presentation/features/form_data/form_data_cu
part 'form_data_state_impl.dart'; part 'form_data_state_impl.dart';
abstract class FormDataCubitImpl extends FormDataCubit<FormDataStateImpl> { abstract class FormDataCubitImpl extends FormDataCubit<FormDataStateImpl> {
FormDataCubitImpl(this._formRepository, this._formName) FormDataCubitImpl(this._formRepository, this._formName)
: super(FormDataStateImpl(form: _formRepository.accessForm(_formName))); : super(FormDataStateImpl(form: _formRepository.accessForm(_formName)));
final FormRepository _formRepository; final FormRepository _formRepository;

View File

@ -66,7 +66,7 @@ Future<void> handleDigest(HttpRequest req) async {
Future<void> handleUnsafe(HttpRequest req) async { Future<void> handleUnsafe(HttpRequest req) async {
print( print(
'Query parameters => ' 'Query parameters => '
'${req.uri.queryParameters}', '${req.uri.queryParameters.toString()}',
); );
} }

View File

@ -37,8 +37,7 @@ enum EmailVerificationAction {
onNonMatch: (n) => n, onNonMatch: (n) => n,
); );
factory EmailVerificationAction.fromString(String str) => factory EmailVerificationAction.fromString(String str) => EmailVerificationAction.values.firstWhere(
EmailVerificationAction.values.firstWhere(
(element) => element.toSnakeCase() == str, (element) => element.toSnakeCase() == str,
); );
} }
@ -57,8 +56,7 @@ class VerifyCode {
String? email, String? email,
String? verificationCode, String? verificationCode,
EmailVerificationAction? action, EmailVerificationAction? action,
}) => }) => VerifyCode(
VerifyCode(
email: email ?? this.email, email: email ?? this.email,
verificationCode: verificationCode ?? this.verificationCode, verificationCode: verificationCode ?? this.verificationCode,
action: action ?? this.action, action: action ?? this.action,
@ -82,8 +80,8 @@ class VerifyCode {
VerifyCode.fromMap(json.decode(source) as Map<String, dynamic>); VerifyCode.fromMap(json.decode(source) as Map<String, dynamic>);
@override @override
String toString() => 'VerifyCode(email: $email, verificationCode: ' String toString() =>
'$verificationCode, action: $action)'; 'VerifyCode(email: $email, verificationCode: $verificationCode, action: $action)';
} }
class Account { class Account {
@ -97,8 +95,7 @@ class Account {
Account copyWith({ Account copyWith({
String? email, String? email,
String? sessionId, String? sessionId,
}) => }) => Account(
Account(
email: email ?? this.email, email: email ?? this.email,
sessionId: sessionId ?? this.sessionId, sessionId: sessionId ?? this.sessionId,
); );
@ -110,8 +107,7 @@ class Account {
factory Account.fromMap(Map<String, dynamic> map) => Account( factory Account.fromMap(Map<String, dynamic> map) => Account(
email: map['email'] as String, email: map['email'] as String,
sessionId: sessionId: map['session_id'] != null ? map['session_id'] as String : null,
map['session_id'] != null ? map['session_id'] as String : null,
); );
String toJson() => json.encode(toMap()); String toJson() => json.encode(toMap());
@ -134,8 +130,7 @@ class SignUp {
SignUp copyWith({ SignUp copyWith({
String? sessionId, String? sessionId,
String? password, String? password,
}) => }) => SignUp(
SignUp(
sessionId: sessionId ?? this.sessionId, sessionId: sessionId ?? this.sessionId,
password: password ?? this.password, password: password ?? this.password,
); );
@ -173,8 +168,7 @@ class TokenSuccess {
String? accessToken, String? accessToken,
String? refreshToken, String? refreshToken,
Account? account, Account? account,
}) => }) => TokenSuccess(
TokenSuccess(
accessToken: accessToken ?? this.accessToken, accessToken: accessToken ?? this.accessToken,
refreshToken: refreshToken ?? this.refreshToken, refreshToken: refreshToken ?? this.refreshToken,
account: account ?? this.account, account: account ?? this.account,
@ -198,8 +192,8 @@ class TokenSuccess {
TokenSuccess.fromMap(json.decode(source) as Map<String, dynamic>); TokenSuccess.fromMap(json.decode(source) as Map<String, dynamic>);
@override @override
String toString() => 'TokenSuccess(accessToken: $accessToken, refreshToken: ' String toString() =>
'$refreshToken, account: $account)'; 'TokenSuccess(accessToken: $accessToken, refreshToken: $refreshToken, account: $account)';
} }
class Login { class Login {
@ -213,8 +207,7 @@ class Login {
Login copyWith({ Login copyWith({
String? email, String? email,
String? password, String? password,
}) => }) => Login(
Login(
email: email ?? this.email, email: email ?? this.email,
password: password ?? this.password, password: password ?? this.password,
); );
@ -353,19 +346,19 @@ void main(List<String> args) async {
); );
await api.sendSignUpCode('git@pcl.ovh'); await api.sendSignUpCode('git@pcl.ovh');
// final verifiedAccount = await api.verifyCode( final verifiedAccount = await api.verifyCode(
// VerifyCode( VerifyCode(
// email: 'git@pcl.ovh', email: 'git@pcl.ovh',
// verificationCode: '000000000', verificationCode: '000000000',
// action: EmailVerificationAction.signUp, action: EmailVerificationAction.signUp,
// ), ),
// ); );
// final registeredAccount = await api.signUp( final registeredAccount = await api.signUp(
// SignUp(sessionId: verifiedAccount.sessionId ?? '', password: 'password'), SignUp(sessionId: verifiedAccount.sessionId ?? '', password: 'password'),
// ); );
// final signedInAccount = await api.signInWithPassword( final signedInAccount = await api.signInWithPassword(
// Login(email: 'git@pcl.ovh', password: 'password'), Login(email: 'git@pcl.ovh', password: 'password'),
// ); );
final accountList = await api.getAccountList(); final accountList = await api.getAccountList();
print(accountList); print(accountList);
} }

View File

@ -45,8 +45,7 @@ import 'package:wyatt_http_client/src/utils/protocols.dart';
// BaseResponse onResponse(BaseResponse response) { // BaseResponse onResponse(BaseResponse response) {
// final res = child?.onResponse(response) ?? response; // final res = child?.onResponse(response) ?? response;
// print( // print(
// 'RequestMutator::OnResponse: ${res.statusCode} -> ${res.contentLength} // 'RequestMutator::OnResponse: ${res.statusCode} -> ${res.contentLength} bytes',
// bytes',
// ); // );
// return res; // return res;
// } // }
@ -76,8 +75,7 @@ import 'package:wyatt_http_client/src/utils/protocols.dart';
// if (response != null) return response; // if (response != null) return response;
// return Future.sync(() => innerHandler(request)) // return Future.sync(() => innerHandler(request))
// .then((response) => responseHandler!(response), onError: // .then((response) => responseHandler!(response), onError: onError);
// onError);
// }); // });
// }; // };
// }; // };

View File

@ -25,6 +25,7 @@ import 'package:wyatt_http_client/src/pipeline.dart';
import 'package:wyatt_http_client/src/utils/http_methods.dart'; import 'package:wyatt_http_client/src/utils/http_methods.dart';
class MiddlewareClient extends BaseClient { class MiddlewareClient extends BaseClient {
MiddlewareClient({ MiddlewareClient({
Pipeline? pipeline, Pipeline? pipeline,
Client? inner, Client? inner,

View File

@ -13,3 +13,4 @@
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -23,6 +23,7 @@ import 'package:wyatt_http_client/src/utils/authentication_methods.dart';
import 'package:wyatt_http_client/src/utils/header_keys.dart'; import 'package:wyatt_http_client/src/utils/header_keys.dart';
class BasicAuthMiddleware with OnRequestMiddleware implements Middleware { class BasicAuthMiddleware with OnRequestMiddleware implements Middleware {
BasicAuthMiddleware({ BasicAuthMiddleware({
this.username, this.username,
this.password, this.password,

View File

@ -25,6 +25,7 @@ import 'package:wyatt_http_client/src/utils/http_status.dart';
class DigestAuthMiddleware class DigestAuthMiddleware
with OnRequestMiddleware, OnResponseMiddleware with OnRequestMiddleware, OnResponseMiddleware
implements Middleware { implements Middleware {
DigestAuthMiddleware({ DigestAuthMiddleware({
required this.username, required this.username,
required this.password, required this.password,

View File

@ -31,6 +31,7 @@ typedef TokenParser = String Function(Map<String, dynamic>);
class RefreshTokenAuthMiddleware class RefreshTokenAuthMiddleware
with OnRequestMiddleware, OnResponseMiddleware with OnRequestMiddleware, OnResponseMiddleware
implements Middleware { implements Middleware {
RefreshTokenAuthMiddleware({ RefreshTokenAuthMiddleware({
required this.authorizationEndpoint, required this.authorizationEndpoint,
required this.tokenEndpoint, required this.tokenEndpoint,

View File

@ -20,6 +20,7 @@ import 'package:wyatt_http_client/src/models/middleware_request.dart';
import 'package:wyatt_http_client/src/utils/convert.dart'; import 'package:wyatt_http_client/src/utils/convert.dart';
class UnsafeAuthMiddleware with OnRequestMiddleware implements Middleware { class UnsafeAuthMiddleware with OnRequestMiddleware implements Middleware {
UnsafeAuthMiddleware({ UnsafeAuthMiddleware({
this.username, this.username,
this.password, this.password,

View File

@ -20,6 +20,7 @@ import 'package:wyatt_http_client/src/models/middleware_request.dart';
import 'package:wyatt_http_client/src/utils/protocols.dart'; import 'package:wyatt_http_client/src/utils/protocols.dart';
class UriPrefixMiddleware with OnRequestMiddleware implements Middleware { class UriPrefixMiddleware with OnRequestMiddleware implements Middleware {
UriPrefixMiddleware({ UriPrefixMiddleware({
required this.protocol, required this.protocol,
required this.authority, required this.authority,

View File

@ -44,8 +44,7 @@ class MiddlewareContext {
MiddlewareRequest? lastRequest, MiddlewareRequest? lastRequest,
MiddlewareResponse? originalResponse, MiddlewareResponse? originalResponse,
MiddlewareResponse? lastResponse, MiddlewareResponse? lastResponse,
}) => }) => MiddlewareContext(
MiddlewareContext(
pipeline: pipeline ?? this.pipeline, pipeline: pipeline ?? this.pipeline,
client: client ?? this.client, client: client ?? this.client,
originalRequest: originalRequest ?? this.originalRequest, originalRequest: originalRequest ?? this.originalRequest,
@ -55,8 +54,5 @@ class MiddlewareContext {
); );
@override @override
String toString() => String toString() => 'MiddlewareContext(pipeline: $pipeline, client: $client, originalRequest: $originalRequest, lastRequest: $lastRequest, originalResponse: $originalResponse, lastResponse: $lastResponse)';
'MiddlewareContext(pipeline: $pipeline, client: $client, '
'originalRequest: $originalRequest, lastRequest: $lastRequest, '
'originalResponse: $originalResponse, lastResponse: $lastResponse)';
} }

View File

@ -31,7 +31,6 @@ class MiddlewareResponse {
return ''; return '';
} }
} }
int? get contentLength => httpResponse.contentLength; int? get contentLength => httpResponse.contentLength;
Map<String, String> get headers => httpResponse.headers; Map<String, String> get headers => httpResponse.headers;
@ -41,11 +40,11 @@ class MiddlewareResponse {
MiddlewareResponse copyWith({ MiddlewareResponse copyWith({
BaseResponse? httpResponse, BaseResponse? httpResponse,
}) => }) => MiddlewareResponse(
MiddlewareResponse(
httpResponse: httpResponse ?? this.httpResponse, httpResponse: httpResponse ?? this.httpResponse,
); );
@override @override
String toString() => 'MiddlewareResponse(httpResponse: $httpResponse)'; String toString() =>
'MiddlewareResponse(httpResponse: $httpResponse)';
} }

View File

@ -17,6 +17,7 @@
import 'dart:convert'; import 'dart:convert';
class UnfreezedRequest { class UnfreezedRequest {
UnfreezedRequest({ UnfreezedRequest({
required this.method, required this.method,
required this.url, required this.url,
@ -36,8 +37,7 @@ class UnfreezedRequest {
Map<String, String>? headers, Map<String, String>? headers,
Object? body, Object? body,
Encoding? encoding, Encoding? encoding,
}) => }) => UnfreezedRequest(
UnfreezedRequest(
method: method ?? this.method, method: method ?? this.method,
url: url ?? this.url, url: url ?? this.url,
headers: headers ?? this.headers, headers: headers ?? this.headers,

View File

@ -20,6 +20,7 @@ import 'package:wyatt_http_client/src/models/middleware_request.dart';
import 'package:wyatt_http_client/src/models/middleware_response.dart'; import 'package:wyatt_http_client/src/models/middleware_response.dart';
class Pipeline { class Pipeline {
Pipeline() : _middlewares = <Middleware>[]; Pipeline() : _middlewares = <Middleware>[];
Pipeline.fromIterable(Iterable<Middleware> middlewares) Pipeline.fromIterable(Iterable<Middleware> middlewares)
: _middlewares = middlewares.toList(); : _middlewares = middlewares.toList();
@ -30,8 +31,6 @@ class Pipeline {
/// Add a [Middleware] to this [Pipeline] /// Add a [Middleware] to this [Pipeline]
Pipeline addMiddleware(Middleware middleware) { Pipeline addMiddleware(Middleware middleware) {
_middlewares.add(middleware); _middlewares.add(middleware);
// TODO(hpcl): use Dart cascades instead of returning this
// ignore: avoid_returning_this
return this; return this;
} }
@ -66,7 +65,8 @@ class Pipeline {
MiddlewareContext ctx = context.copyWith(lastRequest: req); MiddlewareContext ctx = context.copyWith(lastRequest: req);
for (final middleware in _middlewares) { for (final middleware in _middlewares) {
if (middleware is OnRequestMiddleware) { if (middleware is OnRequestMiddleware) {
req = await (middleware as OnRequestMiddleware).onRequest(ctx, request); req = await (middleware as OnRequestMiddleware)
.onRequest(ctx, request);
ctx = context.copyWith(lastRequest: req); ctx = context.copyWith(lastRequest: req);
} }
} }

View File

@ -34,12 +34,10 @@ class Convert {
static String mapToQuery(Map<String, String> map, {Encoding? encoding}) { static String mapToQuery(Map<String, String> map, {Encoding? encoding}) {
final pairs = <List<String>>[]; final pairs = <List<String>>[];
map.forEach( map.forEach((key, value) => pairs.add([
(key, value) => pairs.add([
Uri.encodeQueryComponent(key, encoding: encoding ?? utf8), Uri.encodeQueryComponent(key, encoding: encoding ?? utf8),
Uri.encodeQueryComponent(value, encoding: encoding ?? utf8) Uri.encodeQueryComponent(value, encoding: encoding ?? utf8)
]), ]),);
);
return pairs.map((pair) => '${pair[0]}=${pair[1]}').join('&'); return pairs.map((pair) => '${pair[0]}=${pair[1]}').join('&');
} }
} }

View File

@ -19,8 +19,7 @@ import 'dart:math';
import 'package:wyatt_http_client/src/utils/convert.dart'; import 'package:wyatt_http_client/src/utils/convert.dart';
import 'package:wyatt_http_client/src/utils/crypto.dart'; import 'package:wyatt_http_client/src/utils/crypto.dart';
class DigestAuth { class DigestAuth { // request counter
// request counter
DigestAuth(this.username, this.password); DigestAuth(this.username, this.password);
String username; String username;

View File

@ -22,7 +22,7 @@ enum HttpMethods {
patch('PATCH'), patch('PATCH'),
delete('DELETE'); delete('DELETE');
const HttpMethods(this.method);
final String method; final String method;
const HttpMethods(this.method);
} }

Some files were not shown because too many files have changed in this diff Show More