From ac1d7680bb65b7e0de7a1ecfd8a7374a3fd17e39 Mon Sep 17 00:00:00 2001 From: orangdeso Date: Sat, 31 May 2025 18:49:42 +0700 Subject: [PATCH] Feat: add package animation --- .dart_tool/package_config.json | 8 +- .dart_tool/package_config_subset | 4 + lib/domain/bindings/app_binding.dart | 26 +++- .../screens/auth/pages/login_screen.dart | 1 - .../screens/onboarding/onboarding_screen.dart | 71 +++++++---- .../screens/routes/app_rountes.dart | 8 +- .../screens/splash/splash_screen.dart | 29 ++++- .../widgets/animations/animation_configs.dart | 31 +++++ .../animations/container_transform.dart | 90 +++++++++++++ .../animations/fade_slide_animation.dart | 120 ++++++++++++++++++ .../widgets/animations/fade_through.dart | 54 ++++++++ .../widgets/animations/staggered_fade.dart | 82 ++++++++++++ .../widgets/shimer/skeleton_widget.dart | 30 +++++ pubspec.lock | 8 ++ pubspec.yaml | 1 + 15 files changed, 526 insertions(+), 37 deletions(-) create mode 100644 lib/presentation/widgets/animations/animation_configs.dart create mode 100644 lib/presentation/widgets/animations/container_transform.dart create mode 100644 lib/presentation/widgets/animations/fade_slide_animation.dart create mode 100644 lib/presentation/widgets/animations/fade_through.dart create mode 100644 lib/presentation/widgets/animations/staggered_fade.dart create mode 100644 lib/presentation/widgets/shimer/skeleton_widget.dart diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json index bdc5983..3ace412 100644 --- a/.dart_tool/package_config.json +++ b/.dart_tool/package_config.json @@ -7,6 +7,12 @@ "packageUri": "lib/", "languageVersion": "3.2" }, + { + "name": "animations", + "rootUri": "file:///C:/Users/ASUS/AppData/Local/Pub/Cache/hosted/pub.dev/animations-2.0.11", + "packageUri": "lib/", + "languageVersion": "3.2" + }, { "name": "archive", "rootUri": "file:///C:/Users/ASUS/AppData/Local/Pub/Cache/hosted/pub.dev/archive-4.0.7", @@ -680,7 +686,7 @@ "languageVersion": "3.4" } ], - "generated": "2025-05-20T21:06:43.916068Z", + "generated": "2025-05-29T17:34:26.701705Z", "generator": "pub", "generatorVersion": "3.5.0", "flutterRoot": "file:///D:/Flutter/flutter_sdk/flutter_3.24.0", diff --git a/.dart_tool/package_config_subset b/.dart_tool/package_config_subset index 883b78d..093d94b 100644 --- a/.dart_tool/package_config_subset +++ b/.dart_tool/package_config_subset @@ -2,6 +2,10 @@ _flutterfire_internals 3.2 file:///C:/Users/ASUS/AppData/Local/Pub/Cache/hosted/pub.dev/_flutterfire_internals-1.3.54/ file:///C:/Users/ASUS/AppData/Local/Pub/Cache/hosted/pub.dev/_flutterfire_internals-1.3.54/lib/ +animations +3.2 +file:///C:/Users/ASUS/AppData/Local/Pub/Cache/hosted/pub.dev/animations-2.0.11/ +file:///C:/Users/ASUS/AppData/Local/Pub/Cache/hosted/pub.dev/animations-2.0.11/lib/ archive 3.0 file:///C:/Users/ASUS/AppData/Local/Pub/Cache/hosted/pub.dev/archive-4.0.7/ diff --git a/lib/domain/bindings/app_binding.dart b/lib/domain/bindings/app_binding.dart index efd7f05..f496798 100644 --- a/lib/domain/bindings/app_binding.dart +++ b/lib/domain/bindings/app_binding.dart @@ -1,4 +1,7 @@ +import 'package:e_porter/domain/bindings/auth_binding.dart'; +import 'package:e_porter/domain/bindings/navigation_binding.dart'; import 'package:e_porter/presentation/screens/boarding_pass/provider/porter_service_provider.dart'; +import 'package:e_porter/presentation/widgets/animations/animation_configs.dart'; import 'package:get/get.dart'; import 'package:e_porter/data/repositories/transaction_repository_impl.dart'; import 'package:e_porter/_core/service/transaction_expiry_service.dart'; @@ -6,17 +9,30 @@ import 'package:e_porter/_core/service/transaction_expiry_service.dart'; class AppBinding extends Bindings { @override void dependencies() { - // Inisialisasi TransactionExpiryService + _initCoreBindings(); + _initServices(); + _configureGlobalTransitions(); + } + + void _initCoreBindings() { + AuthBinding().dependencies(); + MainNavigationBinding().dependencies(); + } + + void _initServices() { Get.put(TransactionRepositoryImpl(), permanent: true); - // Inisialisasi dan mulai service final repository = Get.find(); TransactionExpiryService().initialize(repository); - // Inisialisasi dependency Porter PorterServiceProvider.registerDependencies(); - - // Mulai layanan pengalihan transaksi PorterServiceProvider.initServices(); } + + void _configureGlobalTransitions() { + Get.config( + defaultTransition: Transition.fadeIn, + defaultDurationTransition: AnimationConfigs.sharedAxisDuration, + ); + } } diff --git a/lib/presentation/screens/auth/pages/login_screen.dart b/lib/presentation/screens/auth/pages/login_screen.dart index dd2f284..460dba8 100644 --- a/lib/presentation/screens/auth/pages/login_screen.dart +++ b/lib/presentation/screens/auth/pages/login_screen.dart @@ -1,5 +1,4 @@ import 'dart:developer'; - import 'package:e_porter/_core/component/button/button_fill.dart'; import 'package:e_porter/_core/constants/colors.dart'; import 'package:e_porter/_core/constants/typography.dart'; diff --git a/lib/presentation/screens/onboarding/onboarding_screen.dart b/lib/presentation/screens/onboarding/onboarding_screen.dart index 06e546d..64ef0ff 100644 --- a/lib/presentation/screens/onboarding/onboarding_screen.dart +++ b/lib/presentation/screens/onboarding/onboarding_screen.dart @@ -1,8 +1,12 @@ +import 'package:animations/animations.dart'; import 'package:e_porter/_core/component/button/button_fill.dart'; import 'package:e_porter/_core/component/button/button_outline.dart'; import 'package:e_porter/_core/constants/colors.dart'; import 'package:e_porter/_core/constants/typography.dart'; import 'package:e_porter/presentation/screens/routes/app_rountes.dart'; +import 'package:e_porter/presentation/widgets/animations/container_transform.dart'; +import 'package:e_porter/presentation/widgets/animations/fade_through.dart'; +import 'package:e_porter/presentation/widgets/animations/staggered_fade.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/svg.dart'; @@ -24,17 +28,28 @@ class OnboardingScreen extends StatelessWidget { padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h), child: Column( children: [ - SvgPicture.asset( - 'assets/images/ilustrasi_onboarding.svg', + StaggeredFadeAnimation( + index: 0, + delay: const Duration(milliseconds: 500), + duration: const Duration(milliseconds: 1000), + reverse: true, + transitionType: SharedAxisTransitionType.vertical, + child: SvgPicture.asset( + 'assets/images/ilustrasi_onboarding.svg', + ), ), SizedBox(height: 16.h), - TypographyStyles.h6( - 'Hemat waktu Anda di bandara dengan layanan E-Porter. Kami siap membantu setiap kebutuhan perjalanan prioritas Anda dengan mudah dan cepat', - fontWeight: FontWeight.w600, - color: GrayColors.gray600, - textAlign: TextAlign.center, - maxlines: 5, - ) + FadeThroughAnimation( + delay: const Duration(milliseconds: 1200), + duration: const Duration(milliseconds: 800), + child: TypographyStyles.h6( + 'Hemat waktu Anda di bandara dengan layanan E-Porter. Kami siap membantu setiap kebutuhan perjalanan prioritas Anda dengan mudah dan cepat', + fontWeight: FontWeight.w600, + color: GrayColors.gray600, + textAlign: TextAlign.center, + maxlines: 5, + ), + ), ], ), ), @@ -44,25 +59,35 @@ class OnboardingScreen extends StatelessWidget { child: Column( mainAxisSize: MainAxisSize.min, children: [ - ZoomTapAnimation( - child: ButtonFill( - text: 'Masuk sebagai Penumpang', - textColor: Colors.white, - onTap: () { - Get.toNamed(Routes.LOGIN, arguments: 'penumpang'); - }, + ContainerTransformAnimation( + delay: const Duration(milliseconds: 1800), + duration: const Duration(milliseconds: 600), + animationType: AnimationType.fadeThrough, + child: ZoomTapAnimation( + child: ButtonFill( + text: 'Masuk sebagai Penumpang', + textColor: Colors.white, + onTap: () { + Get.toNamed(Routes.LOGIN, arguments: 'penumpang'); + }, + ), ), ), SizedBox( height: 10.h, ), - ZoomTapAnimation( - child: ButtonOutline( - text: 'Masuk sebagai Porter', - textColor: PrimaryColors.primary800, - onTap: () { - Get.toNamed(Routes.LOGIN, arguments: 'porter'); - }, + ContainerTransformAnimation( + delay: const Duration(milliseconds: 2100), + duration: const Duration(milliseconds: 600), + animationType: AnimationType.sharedAxisHorizontal, + child: ZoomTapAnimation( + child: ButtonOutline( + text: 'Masuk sebagai Porter', + textColor: PrimaryColors.primary800, + onTap: () { + Get.toNamed(Routes.LOGIN, arguments: 'porter'); + }, + ), ), ), ], diff --git a/lib/presentation/screens/routes/app_rountes.dart b/lib/presentation/screens/routes/app_rountes.dart index b9eb8c8..df40961 100644 --- a/lib/presentation/screens/routes/app_rountes.dart +++ b/lib/presentation/screens/routes/app_rountes.dart @@ -76,6 +76,10 @@ class AppRoutes { page: () => LoginScreen(), binding: AuthBinding(), ), + GetPage( + name: Routes.REGISTER, + page: () => RegisterScreen(), + ), GetPage( name: Routes.VERIFICATION, page: () => VerifikasiScreen(), @@ -93,10 +97,6 @@ class AppRoutes { name: Routes.PROFILE, page: () => ProfileScreen(), ), - GetPage( - name: Routes.REGISTER, - page: () => RegisterScreen(), - ), GetPage( name: Routes.FORGETPASSWORD, page: () => ForgetPasswordScreen(), diff --git a/lib/presentation/screens/splash/splash_screen.dart b/lib/presentation/screens/splash/splash_screen.dart index 2a325a3..8f2b79b 100644 --- a/lib/presentation/screens/splash/splash_screen.dart +++ b/lib/presentation/screens/splash/splash_screen.dart @@ -1,4 +1,5 @@ import 'package:e_porter/presentation/screens/routes/app_rountes.dart'; +import 'package:e_porter/presentation/widgets/animations/fade_slide_animation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:get/get.dart'; @@ -16,7 +17,19 @@ class _SplashScreenState extends State { @override void initState() { super.initState(); - Future.delayed(Duration(seconds: 3), () async { + // Future.delayed(Duration(seconds: 3), () async { + // final userData = await PreferencesService.getUserData(); + // if (userData != null) { + // Get.offAllNamed(Routes.NAVBAR, arguments: userData.role); + // } else { + // Get.offAllNamed(Routes.ONBOARDING); + // } + // }); + _navigateAfterDelay(); + } + + void _navigateAfterDelay() { + Future.delayed(const Duration(seconds: 3), () async { final userData = await PreferencesService.getUserData(); if (userData != null) { Get.offAllNamed(Routes.NAVBAR, arguments: userData.role); @@ -31,8 +44,18 @@ class _SplashScreenState extends State { return Scaffold( backgroundColor: Colors.white, body: Center( - child: SvgPicture.asset( - 'assets/images/eporter-logo.svg', + child: FadeSlideAnimation( + duration: const Duration(milliseconds: 1200), + delay: const Duration(milliseconds: 300), + slideOffset: const Offset(0, 0.3), + curve: Curves.easeOutBack, + enableScale: true, + enableBlur: true, + scaleBegin: 0.2, + scaleEnd: 1.0, + child: SvgPicture.asset( + 'assets/images/eporter-logo.svg', + ), ), ), ); diff --git a/lib/presentation/widgets/animations/animation_configs.dart b/lib/presentation/widgets/animations/animation_configs.dart new file mode 100644 index 0000000..e0029dd --- /dev/null +++ b/lib/presentation/widgets/animations/animation_configs.dart @@ -0,0 +1,31 @@ +import 'package:animations/animations.dart'; +import 'package:flutter/material.dart'; + +class AnimationConfigs { + // === FADE THROUGH TRANSITIONS === + static const Duration fadeTransitionDuration = Duration(milliseconds: 800); + static const Duration fadeTransitionReverseDuration = Duration(milliseconds: 500); + + // === SHARED AXIS TRANSITIONS === + static const Duration sharedAxisDuration = Duration(milliseconds: 600); + static const SharedAxisTransitionType horizontalTransition = SharedAxisTransitionType.horizontal; + static const SharedAxisTransitionType verticalTransition = SharedAxisTransitionType.vertical; + static const SharedAxisTransitionType scaledTransition = SharedAxisTransitionType.scaled; + + // === CONTAINER TRANSFORM === + static const Duration containerTransformDuration = Duration(milliseconds: 700); + + // === CUSTOM CURVES === + static const Curve defaultCurve = Curves.easeOutCubic; + static const Curve bouncyCurve = Curves.elasticOut; + static const Curve smoothCurve = Curves.easeInOutCubic; + + // === STAGGER DELAYS === + static const Duration baseDelay = Duration(milliseconds: 300); + static const Duration itemDelay = Duration(milliseconds: 150); + static const Duration buttonDelay = Duration(milliseconds: 200); + + // === MODAL TRANSITIONS === + static const Duration modalDuration = Duration(milliseconds: 500); + static const Duration overlayDuration = Duration(milliseconds: 300); +} \ No newline at end of file diff --git a/lib/presentation/widgets/animations/container_transform.dart b/lib/presentation/widgets/animations/container_transform.dart new file mode 100644 index 0000000..93201ee --- /dev/null +++ b/lib/presentation/widgets/animations/container_transform.dart @@ -0,0 +1,90 @@ +import 'package:animations/animations.dart'; +import 'package:e_porter/presentation/widgets/animations/animation_configs.dart'; +import 'package:flutter/material.dart'; + +enum AnimationType { + fadeThrough, + sharedAxisVertical, + sharedAxisHorizontal, + sharedAxisScaled, +} + +class ContainerTransformAnimation extends StatefulWidget { + final Widget child; + final Duration delay; + final Duration? duration; + final AnimationType animationType; + + const ContainerTransformAnimation({ + Key? key, + required this.child, + this.delay = Duration.zero, + this.duration, + this.animationType = AnimationType.fadeThrough, + }) : super(key: key); + + @override + State createState() => _ContainerTransformAnimationState(); +} + +class _ContainerTransformAnimationState extends State { + bool _isVisible = false; + + @override + void initState() { + super.initState(); + + Future.delayed(widget.delay, () { + if (mounted) { + setState(() { + _isVisible = true; + }); + } + }); + } + + Widget _buildTransition(Widget child, Animation primaryAnimation, Animation secondaryAnimation) { + switch (widget.animationType) { + case AnimationType.fadeThrough: + return FadeThroughTransition( + animation: primaryAnimation, + secondaryAnimation: secondaryAnimation, + child: child, + ); + case AnimationType.sharedAxisVertical: + return SharedAxisTransition( + animation: primaryAnimation, + secondaryAnimation: secondaryAnimation, + transitionType: SharedAxisTransitionType.vertical, + child: child, + ); + case AnimationType.sharedAxisHorizontal: + return SharedAxisTransition( + animation: primaryAnimation, + secondaryAnimation: secondaryAnimation, + transitionType: SharedAxisTransitionType.horizontal, + child: child, + ); + case AnimationType.sharedAxisScaled: + return SharedAxisTransition( + animation: primaryAnimation, + secondaryAnimation: secondaryAnimation, + transitionType: SharedAxisTransitionType.scaled, + child: child, + ); + } + } + + @override + Widget build(BuildContext context) { + return Center( + child: PageTransitionSwitcher( + duration: widget.duration ?? AnimationConfigs.containerTransformDuration, + transitionBuilder: (child, primaryAnimation, secondaryAnimation) { + return _buildTransition(child, primaryAnimation, secondaryAnimation); + }, + child: _isVisible ? widget.child : const SizedBox.shrink(), + ), + ); + } +} diff --git a/lib/presentation/widgets/animations/fade_slide_animation.dart b/lib/presentation/widgets/animations/fade_slide_animation.dart new file mode 100644 index 0000000..e6c4da3 --- /dev/null +++ b/lib/presentation/widgets/animations/fade_slide_animation.dart @@ -0,0 +1,120 @@ +import 'dart:ui'; + +import 'package:flutter/material.dart'; + +class FadeSlideAnimation extends StatefulWidget { + final Widget child; + final Duration duration; + final Duration delay; + final Offset slideOffset; + final Curve curve; + final bool enableScale; + final bool enableBlur; + final double scaleBegin; + final double scaleEnd; + + const FadeSlideAnimation({ + Key? key, + required this.child, + this.duration = const Duration(milliseconds: 800), + this.delay = Duration.zero, + this.slideOffset = const Offset(0, 0.3), + this.curve = Curves.easeOutCubic, + this.enableScale = false, + this.enableBlur = false, + this.scaleBegin = 0.3, + this.scaleEnd = 1.0, + }) : super(key: key); + + @override + State createState() => _FadeSlideAnimationState(); +} + +class _FadeSlideAnimationState extends State + with SingleTickerProviderStateMixin { + late AnimationController _controller; + late Animation _fadeAnimation; + late Animation _scaleAnimation; + late Animation _blurAnimation; + + @override + void initState() { + super.initState(); + + _controller = AnimationController( + duration: widget.duration, + vsync: this, + ); + + // Fade animation + _fadeAnimation = Tween( + begin: 0.0, + end: 1.0, + ).animate(CurvedAnimation( + parent: _controller, + curve: widget.curve, + )); + + // Scale animation (dari kecil ke besar) + _scaleAnimation = Tween( + begin: widget.scaleBegin, + end: widget.scaleEnd, + ).animate(CurvedAnimation( + parent: _controller, + curve: widget.enableScale ? Curves.elasticOut : widget.curve, + )); + + // Blur animation (blur tinggi ke blur rendah/hilang) + _blurAnimation = Tween( + begin: widget.enableBlur ? 10.0 : 0.0, + end: 0.0, + ).animate(CurvedAnimation( + parent: _controller, + curve: Curves.easeOutQuart, + )); + + Future.delayed(widget.delay, () { + if (mounted) { + _controller.forward(); + } + }); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return AnimatedBuilder( + animation: _controller, + builder: (context, child) { + Widget animatedChild = widget.child; + + if (widget.enableScale) { + animatedChild = Transform.scale( + scale: _scaleAnimation.value, + child: animatedChild, + ); + } + + if (widget.enableBlur) { + animatedChild = ImageFiltered( + imageFilter: ImageFilter.blur( + sigmaX: _blurAnimation.value, + sigmaY: _blurAnimation.value, + ), + child: animatedChild, + ); + } + + return FadeTransition( + opacity: _fadeAnimation, + child: animatedChild, + ); + }, + ); + } +} \ No newline at end of file diff --git a/lib/presentation/widgets/animations/fade_through.dart b/lib/presentation/widgets/animations/fade_through.dart new file mode 100644 index 0000000..4113c8f --- /dev/null +++ b/lib/presentation/widgets/animations/fade_through.dart @@ -0,0 +1,54 @@ +import 'package:animations/animations.dart'; +import 'package:e_porter/presentation/widgets/animations/animation_configs.dart'; +import 'package:flutter/material.dart'; + +class FadeThroughAnimation extends StatefulWidget { + final Widget child; + final Duration delay; + final Duration? duration; + + const FadeThroughAnimation({ + Key? key, + required this.child, + this.delay = Duration.zero, + this.duration, + }) : super(key: key); + + @override + State createState() => _FadeThroughAnimationState(); +} + +class _FadeThroughAnimationState extends State { + bool _isVisible = false; + + @override + void initState() { + super.initState(); + + Future.delayed(widget.delay, () { + if (mounted) { + setState(() { + _isVisible = true; + }); + } + }); + } + + @override + Widget build(BuildContext context) { + return PageTransitionSwitcher( + duration: widget.duration ?? AnimationConfigs.fadeTransitionDuration, + transitionBuilder: (child, primaryAnimation, secondaryAnimation) { + return FadeThroughTransition( + fillColor: Colors.transparent, + animation: primaryAnimation, + secondaryAnimation: secondaryAnimation, + child: child, + ); + }, + child: _isVisible + ? widget.child + : const SizedBox.shrink(), + ); + } +} \ No newline at end of file diff --git a/lib/presentation/widgets/animations/staggered_fade.dart b/lib/presentation/widgets/animations/staggered_fade.dart new file mode 100644 index 0000000..f6e4b24 --- /dev/null +++ b/lib/presentation/widgets/animations/staggered_fade.dart @@ -0,0 +1,82 @@ +import 'package:animations/animations.dart'; +import 'package:e_porter/presentation/widgets/animations/animation_configs.dart'; +import 'package:flutter/material.dart'; + +class StaggeredFadeAnimation extends StatefulWidget { + final Widget child; + final int index; + final Duration? delay; + final Duration? duration; + final SharedAxisTransitionType transitionType; + final bool reverse; + + const StaggeredFadeAnimation({ + Key? key, + required this.child, + required this.index, + this.delay, + this.duration, + this.transitionType = SharedAxisTransitionType.vertical, + this.reverse = false, + }) : super(key: key); + + @override + State createState() => _StaggeredFadeAnimationState(); +} + +class _StaggeredFadeAnimationState extends State + with SingleTickerProviderStateMixin { + late AnimationController _controller; + bool _isVisible = false; + + @override + void initState() { + super.initState(); + + _controller = AnimationController( + duration: widget.duration ?? AnimationConfigs.sharedAxisDuration, + vsync: this, + ); + + // Calculate staggered delay + final totalDelay = (widget.delay ?? AnimationConfigs.baseDelay) + + Duration(milliseconds: AnimationConfigs.itemDelay.inMilliseconds * widget.index); + + // Start animation after delay + Future.delayed(totalDelay, () { + if (mounted) { + setState(() { + _isVisible = true; + }); + } + }); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Center( + child: PageTransitionSwitcher( + duration: widget.duration ?? AnimationConfigs.sharedAxisDuration, + reverse: widget.reverse, + transitionBuilder: (child, primaryAnimation, secondaryAnimation) { + return SharedAxisTransition( + fillColor: Colors.transparent, + animation: primaryAnimation, + secondaryAnimation: secondaryAnimation, + transitionType: widget.transitionType, + child: child, + ); + }, + child: _isVisible + ? widget.child + : const SizedBox.shrink(), + ), + ); + } +} \ No newline at end of file diff --git a/lib/presentation/widgets/shimer/skeleton_widget.dart b/lib/presentation/widgets/shimer/skeleton_widget.dart new file mode 100644 index 0000000..dc9492e --- /dev/null +++ b/lib/presentation/widgets/shimer/skeleton_widget.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:shimmer/shimmer.dart'; + +class SkeletonWidget extends StatelessWidget { + final double height; + final double width; + + const SkeletonWidget({ + Key? key, + required this.height, + required this.width, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Shimmer.fromColors( + baseColor: Colors.grey[200]!, + highlightColor: Colors.grey[50]!, + child: Container( + height: height, + width: width, + decoration: BoxDecoration( + color: Colors.grey[300], + borderRadius: BorderRadius.circular(10.r), + ), + ), + ); + } +} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index a4a9cd5..59b53f5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -9,6 +9,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.54" + animations: + dependency: "direct main" + description: + name: animations + sha256: d3d6dcfb218225bbe68e87ccf6378bbb2e32a94900722c5f81611dad089911cb + url: "https://pub.dev" + source: hosted + version: "2.0.11" archive: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 8855311..142cb92 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -61,6 +61,7 @@ dependencies: mobile_scanner: ^6.0.10 pdf: ^3.11.3 printing: ^5.14.2 + animations: ^2.0.11 # firebase_dynamic_links: ^6.1.5 # workmanager: ^0.5.2