import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:loading_animation_widget/loading_animation_widget.dart'; import 'package:marco/images.dart'; import 'package:marco/helpers/widgets/my_card.dart'; import 'package:marco/helpers/widgets/my_spacing.dart'; import 'package:marco/helpers/utils/my_shadow.dart'; class LoadingComponent extends StatelessWidget { final bool isLoading; final Widget child; final Color overlayColor; final double overlayOpacity; final double imageSize; final bool showDots; final String loadingText; const LoadingComponent({ Key? key, required this.isLoading, required this.child, this.overlayColor = Colors.black, this.overlayOpacity = 0.2, this.imageSize = 100, this.showDots = true, this.loadingText = 'Loading...', }) : super(key: key); @override Widget build(BuildContext context) { return Stack( children: [ child, if (isLoading) _buildLoadingOverlay(), ], ); } Widget _buildLoadingOverlay() { return Positioned.fill( child: Semantics( label: 'Loading...', child: Stack( children: [ BackdropFilter( filter: ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0), child: Container( color: overlayColor.withOpacity(overlayOpacity), ), ), Center( child: _LoadingAnimation( imageSize: imageSize, showDots: showDots, loadingText: loadingText, ), ), ], ), ), ); } } Widget contactSkeletonCard() { return MyCard.bordered( margin: MySpacing.only(bottom: 12), paddingAll: 16, borderRadiusAll: 16, shadow: MyShadow( elevation: 1.5, position: MyShadowPosition.bottom, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( height: 40, width: 40, decoration: BoxDecoration( color: Colors.grey.shade300, shape: BoxShape.circle, ), ), MySpacing.width(12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( height: 12, width: 100, color: Colors.grey.shade300, ), MySpacing.height(6), Container( height: 10, width: 60, color: Colors.grey.shade300, ), ], ), ), ], ), MySpacing.height(16), Container(height: 10, width: 150, color: Colors.grey.shade300), MySpacing.height(8), Container(height: 10, width: 100, color: Colors.grey.shade300), MySpacing.height(8), Container(height: 10, width: 120, color: Colors.grey.shade300), ], ), ); } class _LoadingAnimation extends StatelessWidget { final double imageSize; final bool showDots; final String loadingText; const _LoadingAnimation({ Key? key, required this.imageSize, required this.showDots, required this.loadingText, }) : super(key: key); static const _textStyle = TextStyle( fontSize: 12, color: Colors.white, ); @override Widget build(BuildContext context) { return SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: [ Image.asset( Images.loadingLogo, height: imageSize, width: imageSize, fit: BoxFit.contain, ), const SizedBox(height: 8), Text( loadingText, style: _textStyle, textAlign: TextAlign.center, ), const SizedBox(height: 4), if (showDots) LoadingAnimationWidget.waveDots( color: const Color(0xFFEF0000), size: 50, ), ], ), ); } }