Hibok
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

341 строка
9.9 KiB

  1. import 'dart:io';
  2. import 'dart:typed_data';
  3. import 'package:chat/chat/ChatPageItem.dart';
  4. import 'package:chat/data/chat_data_mgr.dart';
  5. import 'package:chat/data/constants.dart';
  6. import 'package:chat/generated/i18n.dart';
  7. import 'package:chat/models/ChatMsg.dart';
  8. import 'package:chat/models/UserInfo.dart';
  9. import 'package:chat/photo/entity/options.dart';
  10. import 'package:chat/photo/photo.dart';
  11. import 'package:chat/proto/chat.pb.dart';
  12. import 'package:chat/r.dart';
  13. import 'package:chat/utils/CustomUI.dart';
  14. import 'package:chat/utils/HttpUtil.dart';
  15. import 'package:chat/utils/image_util.dart';
  16. import 'package:chat/utils/keyboard_utils.dart';
  17. import 'package:chat/utils/msgHandler.dart';
  18. import 'package:chat/utils/screen.dart';
  19. import 'package:flutter/material.dart';
  20. import 'package:flutter/services.dart';
  21. import 'package:flutter_screenutil/flutter_screenutil.dart';
  22. import 'package:oktoast/oktoast.dart';
  23. import 'package:photo_manager/photo_manager.dart';
  24. import 'package:chat/utils/MessageMgr.dart';
  25. class CompanyServerPage extends StatefulWidget {
  26. @override
  27. _CompanyServerPageState createState() => _CompanyServerPageState();
  28. }
  29. class _CompanyServerPageState extends State<CompanyServerPage> {
  30. final TextEditingController _textCtrl = TextEditingController();
  31. FocusNode editFocus = NoKeyboardEditableTextFocusNode();
  32. bool _isComposingMessage = false;
  33. double keyboardHeight;
  34. KeyboardBloc _bloc = KeyboardBloc();
  35. ScrollController _scrollCtrl = ScrollController();
  36. List<MsgModel> msgList = [];
  37. static int companyId = 10000;
  38. UserInfo companyInfo = UserInfo(
  39. userId: companyId,
  40. headimgurl: R.assetsImagesServerIcon,
  41. nickName: '反馈小助手');
  42. @override
  43. void initState() {
  44. super.initState();
  45. _bloc.start();
  46. //10000号为服务小助手
  47. MsgHandler.updateActiveSesstion(companyId);
  48. msgList = ChatDataMgr().getRecord();
  49. MessageMgr().on('New Chat Message', receiveMsg);
  50. }
  51. @override
  52. void dispose() {
  53. MsgHandler.curActiveSession = 0;
  54. _textCtrl.dispose();
  55. _bloc.dispose();
  56. editFocus.dispose();
  57. _scrollCtrl.dispose();
  58. MessageMgr().off('New Chat Message', receiveMsg);
  59. super.dispose();
  60. }
  61. receiveMsg(sessionId) {
  62. print('收到反馈助手消息');
  63. if (mounted) {
  64. setState(() {});
  65. if (_scrollCtrl.hasClients) {
  66. _scrollCtrl.animateTo(0,
  67. duration: new Duration(milliseconds: 500), curve: Curves.ease);
  68. }
  69. }
  70. }
  71. hideKeyBoard() {
  72. editFocus.unfocus();
  73. }
  74. bool checkMessage() {
  75. if (_textCtrl.text.length == 0) {
  76. showToast(I18n.of(context).msg_not);
  77. return false;
  78. }
  79. return true;
  80. }
  81. Future<Null> _textMessageSubmitted(String text) async {
  82. if (!checkMessage()) {
  83. _textCtrl.clear();
  84. return;
  85. }
  86. _textCtrl.clear();
  87. _sendMessage(text);
  88. }
  89. _sendTextMessage() {
  90. if (!checkMessage()) {
  91. return;
  92. }
  93. var sendStr = _textCtrl.text;
  94. _textCtrl.clear();
  95. _sendMessage(sendStr);
  96. }
  97. _sendMessage(String messageText) {
  98. MsgModel msg = MsgHandler.createSendMsg(ChatType.TextChatType, messageText,
  99. friendId: companyId, channelType: ChatChannelType.CSD);
  100. setState(() {
  101. _isComposingMessage = _textCtrl.text.length > 0;
  102. });
  103. sendMsg(msg);
  104. }
  105. sendMsg(MsgModel msg) async {
  106. ChatDataMgr().saveCompanyMsg(msg);
  107. if (mounted) {
  108. setState(() {});
  109. if (_scrollCtrl.hasClients) {
  110. _scrollCtrl.animateTo(0,
  111. duration: new Duration(milliseconds: 500), curve: Curves.ease);
  112. }
  113. }
  114. await HttpUtil().commitInfoToCompany(msg);
  115. if (mounted) {
  116. setState(() {});
  117. }
  118. }
  119. void _openPhotoView() async {
  120. var photos = await PhotoPicker.pickAsset(
  121. context: context,
  122. themeColor: Color(0xFFF0F0F0),
  123. textColor: Color(0xFF3F3F3F),
  124. pickType: PickType.onlyImage);
  125. if (photos != null && photos.length > 0) {
  126. for (var i = 0; i < photos.length; i++) {
  127. AssetEntity photoEntity = photos[i];
  128. var file = await photoEntity.file;
  129. _sendPhotoFile(file);
  130. }
  131. }
  132. }
  133. void _sendPhotoFile(File imgFile) async {
  134. var imgSize = await imgFile.length();
  135. print('图片大小:${imgSize / 1024}KB');
  136. var sendImg;
  137. if (imgSize > 33 * 1024 * 1024) {
  138. showToast(I18n.of(context).video_more_big);
  139. return;
  140. }
  141. bool isNeedUpload = false;
  142. if (imgSize > ImgSizeLimit) {
  143. print('图片大于 $ImgSizeLimit,压缩');
  144. //发送压缩图
  145. sendImg = await WidgetUtil.getCompressImg(imgFile.absolute.path);
  146. isNeedUpload = true;
  147. } else {
  148. sendImg = imgFile.readAsBytesSync();
  149. }
  150. var rect = await WidgetUtil.getImageWH(
  151. image: Image.memory(Uint8List.fromList(sendImg)));
  152. print('图片大小 Rect : $rect');
  153. int aspectRatio = rect.width * 100 ~/ rect.height;
  154. var msg = MsgHandler.createSendMsg(ChatType.ImageChatType, sendImg,
  155. localFile: isNeedUpload ? imgFile.absolute.path : null,
  156. extra: aspectRatio,
  157. friendId: companyId,
  158. channelType: ChatChannelType.CSD);
  159. sendMsg(msg);
  160. }
  161. _inputBar() {
  162. Widget input = Container(
  163. child: TextField(
  164. keyboardAppearance: Brightness.light,
  165. onChanged: (String messageText) {
  166. setState(() {
  167. _isComposingMessage = _textCtrl.text.length > 0;
  168. });
  169. },
  170. cursorColor: Constants.BlueTextColor,
  171. style: TextStyle(
  172. fontSize: ScreenUtil().setSp(16),
  173. textBaseline: TextBaseline.alphabetic),
  174. maxLines: 3,
  175. minLines: 1,
  176. controller: _textCtrl,
  177. textInputAction: TextInputAction.newline,
  178. inputFormatters: <TextInputFormatter>[
  179. LengthLimitingTextInputFormatter(600) //限制长度
  180. ],
  181. onSubmitted: _textMessageSubmitted,
  182. focusNode: editFocus,
  183. decoration: InputDecoration(
  184. hintText: I18n.of(context).input_content,
  185. hintStyle: TextStyle(color: const Color(0xffBDBDBD), fontSize: 16),
  186. border: null,
  187. hintMaxLines: 1,
  188. contentPadding: EdgeInsets.only(left: 5, right: 5, top: 8, bottom: 8),
  189. ),
  190. ),
  191. );
  192. return GestureDetector(
  193. onTap: () {
  194. print('放置触控隐藏键盘');
  195. },
  196. child: Container(
  197. width: Screen.width,
  198. color: Colors.white,
  199. child: Container(
  200. padding: EdgeInsets.symmetric(horizontal: 7, vertical: 7),
  201. alignment: Alignment.topCenter,
  202. decoration: BoxDecoration(
  203. color: Colors.white,
  204. border: Border(top: BorderSide(color: Color(0xFFDFDFDF)))),
  205. child: Row(
  206. children: <Widget>[
  207. //输入框
  208. Expanded(child: input), SizedBox(width: 10),
  209. _isComposingMessage
  210. ? InkWell(
  211. child: Padding(
  212. padding: EdgeInsets.fromLTRB(50, 2, 10, 2),
  213. child: Icon(
  214. Icons.send,
  215. color: Color(0xFF087FF3),
  216. size: 28,
  217. )),
  218. onTap: _sendTextMessage)
  219. : InkWell(
  220. child: Icon(
  221. IconData(0xe60c,
  222. fontFamily: Constants.IconFontFamily),
  223. color: Color(0xFF797A7C),
  224. size: 26,
  225. ),
  226. onTap: () {
  227. _openPhotoView();
  228. }),
  229. ],
  230. ))));
  231. }
  232. Widget _buildMessageList() {
  233. return Container(
  234. alignment: Alignment.topCenter,
  235. child: msgList.length == 0
  236. ? Padding(
  237. padding: EdgeInsets.all(8),
  238. child: Text(
  239. '有什么问题都可以反馈给我哦',
  240. textAlign: TextAlign.center,
  241. textScaleFactor: 1.0,
  242. style: TextStyle(color: Colors.grey, fontSize: 12),
  243. ))
  244. : Scrollbar(
  245. child: ListView.builder(
  246. reverse: true,
  247. shrinkWrap: true,
  248. itemCount: msgList.length,
  249. controller: _scrollCtrl,
  250. padding: EdgeInsets.all(8.0),
  251. itemBuilder: _buildItem,
  252. )),
  253. );
  254. }
  255. Widget _buildItem(BuildContext context, int index) {
  256. var lastMsgTime;
  257. if (index < msgList.length - 1) {
  258. lastMsgTime = msgList[index + 1].time;
  259. }
  260. MsgModel msg = msgList[index];
  261. return ChatPageItem(
  262. key: Key(msg.time.toString()),
  263. msg: msg,
  264. lastMsgTime: lastMsgTime,
  265. friendInfo: companyInfo);
  266. }
  267. @override
  268. Widget build(BuildContext context) {
  269. return GestureDetector(
  270. onTap: hideKeyBoard,
  271. child: Scaffold(
  272. backgroundColor: const Color(0xFFE2E9F1),
  273. appBar: AppBar(
  274. title: Text(
  275. '反馈小助手',
  276. textScaleFactor: 1.0,
  277. style:
  278. TextStyle(color: Constants.BlackTextColor, fontSize: 16.47),
  279. ),
  280. leading: CustomUI.buildCustomLeading(context),
  281. titleSpacing: -10,
  282. centerTitle: false,
  283. elevation: 1,
  284. ),
  285. body: SafeArea(
  286. child: Column(
  287. children: <Widget>[
  288. Expanded(child: _buildMessageList()),
  289. _inputBar(),
  290. ],
  291. ))),
  292. );
  293. }
  294. }