diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json index cd7d15e..ef6cc31 100644 --- a/.dart_tool/package_config.json +++ b/.dart_tool/package_config.json @@ -265,6 +265,12 @@ "packageUri": "lib/", "languageVersion": "3.9" }, + { + "name": "json_serializable", + "rootUri": "file:///C:/Users/Yael/AppData/Local/Pub/Cache/hosted/pub.dev/json_serializable-6.13.2", + "packageUri": "lib/", + "languageVersion": "3.9" + }, { "name": "leak_tracker", "rootUri": "file:///C:/Users/Yael/AppData/Local/Pub/Cache/hosted/pub.dev/leak_tracker-11.0.2", @@ -481,6 +487,12 @@ "packageUri": "lib/", "languageVersion": "3.9" }, + { + "name": "source_helper", + "rootUri": "file:///C:/Users/Yael/AppData/Local/Pub/Cache/hosted/pub.dev/source_helper-1.3.12", + "packageUri": "lib/", + "languageVersion": "3.9" + }, { "name": "source_span", "rootUri": "file:///C:/Users/Yael/AppData/Local/Pub/Cache/hosted/pub.dev/source_span-1.10.2", diff --git a/lib/app/app.bottomsheets.dart b/lib/app/app.bottomsheets.dart index 777004c..bc4ed33 100644 --- a/lib/app/app.bottomsheets.dart +++ b/lib/app/app.bottomsheets.dart @@ -1,4 +1,5 @@ // GENERATED CODE - DO NOT MODIFY BY HAND +// dart format width=80 // ************************************************************************** // StackedBottomsheetGenerator diff --git a/lib/app/app.dialogs.dart b/lib/app/app.dialogs.dart index 2a4e944..b0cf86b 100644 --- a/lib/app/app.dialogs.dart +++ b/lib/app/app.dialogs.dart @@ -1,4 +1,5 @@ // GENERATED CODE - DO NOT MODIFY BY HAND +// dart format width=80 // ************************************************************************** // StackedDialogGenerator diff --git a/lib/app/app.locator.dart b/lib/app/app.locator.dart index 9d4a8da..0c39963 100644 --- a/lib/app/app.locator.dart +++ b/lib/app/app.locator.dart @@ -1,4 +1,5 @@ // GENERATED CODE - DO NOT MODIFY BY HAND +// dart format width=80 // ************************************************************************** // StackedLocatorGenerator @@ -13,10 +14,8 @@ import 'package:stacked_shared/stacked_shared.dart'; final locator = StackedLocator.instance; -Future setupLocator({ - String? environment, - EnvironmentFilter? environmentFilter, -}) async { +Future setupLocator( + {String? environment, EnvironmentFilter? environmentFilter}) async { // Register environments locator.registerEnvironment( environment: environment, environmentFilter: environmentFilter); diff --git a/lib/app/app.router.dart b/lib/app/app.router.dart index a9e4249..5d91956 100644 --- a/lib/app/app.router.dart +++ b/lib/app/app.router.dart @@ -1,4 +1,5 @@ // GENERATED CODE - DO NOT MODIFY BY HAND +// dart format width=80 // ************************************************************************** // StackedNavigatorGenerator @@ -16,6 +17,8 @@ import 'package:stacked/stacked.dart' as _i1; import 'package:stacked_services/stacked_services.dart' as _i7; class Routes { + static const homeView = '/home-view'; + static const startupView = '/startup-view'; static const mainView = '/main-view'; @@ -24,6 +27,8 @@ class Routes { static const eventDetailsView = '/event-details-view'; + static const eventDetailsView = '/event-details-view'; + static const all = { homeView, startupView, @@ -34,6 +39,10 @@ class Routes { class StackedRouter extends _i1.RouterBase { final _routes = <_i1.RouteDef>[ + _i1.RouteDef( + Routes.homeView, + page: _i2.HomeView, + ), _i1.RouteDef( Routes.startupView, page: _i3.StartupView, @@ -50,24 +59,37 @@ class StackedRouter extends _i1.RouterBase { Routes.eventDetailsView, page: _i5.EventDetailsView, ), + _i1.RouteDef( + Routes.eventDetailsView, + page: _i5.EventDetailsView, + ), ]; final _pagesMap = { _i2.HomeView: (data) { + final args = data.getArgs( + orElse: () => const HomeViewArguments(), + ); return _i6.MaterialPageRoute( - builder: (context) => const _i2.HomeView(), + builder: (context) => _i2.HomeView(key: args.key), settings: data, ); }, _i3.StartupView: (data) { + final args = data.getArgs( + orElse: () => const StartupViewArguments(), + ); return _i6.MaterialPageRoute( - builder: (context) => const _i3.StartupView(), + builder: (context) => _i3.StartupView(key: args.key), settings: data, ); }, _i4.MainView: (data) { + final args = data.getArgs( + orElse: () => const MainViewArguments(), + ); return _i6.MaterialPageRoute( - builder: (context) => const _i4.MainView(), + builder: (context) => _i4.MainView(key: args.key), settings: data, ); }, @@ -88,6 +110,72 @@ class StackedRouter extends _i1.RouterBase { Map get pagesMap => _pagesMap; } +class HomeViewArguments { + const HomeViewArguments({this.key}); + + final _i6.Key? key; + + @override + String toString() { + return '{"key": "$key"}'; + } + + @override + bool operator ==(covariant HomeViewArguments other) { + if (identical(this, other)) return true; + return other.key == key; + } + + @override + int get hashCode { + return key.hashCode; + } +} + +class StartupViewArguments { + const StartupViewArguments({this.key}); + + final _i6.Key? key; + + @override + String toString() { + return '{"key": "$key"}'; + } + + @override + bool operator ==(covariant StartupViewArguments other) { + if (identical(this, other)) return true; + return other.key == key; + } + + @override + int get hashCode { + return key.hashCode; + } +} + +class MainViewArguments { + const MainViewArguments({this.key}); + + final _i6.Key? key; + + @override + String toString() { + return '{"key": "$key"}'; + } + + @override + bool operator ==(covariant MainViewArguments other) { + if (identical(this, other)) return true; + return other.key == key; + } + + @override + int get hashCode { + return key.hashCode; + } +} + class EventDetailsViewArguments { const EventDetailsViewArguments({ this.key, @@ -116,42 +204,64 @@ class EventDetailsViewArguments { } extension NavigatorStateExtension on _i7.NavigationService { - Future navigateToStartupView([ + Future navigateToHomeView({ + _i6.Key? key, int? routerId, bool preventDuplicates = true, Map? parameters, Widget Function(BuildContext, Animation, Animation, Widget)? transition, - ]) async { - return navigateTo(Routes.startupView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToMainView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { - return navigateTo(Routes.mainView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToHomeView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { + }) async { return navigateTo(Routes.homeView, + arguments: HomeViewArguments(key: key), + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + + Future navigateToStartupView({ + _i6.Key? key, + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + }) async { + return navigateTo(Routes.startupView, + arguments: StartupViewArguments(key: key), + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + + Future navigateToMainView({ + _i6.Key? key, + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + }) async { + return navigateTo(Routes.mainView, + arguments: MainViewArguments(key: key), + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + + Future navigateToHomeView({ + _i6.Key? key, + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + }) async { + return navigateTo(Routes.homeView, + arguments: HomeViewArguments(key: key), id: routerId, preventDuplicates: preventDuplicates, parameters: parameters, @@ -175,42 +285,98 @@ extension NavigatorStateExtension on _i7.NavigationService { transition: transition); } - Future replaceWithStartupView([ + Future navigateToEventDetailsView({ + _i6.Key? key, + required int eventId, int? routerId, bool preventDuplicates = true, Map? parameters, Widget Function(BuildContext, Animation, Animation, Widget)? transition, - ]) async { - return replaceWith(Routes.startupView, + }) async { + return navigateTo(Routes.eventDetailsView, + arguments: EventDetailsViewArguments(key: key, eventId: eventId), id: routerId, preventDuplicates: preventDuplicates, parameters: parameters, transition: transition); } - Future replaceWithMainView([ + Future replaceWithHomeView({ + _i6.Key? key, int? routerId, bool preventDuplicates = true, Map? parameters, Widget Function(BuildContext, Animation, Animation, Widget)? transition, - ]) async { - return replaceWith(Routes.mainView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithHomeView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { + }) async { return replaceWith(Routes.homeView, + arguments: HomeViewArguments(key: key), + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + + Future replaceWithStartupView({ + _i6.Key? key, + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + }) async { + return replaceWith(Routes.startupView, + arguments: StartupViewArguments(key: key), + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + + Future replaceWithMainView({ + _i6.Key? key, + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + }) async { + return replaceWith(Routes.mainView, + arguments: MainViewArguments(key: key), + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + + Future replaceWithHomeView({ + _i6.Key? key, + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + }) async { + return replaceWith(Routes.homeView, + arguments: HomeViewArguments(key: key), + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + + Future replaceWithEventDetailsView({ + _i6.Key? key, + required int eventId, + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + }) async { + return replaceWith(Routes.eventDetailsView, + arguments: EventDetailsViewArguments(key: key, eventId: eventId), id: routerId, preventDuplicates: preventDuplicates, parameters: parameters, diff --git a/lib/models/event.dart b/lib/models/event.dart new file mode 100644 index 0000000..7360144 --- /dev/null +++ b/lib/models/event.dart @@ -0,0 +1,30 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'event.g.dart'; + +@JsonSerializable() +class Event { + String name; + String picture; + String organizer = 'Organizer'; + String? place; + DateTime? date; + bool isFavorite; + + Event({ + required this.name, + required this.picture, + required this.organizer, + this.date, + this.place, + this.isFavorite = false, + }); + + @override + String toString() { + return 'Event{name: $name, picture: $picture}'; + } + + factory Event.fromJson(Map json) => _$EventFromJson(json); + Map toJson() => _$EventToJson(this); +} \ No newline at end of file diff --git a/lib/models/event.g.dart b/lib/models/event.g.dart new file mode 100644 index 0000000..7f6e6d9 --- /dev/null +++ b/lib/models/event.g.dart @@ -0,0 +1,26 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'event.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Event _$EventFromJson(Map json) => Event( + name: json['name'] as String, + picture: json['picture'] as String, + organizer: json['organizer'] as String, + date: + json['date'] == null ? null : DateTime.parse(json['date'] as String), + place: json['place'] as String?, + isFavorite: json['isFavorite'] as bool? ?? false, + ); + +Map _$EventToJson(Event instance) => { + 'name': instance.name, + 'picture': instance.picture, + 'organizer': instance.organizer, + 'place': instance.place, + 'date': instance.date?.toIso8601String(), + 'isFavorite': instance.isFavorite, + }; diff --git a/lib/models/post.dart b/lib/models/post.dart new file mode 100644 index 0000000..177b58d --- /dev/null +++ b/lib/models/post.dart @@ -0,0 +1,33 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'post.g.dart'; + +@JsonSerializable() +class Post { + final String title; + final String content; + final String authorName; + final String authorImageUrl; + final DateTime publishDate; + final List? imageUrls; + final int likesCount; + final int commentsCount; + final int sharesCount; + final double? aspectRatio; // Nouveau paramètre pour le ratio (largeur/hauteur) + + Post({ + required this.title, + required this.content, + required this.authorName, + required this.authorImageUrl, + required this.publishDate, + this.imageUrls, + this.likesCount = 0, + this.commentsCount = 0, + this.sharesCount = 0, + this.aspectRatio, + }); + + factory Post.fromJson(Map json) => _$PostFromJson(json); + Map toJson() => _$PostToJson(this); +} \ No newline at end of file diff --git a/lib/models/post.g.dart b/lib/models/post.g.dart new file mode 100644 index 0000000..455dcbb --- /dev/null +++ b/lib/models/post.g.dart @@ -0,0 +1,35 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'post.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Post _$PostFromJson(Map json) => Post( + title: json['title'] as String, + content: json['content'] as String, + authorName: json['authorName'] as String, + authorImageUrl: json['authorImageUrl'] as String, + publishDate: DateTime.parse(json['publishDate'] as String), + imageUrls: (json['imageUrls'] as List?) + ?.map((e) => e as String) + .toList(), + likesCount: (json['likesCount'] as num?)?.toInt() ?? 0, + commentsCount: (json['commentsCount'] as num?)?.toInt() ?? 0, + sharesCount: (json['sharesCount'] as num?)?.toInt() ?? 0, + aspectRatio: (json['aspectRatio'] as num?)?.toDouble(), + ); + +Map _$PostToJson(Post instance) => { + 'title': instance.title, + 'content': instance.content, + 'authorName': instance.authorName, + 'authorImageUrl': instance.authorImageUrl, + 'publishDate': instance.publishDate.toIso8601String(), + 'imageUrls': instance.imageUrls, + 'likesCount': instance.likesCount, + 'commentsCount': instance.commentsCount, + 'sharesCount': instance.sharesCount, + 'aspectRatio': instance.aspectRatio, + }; diff --git a/lib/ui/views/home/home_viewmodel.dart b/lib/ui/views/home/home_viewmodel.dart index df02ca0..c65b985 100644 --- a/lib/ui/views/home/home_viewmodel.dart +++ b/lib/ui/views/home/home_viewmodel.dart @@ -2,6 +2,7 @@ import 'package:bahla_front/app/app.locator.dart'; import 'package:bahla_front/app/app.router.dart'; import 'package:stacked/stacked.dart'; import 'package:stacked_services/stacked_services.dart'; +import '../../../models/event.dart'; class HomeViewModel extends BaseViewModel { final _navigationService = locator(); @@ -45,25 +46,4 @@ class HomeViewModel extends BaseViewModel { } } -class Event { - String name; - String picture; - String organizer = 'Organizer'; - String? place; - DateTime? date; - bool isFavorite; - Event({ - required this.name, - required this.picture, - required this.organizer, - this.date, - this.place, - this.isFavorite = false, - }); - - @override - String toString() { - return 'Event{name: $name, picture: $picture}'; - } -} diff --git a/pubspec.lock b/pubspec.lock index 4cf5976..af90eb8 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -337,13 +337,21 @@ packages: source: hosted version: "1.0.1" json_annotation: - dependency: transitive + dependency: "direct main" description: name: json_annotation sha256: cb09e7dac6210041fad964ed7fbee004f14258b4eca4040f72d1234062ace4c8 url: "https://pub.dev" source: hosted version: "4.11.0" + json_serializable: + dependency: "direct dev" + description: + name: json_serializable + sha256: "2c15e78e1cc6e62aadecf59f81566fd56829713d96a8c4177699e2b2e17f20db" + url: "https://pub.dev" + source: hosted + version: "6.13.2" leak_tracker: dependency: transitive description: @@ -629,6 +637,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.2.3" + source_helper: + dependency: transitive + description: + name: source_helper + sha256: "4227d54ceefd0bb8ca4c8fcb96e1719dc53f1ee1b6e2ca9d7a6069da160e4eae" + url: "https://pub.dev" + source: hosted + version: "1.3.12" source_span: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 1382b3a..8ee397e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -13,18 +13,20 @@ dependencies: sdk: flutter flutter_svg: ^2.0.11 google_fonts: ^8.1.0 - http: ^1.2.2 + http: ^1.6.0 intl: any + json_annotation: ^4.11.0 stacked: ^3.4.0 stacked_services: ^1.1.0 dev_dependencies: - build_runner: ^2.4.5 + build_runner: ^2.15.0 flutter_test: sdk: flutter flutter_lints: ^6.0.0 mockito: ^5.4.1 stacked_generator: ^2.0.3 + json_serializable: ^6.13.2 flutter: uses-material-design: true diff --git a/test/helpers/test_helpers.mocks.dart b/test/helpers/test_helpers.mocks.dart index afff92f..65c5b1a 100644 --- a/test/helpers/test_helpers.mocks.dart +++ b/test/helpers/test_helpers.mocks.dart @@ -1,4 +1,4 @@ -// Mocks generated by Mockito 5.4.4 from annotations +// Mocks generated by Mockito 5.4.6 from annotations // in bahla_front/test/helpers/test_helpers.dart. // Do not manually edit this file. @@ -19,10 +19,12 @@ import 'package:stacked_services/stacked_services.dart' as _i2; // ignore_for_file: deprecated_member_use_from_same_package // ignore_for_file: implementation_imports // ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: must_be_immutable // ignore_for_file: prefer_const_constructors // ignore_for_file: unnecessary_parenthesis // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class +// ignore_for_file: invalid_use_of_internal_member /// A class which mocks [NavigationService]. /// @@ -95,7 +97,7 @@ class MockNavigationService extends _i1.Mock implements _i2.NavigationService { _i5.Future? navigateWithTransition( _i4.Widget? page, { bool? opaque, - String? transition = r'', + String? transition = '', Duration? duration, bool? popGesture, int? id, @@ -131,7 +133,7 @@ class MockNavigationService extends _i1.Mock implements _i2.NavigationService { _i5.Future? replaceWithTransition( _i4.Widget? page, { bool? opaque, - String? transition = r'', + String? transition = '', Duration? duration, bool? popGesture, int? id, @@ -404,7 +406,7 @@ class MockBottomSheetService extends _i1.Mock _i5.Future<_i2.SheetResponse?> showBottomSheet({ required String? title, String? description, - String? confirmButtonTitle = r'Ok', + String? confirmButtonTitle = 'Ok', String? cancelButtonTitle, bool? enableDrag = true, bool? barrierDismissible = true, @@ -457,7 +459,7 @@ class MockBottomSheetService extends _i1.Mock double? elevation = 1.0, bool? barrierDismissible = true, bool? isScrollControlled = false, - String? barrierLabel = r'', + String? barrierLabel = '', dynamic customData, R? data, bool? enableDrag = true, @@ -554,9 +556,11 @@ class MockDialogService extends _i1.Mock implements _i2.DialogService { String? description, String? cancelTitle, _i6.Color? cancelTitleColor, - String? buttonTitle = r'Ok', + String? buttonTitle = 'Ok', _i6.Color? buttonTitleColor, bool? barrierDismissible = false, + _i4.RouteSettings? routeSettings, + _i4.GlobalKey<_i4.NavigatorState>? navigatorKey, _i2.DialogPlatform? dialogPlatform, }) => (super.noSuchMethod( @@ -571,6 +575,8 @@ class MockDialogService extends _i1.Mock implements _i2.DialogService { #buttonTitle: buttonTitle, #buttonTitleColor: buttonTitleColor, #barrierDismissible: barrierDismissible, + #routeSettings: routeSettings, + #navigatorKey: navigatorKey, #dialogPlatform: dialogPlatform, }, ), @@ -595,8 +601,11 @@ class MockDialogService extends _i1.Mock implements _i2.DialogService { bool? takesInput = false, _i6.Color? barrierColor = const _i6.Color(2315255808), bool? barrierDismissible = false, - String? barrierLabel = r'', + String? barrierLabel = '', bool? useSafeArea = true, + _i4.RouteSettings? routeSettings, + _i4.GlobalKey<_i4.NavigatorState>? navigatorKey, + _i4.RouteTransitionsBuilder? transitionBuilder, dynamic customData, R? data, }) => @@ -621,6 +630,9 @@ class MockDialogService extends _i1.Mock implements _i2.DialogService { #barrierDismissible: barrierDismissible, #barrierLabel: barrierLabel, #useSafeArea: useSafeArea, + #routeSettings: routeSettings, + #navigatorKey: navigatorKey, + #transitionBuilder: transitionBuilder, #customData: customData, #data: data, }, @@ -633,11 +645,12 @@ class MockDialogService extends _i1.Mock implements _i2.DialogService { _i5.Future<_i2.DialogResponse?> showConfirmationDialog({ String? title, String? description, - String? cancelTitle = r'Cancel', + String? cancelTitle = 'Cancel', _i6.Color? cancelTitleColor, - String? confirmationTitle = r'Ok', + String? confirmationTitle = 'Ok', _i6.Color? confirmationTitleColor, bool? barrierDismissible = false, + _i4.RouteSettings? routeSettings, _i2.DialogPlatform? dialogPlatform, }) => (super.noSuchMethod( @@ -652,6 +665,7 @@ class MockDialogService extends _i1.Mock implements _i2.DialogService { #confirmationTitle: confirmationTitle, #confirmationTitleColor: confirmationTitleColor, #barrierDismissible: barrierDismissible, + #routeSettings: routeSettings, #dialogPlatform: dialogPlatform, }, ),