import 'dart:async'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:together_mobile/database/box_type.dart'; import 'package:together_mobile/models/contact_model.dart'; import 'package:together_mobile/models/init_get_it.dart'; import 'package:together_mobile/models/route_state_model.dart'; import 'package:together_mobile/utils/format_datetime.dart'; import 'components/group_chat_message_bubble.dart'; import 'components/message_input_box.dart'; import 'image_view_screen/image_view_screen.dart'; class GroupChatMessageScreen extends StatefulWidget { const GroupChatMessageScreen({ super.key, required this.groupChatId, }); final String groupChatId; @override State createState() => _GroupChatMessageScreenState(); } class _GroupChatMessageScreenState extends State { final ScrollController _controller = ScrollController(); final Box _chatSettingBox = Hive.box('chat_setting'); @override void dispose() { super.dispose(); _controller.dispose(); } @override Widget build(BuildContext context) { Timer( const Duration(milliseconds: 300), () => getIt.get().changeRoute( 'Message', newQuery: {'groupChatId': widget.groupChatId}, ), ); return Scaffold( appBar: AppBar( leading: IconButton( onPressed: () { context.go('/chat'); }, icon: const Icon(Icons.arrow_back), ), // friend remark or nickname title: getIt .get() .groupChats[widget.groupChatId]! .groupChatRemark .isEmpty ? Text( getIt .get() .groupChats[widget.groupChatId]! .name, ) : Text( getIt .get() .groupChats[widget.groupChatId]! .groupChatRemark, ), centerTitle: true, actions: [ IconButton( onPressed: () { context.pushNamed( 'GroupChatProfile', queryParameters: { 'groupChatId': widget.groupChatId, }, ); }, icon: const Icon(Icons.menu), splashRadius: 18, ), ], ), body: Column( children: [ Expanded( child: Align( alignment: Alignment.topCenter, child: ValueListenableBuilder( valueListenable: Hive.box('message_${widget.groupChatId}') .listenable(), builder: (context, value, _) { // Set unreadCount to 0 when at message screen ChatSetting? chatSetting = _chatSettingBox.get(widget.groupChatId); // whethe it is a brand new chat if (chatSetting != null) { chatSetting.unreadCount = 0; _chatSettingBox.put(widget.groupChatId, chatSetting); } Future.delayed( const Duration( milliseconds: 100, ), () => _controller.animateTo( 0, duration: const Duration(milliseconds: 500), curve: Curves.linear, ), ); return ListView.builder( physics: const BouncingScrollPhysics( parent: AlwaysScrollableScrollPhysics(), ), controller: _controller, shrinkWrap: true, reverse: true, itemCount: Hive.box('message_${widget.groupChatId}') .length, itemBuilder: (context, index) { Box messageTBox = Hive.box('message_${widget.groupChatId}'); int length = messageTBox.length; int i = length - index - 1; MessageT messageT = messageTBox.getAt(i)!; List allAttachments = []; for (var element in messageTBox.values) { if (element.attachments.isNotEmpty) { allAttachments.addAll(element.attachments); } } // Do not reverse the list, cause what i want is // rigth slide to next image, left to last otherwise // allAttachments = List.from(allAttachments.reversed); List attachmentItems = List.generate( allAttachments.length, (int index) { return AttachmentItem( id: index, resource: allAttachments[index], ); }, ); return GroupChatMessageBubble( key: ValueKey(i), index: i, length: length, contactId: widget.groupChatId, senderId: messageT.senderId, dateTime: formatMessageDateTime(messageT.dateTime), isShowTime: messageT.isShowTime, type: messageT.type, text: messageT.text, attachments: messageT.attachments, attachmentItems: attachmentItems, ); }, ); }, ), ), ), MessageInputBox( chatType: 1, contactId: widget.groupChatId, scrollController: _controller, ), ], ), bottomNavigationBar: null, ); } }