248 lines
6.7 KiB
Dart
248 lines
6.7 KiB
Dart
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/widgets/common/image.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 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(),
|
||
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).primaryColor,
|
||
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]),
|
||
);
|
||
}
|
||
|
||
// 构建点赞和评论按钮
|
||
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]),
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
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]);
|
||
},
|
||
),
|
||
);
|
||
}
|
||
}
|