Files
food_hub_app/lib/widgets/moment/card.dart
2025-11-24 19:56:13 +08:00

248 lines
6.8 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
import 'package:flutter_common/widget/common_widget.dart';
import 'package:food_hub_app/config/app_config.dart';
import 'package:food_hub_app/models/moment.dart';
import 'package:food_hub_app/provider/food_provider.dart';
import 'package:food_hub_app/widgets/common/image.dart';
import 'package:provider/provider.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
class MomentCard extends StatelessWidget {
final Moment moment;
final bool isUser;
const MomentCard({super.key, required this.moment, required this.isUser});
@override
Widget build(BuildContext context) {
return CommonCard(
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(context),
if (moment.commentList!.isNotEmpty) ...[
const SizedBox(height: 8),
_buildCommentList(),
],
],
),
),
],
),
);
}
// 构建头像组件
Widget _buildAvatar(BuildContext context) {
if (moment.avatar!.isEmpty) {
return TDAvatar(
size: TDAvatarSize.medium,
type: TDAvatarType.customText,
shape: TDAvatarShape.circle,
backgroundColor: Theme.of(context).colorScheme.primary,
text: moment.username?[0],
);
} else {
return TDAvatar(
size: TDAvatarSize.medium,
type: TDAvatarType.normal,
fit: BoxFit.contain,
avatarUrl: '${AppConfig.imageBaseUrl}/${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<String> imageUrls =
moment.imageList.map((path) => path).toList();
return GridView.count(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
crossAxisCount: crossAxisCount,
crossAxisSpacing: 4,
mainAxisSpacing: 4,
childAspectRatio: itemAspectRatio,
children: List.generate(imageCount, (index) {
return CommonImage(imageUrls: imageUrls, index: index);
}),
);
}
// 构建时间组件
Widget _buildTime() {
return Text(
moment.date ?? "",
style: TextStyle(fontSize: 12, color: Colors.grey[500]),
);
}
void _onTapEdit(BuildContext context) {
final provider = Provider.of<FoodProvider>(context, listen: false);
provider.isEditing = true;
provider.momentFormItem = moment;
Navigator.pushNamed(context, '/momentForm');
}
// 构建点赞和评论按钮
Widget _buildActionButtons(BuildContext context) {
return Row(
children: [
if (isUser)
SizedBox(
width: 42,
height: 36,
child: Stack(
alignment: Alignment.bottomLeft,
children: [
InkWell(
onTap: () => _onTapEdit(context),
child: Icon(Icons.edit),
),
],
),
),
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(),
),
),
],
),
),
],
);
}
Widget _buildCommentItem(Comment comment) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RichText(
text: TextSpan(
children: [
TextSpan(
text: comment.username,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
fontFamily: 'CustomFont',
color: Colors.black,
),
),
const TextSpan(text: ': ', style: TextStyle(color: Colors.black)),
TextSpan(
text: comment.content,
style: const TextStyle(
fontSize: 14,
fontFamily: 'CustomFont',
color: Colors.black87,
),
),
],
),
),
],
);
}
Widget _buildCommentList() {
return Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(8),
),
child: ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: moment.commentList!.length,
separatorBuilder: (context, index) => SizedBox(height: 8),
itemBuilder: (context, index) {
return _buildCommentItem(moment.commentList![index]);
},
),
);
}
}