264 lines
7.4 KiB
Dart
264 lines
7.4 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:flutter_common/flutter_common.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/provider/user_provider.dart';
|
||
import 'package:food_hub_app/widgets/common/image.dart';
|
||
import 'package:provider/provider.dart';
|
||
|
||
class MomentCard extends StatefulWidget {
|
||
final Moment moment;
|
||
final bool isUser;
|
||
|
||
const MomentCard({super.key, required this.moment, required this.isUser});
|
||
|
||
@override
|
||
State<StatefulWidget> createState() => MomentCardState();
|
||
}
|
||
|
||
class MomentCardState extends State<MomentCard> {
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return CommonCard(
|
||
child: Row(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
InkWell(
|
||
onTap: () => _onTapUser(context),
|
||
child: _buildAvatar(context),
|
||
),
|
||
const SizedBox(width: 12),
|
||
Expanded(
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
_buildNickname(context),
|
||
const SizedBox(height: 5),
|
||
_buildContent(context),
|
||
if (widget.moment.imageList.isNotEmpty) ...[
|
||
const SizedBox(height: 8),
|
||
_buildPostImages(),
|
||
],
|
||
const SizedBox(height: 10),
|
||
_buildTime(context),
|
||
const SizedBox(height: 5),
|
||
_buildActionButtons(),
|
||
if (widget.moment.commentList!.isNotEmpty) ...[
|
||
const SizedBox(height: 8),
|
||
_buildCommentList(),
|
||
],
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
void _onTapUser(BuildContext context) async {
|
||
final provider = context.read<UserProvider>();
|
||
|
||
if (widget.moment.userId != SPUtil.getInt('userId')) {
|
||
await provider.refreshUser(widget.moment.userId!);
|
||
await provider.queryMomentByUserId(widget.moment.userId!);
|
||
|
||
if (mounted) {
|
||
Navigator.pushNamed(context, '/ProfileUser');
|
||
}
|
||
}
|
||
}
|
||
|
||
// 构建头像组件
|
||
Widget _buildAvatar(BuildContext context) {
|
||
if (widget.moment.avatar!.isEmpty) {
|
||
return CircleAvatar(
|
||
radius: 18,
|
||
backgroundColor: Theme.of(context).colorScheme.primary,
|
||
foregroundColor: Theme.of(context).colorScheme.surface,
|
||
child: Text(widget.moment.username![0], style: TextStyle(fontSize: 14)),
|
||
);
|
||
} else {
|
||
return CircleAvatar(
|
||
radius: 18,
|
||
backgroundImage: NetworkImage('${AppConfig.imageBaseUrl}/${widget.moment.avatar}')
|
||
);
|
||
}
|
||
}
|
||
|
||
// 构建昵称组件
|
||
Widget _buildNickname(BuildContext context) {
|
||
return Text(
|
||
widget.moment.username ?? "",
|
||
style: Theme.of(context).textTheme.titleMedium,
|
||
);
|
||
}
|
||
|
||
// 构建内容组件
|
||
Widget _buildContent(BuildContext context) {
|
||
return Text(
|
||
widget.moment.content,
|
||
style: Theme.of(context).textTheme.bodyMedium,
|
||
);
|
||
}
|
||
|
||
// 构建朋友圈图片列表(网格布局)
|
||
Widget _buildPostImages() {
|
||
final imageCount = widget.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 =
|
||
widget.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(BuildContext context) {
|
||
return Text(
|
||
widget.moment.date ?? "",
|
||
style: Theme.of(context).textTheme.bodySmall,
|
||
);
|
||
}
|
||
|
||
void _onTapEdit() {
|
||
final provider = Provider.of<FoodProvider>(context, listen: false);
|
||
provider.isEditing = true;
|
||
provider.momentFormItem = widget.moment;
|
||
Navigator.pushNamed(context, '/momentForm');
|
||
}
|
||
|
||
// 构建点赞和评论按钮
|
||
Widget _buildActionButtons() {
|
||
return Row(
|
||
children: [
|
||
if (widget.isUser)
|
||
SizedBox(
|
||
width: 42,
|
||
height: 36,
|
||
child: Stack(
|
||
alignment: Alignment.bottomLeft,
|
||
children: [
|
||
InkWell(onTap: () => _onTapEdit(), 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: (widget.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: (widget.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: widget.moment.commentList!.length,
|
||
separatorBuilder: (context, index) => SizedBox(height: 8),
|
||
itemBuilder: (context, index) {
|
||
return _buildCommentItem(widget.moment.commentList![index]);
|
||
},
|
||
),
|
||
);
|
||
}
|
||
}
|