import 'dart:io'; import 'dart:typed_data'; import 'package:chat/chat/ChatPageItem.dart'; import 'package:chat/data/chat_data_mgr.dart'; import 'package:chat/data/constants.dart'; import 'package:chat/generated/i18n.dart'; import 'package:chat/models/ChatMsg.dart'; import 'package:chat/models/UserInfo.dart'; import 'package:chat/photo/entity/options.dart'; import 'package:chat/photo/photo.dart'; import 'package:chat/proto/chat.pb.dart'; import 'package:chat/r.dart'; import 'package:chat/utils/CustomUI.dart'; import 'package:chat/utils/HttpUtil.dart'; import 'package:chat/utils/file_cache_mgr.dart'; import 'package:chat/utils/image_util.dart'; import 'package:chat/utils/keyboard_utils.dart'; import 'package:chat/utils/msgHandler.dart'; import 'package:chat/utils/screen.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:multi_image_picker/multi_image_picker.dart'; import 'package:oktoast/oktoast.dart'; import 'package:photo_manager/photo_manager.dart'; import 'package:chat/utils/MessageMgr.dart'; class CompanyServerPage extends StatefulWidget { @override _CompanyServerPageState createState() => _CompanyServerPageState(); } class _CompanyServerPageState extends State { final TextEditingController _textCtrl = TextEditingController(); FocusNode editFocus = NoKeyboardEditableTextFocusNode(); bool _isComposingMessage = false; double keyboardHeight; KeyboardBloc _bloc = KeyboardBloc(); ScrollController _scrollCtrl = ScrollController(); List msgList = []; static int companyId = 10000; UserInfo companyInfo = UserInfo( userId: companyId, headimgurl: R.assetsImagesServerIcon, nickName: I18n.of(Constants.getCurrentContext()).feedback_assistant); @override void initState() { super.initState(); _bloc.start(); //10000号为服务小助手 MsgHandler.updateActiveSesstion(companyId); msgList = ChatDataMgr().getRecord(); MessageMgr().on('New Chat Message', receiveMsg); } @override void dispose() { MsgHandler.curActiveSession = 0; _textCtrl.dispose(); _bloc.dispose(); editFocus.dispose(); _scrollCtrl.dispose(); MessageMgr().off('New Chat Message', receiveMsg); super.dispose(); } receiveMsg(sessionId) { print('收到反馈助手消息'); if (mounted) { setState(() {}); if (_scrollCtrl.hasClients) { _scrollCtrl.animateTo(0, duration: new Duration(milliseconds: 500), curve: Curves.ease); } } } hideKeyBoard() { editFocus.unfocus(); } bool checkMessage() { if (_textCtrl.text.length == 0) { showToast(I18n.of(context).msg_not); return false; } return true; } Future _textMessageSubmitted(String text) async { if (!checkMessage()) { _textCtrl.clear(); return; } _textCtrl.clear(); _sendMessage(text); } _sendTextMessage() { if (!checkMessage()) { return; } var sendStr = _textCtrl.text; _textCtrl.clear(); _sendMessage(sendStr); } _sendMessage(String messageText) { MsgModel msg = MsgHandler.createSendMsg(ChatType.TextChatType, messageText, friendId: companyId, channelType: ChatChannelType.CSD); setState(() { _isComposingMessage = _textCtrl.text.length > 0; }); sendMsg(msg); } sendMsg(MsgModel msg) async { ChatDataMgr().saveCompanyMsg(msg); if (mounted) { setState(() {}); if (_scrollCtrl.hasClients) { _scrollCtrl.animateTo(0, duration: new Duration(milliseconds: 500), curve: Curves.ease); } } await HttpUtil().commitInfoToCompany(msg); if (mounted) { setState(() {}); } } void _openPhotoView() async { List resultList = List(); try { resultList = await MultiImagePicker.pickImages( maxImages: 9, enableCamera: false, selectedAssets: [], cupertinoOptions: CupertinoOptions(takePhotoIcon: "chat"), materialOptions: MaterialOptions( actionBarColor: "#50A7F9", actionBarTitle: "Hibok", allViewTitle: "", useDetailsView: false, selectCircleStrokeColor: "#000000", ), ); if (resultList != null && resultList.length > 0) { for (var i = 0; i < resultList.length; i++) { Asset photoEntity = resultList[i]; ByteData byteData = await photoEntity.getByteData(); File file = await FileCacheMgr().writeFile('temp-photo-${DateTime.now().millisecondsSinceEpoch}-$i', byteData.buffer.asInt8List(0)); _sendPhotoFile(file); } } } on Exception catch (e) { print(e.toString()); } // var photos = await PhotoPicker.pickAsset( // context: context, // themeColor: Color(0xFFF0F0F0), // textColor: Color(0xFF3F3F3F), // pickType: PickType.onlyImage); // // if (photos != null && photos.length > 0) { // for (var i = 0; i < photos.length; i++) { // AssetEntity photoEntity = photos[i]; // var file = await photoEntity.file; // _sendPhotoFile(file); // } // } } void _sendPhotoFile(File imgFile) async { var imgSize = await imgFile.length(); print('图片大小:${imgSize / 1024}KB'); var sendImg; if (imgSize > 33 * 1024 * 1024) { showToast(I18n.of(context).video_more_big); return; } bool isNeedUpload = false; if (imgSize > ImgSizeLimit) { print('图片大于 $ImgSizeLimit,压缩'); //发送压缩图 sendImg = await WidgetUtil.getCompressImg(imgFile.absolute.path ); isNeedUpload = true; } else { sendImg = imgFile.readAsBytesSync(); } var rect = await WidgetUtil.getImageWH( image: Image.memory(Uint8List.fromList(sendImg))); print('图片大小 Rect : $rect'); int aspectRatio = rect.width * 100 ~/ rect.height; var msg = MsgHandler.createSendMsg(ChatType.ImageChatType, sendImg, localFile: isNeedUpload ? imgFile.absolute.path : null, extra: aspectRatio, friendId: companyId, channelType: ChatChannelType.CSD); sendMsg(msg); } _inputBar() { Widget input = Container( child: TextField( keyboardAppearance: Brightness.light, onChanged: (String messageText) { setState(() { _isComposingMessage = _textCtrl.text.length > 0; }); }, cursorColor: Constants.BlueTextColor, style: TextStyle( fontSize: ScreenUtil().setSp(16), textBaseline: TextBaseline.alphabetic), maxLines: 3, minLines: 1, controller: _textCtrl, textInputAction: TextInputAction.newline, inputFormatters: [ LengthLimitingTextInputFormatter(600) //限制长度 ], onSubmitted: _textMessageSubmitted, focusNode: editFocus, decoration: InputDecoration( hintText: I18n.of(context).input_content, hintStyle: TextStyle(color: const Color(0xffBDBDBD), fontSize: 16), border: null, hintMaxLines: 1, contentPadding: EdgeInsets.only(left: 5, right: 5, top: 8, bottom: 8), ), ), ); return GestureDetector( onTap: () { print('放置触控隐藏键盘'); }, child: Container( width: Screen.width, color: Colors.white, child: Container( padding: EdgeInsets.symmetric(horizontal: 7, vertical: 7), alignment: Alignment.topCenter, decoration: BoxDecoration( color: Colors.white, border: Border(top: BorderSide(color: Color(0xFFDFDFDF)))), child: Row( children: [ //输入框 Expanded(child: input), SizedBox(width: 10), _isComposingMessage ? InkWell( child: Padding( padding: EdgeInsets.fromLTRB(50, 2, 10, 2), child: Icon( Icons.send, color: Color(0xFF087FF3), size: 28, )), onTap: _sendTextMessage) : InkWell( child: Icon( IconData(0xe60c, fontFamily: Constants.IconFontFamily), color: Color(0xFF797A7C), size: 26, ), onTap: () { _openPhotoView(); }), ], )))); } Widget _buildMessageList() { return Container( alignment: Alignment.topCenter, child: msgList.length == 0 ? Padding( padding: EdgeInsets.all(8), child: Text( I18n.of(context).feedback_tips, textAlign: TextAlign.center, textScaleFactor: 1.0, style: TextStyle(color: Colors.grey, fontSize: 12), )) : Scrollbar( child: ListView.builder( reverse: true, shrinkWrap: true, itemCount: msgList.length, controller: _scrollCtrl, padding: EdgeInsets.all(8.0), itemBuilder: _buildItem, )), ); } Widget _buildItem(BuildContext context, int index) { var lastMsgTime; if (index < msgList.length - 1) { lastMsgTime = msgList[index + 1].time; } MsgModel msg = msgList[index]; return ChatPageItem( key: Key(msg.time.toString()), msg: msg, lastMsgTime: lastMsgTime, friendInfo: companyInfo); } @override Widget build(BuildContext context) { return GestureDetector( onTap: hideKeyBoard, child: Scaffold( backgroundColor: const Color(0xFFE2E9F1), appBar: AppBar( title: Text( I18n.of(context).feedback_assistant, textScaleFactor: 1.0, style: TextStyle(color: Constants.BlackTextColor, fontSize: 16.47), ), leading: CustomUI.buildCustomLeading(context), titleSpacing: -10, centerTitle: false, elevation: 1, ), body: SafeArea( child: Column( children: [ Expanded(child: _buildMessageList()), _inputBar(), ], ))), ); } }