import 'package:flutter/material.dart'; import 'package:food_hub_app/config/app_config.dart'; import 'package:food_hub_app/models/moment.dart'; import 'package:food_hub_app/widgets/common/image_preview.dart'; import 'package:tdesign_flutter/tdesign_flutter.dart'; class MomentCard extends StatelessWidget { final Moment moment; const MomentCard({super.key, required this.moment}); @override Widget build(BuildContext context) { return Card( elevation: 0, color: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), child: Padding( padding: const EdgeInsets.all(10), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildAvatar(context), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildNickname(), const SizedBox(height: 5), _buildContent(), if (moment.imageList.isNotEmpty) ...[ const SizedBox(height: 8), _buildPostImages(context), ], const SizedBox(height: 10), _buildTime(), const SizedBox(height: 5), _buildActionButtons(), ], ), ), ], ), ), ); } // 构建头像组件 Widget _buildAvatar(BuildContext context) { if (moment.avatar!.isEmpty) { return TDAvatar( size: TDAvatarSize.medium, type: TDAvatarType.customText, shape: TDAvatarShape.circle, backgroundColor: Theme.of(context).primaryColor, text: moment.username?[0]); } else { return TDAvatar( size: TDAvatarSize.medium, type: TDAvatarType.normal, fit: BoxFit.contain, avatarUrl: '${AppConfig.baseApiUrl}/${moment.avatar}'); } } // 构建昵称组件 Widget _buildNickname() { return Text( moment.username ?? "", style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, ), ); } // 构建内容组件 Widget _buildContent() { return Text( moment.content, style: const TextStyle(fontSize: 15, height: 1.3), ); } // 构建朋友圈图片列表(网格布局) Widget _buildPostImages(BuildContext context) { final imageCount = moment.imageList.length; // 计算网格列数 int crossAxisCount; if (imageCount == 1) { crossAxisCount = 1; } else if (imageCount == 2 || imageCount == 4) { crossAxisCount = 2; } else { crossAxisCount = 3; } // 计算宽高比 double itemAspectRatio = 1.0; if (imageCount == 1) { itemAspectRatio = 1.5; } // 生成图片URL列表(用于预览时切换) final List imageUrls = moment.imageList .map((path) => '${AppConfig.baseApiUrl}/$path') .toList(); return GridView.count( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), crossAxisCount: crossAxisCount, crossAxisSpacing: 4, mainAxisSpacing: 4, childAspectRatio: itemAspectRatio, children: List.generate(imageCount, (index) { // 单个图片项:添加点击事件 return GestureDetector( // 点击图片时,跳转到预览页面 onTap: () { // 导航到全屏预览页面,传入所有图片URL和当前点击的索引 Navigator.push( context, MaterialPageRoute( builder: (context) => ImagePreviewPage( images: imageUrls, initialIndex: index, ), ), ); }, // 原图片组件 child: ClipRRect( borderRadius: BorderRadius.circular(8), child: Image.network( imageUrls[index], fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return Container( color: Colors.grey[200], child: const Icon(Icons.image, color: Colors.grey, size: 30), ); }, ), ), ); }), ); } // 构建时间组件 Widget _buildTime() { return Text( moment.date ?? "", style: TextStyle(fontSize: 12, color: Colors.grey[500]), ); } // 构建点赞和评论按钮 Widget _buildActionButtons() { return Row( children: [ SizedBox( width: 42, height: 36, child: Stack( alignment: Alignment.bottomLeft, children: [ Icon(Icons.thumb_up_alt_outlined), Positioned( left: 20, bottom: 15, child: TDBadge( TDBadgeType.message, count: (moment.likeList?.length ?? 0).toString(), ), ), ], ), ), SizedBox( width: 42, height: 36, child: Stack( alignment: Alignment.bottomLeft, children: [ Icon(Icons.comment_outlined), Positioned( left: 20, bottom: 15, child: TDBadge( TDBadgeType.message, count: (moment.commentList?.length ?? 0).toString(), ), ), ], ), ), // _buildActionButton( // icon: Icons.thumb_up_alt_outlined, // count: moment.likeList?.length ?? 0, // ), // const SizedBox(width: 20), // _buildActionButton( // icon: Icons.comment_outlined, // count: moment.commentList?.length ?? 0, // ), ], ); } // 构建带数字标记的动作按钮 Widget _buildActionButton({required IconData icon, required int count}) { return Row( children: [ Icon(icon, color: Colors.grey[500], size: 18), const SizedBox(width: 4), if (count > 0) Text( count.toString(), style: TextStyle(fontSize: 12, color: Colors.grey[500]), ), ], ); } }