// Author: fruit.com.cn part of '../discover_view.dart'; class _HomeDramaGrid extends StatelessWidget { const _HomeDramaGrid({ required this.l10n, required this.categories, required this.onOpen, }); final AppLocalizations l10n; final CategoryController categories; final ValueChanged onOpen; @override Widget build(BuildContext context) { if (categories.loading && categories.feed.sections.isEmpty) { return const SliverPadding( padding: EdgeInsets.symmetric(vertical: 24), sliver: SliverToBoxAdapter( child: Center(child: CircularProgressIndicator(strokeWidth: 2)), ), ); } if (categories.error != null) { return SliverPadding( padding: const EdgeInsets.fromLTRB(16, 6, 16, 18), sliver: SliverToBoxAdapter( child: Row( children: [ Expanded( child: Text( l10n.categoriesError, style: const TextStyle(color: AppColors.muted), ), ), TextButton(onPressed: categories.load, child: Text(l10n.retry)), ], ), ), ); } final dramas = categories.visibleDramas; if (dramas.isEmpty) { final missingCategory = categories.selectedSectionMissing; return SliverPadding( padding: const EdgeInsets.fromLTRB(16, 6, 16, 24), sliver: SliverToBoxAdapter( child: EmptyState( key: const Key('home-all-dramas-empty'), icon: missingCategory ? Icons.grid_view_rounded : Icons.search_off_rounded, title: missingCategory ? l10n.noCategoryDramas : l10n.noSearchResults, subtitle: l10n.emptyHint, ), ), ); } return SliverPadding( key: const Key('home-all-dramas-section'), padding: const EdgeInsets.symmetric(horizontal: 16), sliver: SliverGrid( key: const Key('home-all-dramas-grid'), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, mainAxisSpacing: 14, crossAxisSpacing: 10, childAspectRatio: 2 / 3, ), delegate: SliverChildBuilderDelegate( (context, index) => _HomeDramaCard( l10n: l10n, drama: dramas[index], onTap: () => onOpen(dramas[index]), ), childCount: dramas.length, ), ), ); } } class _HomeDramaCard extends StatelessWidget { const _HomeDramaCard({ required this.l10n, required this.drama, required this.onTap, }); final AppLocalizations l10n; final Drama drama; final VoidCallback onTap; @override Widget build(BuildContext context) { final genre = drama.genre.isEmpty ? drama.category : drama.genre; return InkWell( key: Key('home-drama-card-${drama.id}'), onTap: onTap, borderRadius: BorderRadius.circular(14), child: AspectRatio( key: Key('home-drama-cover-${drama.id}'), aspectRatio: 2 / 3, child: ClipRRect( borderRadius: BorderRadius.circular(14), child: Stack( fit: StackFit.expand, children: [ RemoteImage( drama.posterUrl, fit: BoxFit.cover, showFallbackIcon: true, ), const DecoratedBox( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Color(0x00000000), Color(0xE6000000)], stops: [0.4, 1], ), ), ), Positioned( left: 10, right: 10, bottom: 10, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( drama.title, key: Key('home-drama-title-${drama.id}'), maxLines: 2, overflow: TextOverflow.ellipsis, style: const TextStyle( color: Colors.white, fontSize: 14, fontWeight: FontWeight.w700, height: 1.2, ), ), const SizedBox(height: 4), Text( genre.isEmpty ? l10n.videoPending : genre, key: Key('home-drama-genre-${drama.id}'), maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle( color: Color(0xE6FFFFFF), fontSize: 11, fontWeight: FontWeight.w400, height: 1.2, ), ), ], ), ), ], ), ), ), ); } }