import 'package:aesthetica_wallpaper/providers/recipe_provider.dart'; import 'package:aesthetica_wallpaper/providers/editor_provider.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:aesthetica_wallpaper/models/recipe.dart'; class FavoritesScreen extends StatelessWidget { const FavoritesScreen({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Favorites'), backgroundColor: Colors.grey[900], elevation: 0, ), body: Consumer( builder: (context, provider, child) { if (provider.recipes.isEmpty) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.favorite_border, size: 80, color: Colors.grey[600], ), const SizedBox(height: 16), Text( 'No Favorites Yet', style: TextStyle( color: Colors.grey[400], fontSize: 20, fontWeight: FontWeight.w500, ), ), const SizedBox(height: 8), Text( 'Start creating and saving your favorite wallpapers!', style: TextStyle(color: Colors.grey[500], fontSize: 14), textAlign: TextAlign.center, ), ], ), ); } return GridView.builder( padding: const EdgeInsets.fromLTRB( 16, 16, 16, 100, ), // 增加底部内边距避免被底部导航栏遮挡 gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, crossAxisSpacing: 12, mainAxisSpacing: 12, childAspectRatio: 0.8, ), itemCount: provider.recipes.length, itemBuilder: (context, index) { final recipe = provider.recipes[index]; return _buildFavoriteCard(context, recipe, provider); }, ); }, ), ); } Widget _buildFavoriteCard( BuildContext context, Recipe recipe, RecipeProvider provider, ) { return Container( decoration: BoxDecoration( color: Colors.grey[800], borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.2), blurRadius: 8, offset: const Offset(0, 4), ), ], ), child: ClipRRect( borderRadius: BorderRadius.circular(16), child: InkWell( onTap: () { // 加载配方到编辑器 Provider.of( context, listen: false, ).loadFromRecipe(recipe); Navigator.pushNamed(context, '/editor'); }, child: Stack( fit: StackFit.expand, children: [ // 壁纸预览 Image.asset( recipe.baseImagePath, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return Container( color: Colors.grey[700], child: const Icon( Icons.image_not_supported, color: Colors.grey, size: 40, ), ); }, ), // 渐变蒙版 Container( decoration: BoxDecoration( gradient: LinearGradient( colors: [ Colors.transparent, Colors.black.withValues(alpha: 0.7), ], begin: Alignment.topCenter, end: Alignment.bottomCenter, ), ), ), // 收藏按钮 Positioned( top: 8, right: 8, child: Container( padding: const EdgeInsets.all(6), decoration: BoxDecoration( color: Colors.black.withValues(alpha: 0.5), shape: BoxShape.circle, ), child: const Icon( Icons.favorite, color: Colors.pinkAccent, size: 20, ), ), ), // 底部信息 Positioned( bottom: 0, left: 0, right: 0, child: Container( padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( _getRecipeName(recipe.baseImagePath), style: const TextStyle( color: Colors.white, fontSize: 14, fontWeight: FontWeight.bold, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 4), Text( _getRecipeDescription(recipe), style: TextStyle(color: Colors.grey[300], fontSize: 12), maxLines: 2, overflow: TextOverflow.ellipsis, ), ], ), ), ), // 删除按钮 Positioned( top: 8, left: 8, child: GestureDetector( onTap: () => _showDeleteDialog(context, recipe, provider), child: Container( padding: const EdgeInsets.all(6), decoration: BoxDecoration( color: Colors.red.withValues(alpha: 0.8), shape: BoxShape.circle, ), child: const Icon( Icons.delete_outline, color: Colors.white, size: 16, ), ), ), ), ], ), ), ), ); } String _getRecipeName(String imagePath) { final fileName = imagePath.split('/').last; // 移除文件扩展名 return fileName.split('.').first; } String _getRecipeDescription(Recipe recipe) { final effects = []; if (recipe.brightness != 0.0) { effects.add('Brightness: ${recipe.brightness.toStringAsFixed(1)}'); } if (recipe.contrast != 1.0) { effects.add('Contrast: ${recipe.contrast.toStringAsFixed(1)}'); } if (recipe.saturation != 1.0) { effects.add('Saturation: ${recipe.saturation.toStringAsFixed(1)}'); } if (recipe.blur > 0.0) { effects.add('Blur: ${recipe.blur.toStringAsFixed(1)}'); } if (recipe.pixelate > 1.0) { effects.add('Pixelate: ${recipe.pixelate.toStringAsFixed(1)}'); } if (recipe.overlayText.isNotEmpty) { effects.add('Text: ${recipe.overlayText}'); } if (effects.isEmpty) { return 'Original image'; } return effects.take(2).join(', '); } void _showDeleteDialog( BuildContext context, Recipe recipe, RecipeProvider provider, ) { showDialog( context: context, builder: (context) => AlertDialog( backgroundColor: Colors.grey[800], title: const Text( 'Remove from Favorites', style: TextStyle(color: Colors.white), ), content: const Text( 'Are you sure you want to remove this wallpaper from your favorites?', style: TextStyle(color: Colors.white), ), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), child: const Text('Cancel', style: TextStyle(color: Colors.grey)), ), TextButton( onPressed: () { provider.deleteRecipe(recipe.id); Navigator.of(context).pop(); }, child: const Text('Remove', style: TextStyle(color: Colors.red)), ), ], ), ); } }