2023-10-04 11:50:28 +08:00
|
|
|
import 'dart:async';
|
|
|
|
|
2023-08-11 23:02:31 +08:00
|
|
|
import 'package:cached_network_image/cached_network_image.dart';
|
2023-06-21 17:44:28 +08:00
|
|
|
import 'package:flutter/material.dart';
|
2023-09-23 17:16:31 +08:00
|
|
|
import 'package:go_router/go_router.dart';
|
2023-09-17 17:45:32 +08:00
|
|
|
import 'package:hive_flutter/hive_flutter.dart';
|
2023-06-21 17:44:28 +08:00
|
|
|
|
2024-04-09 17:23:28 +08:00
|
|
|
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';
|
2023-06-21 17:44:28 +08:00
|
|
|
|
2023-08-23 16:30:41 +08:00
|
|
|
class FriendMessageBubble extends StatefulWidget {
|
|
|
|
const FriendMessageBubble({
|
2023-08-10 19:08:46 +08:00
|
|
|
super.key,
|
2023-09-17 17:45:32 +08:00
|
|
|
required this.index,
|
|
|
|
required this.length,
|
2023-08-10 19:08:46 +08:00
|
|
|
required this.contactId,
|
|
|
|
required this.senderId,
|
|
|
|
required this.type,
|
|
|
|
required this.dateTime,
|
|
|
|
required this.isShowTime,
|
|
|
|
required this.text,
|
|
|
|
required this.attachments,
|
2023-10-01 18:40:14 +08:00
|
|
|
required this.allAttachments,
|
2023-08-10 19:08:46 +08:00
|
|
|
});
|
|
|
|
|
2023-09-17 17:45:32 +08:00
|
|
|
final int index, length;
|
2023-08-10 19:08:46 +08:00
|
|
|
final String contactId, senderId, type, dateTime, text;
|
|
|
|
final bool isShowTime;
|
2023-10-01 18:40:14 +08:00
|
|
|
final List<String> attachments, allAttachments;
|
2023-06-21 17:44:28 +08:00
|
|
|
|
2023-08-15 10:53:30 +08:00
|
|
|
@override
|
2023-08-23 16:30:41 +08:00
|
|
|
State<FriendMessageBubble> createState() => _FriendMessageBubbleState();
|
2023-08-15 10:53:30 +08:00
|
|
|
}
|
|
|
|
|
2023-08-23 16:30:41 +08:00
|
|
|
class _FriendMessageBubbleState extends State<FriendMessageBubble> {
|
2023-08-15 10:53:30 +08:00
|
|
|
// add late here so you can access widget instance
|
2023-09-17 17:45:32 +08:00
|
|
|
late bool _isHideMsg;
|
2023-10-05 12:12:56 +08:00
|
|
|
Timer? _timer;
|
2023-08-15 10:53:30 +08:00
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
super.initState();
|
2023-09-17 17:45:32 +08:00
|
|
|
final chatSettingBox = Hive.box<ChatSetting>('chat_setting');
|
|
|
|
late final chatSetting = chatSettingBox.get(widget.contactId);
|
|
|
|
_isHideMsg = chatSetting!.isHideMsg;
|
2023-10-04 11:50:28 +08:00
|
|
|
if (_isHideMsg) {
|
|
|
|
if (widget.index + 1 == widget.length) {
|
|
|
|
_isHideMsg = false;
|
2023-10-05 12:12:56 +08:00
|
|
|
_timer = Timer(
|
2023-10-04 11:50:28 +08:00
|
|
|
const Duration(milliseconds: 3500),
|
|
|
|
() {
|
|
|
|
setState(() {
|
|
|
|
_isHideMsg = true;
|
|
|
|
});
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2023-08-15 10:53:30 +08:00
|
|
|
}
|
|
|
|
|
2023-10-05 12:12:56 +08:00
|
|
|
@override
|
|
|
|
void dispose() {
|
|
|
|
super.dispose();
|
|
|
|
if (_timer != null) {
|
|
|
|
_timer!.cancel();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-21 17:44:28 +08:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2023-09-16 11:33:57 +08:00
|
|
|
bool isFriend = widget.senderId == widget.contactId;
|
|
|
|
|
2023-06-21 17:44:28 +08:00
|
|
|
return Container(
|
|
|
|
padding: const EdgeInsets.symmetric(
|
|
|
|
vertical: kDefaultPadding / 2,
|
|
|
|
horizontal: kDefaultPadding,
|
|
|
|
),
|
|
|
|
child: Column(
|
|
|
|
children: [
|
2023-08-10 19:08:46 +08:00
|
|
|
// message date time
|
2023-08-15 10:53:30 +08:00
|
|
|
if (widget.isShowTime)
|
2023-08-10 19:08:46 +08:00
|
|
|
SizedBox(
|
|
|
|
height: 35.0,
|
|
|
|
child: Text(
|
2023-08-15 10:53:30 +08:00
|
|
|
widget.dateTime,
|
2023-08-10 19:08:46 +08:00
|
|
|
style: const TextStyle(
|
|
|
|
color: kUnActivatedColor,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
2023-06-21 17:44:28 +08:00
|
|
|
Row(
|
2023-09-16 11:33:57 +08:00
|
|
|
textDirection: isFriend ? TextDirection.ltr : TextDirection.rtl,
|
2023-06-21 17:44:28 +08:00
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: [
|
2023-09-16 11:33:57 +08:00
|
|
|
isFriend
|
2023-08-11 23:02:31 +08:00
|
|
|
? getIt
|
|
|
|
.get<ContactAccountProfile>()
|
2023-08-15 10:53:30 +08:00
|
|
|
.friends[widget.contactId]!
|
2023-08-11 23:02:31 +08:00
|
|
|
.avatar
|
|
|
|
.isEmpty
|
|
|
|
? CircleAvatar(
|
|
|
|
child: Image.asset('assets/images/user_2.png'),
|
|
|
|
)
|
|
|
|
: CircleAvatar(
|
|
|
|
backgroundImage: CachedNetworkImageProvider(
|
2023-09-09 16:48:47 +08:00
|
|
|
'$userAvatarsUrl/${getIt.get<ContactAccountProfile>().friends[widget.contactId]!.avatar}',
|
2023-08-11 23:02:31 +08:00
|
|
|
),
|
|
|
|
)
|
|
|
|
: CircleAvatar(
|
|
|
|
backgroundImage: CachedNetworkImageProvider(
|
2023-09-09 16:48:47 +08:00
|
|
|
'$userAvatarsUrl/${getIt.get<UserProfile>().avatar}',
|
2023-08-11 23:02:31 +08:00
|
|
|
),
|
|
|
|
),
|
2023-06-21 17:44:28 +08:00
|
|
|
const SizedBox(
|
|
|
|
width: 10,
|
|
|
|
),
|
|
|
|
Expanded(
|
|
|
|
child: Column(
|
2023-09-16 11:33:57 +08:00
|
|
|
crossAxisAlignment: isFriend
|
2023-08-10 19:08:46 +08:00
|
|
|
? CrossAxisAlignment.start
|
|
|
|
: CrossAxisAlignment.end,
|
2023-06-21 17:44:28 +08:00
|
|
|
children: [
|
2023-08-15 10:53:30 +08:00
|
|
|
if (widget.type == 'text/multipart')
|
2023-08-10 19:08:46 +08:00
|
|
|
// message box
|
|
|
|
Container(
|
|
|
|
padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
|
|
|
|
decoration: BoxDecoration(
|
2023-09-16 11:33:57 +08:00
|
|
|
color: isFriend
|
2023-08-10 19:08:46 +08:00
|
|
|
? const Color.fromARGB(255, 241, 241, 241)
|
|
|
|
: kPrimaryColor,
|
|
|
|
borderRadius: BorderRadius.circular(10.0),
|
|
|
|
),
|
|
|
|
child: Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: [
|
2023-09-17 17:45:32 +08:00
|
|
|
if (_isHideMsg) const Text('消息已隐藏'),
|
2023-08-10 19:08:46 +08:00
|
|
|
// text message content
|
2023-09-17 17:45:32 +08:00
|
|
|
if (widget.text.isNotEmpty && !_isHideMsg)
|
2023-08-15 10:53:30 +08:00
|
|
|
Text(
|
|
|
|
widget.text,
|
|
|
|
textWidthBasis: TextWidthBasis.longestLine,
|
|
|
|
),
|
2023-08-10 19:08:46 +08:00
|
|
|
const SizedBox(
|
|
|
|
height: 10,
|
2023-06-21 17:44:28 +08:00
|
|
|
),
|
2023-10-01 18:40:14 +08:00
|
|
|
// image content if has
|
2023-09-17 17:45:32 +08:00
|
|
|
if (widget.attachments.isNotEmpty && !_isHideMsg)
|
2023-08-15 10:53:30 +08:00
|
|
|
...List.generate(
|
|
|
|
widget.attachments.length,
|
|
|
|
(int index) {
|
2023-10-01 18:40:14 +08:00
|
|
|
return AttachmentContainer(
|
|
|
|
isMyself: !isFriend,
|
2023-10-04 11:50:28 +08:00
|
|
|
filename: widget.attachments[index],
|
2023-10-01 18:40:14 +08:00
|
|
|
onTapImage: _onTapImage,
|
2023-08-15 10:53:30 +08:00
|
|
|
);
|
|
|
|
},
|
2023-08-10 19:08:46 +08:00
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
2023-06-21 17:44:28 +08:00
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
2023-09-17 17:45:32 +08:00
|
|
|
if (_isHideMsg)
|
|
|
|
TextButton(
|
|
|
|
onPressed: () {
|
|
|
|
setState(() {
|
|
|
|
_isHideMsg = false;
|
|
|
|
});
|
|
|
|
},
|
|
|
|
style: TextButton.styleFrom(
|
|
|
|
padding: EdgeInsets.zero,
|
|
|
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|
|
|
),
|
|
|
|
child: const Text('显示消息'),
|
2023-10-05 12:12:56 +08:00
|
|
|
)
|
2023-06-21 17:44:28 +08:00
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
2023-09-23 17:16:31 +08:00
|
|
|
|
2023-10-01 18:40:14 +08:00
|
|
|
void _onTapImage(String attachment) {
|
|
|
|
int attachmentIndex = widget.allAttachments.indexWhere(
|
|
|
|
(element) => element == attachment,
|
2023-09-23 17:16:31 +08:00
|
|
|
);
|
|
|
|
|
|
|
|
context.pushNamed(
|
|
|
|
'ImageView',
|
|
|
|
extra: {
|
2023-10-01 18:40:14 +08:00
|
|
|
'attachments': widget.allAttachments,
|
2023-09-23 17:16:31 +08:00
|
|
|
'index': attachmentIndex,
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
2023-06-21 17:44:28 +08:00
|
|
|
}
|