import 'package:cached_network_image/cached_network_image.dart'; import 'package:dating_touchme_app/config/emoji_config.dart'; import 'package:dating_touchme_app/extension/ex_widget.dart'; import 'package:dating_touchme_app/generated/assets.dart'; import 'package:dating_touchme_app/model/home/post_data.dart'; import 'package:dating_touchme_app/network/home_api.dart'; import 'package:dating_touchme_app/pages/home/report_page.dart'; import 'package:dating_touchme_app/pages/home/timeline_info.dart'; import 'package:dating_touchme_app/pages/home/user_information_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; class TimelineItem extends StatefulWidget { final Records item; const TimelineItem({super.key, required this.item}); @override State createState() => _TimelineItemState(); } class _TimelineItemState extends State { /// 构建输入框内容(文本+表情) List buildInputContentWidgets() { final List widgets = []; final text = widget.item.content ?? ""; final RegExp emojiRegex = RegExp(r'\[emoji:(\d+)\]'); int lastMatchEnd = 0; final matches = emojiRegex.allMatches(text); for (final match in matches) { // 添加表情之前的文本 if (match.start > lastMatchEnd) { final textPart = text.substring(lastMatchEnd, match.start); widgets.add( Text( textPart, style: TextStyle(fontSize: 14.sp, color: Colors.black), ), ); } // 添加表情图片 final emojiId = match.group(1); if (emojiId != null) { final emoji = EmojiConfig.getEmojiById(emojiId); if (emoji != null) { widgets.add( Padding( padding: EdgeInsets.symmetric(horizontal: 0), child: Image.asset( emoji.path, width: 24.w, height: 24.w, fit: BoxFit.contain, ), ), ); } } lastMatchEnd = match.end; } // 添加剩余的文本 if (lastMatchEnd < text.length) { final textPart = text.substring(lastMatchEnd); widgets.add( Text( textPart, style: TextStyle(fontSize: 14.sp, color: Colors.black), ), ); } return widgets; } List imgList = []; late final HomeApi _homeApi; @override void initState() { super.initState(); _homeApi = Get.find(); getImgList(); } getImgList(){ if(widget.item.mediaUrls != null && widget.item.mediaUrls != ""){ imgList = widget.item.mediaUrls!.split(","); setState(() { }); } } likePost() async { try { final response = await _homeApi.userLikePost({ "id": widget.item.id, "isLiked": !(widget.item.isLiked ?? false), }); if (response.data.isSuccess) { if(widget.item.isLiked ?? false){ SmartDialog.showToast('取消点赞成功'); widget.item.likeCount = widget.item.likeCount! - 1; } else { SmartDialog.showToast('点赞成功'); widget.item.likeCount = widget.item.likeCount! + 1; } widget.item.isLiked = !(widget.item.isLiked ?? false); setState(() { }); } else { // 响应失败,抛出异常 throw Exception(response.data.message ?? '获取数据失败'); } } catch(e){ print('帖子发布失败: $e'); SmartDialog.showToast('帖子发布失败'); rethrow; } } @override Widget build(BuildContext context) { return Container( margin: EdgeInsets.only(bottom: 15.w), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ ClipRRect( borderRadius: BorderRadius.all(Radius.circular(40.w)), child: CachedNetworkImage( imageUrl: widget.item.profilePhoto ?? "", width: 40.w, height: 40.w, fit: BoxFit.cover, ), ).onTap((){ Get.to(() => UserInformationPage(miId: widget.item.miId ?? "", userId: widget.item.userId ?? "",)); }), SizedBox(width: 8.w,), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( widget.item.nickName ?? "", style: TextStyle( fontSize: 13.w, fontWeight: FontWeight.w500 ), ), Text( widget.item.createTime ?? "", style: TextStyle( fontSize: 11.w, color: const Color.fromRGBO(51, 51, 51, .6), fontWeight: FontWeight.w500 ), ) ], ) ], ), PopupMenuButton( tooltip: "", padding: EdgeInsets.zero, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)), color: Colors.white, elevation: 8, offset: Offset(0, 32.w), // 相对按钮下移一点 itemBuilder: (context) => [ const PopupMenuItem(value: 'report', child: Text('举报')), ], onSelected: (v) { if (v == 'report') { print("举报"); Get.to(() => ReportPage(id: widget.item.id ?? "",)); } }, child: Icon( Icons.keyboard_control, size: 15.w, color: const Color.fromRGBO(51, 51, 51, 1), ), // 你的小圆按钮 ), ], ), Container( margin: EdgeInsets.symmetric(vertical: 11.w), child: !widget.item.content!.contains('[emoji:') ? Text( widget.item.content ?? "" ) : Wrap( crossAxisAlignment: WrapCrossAlignment.center, children: buildInputContentWidgets(), ), ), if(imgList.length == 1) CachedNetworkImage( imageUrl: imgList[0], width: 341.w, height: 341.w, fit: BoxFit.cover, imageBuilder: (context, imageProvider) => Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), image: DecorationImage( image: imageProvider, fit: BoxFit.cover, ), ), ), errorWidget: (context, url, error) => Image.asset( Assets.imagesUserAvatar, width: 341.w, height: 341.w, fit: BoxFit.cover, ), ), if(imgList.length == 2) Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ ...imgList.map((e){ return CachedNetworkImage( imageUrl: e, width: 165.w, height: 165.w, fit: BoxFit.cover, imageBuilder: (context, imageProvider) => Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), image: DecorationImage( image: imageProvider, fit: BoxFit.cover, ), ), ), errorWidget: (context, url, error) => Image.asset( Assets.imagesUserAvatar, width: 165.w, height: 165.w, fit: BoxFit.cover, ), ); }), ], ), if(imgList.length > 2) Wrap( spacing: 13.w, runSpacing: 13.w, children: [ ...imgList.map((e){ return CachedNetworkImage( imageUrl: e, width: 105.w, height: 105.w, fit: BoxFit.cover, imageBuilder: (context, imageProvider) => Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), image: DecorationImage( image: imageProvider, fit: BoxFit.cover, ), ), ), errorWidget: (context, url, error) => Image.asset( Assets.imagesUserAvatar, width: 105.w, height: 105.w, fit: BoxFit.cover, ), ); }), ], ), SizedBox(height: 14.w,), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ Row( children: [ Image.asset( (widget.item.isLiked ?? false) ? Assets.imagesLikeActive : Assets.imagesLikeIcon, width: 14.w, height: 12.w, ), SizedBox(width: 6.w,), Text( "${widget.item.likeCount ?? 0}", style: TextStyle( fontSize: 11.w, color: const Color.fromRGBO(144, 144, 144, .6) ), ) ], ).onTap((){ likePost(); }), SizedBox(width: 33.w,), Row( children: [ Image.asset( Assets.imagesCommentIcon, width: 15.w, height: 15.w, ), SizedBox(width: 6.w,), Text( "${widget.item.commentCount ?? 0}", style: TextStyle( fontSize: 11.w, color: const Color.fromRGBO(144, 144, 144, .6) ), ) ], ), ], ) ], ), ).onTap((){ Get.to(() => TimelineInfo(id: widget.item.id ?? "",))?.then((e){ widget.item.likeCount = e.likeCount; widget.item.isLiked = e.isLiked; widget.item.commentCount = e.commentCount; setState(() { }); }); }); } }