LCOV - code coverage report
Current view: top level - app\presentation\widgets\loading_grid.dart - loading_grid.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 53 53 100.0 %
Date: Wed Aug 6 23:43:55 2025 Functions: 0 0 -

          Line data    Source code
       1             : import 'package:flutter/material.dart';
       2             : import 'package:skeleton_loader/skeleton_loader.dart';
       3             : 
       4             : /// Displays a grid of skeleton loaders to indicate loading state for movie cards.
       5             : ///
       6             : /// The `LoadingGrid` widget is used to show a placeholder grid while movie data is being fetched.
       7             : /// It renders a configurable number of skeleton cards, matching the layout of the movie grid.
       8             : ///
       9             : /// ### Parameters
      10             : /// - [itemCount]: Number of skeleton items to display (default: 6).
      11             : /// - [childAspectRatio]: Aspect ratio for each grid item (default: 0.7).
      12             : ///
      13             : /// ### Usage
      14             : /// Use this widget in place of a movie grid when data is loading to provide a smooth user experience.
      15             : class LoadingGrid extends StatelessWidget {
      16             :   final int itemCount;
      17             :   final double childAspectRatio;
      18             : 
      19          14 :   const LoadingGrid({
      20             :     super.key,
      21             :     this.itemCount = 6,
      22             :     this.childAspectRatio = 0.7,
      23             :   });
      24             : 
      25           2 :   @override
      26             :   Widget build(BuildContext context) {
      27           2 :     return GridView.builder(
      28             :       padding: const EdgeInsets.all(16),
      29           2 :       gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
      30             :         crossAxisCount: 2,
      31           2 :         childAspectRatio: childAspectRatio,
      32             :         crossAxisSpacing: 16,
      33             :         mainAxisSpacing: 16,
      34             :       ),
      35           2 :       itemCount: itemCount,
      36           2 :       itemBuilder: (context, index) {
      37             :         return const MovieCardSkeleton();
      38             :       },
      39             :     );
      40             :   }
      41             : }
      42             : 
      43             : /// Displays a skeleton loader for a single movie card, simulating a loading state in grids.
      44             : ///
      45             : /// The `MovieCardSkeleton` widget is used to show a placeholder for a movie card while data is being fetched.
      46             : /// It mimics the layout of a typical movie card, including poster and info placeholders.
      47             : ///
      48             : /// ### Usage
      49             : /// Use this widget in grids to provide a smooth loading experience while movie data is loading.
      50             : class MovieCardSkeleton extends StatelessWidget {
      51          14 :   const MovieCardSkeleton({super.key});
      52             : 
      53           2 :   @override
      54             :   Widget build(BuildContext context) {
      55           2 :     return Card(
      56             :       elevation: 4,
      57           4 :       shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
      58           2 :       child: SkeletonLoader(
      59           2 :         builder: Container(
      60             :           height: 280, // Altura fija para evitar overflow
      61           4 :           decoration: BoxDecoration(borderRadius: BorderRadius.circular(12)),
      62           2 :           child: Column(
      63             :             crossAxisAlignment: CrossAxisAlignment.start,
      64           2 :             children: [
      65             :               // Poster placeholder
      66           2 :               Expanded(
      67             :                 flex: 3,
      68           2 :                 child: Container(
      69             :                   width: double.infinity,
      70             :                   decoration: const BoxDecoration(
      71             :                     color: Colors.grey,
      72             :                     borderRadius: BorderRadius.vertical(
      73             :                       top: Radius.circular(12),
      74             :                     ),
      75             :                   ),
      76             :                 ),
      77             :               ),
      78             : 
      79             :               // Info placeholder
      80           2 :               Expanded(
      81             :                 flex: 1,
      82           2 :                 child: Padding(
      83             :                   padding: const EdgeInsets.all(8.0),
      84           2 :                   child: Column(
      85             :                     crossAxisAlignment: CrossAxisAlignment.start,
      86           2 :                     children: [
      87             :                       // Title placeholder
      88           2 :                       Flexible(
      89           2 :                         child: Container(
      90             :                           height: 14,
      91             :                           width: double.infinity,
      92           2 :                           decoration: BoxDecoration(
      93             :                             color: Colors.grey,
      94           2 :                             borderRadius: BorderRadius.circular(4),
      95             :                           ),
      96             :                         ),
      97             :                       ),
      98             :                       const SizedBox(height: 4),
      99             : 
     100             :                       // Subtitle placeholder
     101           2 :                       Container(
     102             :                         height: 10,
     103             :                         width: 60,
     104           2 :                         decoration: BoxDecoration(
     105             :                           color: Colors.grey,
     106           2 :                           borderRadius: BorderRadius.circular(4),
     107             :                         ),
     108             :                       ),
     109             :                     ],
     110             :                   ),
     111             :                 ),
     112             :               ),
     113             :             ],
     114             :           ),
     115             :         ),
     116             :         items: 1,
     117             :         period: const Duration(seconds: 2),
     118           2 :         highlightColor: Colors.white.withValues(alpha: 0.6),
     119             :         direction: SkeletonDirection.ltr,
     120             :       ),
     121             :     );
     122             :   }
     123             : }
     124             : 
     125             : /// Displays a skeleton loader for a single list item, simulating a loading state for movie rows.
     126             : ///
     127             : /// The `LoadingListItem` widget is used to show a placeholder for a movie list item while data is being fetched.
     128             : /// It mimics the layout of a typical movie row, including poster, title, subtitle, and rating placeholders.
     129             : ///
     130             : /// ### Usage
     131             : /// Use this widget in place of a movie list item when data is loading to provide a smooth user experience.
     132             : class LoadingListItem extends StatelessWidget {
     133           1 :   const LoadingListItem({super.key});
     134             : 
     135           1 :   @override
     136             :   Widget build(BuildContext context) {
     137           1 :     return Card(
     138             :       margin: const EdgeInsets.only(bottom: 16),
     139           1 :       child: SkeletonLoader(
     140           1 :         builder: Container(
     141             :           padding: const EdgeInsets.all(16),
     142           1 :           child: Row(
     143           1 :             children: [
     144             :               // Poster placeholder
     145           1 :               Container(
     146             :                 width: 60,
     147             :                 height: 90,
     148           1 :                 decoration: BoxDecoration(
     149             :                   color: Colors.grey,
     150           1 :                   borderRadius: BorderRadius.circular(8),
     151             :                 ),
     152             :               ),
     153             :               const SizedBox(width: 16),
     154             : 
     155             :               // Content placeholder
     156           1 :               Expanded(
     157           1 :                 child: Column(
     158             :                   crossAxisAlignment: CrossAxisAlignment.start,
     159           1 :                   children: [
     160             :                     // Title placeholder
     161           1 :                     Container(
     162             :                       height: 16,
     163             :                       width: double.infinity,
     164           1 :                       decoration: BoxDecoration(
     165             :                         color: Colors.grey,
     166           1 :                         borderRadius: BorderRadius.circular(4),
     167             :                       ),
     168             :                     ),
     169             :                     const SizedBox(height: 8),
     170             : 
     171             :                     // Subtitle placeholder
     172           1 :                     Container(
     173             :                       height: 12,
     174             :                       width: 100,
     175           1 :                       decoration: BoxDecoration(
     176             :                         color: Colors.grey,
     177           1 :                         borderRadius: BorderRadius.circular(4),
     178             :                       ),
     179             :                     ),
     180             :                     const SizedBox(height: 8),
     181             : 
     182             :                     // Rating placeholder
     183           1 :                     Container(
     184             :                       height: 12,
     185             :                       width: 60,
     186           1 :                       decoration: BoxDecoration(
     187             :                         color: Colors.grey,
     188           1 :                         borderRadius: BorderRadius.circular(4),
     189             :                       ),
     190             :                     ),
     191             :                   ],
     192             :                 ),
     193             :               ),
     194             :             ],
     195             :           ),
     196             :         ),
     197             :         items: 1,
     198             :         period: const Duration(seconds: 2),
     199           1 :         highlightColor: Colors.white.withValues(alpha: 0.6),
     200             :         direction: SkeletonDirection.ltr,
     201             :       ),
     202             :     );
     203             :   }
     204             : }

Generated by: LCOV version 1.15.alpha0w