|
- import 'dart:convert';
- import 'dart:io';
-
- import 'package:chat/chat/group_chat_item.dart';
- import 'package:chat/data/UserData.dart';
- import 'package:chat/data/chat_data_mgr.dart';
- import 'package:chat/data/constants.dart';
- import 'package:chat/data/group_data_mgr.dart';
- import 'package:chat/generated/i18n.dart';
- import 'package:chat/home/group_setting.dart';
- import 'package:chat/models/ChatMsg.dart';
- import 'package:chat/models/group_info_model.dart';
- import 'package:chat/models/keyboard_provider.dart';
- import 'package:chat/models/money_change.dart';
- import 'package:chat/models/voucher_change.dart';
- import 'package:chat/proto/all.pbserver.dart';
- import 'package:chat/utils/CustomUI.dart';
- import 'package:chat/utils/MessageMgr.dart';
- import 'package:chat/utils/analyze_utils.dart';
- import 'package:chat/utils/msgHandler.dart';
- import 'package:chat/utils/net_state_widget.dart';
- import 'package:chat/utils/screen.dart';
- import 'package:chat/utils/sound_util.dart';
- import 'package:chat/utils/sp_utils.dart';
- import 'package:chat/utils/sql_util.dart';
- import 'package:chat/utils/upload_util.dart';
- import 'package:chat/utils/white_opacity_anim.dart';
- import 'package:extended_text/extended_text.dart';
- import 'package:flutter/cupertino.dart';
- import 'package:flutter/material.dart';
- import 'package:oktoast/oktoast.dart';
- import 'package:provider/provider.dart';
- import 'package:scroll_to_index/scroll_to_index.dart';
- import '../r.dart';
- import 'input_bar.dart';
- import 'package:chat/models/ref_name_provider.dart';
- import 'package:fixnum/fixnum.dart';
-
- class GroupChatPage extends StatefulWidget {
- final GroupInfoModel groupInfoModel;
- final int enterType; // 0默认 1图片
- final dynamic enterContent;
- GroupChatPage(
- {Key key, this.groupInfoModel, this.enterType = 0, this.enterContent})
- : super(key: key);
-
- _GroupChatPageState createState() => _GroupChatPageState();
- }
-
- class _GroupChatPageState extends State<GroupChatPage> {
- AutoScrollController controller;
-
- MessageMgr msgMgr = MessageMgr();
-
- List<MsgModel> msgList;
-
- KeyboardIndexProvider _keyboardIndexProvider = KeyboardIndexProvider();
-
- TextEditingController nickNameController = new TextEditingController();
-
- //统计聊天时长
- int startTime;
-
- //子元素的对应偏移量
- Map itemOffsetMap = {};
-
- //未读消息数目
- int unreadNums = 0;
- //最上一条未读消息id
- int unreadTime;
-
- //@消息索引
- int alterTime;
-
- String alterUserName = '';
-
- int jumpTime;
-
- @override
- void dispose() {
- var endTime = DateTime.now().millisecondsSinceEpoch ~/ 1000;
- AnalyzeUtils.commitChatDuration(startTime, endTime);
-
- msgMgr.off('New Chat Message', receiveMsg);
- msgMgr.off('Keyboard Hide', dealWithKeyboardHide);
- msgMgr.off('Update Group Info', updateGroupInfo);
- msgMgr.off('Delete Select Message', _deleteItem);
- msgMgr.off('Jump to Msg', jumpToMsg);
- MsgHandler.curActiveSession = 0;
- SoundUtils().stop();
-
- super.dispose();
- }
-
- @override
- void initState() {
- super.initState();
- print('init group chat page ${widget.groupInfoModel.sessionId}');
-
- getDefaultSetting();
-
- controller = AutoScrollController(
- viewportBoundaryGetter: () =>
- Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom),
- axis: Axis.vertical);
-
- startTime = DateTime.now().millisecondsSinceEpoch ~/ 1000;
-
- unreadNums = ChatDataMgr()
- .groupUnreadProvider
- .getUnreadCount(widget.groupInfoModel.sessionId);
-
- alterTime = ChatDataMgr()
- .groupUnreadProvider
- .getHavaAltertime(widget.groupInfoModel.sessionId);
-
- MsgHandler.updateActiveSesstion(widget.groupInfoModel.sessionId,
- isGroup: true);
-
- msgList = ChatDataMgr().getGroupRecord();
- if (unreadNums >= 10) {
- unreadTime = msgList[unreadNums - 1].time;
- }
- for (int i = 0; i < msgList.length; i++) {
- if (msgList[i].time == alterTime) {
- alterUserName =
- widget.groupInfoModel.getMember(msgList[i].friendId).nickName;
- break;
- }
- }
-
- msgMgr.on('New Chat Message', receiveMsg);
- msgMgr.on('Keyboard Hide', dealWithKeyboardHide);
- msgMgr.on('Update Group Info', updateGroupInfo);
- msgMgr.on('Delete Select Message', _deleteItem);
- msgMgr.on('Jump to Msg', jumpToMsg);
-
- WidgetsBinding.instance.addPostFrameCallback((_) {
- if (widget.enterType == 1) {
- print('接收到的:${widget.enterContent}');
- _sendFile(File(widget.enterContent));
- } else if (widget.enterType == 2) {
- //转发消息
- MsgModel originMsg = widget.enterContent;
- MsgModel msg = MsgHandler.createSendMsg(
- ChatType.valueOf(originMsg.msgType), originMsg.msgContent,
- channelType: ChatChannelType.Group);
- msg.extraInfo = originMsg.extraInfo;
-
- // msg.extraFile = originMsg.extraFile;
- if (originMsg.extraFile == null ||
- originMsg.extraFile.contains('http')) {
- msg.extraFile = originMsg.extraFile;
- } else {
- msg.extraFile = UploadUtil().getFullUrl(
- originMsg.extraFile, originMsg.sessionId, originMsg.channelType);
- }
- msg.localFile = originMsg.localFile;
- if (msg.localFile != null) {
- msg.state = MsgState.Uploaded;
- }
-
- sendMsg(msg);
- }
- });
- }
-
- jumpToMsg(time) async {
- hideKeyBoard();
- int jumIndex = 0;
- jumpTime = time;
- for (int i = 0; i < msgList.length; i++) {
- if (time == msgList[i].time) {
- jumIndex = i;
- break;
- }
- }
- if (jumIndex < 0) {
- jumIndex = 0;
- }
- if (jumIndex > msgList.length - 1) {
- jumIndex = msgList.length - 1;
- }
- await controller.scrollToIndex(jumIndex,
- preferPosition: AutoScrollPosition.begin);
- controller.highlight(jumIndex,
- highlightDuration: new Duration(milliseconds: 500));
- }
-
- void _sendFile(File file) async {
- // File file = await FilePicker.getFile();
- int fileSize = file.lengthSync();
- print('选择的文件 ${file.path} 大小 $fileSize');
-
- if (fileSize > 33 * 1024 * 1024) {
- showToast('文件大于33M');
- return;
- }
-
- var fileName = file.path.split('/').last;
- print('fileName $fileName');
-
- var ext = '';
- var extList = fileName.split('.');
- if (extList.length > 1) {
- ext = extList.last;
- }
- print('ext $ext');
-
- var fileMsg = FileChat.create();
- fileMsg.type = ext;
- fileMsg.size = fileSize;
- fileMsg.name = fileName;
-
- var msg = MsgHandler.createSendMsg(
- ChatType.FileChatType, fileMsg.writeToBuffer(),
- friendId: 0, localFile: file.path, channelType: ChatChannelType.Group);
-
- sendMsg(msg);
- }
-
- updateGroupInfo(args) {
- print('更新群信息');
- if (mounted) {
- setState(() {});
- }
- }
-
- void getDefaultSetting() async {
- bool soundPlayMode =
- (await SPUtils.getBool(Constants.SOUND_PLAY_MODE)) ?? false;
-
- _keyboardIndexProvider.init(soundPlayMode);
- }
-
- dealWithKeyboardHide(args) {
- if (_keyboardIndexProvider.curKeyboardIndex == 0) {
- readOnly();
- }
- }
-
- @override
- Widget build(BuildContext context) {
- List<Widget> actions = [];
- actions.add(Row(
- children: <Widget>[
- CustomUI.buildImageLabel("assets/images/voucher.png",
- Provider.of<VoucherChangeProvider>(context).voucher,
- imgOpc: 0.5, imgHeight: 13),
- CustomUI.buildImageLabel(
- R.assetsImagesCoin, Provider.of<MoneyChangeProvider>(context).money,
- isLeft: false)
- ],
- ));
- actions.add(widget.groupInfoModel.isInGroup
- ? IconButton(
- icon: Icon(Icons.more_horiz),
- iconSize: 22,
- onPressed: () {
- //进入群管理界面
- hideKeyBoard();
-
- Navigator.of(context).push(
- new MaterialPageRoute(
- builder: (context) {
- return GroupSetting(
- groupInfoModel: widget.groupInfoModel,
- );
- },
- ),
- );
- },
- )
- : IconButton(
- icon: Icon(Icons.delete),
- iconSize: 22,
- color: Colors.redAccent,
- onPressed: () {
- //进入群管理界面
- quiteGroup();
- },
- ));
-
- Map refMap = Provider.of<RefNameProvider>(context).refMap;
-
- bool isHaveUnreadNews = unreadTime != null;
- bool isAlterYou = alterTime != null;
-
- return MultiProvider(
- providers: [
- ChangeNotifierProvider(create: (_) => _keyboardIndexProvider),
- Provider<bool>.value(value: true),
- Provider<GroupInfoModel>.value(value: widget.groupInfoModel),
- ],
- child: GestureDetector(
- onTap: hideKeyBoard,
- child: ExtendedTextSelectionPointerHandler(
- ///选择文字,消除弹窗
- builder: (states) {
- return Listener(
- child: Scaffold(
- resizeToAvoidBottomInset: false,
- backgroundColor: const Color(0xFFE2E9F1),
- appBar: AppBar(
- backgroundColor: AppColors.NewAppbarBgColor,
- title: Text(
- widget.groupInfoModel.getGroupName(refMap),
- textScaleFactor: 1.0,
- style: TextStyle(
- color: Constants.BlackTextColor,
- fontSize: 16.47),
- ),
- leading: CustomUI.buildCustomLeading(context),
- titleSpacing: -10,
- elevation: 1,
- centerTitle: false,
- actions: actions),
- body: SafeArea(
- child: Stack(
- children: <Widget>[
- Column(
- children: <Widget>[
- NetStateWidget(),
- Expanded(child: _buildMessageList()),
- InputBar(sendMsg: sendMsg),
- ],
- ),
- isHaveUnreadNews
- ? Positioned(
- top: 32.5,
- right: 0,
- child: InkWell(
- onTap: () {
- jumpToMsg(isAlterYou
- ? alterTime
- : unreadTime);
- unreadTime = null;
- setState(() {});
- },
- child: Container(
- alignment: Alignment.center,
- decoration: BoxDecoration(
- boxShadow: [
- BoxShadow(
- color: Color(0x33000000), //阴影颜色
- blurRadius: 10.0, //阴影大小
- )
- ],
- borderRadius: BorderRadius.only(
- topLeft: Radius.circular(80),
- bottomLeft: Radius.circular(80)),
- color: Colors.white,
- ),
- constraints:
- BoxConstraints(minWidth: 120),
- height: 39,
- child: Row(
- children: <Widget>[
- Icon(
- Icons.arrow_upward,
- color: Color(0xFF3875E9),
- size: 20,
- ),
- Text(
- isAlterYou
- ? '$alterUserName @你'
- : '$unreadNums条新消息',
- style: TextStyle(
- color: Color(0xFF3875E9)),
- )
- ],
- ),
- )))
- : Container()
- ],
- ))),
- onPointerDown: (value) {
- for (var state in states) {
- if (!state.containsPosition(value.position)) {
- //clear other selection
- state.clearSelection();
- }
- }
- },
- onPointerMove: (value) {
- //clear other selection
- for (var state in states) {
- if (!state.containsPosition(value.position)) {
- //clear other selection
- state.clearSelection();
- }
- }
- },
- );
- },
- )));
- }
-
- //更新各个子元素的偏移位置
- _updateMsgItemOffset() {
- if (msgList.length == 0) {
- return;
- }
-
- var myId = UserData().basicInfo.userId;
- double offset = 0;
- for (var i = 0; i < msgList.length; i++) {
- MsgModel msg = msgList[i];
-
- double itemHeight = 70;
- switch (ChatType.valueOf(msg.msgType)) {
- case ChatType.TextChatType:
- //if (msg.from == myId) {
- var text = utf8.decode(msg.msgContent);
- itemHeight = 21 + _getTextHeight(text);
- //} else {}
- break;
- case ChatType.ShortVoiceChatType:
- if (msg.from == myId) {
- itemHeight = 22.5 + 24;
- } else {}
- break;
- case ChatType.ImageChatType:
- itemHeight = _getImgHeight(msg);
- break;
- case ChatType.ShortVideoChatType:
- itemHeight = _getImgHeight(msg);
- break;
- case ChatType.EmoticonType:
- itemHeight = 40;
- break;
- case ChatType.RedWalletChatType:
- print('红包消息');
- itemHeight = 70;
- break;
- case ChatType.PlaceChatType:
- itemHeight = 100 + 40.0;
- break;
- case ChatType.GroupChatNoticeType:
- itemHeight = 40;
- break;
- case ChatType.GiftChatType:
- itemHeight = 40;
- break;
- case ChatType.FileChatType:
- itemHeight = 80;
- break;
- default:
- }
-
- itemOffsetMap[i] = offset;
- offset += itemHeight;
- }
- }
-
- double _getTextHeight(String text) {
- var tp = TextPainter(
- text: TextSpan(style: TextStyle(fontSize: 15), text: text),
- textAlign: TextAlign.left,
- textDirection: TextDirection.ltr,
- textScaleFactor: 1,
- );
-
- tp.layout(maxWidth: Screen.width - 140);
-
- return tp.height;
- }
-
- double _getImgHeight(MsgModel msg) {
- double aspectRatio = msg.extraInfo / 100;
-
- var maxWidth = Screen.width * 0.65;
- var maxHeight = Screen.height / 4;
-
- double height;
- if (maxWidth / maxHeight > aspectRatio) {
- height = maxHeight;
- } else {
- height = maxWidth / aspectRatio;
- }
-
- return height;
- }
-
- Widget _buildMessageList() {
- return Container(
- alignment: Alignment.topCenter,
- child: msgList.length == 0
- ? Padding(
- padding: EdgeInsets.all(10),
- child: Text(
- I18n.of(context).chat_tips,
- textAlign: TextAlign.center,
- textScaleFactor: 1.0,
- style: TextStyle(color: Colors.grey),
- ))
- : Scrollbar(
- child: ListView.builder(
- controller: controller,
- physics: new ClampingScrollPhysics(),
- itemCount: msgList.length,
- itemBuilder: _buildItem,
- padding: EdgeInsets.symmetric(vertical: 8),
- reverse: true,
- shrinkWrap: true,
- )),
- );
- }
-
- Widget _wrapScrollTag({int index, Widget child}) => AutoScrollTag(
- key: ValueKey(index),
- controller: controller,
- index: index,
- child: child,
- highlightColor: Colors.white.withOpacity(1),
- );
-
- hideKeyBoard() {
- _keyboardIndexProvider.changeSelectIndex(-1);
- }
-
- readOnly() {
- _keyboardIndexProvider.changeReadOnlyKey(true);
- }
-
- sendMsg(MsgModel msg) async {
- if (!widget.groupInfoModel.isInGroup) {
- //如果不在该群
- showToast(I18n.of(context).not_in_group);
- return;
- }
-
- MsgHandler.insertMsgToDB(msg);
- MsgHandler.sendChatMsg(msg);
- if (mounted) {
- setState(() {});
- await controller.scrollToIndex(0,
- preferPosition: AutoScrollPosition.begin);
- }
- }
-
- MsgModel msg;
- int count = 0;
- testBig(MsgModel msg) async {
- for (int k = 0; k < 100; k++) {
- msg.msgContent = utf8.encode('测试$count');
- Int64 time = Int64((DateTime.now()).millisecondsSinceEpoch);
- msg.time = time.toInt();
- MsgHandler.insertMsgToDB(msg);
- MsgHandler.sendChatMsg(msg);
- await Future.delayed(Duration(milliseconds: 300), () {});
- count++;
- }
- count = 0;
- print('攻击完毕');
- showToast('攻击完毕');
- }
-
- void receiveMsg(args) {
- print("msgList.length: ${msgList.length}");
- if (args != widget.groupInfoModel.sessionId) {
- return;
- }
- if (mounted) {
- setState(() {});
- }
- }
-
- _deleteItem(msg) {
- MessageMgr().emit('Cancel Request', msg);
- print('#### 开始删除--');
- msgList.remove(msg);
- setState(() {});
- SqlUtil().deleteSigleRecordWith(msg.sessionId, msg.time);
- }
-
- Widget _buildItem(BuildContext context, int index) {
- var lastMsgTime;
-
- if (index < msgList.length - 1) {
- lastMsgTime = msgList[index].time;
- }
-
- MsgModel msg = msgList[index];
- var result;
-
- if (msg.from == 0) {
- result = GroupChatPageItem(
- key: Key(msg.time.toString()), msg: msg, lastMsgTime: lastMsgTime);
- } else {
- result = GroupChatPageItem(
- key: Key(msg.time.toString()),
- msg: msg,
- memberModel: widget.groupInfoModel.getMember(msg.from),
- hideKeyboard: readOnly,
- lastMsgTime: lastMsgTime);
- }
- return _wrapScrollTag(index: index, child: result);
- }
-
- quiteGroup() {
- var function = () {
- GroupInfoMgr().deleteGroup(widget.groupInfoModel.sessionId);
- MessageMgr().emit('Quit Group', widget.groupInfoModel.sessionId);
- Navigator.of(context).popUntil(ModalRoute.withName('/main'));
- MsgHandler.quitGroup(widget.groupInfoModel.sessionId);
- };
-
- showModalBottomSheet(
- context: context,
- backgroundColor: Colors.transparent,
- builder: (BuildContext context) {
- return Container(
- decoration: BoxDecoration(
- color: Colors.white,
- borderRadius: BorderRadius.only(
- topLeft: Radius.circular(13), topRight: Radius.circular(13))),
- height: 225,
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.center,
- mainAxisAlignment: MainAxisAlignment.center,
- children: <Widget>[
- Padding(
- padding: EdgeInsets.fromLTRB(15, 15, 15, 13),
- child: Text(
- I18n.of(context).quit_group_tips,
- textScaleFactor: 1.0,
- style: TextStyle(fontSize: 12, color: Color(0xff777777)),
- ),
- ),
- Divider(
- color: Color(0xffE5E5E5),
- ),
- InkWell(
- onTap: function,
- child: Container(
- height: 60,
- alignment: Alignment.center,
- child: Text(I18n.of(context).determine,
- textScaleFactor: 1.0,
- style: TextStyle(
- fontSize: 18, color: Constants.ConfrimButtonColor)),
- ),
- ),
- Container(
- color: Color(0xffF2F2F2),
- height: 4,
- ),
- InkWell(
- onTap: () {
- Navigator.of(context).pop();
- },
- child: Container(
- height: 60,
- alignment: Alignment.center,
- child: Text(I18n.of(context).cancel,
- textScaleFactor: 1.0,
- style: TextStyle(fontSize: 18, color: Color(0xff4B4B4B))),
- ),
- )
- ],
- ),
- );
- },
- );
- }
- }
|