import 'package:flutter/material.dart'; import 'package:shimmer/shimmer.dart'; import '../main.dart'; /// A reusable skeleton loader that uses the app's theme colors. class SkeletonLoader extends StatelessWidget { final double width; final double height; final double borderRadius; const SkeletonLoader({ super.key, required this.width, required this.height, this.borderRadius = 8.0, }); @override Widget build(BuildContext context) { return Shimmer.fromColors( baseColor: AppColors.shimmerBase, highlightColor: AppColors.shimmerHighlight, child: Container( width: width, height: height, decoration: BoxDecoration( color: AppColors.shimmerBase, borderRadius: BorderRadius.circular(borderRadius), ), ), ); } } /// A standard multi-line text skeleton class TextSkeleton extends StatelessWidget { final int lines; final double width; final double lineHeight; const TextSkeleton({ super.key, this.lines = 3, this.width = double.infinity, this.lineHeight = 12.0, }); @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: List.generate(lines, (index) { // Make the last line slightly shorter for realism double lineWidth = width; if (index == lines - 1 && width == double.infinity) { lineWidth = MediaQuery.of(context).size.width * 0.6; } return Padding( padding: EdgeInsets.only(bottom: index == lines - 1 ? 0 : 8.0), child: SkeletonLoader( width: lineWidth, height: lineHeight, borderRadius: 6.0, ), ); }), ); } } /// A skeleton loader styled like a news/result card class CardSkeleton extends StatelessWidget { const CardSkeleton({super.key}); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: AppColors.cardBg, borderRadius: BorderRadius.circular(16), border: Border.all(color: AppColors.divider), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ const SkeletonLoader(width: 48, height: 48, borderRadius: 24), const SizedBox(width: 16), Column( crossAxisAlignment: CrossAxisAlignment.start, children: const [ SkeletonLoader(width: 140, height: 16), SizedBox(height: 8), SkeletonLoader(width: 80, height: 12), ], ), ], ), const SizedBox(height: 24), const TextSkeleton(lines: 4), const SizedBox(height: 24), Row( children: const [ SkeletonLoader(width: 100, height: 36, borderRadius: 18), SizedBox(width: 12), SkeletonLoader(width: 80, height: 36, borderRadius: 18), ], ), ], ), ); } }