|
- import 'dart:convert';
- import 'dart:io';
- import 'dart:math';
- import 'dart:typed_data';
-
- import 'package:cached_network_image/cached_network_image.dart';
- import 'package:chat/chat/download_item.dart';
- import 'package:chat/chat/file_msg_item.dart';
- import 'package:chat/chat/gift_msg_item.dart';
- import 'package:chat/chat/msg_state_widge.dart';
- import 'package:chat/chat/place_item.dart';
- import 'package:chat/chat/redbag_widget.dart';
- import 'package:chat/chat/upload_item.dart';
- import 'package:chat/chat/video_view.dart';
- import 'package:chat/data/UserData.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/models/group_info_model.dart';
- import 'package:chat/models/keyboard_provider.dart';
- import 'package:chat/models/ref_name_provider.dart';
- import 'package:chat/proto/chat.pbenum.dart';
- import 'package:chat/proto/chat.pbserver.dart';
- import 'package:chat/utils/CustomUI.dart';
- import 'package:chat/utils/HttpUtil.dart';
- import 'package:chat/utils/MessageMgr.dart';
- import 'package:chat/utils/app_navigator.dart';
- import 'package:chat/utils/date_utils.dart';
- import 'package:chat/utils/file_cache_mgr.dart';
- import 'package:chat/utils/msgHandler.dart';
- import 'package:chat/utils/screen.dart';
- import 'package:chat/utils/sound_util.dart';
- import 'package:chat/utils/upload_util.dart';
- import 'package:chat/utils/video_anim.dart';
- import 'package:chat/utils/wpop/w_popup_menu.dart';
- import 'package:dio/dio.dart';
- import 'package:flutter/services.dart';
- import 'package:flutter/cupertino.dart';
- import 'package:flutter/material.dart';
- import 'package:oktoast/oktoast.dart';
- import 'package:provider/provider.dart';
- import 'package:share_extend/share_extend.dart';
- import 'package:url_launcher/url_launcher.dart';
-
- import '../r.dart';
- import 'full_img_view.dart';
- import 'upload_item.dart';
- import 'package:chat/models/money_change.dart';
- import 'package:chat/models/voucher_change.dart';
-
- const double ChatRadius = 7.5;
- const Color SendMsgBg = Color(0xFFD4F0FF);
-
- const double TextHeight = 1.2;
-
- const double PaddingLeft = 9.5;
-
- const Color ReciveBorderColor = Color(0xFFDCDCDC);
-
- const double FontSize = 15;
-
- class ChatPageItem extends StatefulWidget {
- final MsgModel msg;
-
- final UserInfo friendInfo;
- final int lastMsgTime;
-
- final Function hideKeyboard;
-
- const ChatPageItem(
- {Key key, this.msg, this.lastMsgTime, this.friendInfo, this.hideKeyboard})
- : assert(msg != null),
- super(key: key);
-
- @override
- _ChatPageItemState createState() => _ChatPageItemState();
- }
-
- class _ChatPageItemState extends State<ChatPageItem>
- with SingleTickerProviderStateMixin {
- int curTextType = 0; //文字、译文切换索引
- List<String> textList = [];
-
- UserInfo friendInfo;
-
- String curSoundUrl;
-
- CancelToken _cancelToken = CancelToken();
-
- bool isLongPressed = false;
- @override
- void initState() {
- super.initState();
- friendInfo = widget.friendInfo;
-
- if (widget.msg.from == UserData().basicInfo.userId &&
- widget.msg.state == MsgState.None) {
- print('重新发送消息');
- MsgHandler.sendChatMsg(widget.msg);
- }
-
- textList = widget.msg.getTransTextList();
-
- MessageMgr().on('Update Translate Message', updateTranslateMsg);
- MessageMgr().on('Cancel Request', _deleteItem);
-
- MessageMgr().on('Cancel Request', _deleteItem);
- }
-
- @override
- void dispose() {
- MessageMgr().off('Cancel Request', _deleteItem);
- MessageMgr().off('Update Translate Message', updateTranslateMsg);
- super.dispose();
- }
-
- _deleteItem(msg) {
- if (msg == widget.msg) {
- print(widget.msg.state);
- if (widget.msg.state == MsgState.Uploading) {
- print('取消上传');
- UploadUtil().cancelRequests(_cancelToken);
- }
- }
- }
-
- updateTextList() {
- textList.clear();
- curTextType = 0;
- textList = widget.msg.getTransTextList();
- }
-
- updateTranslateMsg(msg) {
- if (msg.time == widget.msg.time) {
- if (mounted) {
- updateTextList();
- if (!mounted) {
- return;
- }
- setState(() {
- print('更新翻译文字');
- });
- }
- }
- }
-
- getTodayTime(msgDate) {
- String showTimeStr;
-
- var sendTime = widget.msg.time;
- var today = DateTime.now();
- //今天
- if (msgDate.year == today.year &&
- msgDate.month == today.month &&
- msgDate.day == today.day) {
- showTimeStr =
- DateUtils().getFormartData(timeSamp: sendTime, format: 'HH:mm');
- } else {
- showTimeStr = DateUtils()
- .getFormartData(timeSamp: sendTime, format: 'yyyy/MM/dd HH:mm');
- }
-
- return showTimeStr;
- }
-
- String getMsgTime() {
- String showTimeStr;
-
- var sendTime = widget.msg.time;
-
- var msgDate = DateTime.fromMillisecondsSinceEpoch(sendTime);
- if (widget.lastMsgTime == null) {
- showTimeStr = getTodayTime(msgDate);
- } else {
- if (sendTime - widget.lastMsgTime > 3 * 60 * 1000) {
- showTimeStr = getTodayTime(msgDate);
- }
- }
-
- return showTimeStr;
- }
-
- @override
- Widget build(BuildContext context) {
- var showTime = getMsgTime();
-
- return Container(
- width: Screen.width,
- margin: const EdgeInsets.symmetric(vertical: 10.0),
- child: Column(
- children: <Widget>[
- showTime == null
- ? SizedBox()
- : Container(
- decoration: BoxDecoration(
- color: Color(0xFF2C2F36).withOpacity(0.25),
- borderRadius: BorderRadius.all(Radius.circular(9.5))),
- padding:
- EdgeInsets.only(left: 7, right: 7, top: 3, bottom: 2),
- child: Text(showTime,
- textScaleFactor: 1.0,
- style: TextStyle(fontSize: 10.0, color: Colors.white)),
- ),
- SizedBox(height: 10),
- _msgWidget()
- ],
- ),
- );
- }
-
- _msgWidget() {
- if (widget.msg.from == 0) {
- return _serverNotifyMsg();
- } else {
- if (widget.msg.from == UserData().basicInfo.userId) {
- return _getSentMessageLayout(context);
- } else {
- return _getReceivedMessageLayout(context);
- }
- }
- }
-
- _serverNotifyMsg() {
- var type = widget.msg.msgType;
-
- if (type == ChatType.RedWalletChatType.value) {
- RedWallet wallet = RedWallet.fromBuffer(widget.msg.msgContent);
-
- var msg = '';
-
- if (wallet.state == RedWalletState.Received) {
- if (wallet.tuId == friendInfo.userId) {
- msg = I18n.of(context).get_money.replaceFirst(
- '/s1',
- Provider.of<RefNameProvider>(context)
- .getRefName(friendInfo.userId, friendInfo.nickName));
- } else {
- msg = I18n.of(context).you_get_money.replaceFirst(
- '/s1',
- Provider.of<RefNameProvider>(context)
- .getRefName(friendInfo.userId, friendInfo.nickName));
- }
- } else {
- if (wallet.tuId == friendInfo.userId) {
- msg = I18n.of(context).your_redMoney_over;
- } else {
- msg = I18n.of(context).other_redMoney_over;
- }
- }
-
- return Container(
- alignment: Alignment.center,
- constraints: BoxConstraints(maxWidth: Screen.width - 120),
- child: extendedText(msg, color: Constants.GreyTextColor, fontSize: 12),
- );
- } else {
- ///todo 翻译管家系统通知消息
-
- if (type == ChatType.GroupChatNoticeType.value) {
- var res = GroupChatNotice.fromBuffer(widget.msg.msgContent);
-
- var groupInfoModel = Provider.of<GroupInfoModel>(context);
- var showStr = MsgHandler.getGroupNoticeMsg(res, groupInfoModel);
- return Container(
- alignment: Alignment.center,
- constraints: BoxConstraints(maxWidth: Screen.width - 120),
- child: Text(
- showStr,
- textScaleFactor: 1.0,
- textAlign: TextAlign.center,
- style: TextStyle(color: Constants.GreyTextColor, fontSize: 12),
- ),
- );
- }
- }
- return Container();
- }
-
- _textGif(List<int> msgContent) {
- var msg = utf8.decode(msgContent);
- return Container(
- constraints: BoxConstraints(maxWidth: Screen.width - 120),
- child: extendedText(
- msg,
- hideKeyboard: widget.hideKeyboard,
- fontSize: FontSize,
- color: Colors.black,
- ),
- );
- }
-
- _textMsg(List<int> msgContent) {
- var msg = utf8.decode(msgContent);
- bool isUrl = false;
- if (textList[curTextType].contains('http')) {
- isUrl = true;
- }
- Widget text = Container(
- constraints: BoxConstraints(maxWidth: Screen.width - 120),
- child: extendedText(
- msg,
- hideKeyboard: widget.hideKeyboard,
- fontSize: FontSize,
- color: isUrl ? Colors.blue : Colors.black,
- ),
- padding: EdgeInsets.symmetric(horizontal: 9, vertical: 10.5),
- decoration: BoxDecoration(
- color: isLongPressed ? Colors.grey[300] : SendMsgBg,
- border: Border.all(color: Color(0xFFB9CBD7), width: 0.6),
- borderRadius: BorderRadius.all(Radius.circular(ChatRadius))),
- );
-
- if (widget.msg.refMsgContent != null &&
- widget.msg.refMsgContent.length > 0) {
- QuoteMsg quoteMsg = QuoteMsg.fromBuffer(widget.msg.refMsgContent);
-
- return Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.end,
- children: <Widget>[
- text,
- SizedBox(height: 2),
- Container(
- constraints: BoxConstraints(maxWidth: Screen.width - 120),
- padding: EdgeInsets.symmetric(vertical: 1, horizontal: 3),
- child: Text(
- quoteMsg.content,
- maxLines: 1,
- textScaleFactor: 1.0,
- overflow: TextOverflow.ellipsis,
- style: TextStyle(fontSize: 12),
- ),
- decoration: BoxDecoration(
- color: Colors.grey[300],
- borderRadius: BorderRadius.circular(5)),
- )
- ],
- );
- } else {
- return text;
- }
- }
-
- _soundMsg() {
- double time = widget.msg.extraInfo / 1000;
- if (time > 60) {
- time = 60.0;
- }
- bool isPlaying = false;
-
- var soundPath = widget.msg.localFile;
-
- isPlaying = SoundUtils().isPlaying(soundPath);
-
- var soundWidget = GestureDetector(
- child: Container(
- width: 120,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.end,
- children: <Widget>[
- Container(
- alignment: Alignment.center,
- padding: EdgeInsets.only(bottom: 2),
- margin: EdgeInsets.only(right: 10),
- width: 25.5,
- height: 25.5,
- decoration: BoxDecoration(
- border:
- Border.all(color: const Color(0xFF1B92C7), width: 0.5),
- color: const Color(0xFF04A4FE),
- shape: BoxShape.circle),
- child: Icon(
- IconData(isPlaying ? 0xe652 : 0xe653,
- fontFamily: Constants.IconFontFamily),
- size: isPlaying ? 15 : 18,
- color: Colors.white,
- ),
- ),
- isPlaying
- ? Stack(
- children: <Widget>[
- Container(
- height: 18,
- width: 19,
- ),
- Positioned(
- bottom: 0,
- child: VideoAnim(
- begin: 18,
- start: 0.444,
- end: 4.5,
- )),
- Positioned(
- left: 7,
- bottom: 0,
- child: VideoAnim(
- begin: 4.5,
- end: 18,
- )),
- Positioned(
- left: 14,
- bottom: 0,
- child: VideoAnim(
- begin: 18,
- end: 4.5,
- ))
- ],
- )
- : Stack(
- children: <Widget>[
- Container(
- height: 18,
- width: 19,
- ),
- Positioned(
- bottom: 0, child: CustomUI.buildAudioContaniner(12)),
- Positioned(
- left: 7,
- bottom: 0,
- child: CustomUI.buildAudioContaniner(4.5)),
- Positioned(
- left: 14,
- bottom: 0,
- child: CustomUI.buildAudioContaniner(18))
- ],
- ),
- Expanded(child: SizedBox()),
- fixedText(time.toStringAsFixed(0),
- color: Constants.BlackTextColor, fontSize: 16)
- ],
- ),
- padding: EdgeInsets.symmetric(horizontal: 15, vertical: 12),
- decoration: BoxDecoration(
- color: SendMsgBg,
- border: Border.all(color: Color(0xFFB9CBD7), width: 0.6),
- borderRadius: BorderRadius.all(Radius.circular(ChatRadius))),
- ),
- onTap: () async {
- print('播放状态 : $isPlaying');
- print('当前文件$soundPath ');
- if (isPlaying) {
- SoundUtils().pause();
- } else {
- SoundUtils().play(soundPath, onPlayed: () {
- if (mounted) {
- setState(() {});
- }
- }, complete: () {
- if (mounted) {
- setState(() {});
- }
- });
- }
- },
- );
-
- return UploadImgItem(
- msg: widget.msg,
- child: soundWidget,
- isShowProgress: false,
- );
- }
-
- Size _getImgSize() {
- double aspectRatio = widget.msg.extraInfo / 100;
-
- var maxWidth = Screen.width * 0.65;
- var maxHeight = Screen.height / 4;
-
- var width, height;
- if (maxWidth / maxHeight > aspectRatio) {
- height = maxHeight;
- width = maxHeight * aspectRatio;
- } else {
- width = maxWidth;
- height = maxWidth / aspectRatio;
- }
-
- return Size(width, height);
- }
-
- _imgMsg(List<int> imgData) {
- var imgSize = _getImgSize();
- ImageProvider provider = MemoryImage(widget.msg.localFile == null
- ? Uint8List.fromList(imgData)
- : File(widget.msg.localFile).readAsBytesSync());
-
- return GestureDetector(
- child: ClipRRect(
- child: UploadImgItem(
- msg: widget.msg,
- cancelToken: _cancelToken,
- child: Container(
- height: imgSize.height,
- width: imgSize.width,
- child: Image(
- fit: BoxFit.contain,
- image: provider,
- ),
- )),
- borderRadius: BorderRadius.circular(5),
- ),
- onTap: () async {
- showFullImg(context, widget.msg);
- });
- }
-
- _videoMsg(BuildContext context, List<int> thumbnail) {
- var imgSize = _getImgSize();
- return InkWell(
- child: ClipRRect(
- child: Stack(
- alignment: Alignment.center,
- children: <Widget>[
- UploadImgItem(
- msg: widget.msg,
- cancelToken: _cancelToken,
- child: Container(
- width: imgSize.width,
- height: imgSize.height,
- child: Image(
- fit: BoxFit.contain,
- image: MemoryImage(Uint8List.fromList(thumbnail)),
- ),
- ))
- ],
- ),
- borderRadius: BorderRadius.circular(5),
- ),
- onTap: () {
- showVideoPage(context, widget.msg.localFile);
- },
- );
- }
-
- _msgLayout(BuildContext context, MsgModel msg) {
- Widget item;
-
- switch (ChatType.valueOf(msg.msgType)) {
- case ChatType.TextChatType:
- item = _textMsg(msg.msgContent);
- break;
-
- case ChatType.EmoticonType:
- item = _textGif(msg.msgContent);
- break;
- case ChatType.ImageChatType:
- item = _imgMsg(msg.msgContent);
- break;
- case ChatType.ShortVideoChatType:
- item = _videoMsg(context, msg.msgContent);
- break;
- case ChatType.ShortVoiceChatType:
- item = _soundMsg();
- break;
- case ChatType.RedWalletChatType:
- item = RedBagItem(
- Key(msg.time.toString()), UserData().basicInfo.userId, msg);
- break;
- case ChatType.PlaceChatType:
- item = PlaceItem(isMe: true, placeContent: msg.msgContent);
- break;
- case ChatType.GiftChatType:
- item = GiftMsgItem(msg.msgContent, true);
- break;
- case ChatType.FileChatType:
- item = _fileMsgItem();
- break;
- default:
- }
-
- return wrapItemWithMenu(item);
- }
-
- Widget _fileMsgItem() {
- return UploadImgItem(
- msg: widget.msg,
- cancelToken: _cancelToken,
- child: Container(
- height: 100,
- constraints: BoxConstraints(maxWidth: Screen.width - 120),
- padding: EdgeInsets.symmetric(horizontal: 9, vertical: 10.5),
- decoration: BoxDecoration(
- color: isLongPressed ? Colors.grey[300] : SendMsgBg,
- borderRadius: BorderRadius.all(Radius.circular(ChatRadius))),
- child: FileMsgItem(widget.msg)));
- }
-
- Widget _getSentMessageLayout(BuildContext context) {
- bool hasHeadImg = true;
- if (UserData().basicInfo.headimgurl == null ||
- UserData().basicInfo.headimgurl.length == 0) {
- hasHeadImg = false;
- }
- return Row(
- crossAxisAlignment: CrossAxisAlignment.start,
- mainAxisAlignment: MainAxisAlignment.end,
- children: <Widget>[
- MsgStateWidget(widget.msg),
- SizedBox(width: 3),
- _msgLayout(context, widget.msg),
- SizedBox(width: 10),
- Column(
- crossAxisAlignment: CrossAxisAlignment.end,
- children: <Widget>[
- ClipRRect(
- borderRadius: BorderRadius.circular(8),
- child: hasHeadImg
- ? CachedNetworkImage(
- imageUrl: UserData().basicInfo.headimgurl,
- placeholder: (context, url) => Image.asset(
- Constants.DefaultHeadImgUrl,
- width: 40,
- height: 40,
- ),
- width: 40,
- height: 40,
- )
- : SizedBox(
- width: 40,
- height: 40,
- child: Image.asset(R.assetsImagesDefaultNorAvatar))),
- ],
- )
- ]);
- }
-
- Widget wrapItemWithMenu(item) {
- List<Function> actionsFunc = [];
- List<String> actions = [
- I18n.of(context).delete,
- I18n.of(context).reply,
- ];
-
- actionsFunc.add(() {
- MessageMgr().emit('Delete Select Message', widget.msg);
- });
- actionsFunc.add(() {
- print('发送引用的消息');
- MessageMgr().emit('Reply Select Message', widget.msg);
- });
-
- ///转发
- if (widget.msg.msgType == ChatType.TextChatType.value ||
- widget.msg.msgType == ChatType.ImageChatType.value ||
- widget.msg.msgType == ChatType.ShortVideoChatType.value ||
- widget.msg.msgType == ChatType.PlaceChatType.value ||
- widget.msg.msgType == ChatType.EmoticonType.value ||
- widget.msg.msgType == ChatType.FileChatType.value) {
- actions.add(I18n.of(context).forward);
- actionsFunc.add(() {
- print('转发消息');
-
- if (widget.msg.msgType == ChatType.FileChatType.value &&
- widget.msg.localFile == null) {
- showToast('请先下载文件');
- return;
- }
-
- AppNavigator.pushForwardPage(context, widget.msg);
- });
- }
-
- if (widget.msg.msgType == ChatType.FileChatType.value &&
- widget.msg.localFile != null) {
- //分享文件
- actions.add(I18n.of(context).copy_download_url);
- actionsFunc.add(() async {
- UploadUtil().copyFileUrl(widget.msg, context);
- String path = widget.msg.localFile;
-
- String type = 'file';
- if (path.contains('mp4') || path.contains('mp3')) {
- type = 'video';
- } else if (path.contains('png') ||
- path.contains('jpg') ||
- path.contains('jpeg') ||
- path.contains('JPG') ||
- path.contains('PNG')) {
- type = 'image';
- }
-
- ShareExtend.share(FileCacheMgr.replacePath(path), type);
- });
- }
-
- if (widget.msg.msgType == ChatType.TextChatType.value) {
- actions.insert(0, I18n.of(context).copy);
- actionsFunc.insert(0, () {
- //复制当前的文字
- print('复制文字 ${textList[curTextType]}');
- ClipboardData clipboardData =
- ClipboardData(text: textList[curTextType]);
- Clipboard.setData(clipboardData);
- });
- }
-
- if (widget.msg.msgType == ChatType.ShortVoiceChatType.value) {
- var soundPlayMode =
- Provider.of<KeyboardIndexProvider>(context).soundPlayMode;
-
- actions.add(soundPlayMode
- ? I18n.of(context).handset_playback
- : I18n.of(context).speaker_play);
- actionsFunc.add(() {
- Provider.of<KeyboardIndexProvider>(context)
- .changeSoundPlayMode(!soundPlayMode);
- SoundUtils.instance.savePlayModeConfig(soundPlayMode);
- });
- }
- // String date2 = DateTime.fromMillisecondsSinceEpoch(widget.msg.time).toString();
- bool isUrl = false;
- if (widget.msg.msgType == ChatType.TextChatType.value) {
- if (textList[curTextType].contains('http')) {
- isUrl = true;
- }
- }
- return WPopupMenu(
- child: item,
- actions: actions,
- onTap: () async {
- if (isUrl) {
- if (await canLaunch(textList[curTextType])) {
- launch(textList[curTextType]);
- }
- }
- },
- onLongPressStart: () {
- isLongPressed = true;
- setState(() {});
- },
- onLongPressEnd: () {
- isLongPressed = false;
- setState(() {});
- },
- onValueChanged: (int value) {
- print('选择的是$value个菜单');
- if (value >= 0 && value < actionsFunc.length) {
- actionsFunc[value]();
- }
- },
- );
- }
-
- //用户评价人工翻译,差评
- rateTranslateResult() async {
- return await HttpUtil().rateTranslateResult(widget.msg, () {
- if (mounted) {
- setState(() {});
- }
- });
- }
-
- _receiveJIF(MsgModel msg) {
- var text = utf8.decode(msg.msgContent);
- return extendedText(text, hideKeyboard: widget.hideKeyboard);
- }
-
- double _getTextWidth(String text) {
- var tp = TextPainter(
- text: TextSpan(style: TextStyle(fontSize: FontSize), text: text),
- textAlign: TextAlign.left,
- textDirection: TextDirection.ltr,
- textScaleFactor: 1,
- );
-
- tp.layout(maxWidth: Screen.width - 140);
-
- RegExp alterStr = RegExp(r'\[([0-9]+)\]');
- Iterable<Match> matches = alterStr.allMatches(text);
- // print('~~~~~~~~~~~~~~${matches.length}~~~~~~~~~~~~~~~');
-
- double delta = 0;
- for (Match m in matches) {
- // print('~~~~~~~~~~~~~~${m.group(1)}~~~~~~~~~~~~~~~');
- if (int.parse(m.group(1)) > 10) {
- delta += 20 + 4 - 25;
- } else {
- delta += 20 + 4 - 16.8;
- }
- }
-
- return tp.width + delta;
- }
-
- _receiveText(MsgModel msg) {
- List<Widget> showMsg = [];
- if (textList.length > 0) {
- bool isUrl = false;
- if (textList[curTextType].contains('http')) {
- isUrl = true;
- }
-
- showMsg.add(InkWell(
- onTap: () {
- if (msg.transTag == 1) {
- return;
- }
- if (msg.transTag == 2 || msg.transTag == 3) {
- setState(() {
- curTextType += 1;
- curTextType %= textList.length;
- });
- return;
- }
- },
- child: Container(
- constraints:
- BoxConstraints(maxWidth: Screen.width - 140, minHeight: 22),
- alignment: Alignment.centerLeft,
- child: extendedText(
- textList[curTextType],
- color: isUrl ? Colors.blue : Constants.BlackTextColor,
- hideKeyboard: widget.hideKeyboard,
- fontSize: FontSize,
- ))));
- }
-
- var width = _getTextWidth(textList[curTextType]);
-
- var minWidth = width;
- if (msg.transTag != 0) {
- minWidth = 200;
- showMsg.add(Padding(
- padding: EdgeInsets.symmetric(vertical: 5),
- child: Divider(color: Color(0xFFECECEC), height: 1)));
- Widget tranWidget = _transProcessWidget(msg.transTag);
- showMsg.add(tranWidget);
- }
-
- ///todo
- Widget text = Stack(children: <Widget>[
- Container(
- width: width + 20,
- constraints:
- BoxConstraints(maxWidth: Screen.width - 120, minWidth: minWidth),
- padding: EdgeInsets.symmetric(horizontal: 9, vertical: 10.5),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start, children: showMsg),
- decoration: BoxDecoration(
- border: Border.all(color: ReciveBorderColor, width: 0.5),
- color: isLongPressed ? Colors.grey[300] : Colors.white,
- borderRadius: BorderRadius.all(Radius.circular(ChatRadius))),
- ),
- msg.transTag != 1
- ? Positioned(
- right: 5,
- top: 5,
- child: Container(
- child: Row(children: <Widget>[
- blueDot(curTextType == 0),
- blueDot(curTextType == 1),
- blueDot(curTextType == 2),
- //blueDot(true),
- ])))
- : Container()
- ]);
-
- if (msg.refMsgContent != null && msg.refMsgContent.length > 0) {
- QuoteMsg quoteMsg = QuoteMsg.fromBuffer(msg.refMsgContent);
-
- return Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: <Widget>[
- text,
- SizedBox(height: 2),
- Container(
- constraints: BoxConstraints(maxWidth: Screen.width - 120),
- padding: EdgeInsets.symmetric(vertical: 1, horizontal: 3),
- child: Text(
- quoteMsg.content,
- maxLines: 1,
- textScaleFactor: 1.0,
- overflow: TextOverflow.ellipsis,
- style: TextStyle(fontSize: 12),
- ),
- decoration: BoxDecoration(
- color: Colors.grey[300],
- borderRadius: BorderRadius.circular(5)),
- )
- ],
- );
- } else {
- return text;
- }
- }
-
- _translateItemWidget(int code, String title, Function onTap) {
- Color color = onTap == null ? Constants.GreyTextColor : Color(0xFF087FF3);
- return InkWell(
- onTap: onTap,
- splashColor: Colors.red,
- child: Container(
- width: 80,
- child: Row(
- children: <Widget>[
- Icon(IconData(code, fontFamily: Constants.IconFontFamily),
- color: color, size: 20),
- SizedBox(width: 5),
- Expanded(
- child: SizedBox(
- child: Text(
- title,
- style: TextStyle(color: color, fontSize: 10),
- textScaleFactor: 1.0,
- maxLines: 1,
- overflow: TextOverflow.ellipsis,
- ),
- ))
- ],
- )));
- }
-
- bool isTranslating = false;
- _transProcessWidget(int transTag) {
- double width = 160;
-
- Widget userTranslateWidget;
- Widget machineTranslateWidget;
-
- if (transTag == 1) {
- //机器翻译中
- userTranslateWidget =
- _translateItemWidget(0xe670, I18n.of(context).man_retranslate, null);
-
- machineTranslateWidget =
- _translateItemWidget(0xe671, I18n.of(context).robotTranslate, null);
- } else if (transTag == 2) {
- //人工翻译中
- userTranslateWidget =
- _translateItemWidget(0xe670, I18n.of(context).ManTranslate, null);
- machineTranslateWidget =
- _translateItemWidget(0xe671, I18n.of(context).robot_retranslate, () {
- setState(() {
- curTextType += 1;
- curTextType %= textList.length;
- });
- });
- } else if (transTag == 3) {
- //机器翻译完成
- userTranslateWidget = _translateItemWidget(
- 0xe670,
- I18n.of(context).man_retranslate,
- isTranslating
- ? null
- : () async {
- isTranslating = true;
-
- int money =
- Provider.of<MoneyChangeProvider>(context, listen: false)
- .money;
-
- int voucher =
- Provider.of<VoucherChangeProvider>(context, listen: false)
- .voucher;
-
- int needMoney = widget.msg.getNeedMoney();
-
- if (needMoney > voucher + money) {
- showToast('翻译券和H币不足');
- return;
- }
- var res = await HttpUtil().getPersonalTranslate(widget.msg);
- if (res) {
- print('请求人工翻译成功,进行扣费');
- setState(() {
- widget.msg.transTag = 2;
-
- //优先扣券
- if (voucher > 0) {
- int costQuan = min(voucher, needMoney);
- Provider.of<VoucherChangeProvider>(context,
- listen: false)
- .subVoucher(costQuan);
- }
-
- //不足的话再扣H币
- if (needMoney > voucher) {
- Provider.of<MoneyChangeProvider>(context, listen: false)
- .subMoney(needMoney - voucher);
- }
- });
- }
- });
- machineTranslateWidget =
- _translateItemWidget(0xe671, I18n.of(context).robot_retranslate, () {
- setState(() {
- curTextType += 1;
- curTextType %= textList.length;
- });
- });
- } else if (transTag == 4 || transTag == 10) {
- //4人工翻译完成,未评论 10人工翻译完成已评论
- userTranslateWidget = InkWell(
- onTap: () {
- setState(() {
- curTextType = 0;
- });
- },
- child: Container(
- width: width / 2,
- child: Row(
- children: <Widget>[
- InkWell(
- child: Icon(
- IconData(0xe641, fontFamily: Constants.IconFontFamily),
- size: 18,
- color:
- transTag == 10 ? Colors.grey : Color(0xFF087FF3)),
- onTap: transTag == 10
- ? null
- : () {
- CustomUI.showIosDialog(
- context, I18n.of(context).bad_ev, () async {
- bool isSuccess = await rateTranslateResult();
- if (isSuccess) {
- Navigator.of(context).pop(true);
- showToast(I18n.of(context).success);
- } else {
- showToast(I18n.of(context).fail);
- Navigator.of(context).pop();
- }
- }, () {
- Navigator.of(context).pop();
- });
- },
- ),
- SizedBox(width: 5),
- Expanded(
- child: SizedBox(
- child: Text(
- I18n.of(context).over,
- style: TextStyle(color: Color(0xFF087FF3), fontSize: 10),
- textScaleFactor: 1.0,
- maxLines: 1,
- overflow: TextOverflow.ellipsis,
- ),
- ))
- ],
- )));
- machineTranslateWidget =
- _translateItemWidget(0xe675, I18n.of(context).see_original, () {
- setState(() {
- curTextType = textList.length - 1;
- });
- });
- }
-
- return Container(
- height: 26,
- alignment: Alignment.center,
- child: Row(
- children: <Widget>[
- userTranslateWidget,
- Expanded(
- child: SizedBox(child: VerticalDivider(), height: 20, width: 2)),
- machineTranslateWidget
- ],
- ),
- );
- }
-
- _receiveImg(BuildContext context, List<int> imgData, {String downloadData}) {
- ImageProvider provider = MemoryImage(widget.msg.localFile == null
- ? Uint8List.fromList(imgData)
- : File(widget.msg.localFile).readAsBytesSync());
-
- var imgSize = _getImgSize();
-
- return DownloadItem(
- isAutoDown: false,
- msg: widget.msg,
- onFinishTap: () {
- widget.hideKeyboard();
- showFullImg(context, widget.msg);
- },
- child: Container(
- width: imgSize.width,
- height: imgSize.height,
- child: ClipRRect(
- child: Image(
- image: provider ?? AssetImage(R.assetsImagesIcAlbum),
- ),
- borderRadius: BorderRadius.circular(5),
- ),
- ),
- );
- }
-
- _receiveVideo(BuildContext context, List<int> imgData,
- {String downloadData}) {
- ImageProvider provider = MemoryImage(Uint8List.fromList(imgData));
- var imgSize = _getImgSize();
- return InkWell(
- onTap: () {
- if (widget.msg.localFile != null) {
- showVideoPage(context, widget.msg.localFile);
- }
- },
- child: DownloadItem(
- isAutoDown: false,
- msg: widget.msg,
- child: Container(
- width: imgSize.width,
- height: imgSize.height,
- child: ClipRRect(
- child: Image(
- image: provider ?? AssetImage(R.assetsImagesIcAlbum),
- ),
- borderRadius: BorderRadius.circular(5),
- ),
- ),
- ));
- }
-
- showVideoPage(BuildContext context, String filePath) {
- widget.hideKeyboard();
- Navigator.push(context,
- MaterialPageRoute<void>(builder: (BuildContext context) {
- return VideoPage(videoPath: filePath);
- }));
- }
-
- Widget _receiveFileMsgItem() {
- return DownloadItem(
- isAutoDown: false,
- msg: widget.msg,
- onComplete: () {
- if (mounted) {
- setState(() {});
- }
- },
- child: Container(
- height: 100,
- constraints: BoxConstraints(maxWidth: Screen.width - 120),
- padding: EdgeInsets.symmetric(horizontal: 9, vertical: 10.5),
- decoration: BoxDecoration(
- color: Colors.white,
- border: Border.all(color: ReciveBorderColor, width: 0.5),
- borderRadius: BorderRadius.all(Radius.circular(ChatRadius))),
- child: FileMsgItem(widget.msg)));
- }
-
- _receiveSound(BuildContext context, List<int> soundData) {
- print('收到语音消息');
-
- MsgModel msg = widget.msg;
- var time = widget.msg.extraInfo / 1000;
- if (time > 60) {
- time = 60.0;
- }
- bool isPlaying = false;
-
- if (curSoundUrl != null) {
- isPlaying = SoundUtils().isPlaying(curSoundUrl);
- }
-
- var soundWidget = InkWell(
- onTap: () async {
- bool isLocal = true;
-
- if (msg.localFile != null) {
- isLocal = true;
- curSoundUrl = msg.localFile;
- } else {
- isLocal = false;
- var sessionId = msg.sessionId;
- curSoundUrl = UploadUtil()
- .getFullUrl(msg.extraFile, sessionId, msg.channelType);
- }
-
- print('当前文件$curSoundUrl 本地?$isLocal');
- if (isPlaying) {
- await SoundUtils().pause();
- } else {
- print('开始播放');
-
- if (widget.msg.soundListened == 0) {
- widget.msg.updateSoundListened();
- } //设置为已经播放
- await SoundUtils().play(curSoundUrl, isLocal: isLocal, onPlayed: () {
- if (mounted) {
- this.setState(() {});
- }
- }, complete: () {
- if (mounted) {
- this.setState(() {});
- }
- });
- }
- },
- child: Container(
- width: 130,
- child: Row(children: <Widget>[
- Container(
- alignment: Alignment.center,
- padding: EdgeInsets.only(bottom: 2),
- margin: EdgeInsets.only(right: 10),
- width: 25.5,
- height: 25.5,
- decoration: BoxDecoration(
- border:
- Border.all(color: const Color(0xFF1B92C7), width: 0.5),
- color: const Color(0xFF04A4FE),
- shape: BoxShape.circle),
- child: Icon(
- IconData(isPlaying ? 0xe652 : 0xe653,
- fontFamily: Constants.IconFontFamily),
- size: isPlaying ? 15 : 18,
- color: Colors.white,
- ),
- ),
- isPlaying
- ? Stack(
- children: <Widget>[
- Container(
- height: 18,
- width: 19,
- ),
- Positioned(
- bottom: 0,
- child: VideoAnim(
- begin: 18,
- start: 0.444,
- end: 4.5,
- )),
- Positioned(
- left: 7,
- bottom: 0,
- child: VideoAnim(
- begin: 4.5,
- end: 18,
- )),
- Positioned(
- left: 14,
- bottom: 0,
- child: VideoAnim(
- begin: 18,
- end: 4.5,
- ))
- ],
- )
- : Stack(
- children: <Widget>[
- Container(
- height: 18,
- width: 19,
- ),
- Positioned(
- bottom: 0, child: CustomUI.buildAudioContaniner(12)),
- Positioned(
- left: 7,
- bottom: 0,
- child: CustomUI.buildAudioContaniner(4.5)),
- Positioned(
- left: 14,
- bottom: 0,
- child: CustomUI.buildAudioContaniner(18))
- ],
- ),
- Expanded(child: SizedBox()),
- fixedText(time.toStringAsFixed(0),
- color: Constants.BlackTextColor, fontSize: 16)
- ])),
- );
-
- List<Widget> showMsg = [];
-
- showMsg.add(DownloadItem(
- msg: widget.msg,
- child: soundWidget,
- isShowProgress: false,
- ));
-
- double width = 130;
- double minWidth = 0;
- if (textList.length > 0) {
- width = _getTextWidth(textList[curTextType]) + 20;
- width = min(width, Screen.width - 120);
-
- showMsg.add(Padding(
- padding: EdgeInsets.symmetric(vertical: 5),
- child: Divider(
- height: 1,
- )));
- showMsg.add(Container(
- child: extendedText(
- textList[curTextType],
- color: Constants.BlackTextColor,
- hideKeyboard: widget.hideKeyboard,
- fontSize: FontSize,
- ),
- alignment: Alignment.centerLeft,
- constraints:
- BoxConstraints(maxWidth: Screen.width - 120, minHeight: 22),
- ));
- }
-
- if (msg.transTag != 0) {
- minWidth = 200;
- showMsg.add(Divider(color: Color(0xFFECECEC), height: 3));
- Widget tranWidget = _transProcessWidget(msg.transTag);
- showMsg.add(tranWidget);
- }
-
- return Container(
- width: width + 20,
- constraints:
- BoxConstraints(maxWidth: Screen.width - 120, minWidth: minWidth),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start, children: showMsg),
- padding: EdgeInsets.symmetric(horizontal: 9, vertical: 10.5),
- decoration: BoxDecoration(
- color: Colors.white,
- border: Border.all(color: ReciveBorderColor, width: 0.5),
- borderRadius: BorderRadius.all(Radius.circular(ChatRadius))),
- );
- }
-
- void showFullImg(BuildContext context, MsgModel msg) {
- print('显示图片');
- Navigator.push(context,
- MaterialPageRoute<void>(builder: (BuildContext context) {
- return PhotoPage(msg: msg);
- }));
- }
-
- blueDot(bool isShow) {
- return Container(
- margin: EdgeInsets.only(right: 5),
- decoration: BoxDecoration(
- shape: BoxShape.circle,
- color: isShow ? Color(0xFFFF7E00) : Color(0xFFCFCFCF),
- ),
- width: 6,
- height: 6,
- );
- }
-
- _reveiveMsg(BuildContext context) {
- Widget item;
- switch (ChatType.valueOf(widget.msg.msgType)) {
- case ChatType.TextChatType:
- item = _receiveText(widget.msg);
- break;
- case ChatType.EmoticonType:
- item = _receiveJIF(widget.msg);
- break;
-
- case ChatType.ImageChatType:
- if (widget.msg.extraFile != null) {
- item = _receiveImg(context, widget.msg.msgContent,
- downloadData: widget.msg.extraFile);
- } else {
- item = _receiveImg(context, widget.msg.msgContent);
- }
- break;
- case ChatType.ShortVideoChatType:
- item = _receiveVideo(context, widget.msg.msgContent,
- downloadData: widget.msg.extraFile);
- break;
- case ChatType.ShortVoiceChatType:
- item = _receiveSound(context, widget.msg.msgContent);
- break;
-
- case ChatType.RedWalletChatType:
- item = RedBagItem(
- Key(widget.msg.time.toString()), friendInfo.userId, widget.msg);
- break;
- case ChatType.PlaceChatType:
- item = PlaceItem(isMe: false, placeContent: widget.msg.msgContent);
- break;
- case ChatType.GiftChatType:
- item = GiftMsgItem(widget.msg.msgContent, false);
- break;
- case ChatType.FileChatType:
- item = _receiveFileMsgItem();
- break;
- default:
- }
-
- return wrapItemWithMenu(item);
- }
-
- Widget _getReceivedMessageLayout(BuildContext context) {
- bool hasHeadImg = true;
-
- if (friendInfo.headimgurl == null || friendInfo.headimgurl.length == 0) {
- hasHeadImg = false;
- }
-
- bool isShowSoundSate =
- widget.msg.msgType == ChatType.ShortVoiceChatType.value &&
- widget.msg.soundListened == 0;
-
- return Row(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
- Container(
- margin: const EdgeInsets.only(right: 8.0),
- child: InkWell(
- child: ClipRRect(
- borderRadius: BorderRadius.circular(8),
- child: hasHeadImg
- ? CachedNetworkImage(
- imageUrl: friendInfo.headimgurl,
- placeholder: (context, url) => Image.asset(
- Constants.DefaultHeadImgUrl,
- width: 40,
- height: 40,
- ),
- width: 40,
- height: 40,
- )
- : SizedBox(
- width: 40,
- height: 40,
- child: Image.asset(R.assetsImagesDefaultNorAvatar))),
- onTap: () {
- AppNavigator.pushProfileInfoPage(context, friendInfo.userId,
- fromWhere: 0);
- },
- )),
- _reveiveMsg(context),
- isShowSoundSate
- ? Container(
- margin: EdgeInsets.only(left: 8),
- width: 40,
- height: 40,
- alignment: Alignment.centerLeft,
- child: CircleAvatar(
- radius: 3.5,
- backgroundColor: Colors.red,
- ))
- : Container()
- ]);
- }
- }
|