From b946ef0f592497d730e5e247f9229add760df596 Mon Sep 17 00:00:00 2001 From: komekh Date: Fri, 30 Aug 2024 16:07:22 +0500 Subject: [PATCH] added painter --- assets/images/circle.png | Bin 0 -> 774 bytes assets/images/circle2.png | Bin 0 -> 243 bytes .../order_detail_bloc/order_detail_bloc.dart | 88 +++++++++++++++- .../order_detail_bloc/order_detail_state.dart | 10 +- lib/core/constants/assets.dart | 2 + lib/core/constants/colors.dart | 1 + lib/presentation/screens/order_details.dart | 50 ++++----- lib/presentation/widgets/circle_painter.dart | 44 ++++++++ lib/presentation/widgets/location_card.dart | 95 +++++++----------- lib/presentation/widgets/widgets.dart | 1 + pubspec.lock | 8 ++ pubspec.yaml | 1 + 12 files changed, 205 insertions(+), 95 deletions(-) create mode 100644 assets/images/circle.png create mode 100644 assets/images/circle2.png create mode 100644 lib/presentation/widgets/circle_painter.dart diff --git a/assets/images/circle.png b/assets/images/circle.png new file mode 100644 index 0000000000000000000000000000000000000000..a264d3811cb09298a8650c533a47a2c88185469f GIT binary patch literal 774 zcmV+h1Nr=kP)F|NQ$1%?^h_(2(<19yN@K}ZEC9q{NeNSFNp znUnZ2cqTi;NO!v1Z@>LT(H6P8>z>$lcCD1I5-EpBJJ{En#!Aspp3nGQT?KzP=};RK zJC#b>mCLSWsa}@pUrJ4ewOTE~_fDtd5Pgy#U&xuN);gAFxDIFq;Nc+>i&axB>>VC* z+xPu3y(68@&s#B~DX(Fp5wte~;GkIJ*)~;!U^DIYAYDi6Y#>Z}jmGyM`97PLe^fc7 zR`V03_=_<2psTr83T_3fRaXA^ z7+nbPNU|t2ltWwqB9lyOmrPWTnR+t@i;Nl6>%p0Ma2{-G(Qe|&{eF>kI(mJz&RAZ~ zMNv#ew>a_$X-5%PwV*U#-`x0Puz+h>sC=DHb>F-ImkH>}t^ha-W#%5Uicz2}!Eld` z)TnqtyR@gs9nV~At^UZvVW6)`%e?`h%v>PYGXVO}A^<9hqUf}^trFT(P#5NUUJo=D z7wP2Xg$pi0AEG@)lBED(S^5-p0tPWN+VN5ZunlzDQE>L)pqSQ^iT2RSd9F-*t9i^# z+FinOqKNfXX+6&jWuRBi<9hvDU-p~Zm@K||``W z$lZxy-8q?;Kn_c~qpu?a!^VE@KZ&eBeut-vV@L&KY42U$W&?rdxr@ExtexB!%r0SF zvPa?L0X50Sz5^V07sxKmIl%PihLD1yp!dY0^xxL(T1(#v9=f8-?e)Ci`KtNpTYQDt z)i3{kxm&VbLN0X2#+erLeLPwBZU6Y+$xUfSz|IDZv^M!quPPU)|F{HYJzf#XvVPc)I$ztaD0e0sx { final result = await _getRoutesUseCase(event.cargoId); result.fold( (failure) => emit(RoutesError(failure: failure)), - (response) => emit(RoutesLoaded(routes: response.routes)), + (response) { + // Find the index of the current route + int currentIndex = response.routes.indexWhere((r) => r.isCurrent); + + emit( + RoutesLoaded( + routes: response.routes, + activeIndex: currentIndex, + steppers: response.routes.mapIndexed((index, route) { + // Determine if the icon should be splashed + final bool isSplashedIcon = index == 0 || index == response.routes.length - 1; + + // Determine the color based on the conditions + Color textColor; + Color iconColor; + + if (route.isCurrent) { + textColor = AppColors.greenDark; + iconColor = AppColors.greenDark; + } else if (index < currentIndex) { + textColor = const Color(0xFFD8D8DA); + iconColor = AppColors.greenDark; + } else { + textColor = AppColors.darkGrey; + iconColor = AppColors.darkGrey; + } + + return StepperData( + title: StepperText( + route.name, + textStyle: TextStyle( + color: textColor, + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + subtitle: StepperText( + route.dateAt, + textStyle: TextStyle( + color: textColor, + fontWeight: FontWeight.bold, + fontSize: 14, + ), + ), + iconWidget: isSplashedIcon + ? Image.asset( + AppAssets.circle, + color: iconColor, + ) + : CirclePainterWidget( + radius: 8, + color: iconColor, + ), + ); + }).toList(), + ), + /* RoutesLoaded( + routes: response.routes, + steppers: response.routes.mapIndexed((index, route) { + return StepperData( + title: StepperText( + route.name, + textStyle: const TextStyle( + color: Colors.grey, + ), + ), + subtitle: StepperText(route.dateAt), + iconWidget: Container( + padding: const EdgeInsets.all(8), + decoration: const BoxDecoration( + color: Colors.green, + borderRadius: BorderRadius.all( + Radius.circular(18), + ), + ), + ), + ); + }).toList(), + ), */ + ); + }, ); } catch (e) { emit(RoutesError(failure: ExceptionFailure())); diff --git a/lib/application/order_detail_bloc/order_detail_state.dart b/lib/application/order_detail_bloc/order_detail_state.dart index e3eeaf6..1b728f0 100644 --- a/lib/application/order_detail_bloc/order_detail_state.dart +++ b/lib/application/order_detail_bloc/order_detail_state.dart @@ -13,9 +13,15 @@ class RoutesLoading extends OrderDetailState {} class RoutesLoaded extends OrderDetailState { final List routes; - const RoutesLoaded({required this.routes}); + final List steppers; + final int activeIndex; + const RoutesLoaded({ + required this.routes, + required this.steppers, + required this.activeIndex, + }); @override - List get props => [routes]; + List get props => [routes, steppers, activeIndex]; } class RoutesError extends OrderDetailState { diff --git a/lib/core/constants/assets.dart b/lib/core/constants/assets.dart index 906eaea..61ffc1e 100644 --- a/lib/core/constants/assets.dart +++ b/lib/core/constants/assets.dart @@ -10,6 +10,8 @@ sealed class AppAssets { static const String boxesPng = 'assets/images/boxes.png'; static const String trucksPng = 'assets/images/trucks.png'; static const String header = 'assets/images/header.png'; + static const String circle = 'assets/images/circle.png'; + static const String circle2 = 'assets/images/circle2.png'; static const String search = 'assets/images/search.png'; static const String searchGif = 'assets/images/search.gif'; } diff --git a/lib/core/constants/colors.dart b/lib/core/constants/colors.dart index 8255390..6993a51 100644 --- a/lib/core/constants/colors.dart +++ b/lib/core/constants/colors.dart @@ -5,6 +5,7 @@ sealed class AppColors { static const Color yellow = Color(0xFFFFC71E); static const Color surface = Color(0xFFEDEEFC); static const Color green = Color(0xFFA2E052); + static const Color greenDark = Color(0xFF61971B); static const Color grey = Color(0xFF96969C); static const Color darkGrey = Color(0xFF57575C); static const Color lightGrey = Color(0xFFE5E5E6); diff --git a/lib/presentation/screens/order_details.dart b/lib/presentation/screens/order_details.dart index 8aadb4d..7b7733e 100644 --- a/lib/presentation/screens/order_details.dart +++ b/lib/presentation/screens/order_details.dart @@ -99,6 +99,15 @@ class _OrderDetailsScreenState extends State { ), if (!_isFullScreen) ...[ + /// current location info + if (_showLocation) + SliverToBoxAdapter( + child: Padding( + padding: Space.all(1, 1), + child: LocationCard(cargoId: widget.order.cargoId), + ), + ), + /// info text SliverToBoxAdapter( child: Padding( @@ -116,42 +125,19 @@ class _OrderDetailsScreenState extends State { /// info card InfoCard(order: widget.order), + + /// gap + Space.y!, + + ///images widget + ImagesWidget(imageStrings: _images), + + /// gap + Space.yf(2), ], ), ), ), - - /// current location info - if (_showLocation) - SliverToBoxAdapter( - child: Padding( - padding: Space.all(1, 1), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'route'.tr(), - style: AppText.h2b, - ), - - /// gap - Space.y!, - - /// location card - LocationCard(cargoId: widget.order.cargoId), - - /// gap - Space.y!, - - ///images widget - ImagesWidget(imageStrings: _images), - - /// gap - Space.yf(2), - ], - ), - ), - ), ], ], ), diff --git a/lib/presentation/widgets/circle_painter.dart b/lib/presentation/widgets/circle_painter.dart new file mode 100644 index 0000000..77d632c --- /dev/null +++ b/lib/presentation/widgets/circle_painter.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; + +class CirclePainter extends CustomPainter { + final double radius; + final Color color; + + CirclePainter({required this.radius, required this.color}); + + @override + void paint(Canvas canvas, Size size) { + // Create a paint object with the specified color + final paint = Paint() + ..color = color + ..style = PaintingStyle.fill; + + // Draw the circle in the center of the canvas + canvas.drawCircle( + Offset(size.width / 2, size.height / 2), + radius, + paint, + ); + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) { + return false; + } +} + +class CirclePainterWidget extends StatelessWidget { + final double radius; + final Color color; + + const CirclePainterWidget({super.key, required this.radius, required this.color}); + + @override + Widget build(BuildContext context) { + return CustomPaint( + painter: CirclePainter(radius: radius, color: color), + // Ensure the widget is large enough to fit the circle + size: Size(radius * 2, radius * 2), + ); + } +} diff --git a/lib/presentation/widgets/location_card.dart b/lib/presentation/widgets/location_card.dart index 5fee6a1..e533c66 100644 --- a/lib/presentation/widgets/location_card.dart +++ b/lib/presentation/widgets/location_card.dart @@ -1,10 +1,11 @@ +import 'package:another_stepper/another_stepper.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../application/application.dart'; import '../../configs/configs.dart'; import '../../core/core.dart'; -import 'dashed_line.dart'; import 'retry_widget.dart'; class LocationCard extends StatelessWidget { @@ -16,69 +17,43 @@ class LocationCard extends StatelessWidget { return BlocBuilder( builder: (context, state) { if (state is RoutesLoading) { - return const Center( - child: CircularProgressIndicator(), - ); + return const SizedBox.shrink(); + // const Center( + // child: CircularProgressIndicator(), + // ); } else if (state is RoutesLoaded) { - final routes = state.routes; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'route'.tr(), + style: AppText.h2b, + ), - return SizedBox( - width: double.infinity, - child: Card( - color: Colors.white, - child: Padding( - padding: const EdgeInsets.all(16.0), - child: ListView.separated( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - final route = routes[index]; - return Row( - children: [ - route.isCurrent - ? const Icon( - Icons.radio_button_checked, - color: AppColors.primary, - ) - : Container( - margin: Space.hf(0.35), - height: AppDimensions.normalize(4.5), - width: AppDimensions.normalize(4.5), - decoration: const BoxDecoration( - color: AppColors.grey, - shape: BoxShape.circle, - ), - ), - Space.x!, - Text( - routes[index].name, - style: AppText.h3b, - ), - const Spacer(), - Text( - routes[index].dateAt, - style: AppText.b1!.copyWith(color: AppColors.grey), - ), - ], - ); - }, - itemCount: routes.length, - separatorBuilder: (BuildContext context, int index) { - return Padding( - padding: Space.vf(0.5), - child: DashedLine( - height: 1, - width: AppDimensions.normalize(8), - color: AppColors.lightGrey, - strokeWidth: 1, - dashWidth: 5, - dashSpace: AppDimensions.normalize(2), - ), - ); - }, + /// gap + Space.y!, + SizedBox( + width: double.infinity, + child: Card( + color: Colors.white, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: AnotherStepper( + stepperList: state.steppers, + stepperDirection: Axis.vertical, + iconWidth: 30, + iconHeight: 30, + activeBarColor: AppColors.greenDark, + inActiveBarColor: AppColors.darkGrey, + inverted: false, + verticalGap: 25, + activeIndex: state.activeIndex, + barThickness: 2.6, + ), + ), ), ), - ), + ], ); } else if (state is RoutesError) { return Center( diff --git a/lib/presentation/widgets/widgets.dart b/lib/presentation/widgets/widgets.dart index 3031313..e2b55ad 100644 --- a/lib/presentation/widgets/widgets.dart +++ b/lib/presentation/widgets/widgets.dart @@ -13,3 +13,4 @@ export 'successful_auth_dialog.dart'; export 'vertical_line.dart'; export 'images.dart'; export 'empty_order.dart'; +export 'circle_painter.dart'; diff --git a/pubspec.lock b/pubspec.lock index 83f399e..10abb6c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,14 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + another_stepper: + dependency: "direct main" + description: + name: another_stepper + sha256: "04f5166c57f2412c612b17101e8a3d819f210c53f6bc1b5be541dc4c6987c681" + url: "https://pub.dev" + source: hosted + version: "1.2.2" ansicolor: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 676bc25..a9d12de 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,6 +30,7 @@ dependencies: # cached_network_image: ^3.4.1 flutter_native_splash: ^2.4.1 url_launcher: ^6.3.0 + another_stepper: ^1.2.2 dev_dependencies: flutter_test: