together_mobile/lib/screens/message/components/friend_message_bubble.dart

278 lines
10 KiB
Dart
Raw Normal View History

import 'dart:async';
import 'dart:io';
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
import 'package:together_mobile/common/constants.dart';
2023-09-17 17:45:32 +08:00
import 'package:together_mobile/database/box_type.dart';
2023-08-11 23:02:31 +08:00
import 'package:together_mobile/models/contact_model.dart';
import 'package:together_mobile/models/init_get_it.dart';
import 'package:together_mobile/models/user_model.dart';
import 'package:together_mobile/request/server.dart';
2023-09-23 17:16:31 +08:00
import 'package:together_mobile/screens/message/image_view_screen/image_view_screen.dart';
2023-06-21 17:44:28 +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-09-23 17:16:31 +08:00
required this.attachmentItems,
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;
final List<String> attachments;
2023-09-23 17:16:31 +08:00
final List<AttachmentItem> attachmentItems;
2023-06-21 17:44:28 +08:00
@override
State<FriendMessageBubble> createState() => _FriendMessageBubbleState();
}
class _FriendMessageBubbleState extends State<FriendMessageBubble> {
// add late here so you can access widget instance
List<bool> _isImagesLoaded = [];
final List<Timer> _timerList = [];
2023-09-17 17:45:32 +08:00
late bool _isHideMsg;
@override
void initState() {
super.initState();
_isImagesLoaded = List.filled(widget.attachments.length, false);
2023-09-17 17:45:32 +08:00
for (var i = 0; i < widget.attachments.length; i++) {
String imagePath =
'${getIt.get<UserProfile>().baseImageDir}/${widget.attachments[i]}';
File file = File(imagePath);
if (file.existsSync()) {
_isImagesLoaded[i] = true;
} else {
_isImagesLoaded[i] = false;
2023-09-17 17:45:32 +08:00
_timerList.add(
Timer.periodic(
const Duration(milliseconds: 200),
(timer) {
if ((file.existsSync())) {
setState(() {
_isImagesLoaded[i] = true;
});
timer.cancel();
}
},
),
);
}
}
final chatSettingBox = Hive.box<ChatSetting>('chat_setting');
late final chatSetting = chatSettingBox.get(widget.contactId);
_isHideMsg = chatSetting!.isHideMsg;
if (_isHideMsg) {
if (widget.index + 1 == widget.length) {
_isHideMsg = false;
Timer(
const Duration(milliseconds: 3500),
() {
setState(() {
_isHideMsg = true;
});
},
2023-09-17 17:45:32 +08:00
);
}
}
}
@override
void dispose() {
for (var element in _timerList) {
element.cancel();
}
2023-09-17 17:45:32 +08:00
super.dispose();
}
2023-06-21 17:44:28 +08:00
@override
Widget build(BuildContext context) {
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
if (widget.isShowTime)
2023-08-10 19:08:46 +08:00
SizedBox(
height: 35.0,
child: Text(
widget.dateTime,
2023-08-10 19:08:46 +08:00
style: const TextStyle(
color: kUnActivatedColor,
),
),
),
2023-06-21 17:44:28 +08:00
Row(
textDirection: isFriend ? TextDirection.ltr : TextDirection.rtl,
2023-06-21 17:44:28 +08:00
crossAxisAlignment: CrossAxisAlignment.start,
children: [
isFriend
2023-08-11 23:02:31 +08:00
? getIt
.get<ContactAccountProfile>()
.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(
crossAxisAlignment: isFriend
2023-08-10 19:08:46 +08:00
? CrossAxisAlignment.start
: CrossAxisAlignment.end,
2023-06-21 17:44:28 +08:00
children: [
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(
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)
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
),
// image content if have
2023-09-17 17:45:32 +08:00
if (widget.attachments.isNotEmpty && !_isHideMsg)
...List.generate(
widget.attachments.length,
(int index) {
2023-09-23 17:16:31 +08:00
int attachmentItemIndex =
widget.attachmentItems.indexWhere(
(element) =>
element.resource ==
widget.attachments[index],
);
int heroTagId = widget
.attachmentItems[attachmentItemIndex].id;
return Container(
margin: const EdgeInsets.only(
bottom: 15,
),
constraints: const BoxConstraints(
maxHeight: 120,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
),
child: _isImagesLoaded[index]
2023-09-23 17:16:31 +08:00
? GestureDetector(
onTap: () {
_onTapImage(
context,
widget.attachments[index],
);
},
child: Hero(
tag: heroTagId,
child: Image.file(
File(
'${getIt.get<UserProfile>().baseImageDir}/${widget.attachments[index]}',
),
),
),
)
: Container(
width: 20,
height: 40,
padding: const EdgeInsets.symmetric(
2023-09-23 17:16:31 +08:00
vertical: 10,
),
child:
const CircularProgressIndicator(
color: kSecondaryColor,
strokeWidth: 3.0,
),
),
);
},
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-08-10 19:08:46 +08:00
),
2023-06-21 17:44:28 +08:00
],
),
);
}
2023-09-23 17:16:31 +08:00
void _onTapImage(BuildContext context, String attachment) {
int attachmentIndex = widget.attachmentItems.indexWhere(
(element) => element.resource == attachment,
);
context.pushNamed(
'ImageView',
extra: {
'attachmentItems': widget.attachmentItems,
'index': attachmentIndex,
},
);
}
2023-06-21 17:44:28 +08:00
}