import 'dart:async'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:hive_flutter/hive_flutter.dart'; import '/common/constants.dart'; import '/database/box_type.dart'; import '/models/contact_model.dart'; import '/models/init_get_it.dart'; import '/models/user_model.dart'; import '/request/server.dart'; import '/screens/message/components/attachment_container.dart'; class FriendMessageBubble extends StatefulWidget { const FriendMessageBubble({ super.key, required this.index, required this.length, required this.contactId, required this.senderId, required this.type, required this.dateTime, required this.isShowTime, required this.text, required this.attachments, required this.allAttachments, }); final int index, length; final String contactId, senderId, type, dateTime, text; final bool isShowTime; final List attachments, allAttachments; @override State createState() => _FriendMessageBubbleState(); } class _FriendMessageBubbleState extends State { // add late here so you can access widget instance late bool _isHideMsg; Timer? _timer; @override void initState() { super.initState(); final chatSettingBox = Hive.box('chat_setting'); late final chatSetting = chatSettingBox.get(widget.contactId); _isHideMsg = chatSetting!.isHideMsg; if (_isHideMsg) { if (widget.index + 1 == widget.length) { _isHideMsg = false; _timer = Timer( const Duration(milliseconds: 3500), () { setState(() { _isHideMsg = true; }); }, ); } } } @override void dispose() { super.dispose(); if (_timer != null) { _timer!.cancel(); } } @override Widget build(BuildContext context) { bool isFriend = widget.senderId == widget.contactId; return Container( padding: const EdgeInsets.symmetric( vertical: kDefaultPadding / 2, horizontal: kDefaultPadding, ), child: Column( children: [ // message date time if (widget.isShowTime) SizedBox( height: 35.0, child: Text( widget.dateTime, style: const TextStyle( color: kUnActivatedColor, ), ), ), Row( textDirection: isFriend ? TextDirection.ltr : TextDirection.rtl, crossAxisAlignment: CrossAxisAlignment.start, children: [ isFriend ? getIt .get() .friends[widget.contactId]! .avatar .isEmpty ? CircleAvatar( child: Image.asset('assets/images/user_2.png'), ) : CircleAvatar( backgroundImage: CachedNetworkImageProvider( '$userAvatarsUrl/${getIt.get().friends[widget.contactId]!.avatar}', ), ) : CircleAvatar( backgroundImage: CachedNetworkImageProvider( '$userAvatarsUrl/${getIt.get().avatar}', ), ), const SizedBox( width: 10, ), Expanded( child: Column( crossAxisAlignment: isFriend ? CrossAxisAlignment.start : CrossAxisAlignment.end, children: [ if (widget.type == 'text/multipart') // message box Container( padding: const EdgeInsets.fromLTRB(10, 10, 10, 0), decoration: BoxDecoration( color: isFriend ? const Color.fromARGB(255, 241, 241, 241) : kPrimaryColor, borderRadius: BorderRadius.circular(10.0), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (_isHideMsg) const Text('消息已隐藏'), // text message content if (widget.text.isNotEmpty && !_isHideMsg) Text( widget.text, textWidthBasis: TextWidthBasis.longestLine, ), const SizedBox( height: 10, ), // image content if has if (widget.attachments.isNotEmpty && !_isHideMsg) ...List.generate( widget.attachments.length, (int index) { return AttachmentContainer( isMyself: !isFriend, filename: widget.attachments[index], onTapImage: _onTapImage, ); }, ), ], ), ), ], ), ), ], ), if (_isHideMsg) TextButton( onPressed: () { setState(() { _isHideMsg = false; }); }, style: TextButton.styleFrom( padding: EdgeInsets.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), child: const Text('显示消息'), ) ], ), ); } void _onTapImage(String attachment) { int attachmentIndex = widget.allAttachments.indexWhere( (element) => element == attachment, ); context.pushNamed( 'ImageView', extra: { 'attachments': widget.allAttachments, 'index': attachmentIndex, }, ); } }