1.被艾特后,要有推送提醒,并且右上角可以点击到@位置 2. 内容窗口右上角增加状态显示 3. 点击文字内容区域视点击为“机器重译”。 4. 进入聊天对话框后,右上角显示未读消息条数。点击跳转到最开始那条未读消息master
@@ -56,9 +56,9 @@ android { | |||
// manifestPlaceholders = [ | |||
// AMAP_KEY : "1fd4e93e3b4b13747da41f484c955fe2", /// 高德地图key | |||
// ] | |||
// ndk { | |||
// abiFilters 'armeabi-v7a' | |||
// } | |||
// ndk { | |||
// abiFilters 'armeabi-v7a' | |||
// } | |||
multiDexEnabled true | |||
manifestPlaceholders = [ | |||
JPUSH_PKGNAME : 'com.cyhd.henhoandroid', | |||
@@ -1,11 +1,10 @@ | |||
#!/bin/sh | |||
# This is a generated file; do not edit or check into version control. | |||
export "FLUTTER_ROOT=/Users/random/sdk/flutter_sdk" | |||
export "FLUTTER_APPLICATION_PATH=/Users/random/code/flutter/project/hibok" | |||
export "FLUTTER_TARGET=/Users/random/code/flutter/project/hibok/lib/main.dart" | |||
export "FLUTTER_ROOT=D:\flutter" | |||
export "FLUTTER_APPLICATION_PATH=E:\flutterCode\Hibok" | |||
export "FLUTTER_TARGET=lib\main.dart" | |||
export "FLUTTER_BUILD_DIR=build" | |||
export "SYMROOT=${SOURCE_ROOT}/../build/ios" | |||
export "FLUTTER_FRAMEWORK_DIR=/Users/random/sdk/flutter_sdk/bin/cache/artifacts/engine/ios" | |||
export "SYMROOT=${SOURCE_ROOT}/../build\ios" | |||
export "FLUTTER_FRAMEWORK_DIR=D:\flutter\bin\cache\artifacts\engine\ios" | |||
export "FLUTTER_BUILD_NAME=1.0.9" | |||
export "FLUTTER_BUILD_NUMBER=13" | |||
export "TRACK_WIDGET_CREATION=true" |
@@ -257,8 +257,6 @@ class _ChatPageItemState extends State<ChatPageItem> | |||
} else { | |||
///todo 翻译管家系统通知消息 | |||
if (type == ChatType.GroupChatNoticeType.value) { | |||
var res = GroupChatNotice.fromBuffer(widget.msg.msgContent); | |||
@@ -294,9 +292,9 @@ class _ChatPageItemState extends State<ChatPageItem> | |||
_textMsg(List<int> msgContent) { | |||
var msg = utf8.decode(msgContent); | |||
bool isUrl =false; | |||
if(textList[curTextType].contains('http') ){ | |||
isUrl =true; | |||
bool isUrl = false; | |||
if (textList[curTextType].contains('http')) { | |||
isUrl = true; | |||
} | |||
Widget text = Container( | |||
constraints: BoxConstraints(maxWidth: Screen.width - 120), | |||
@@ -304,7 +302,7 @@ class _ChatPageItemState extends State<ChatPageItem> | |||
msg, | |||
hideKeyboard: widget.hideKeyboard, | |||
fontSize: FontSize, | |||
color: isUrl?Colors.blue:Colors.black, | |||
color: isUrl ? Colors.blue : Colors.black, | |||
), | |||
padding: EdgeInsets.symmetric(horizontal: 9, vertical: 10.5), | |||
decoration: BoxDecoration( | |||
@@ -484,7 +482,9 @@ class _ChatPageItemState extends State<ChatPageItem> | |||
_imgMsg(List<int> imgData) { | |||
var imgSize = _getImgSize(); | |||
ImageProvider provider = MemoryImage(widget.msg.localFile==null?Uint8List.fromList(imgData):File(widget.msg.localFile).readAsBytesSync()); | |||
ImageProvider provider = MemoryImage(widget.msg.localFile == null | |||
? Uint8List.fromList(imgData) | |||
: File(widget.msg.localFile).readAsBytesSync()); | |||
return GestureDetector( | |||
child: ClipRRect( | |||
@@ -631,7 +631,6 @@ class _ChatPageItemState extends State<ChatPageItem> | |||
List<String> actions = [ | |||
I18n.of(context).delete, | |||
I18n.of(context).reply, | |||
]; | |||
actionsFunc.add(() { | |||
@@ -642,53 +641,48 @@ class _ChatPageItemState extends State<ChatPageItem> | |||
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); | |||
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){ | |||
if (widget.msg.msgType == ChatType.FileChatType.value && | |||
widget.msg.localFile == null) { | |||
showToast('请先下载文件'); | |||
return ; | |||
return; | |||
} | |||
AppNavigator.pushForwardPage(context, widget.msg); | |||
}); | |||
} | |||
if (widget.msg.msgType == ChatType.FileChatType.value &&widget.msg.localFile!=null) { | |||
if (widget.msg.msgType == ChatType.FileChatType.value && | |||
widget.msg.localFile != null) { | |||
//分享文件 | |||
actions.add(I18n.of(context).copy_download_url); | |||
actionsFunc.add(() async{ | |||
actionsFunc.add(() async { | |||
UploadUtil().copyFileUrl(widget.msg, context); | |||
String path = widget.msg.localFile; | |||
String type='file'; | |||
if(path.contains('mp4') ||path.contains('mp3')){ | |||
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')){ | |||
} 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) { | |||
@@ -716,18 +710,17 @@ class _ChatPageItemState extends State<ChatPageItem> | |||
}); | |||
} | |||
// 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; | |||
bool isUrl = false; | |||
if (widget.msg.msgType == ChatType.TextChatType.value) { | |||
if (textList[curTextType].contains('http')) { | |||
isUrl = true; | |||
} | |||
} | |||
return WPopupMenu( | |||
return WPopupMenu( | |||
child: item, | |||
actions: actions, | |||
onTap: ()async{ | |||
if(isUrl){ | |||
onTap: () async { | |||
if (isUrl) { | |||
if (await canLaunch(textList[curTextType])) { | |||
launch(textList[curTextType]); | |||
} | |||
@@ -794,22 +787,34 @@ class _ChatPageItemState extends State<ChatPageItem> | |||
_receiveText(MsgModel msg) { | |||
List<Widget> showMsg = []; | |||
if (textList.length > 0) { | |||
bool isUrl =false; | |||
if(textList[curTextType].contains('http') ){ | |||
isUrl =true; | |||
bool isUrl = false; | |||
if (textList[curTextType].contains('http')) { | |||
isUrl = true; | |||
} | |||
showMsg.add(Container( | |||
constraints: | |||
BoxConstraints(maxWidth: Screen.width - 140, minHeight: 24), | |||
alignment: Alignment.centerLeft, | |||
child: extendedText( | |||
textList[curTextType], | |||
color: isUrl?Colors.blue:Constants.BlackTextColor, | |||
hideKeyboard: widget.hideKeyboard, | |||
fontSize: FontSize, | |||
))); | |||
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]); | |||
@@ -825,18 +830,32 @@ class _ChatPageItemState extends State<ChatPageItem> | |||
} | |||
///todo | |||
Widget text = 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))), | |||
); | |||
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); | |||
@@ -903,14 +922,17 @@ class _ChatPageItemState extends State<ChatPageItem> | |||
if (transTag == 1) { | |||
//机器翻译中 | |||
userTranslateWidget = _translateItemWidget(0xe670, I18n.of(context).man_retranslate, null); | |||
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, () { | |||
userTranslateWidget = | |||
_translateItemWidget(0xe670, I18n.of(context).ManTranslate, null); | |||
machineTranslateWidget = | |||
_translateItemWidget(0xe671, I18n.of(context).robot_retranslate, () { | |||
setState(() { | |||
curTextType += 1; | |||
curTextType %= textList.length; | |||
@@ -962,7 +984,8 @@ class _ChatPageItemState extends State<ChatPageItem> | |||
}); | |||
} | |||
}); | |||
machineTranslateWidget = _translateItemWidget(0xe671, I18n.of(context).robot_retranslate, () { | |||
machineTranslateWidget = | |||
_translateItemWidget(0xe671, I18n.of(context).robot_retranslate, () { | |||
setState(() { | |||
curTextType += 1; | |||
curTextType %= textList.length; | |||
@@ -1017,7 +1040,8 @@ class _ChatPageItemState extends State<ChatPageItem> | |||
)) | |||
], | |||
))); | |||
machineTranslateWidget = _translateItemWidget(0xe675, I18n.of(context).see_original, () { | |||
machineTranslateWidget = | |||
_translateItemWidget(0xe675, I18n.of(context).see_original, () { | |||
setState(() { | |||
curTextType = textList.length - 1; | |||
}); | |||
@@ -1039,15 +1063,16 @@ class _ChatPageItemState extends State<ChatPageItem> | |||
} | |||
_receiveImg(BuildContext context, List<int> imgData, {String downloadData}) { | |||
ImageProvider provider = MemoryImage(widget.msg.localFile==null?Uint8List.fromList(imgData):File(widget.msg.localFile).readAsBytesSync()); | |||
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: (){ | |||
onFinishTap: () { | |||
widget.hideKeyboard(); | |||
showFullImg(context, widget.msg); | |||
}, | |||
@@ -1062,7 +1087,6 @@ class _ChatPageItemState extends State<ChatPageItem> | |||
), | |||
), | |||
); | |||
} | |||
_receiveVideo(BuildContext context, List<int> imgData, | |||
@@ -1303,6 +1327,18 @@ class _ChatPageItemState extends State<ChatPageItem> | |||
})); | |||
} | |||
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)) { | |||
@@ -790,16 +790,29 @@ class _GroupChatPageItemState extends State<GroupChatPageItem> | |||
isUrl = true; | |||
} | |||
showMsg.add(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, | |||
))); | |||
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]); | |||
@@ -827,18 +840,18 @@ class _GroupChatPageItemState extends State<GroupChatPageItem> | |||
color: isLongPressed ? Colors.grey[300] : Colors.white, | |||
borderRadius: BorderRadius.all(Radius.circular(ChatRadius))), | |||
), | |||
// msg.transTag != 0 | |||
// ? Positioned( | |||
// right: 5, | |||
// top: 5, | |||
// child: Container( | |||
// child: Row(children: <Widget>[ | |||
// blueDot(true), | |||
// blueDot(true), | |||
// blueDot(true), | |||
// blueDot(true), | |||
// ]))) | |||
// : Container() | |||
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) { | |||
@@ -47,8 +47,6 @@ class GroupChatPage extends StatefulWidget { | |||
} | |||
class _GroupChatPageState extends State<GroupChatPage> { | |||
ScrollController _scrollCtrl = ScrollController(); | |||
final ItemScrollController itemScrollController = ItemScrollController(); | |||
final ItemPositionsListener itemPositionListener = | |||
ItemPositionsListener.create(); | |||
@@ -67,6 +65,16 @@ class _GroupChatPageState extends State<GroupChatPage> { | |||
//子元素的对应偏移量 | |||
Map itemOffsetMap = {}; | |||
//未读消息数目 | |||
int unreadNums = 0; | |||
//最上一条未读消息id | |||
int unreadTime; | |||
//@消息索引 | |||
int alterTime; | |||
String alterUserName = ''; | |||
@override | |||
void dispose() { | |||
var endTime = DateTime.now().millisecondsSinceEpoch ~/ 1000; | |||
@@ -78,7 +86,6 @@ class _GroupChatPageState extends State<GroupChatPage> { | |||
msgMgr.off('Delete Select Message', _deleteItem); | |||
MsgHandler.curActiveSession = 0; | |||
SoundUtils().stop(); | |||
_scrollCtrl.dispose(); | |||
super.dispose(); | |||
} | |||
@@ -91,14 +98,28 @@ class _GroupChatPageState extends State<GroupChatPage> { | |||
getDefaultSetting(); | |||
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(); | |||
for (int k = 0; k < msgList.length; k++) { | |||
MsgModel msg = msgList[k]; | |||
print('msgList ${msg.msgType} ${msg.from}'); | |||
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); | |||
@@ -117,6 +138,7 @@ class _GroupChatPageState extends State<GroupChatPage> { | |||
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')) { | |||
@@ -133,12 +155,6 @@ class _GroupChatPageState extends State<GroupChatPage> { | |||
sendMsg(msg); | |||
} | |||
}); | |||
itemPositionListener.itemPositions.addListener(() { | |||
print(itemPositionListener.itemPositions.value); | |||
//itemScrollController.jumpTo(index: 1, alignment: -0.02208835341365462); | |||
//-0.02208835341365462, itemTrailingEdge: 0.12650602409638553 | |||
}); | |||
} | |||
void _sendFile(File file) async { | |||
@@ -237,6 +253,9 @@ class _GroupChatPageState extends State<GroupChatPage> { | |||
Map refMap = Provider.of<RefNameProvider>(context).refMap; | |||
bool isHaveUnreadNews = unreadTime !=null; | |||
bool isAlterYou = alterTime != null; | |||
return MultiProvider( | |||
providers: [ | |||
ChangeNotifierProvider(create: (_) => _keyboardIndexProvider), | |||
@@ -276,27 +295,77 @@ class _GroupChatPageState extends State<GroupChatPage> { | |||
InputBar(sendMsg: sendMsg), | |||
], | |||
), | |||
// Positioned( | |||
// top: 32.5, | |||
// right: 0, | |||
// child: Container( | |||
// decoration: BoxDecoration( | |||
// boxShadow: [ | |||
// BoxShadow( | |||
// color: Color(0x33000000), //阴影颜色 | |||
// blurRadius: 10.0, //阴影大小 | |||
// ) | |||
// ], | |||
// borderRadius: BorderRadius.only( | |||
// topLeft: Radius.circular(80), | |||
// bottomLeft: Radius.circular(80)), | |||
// color: Colors.white, | |||
// ), | |||
// width: 120, | |||
// height: 39)) | |||
isHaveUnreadNews | |||
? Positioned( | |||
top: 32.5, | |||
right: 0, | |||
child: InkWell( | |||
onTap: () { | |||
var screenItemNums = | |||
itemPositionListener | |||
.itemPositions.value.length; | |||
int jumIndex = 0; | |||
if (isAlterYou) { | |||
for (int i = 0; | |||
i < msgList.length; | |||
i++) { | |||
if (alterTime == msgList[i].time) { | |||
jumIndex = i - screenItemNums + 2; | |||
break; | |||
} | |||
} | |||
} else { | |||
for (int i = 0; | |||
i < msgList.length; | |||
i++) { | |||
if (unreadTime == msgList[i].time) { | |||
jumIndex = i - screenItemNums + 2; | |||
break; | |||
} | |||
} | |||
} | |||
itemScrollController.jumpTo( | |||
index: jumIndex); | |||
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.file_upload, | |||
color: Color(0xFF3875E9), | |||
size: 20, | |||
), | |||
Text( | |||
isAlterYou | |||
? '$alterUserName @你' | |||
: '$unreadNums条新消息', | |||
style: TextStyle( | |||
color: Color(0xFF3875E9)), | |||
) | |||
], | |||
), | |||
))) | |||
: Container() | |||
], | |||
))), | |||
behavior: HitTestBehavior.translucent, | |||
onPointerDown: (value) { | |||
for (var state in states) { | |||
if (!state.containsPosition(value.position)) { | |||
@@ -418,25 +487,15 @@ class _GroupChatPageState extends State<GroupChatPage> { | |||
style: TextStyle(color: Colors.grey), | |||
)) | |||
: Scrollbar( | |||
child: | |||
// ScrollablePositionedList.builder( | |||
// itemCount: msgList.length, | |||
// itemBuilder: _buildItem, | |||
// itemScrollController: itemScrollController, | |||
// itemPositionsListener: itemPositionListener, | |||
// padding: EdgeInsets.all(8.0), | |||
// reverse: true, | |||
// ) | |||
ListView.builder( | |||
reverse: true, | |||
shrinkWrap: true, | |||
itemCount: msgList.length, | |||
controller: _scrollCtrl, | |||
padding: EdgeInsets.all(8.0), | |||
itemBuilder: _buildItem, | |||
) | |||
), | |||
child: ScrollablePositionedList.builder( | |||
physics: new ClampingScrollPhysics(), | |||
itemCount: msgList.length, | |||
itemBuilder: _buildItem, | |||
itemScrollController: itemScrollController, | |||
itemPositionsListener: itemPositionListener, | |||
padding: EdgeInsets.all(8.0), | |||
reverse: true, | |||
)), | |||
); | |||
} | |||
@@ -460,13 +519,7 @@ class _GroupChatPageState extends State<GroupChatPage> { | |||
if (mounted) { | |||
setState(() {}); | |||
} | |||
if (_scrollCtrl.hasClients) { | |||
_scrollCtrl.animateTo(0, | |||
duration: new Duration(milliseconds: 500), curve: Curves.ease); | |||
} | |||
// testBig(msg); | |||
itemScrollController.jumpTo(index: 0); | |||
} | |||
MsgModel msg; | |||
@@ -487,17 +540,12 @@ class _GroupChatPageState extends State<GroupChatPage> { | |||
} | |||
void receiveMsg(args) { | |||
print("msgList.length: ${msgList.length}"); | |||
if (args != widget.groupInfoModel.sessionId) { | |||
return; | |||
} | |||
if (mounted) { | |||
setState(() { | |||
//itemScrollController.jumpTo(index: 3); | |||
if (_scrollCtrl.hasClients) { | |||
// _scrollCtrl.animateTo(0, | |||
// duration: new Duration(milliseconds: 500), curve: Curves.ease); | |||
} | |||
}); | |||
setState(() {}); | |||
} | |||
} | |||
@@ -513,7 +561,7 @@ class _GroupChatPageState extends State<GroupChatPage> { | |||
var lastMsgTime; | |||
if (index < msgList.length - 1) { | |||
lastMsgTime = msgList[index + 1].time; | |||
lastMsgTime = msgList[index].time; | |||
} | |||
MsgModel msg = msgList[index]; | |||
@@ -313,7 +313,7 @@ class ChatDataMgr { | |||
print('数据为空,无法插入'); | |||
} else { | |||
record.insert(0, msg); | |||
//record.add(msg); | |||
SqlUtil.insert(msg); | |||
updateLastRecordWithMsg(msg); | |||
@@ -149,8 +149,8 @@ class _GroupItemState extends State<GroupItem> { | |||
//有人@你就优先展示 | |||
ChatDataMgr() | |||
.groupUnreadProvider | |||
.getHavaAlterme(widget | |||
.groupInfoModel.lastMsg.sessionId) | |||
.getHavaAltertime(widget | |||
.groupInfoModel.lastMsg.sessionId) != null | |||
? Text( | |||
'[有人@我]', | |||
textScaleFactor: 1.0, | |||
@@ -5,7 +5,7 @@ class UnreadCountProvider { | |||
Map<int, int> unreadCountMap = {}; | |||
//是否有@我的消息 | |||
Map<int, bool> isHaveAlterme = {}; | |||
Map<int, int> isHaveAlterme = {}; | |||
updateUnreadCount(int sessionId, int count) { | |||
if (unreadCountMap[sessionId] == null) { | |||
@@ -16,12 +16,12 @@ class UnreadCountProvider { | |||
MessageMgr().emit('Update UnreadCount', sessionId); | |||
} | |||
getHavaAlterme(int sessionId) { | |||
return isHaveAlterme[sessionId] ?? false; | |||
getHavaAltertime(int sessionId) { | |||
return isHaveAlterme[sessionId] ?? null; | |||
} | |||
setAlterMe(int sessionId){ | |||
isHaveAlterme[sessionId] = true; | |||
setAlterMe(int sessionId, int time) { | |||
isHaveAlterme[sessionId] = time; | |||
} | |||
clear() { | |||
@@ -45,7 +45,7 @@ class UnreadCountProvider { | |||
print('消除未读标记:$sessionId'); | |||
int count = getUnreadCount(sessionId); | |||
isHaveAlterme[sessionId] = false; | |||
isHaveAlterme[sessionId] = null; | |||
if (count > 0) { | |||
unreadCountMap[sessionId] = 0; | |||
@@ -509,9 +509,9 @@ class MsgHandler { | |||
var myId = UserData().basicInfo.userId; | |||
for (var i = 0; i < msgModel.altUsers.length; i++) { | |||
if (msgModel.altUsers[i] == myId) { | |||
if (msgModel.altUsers[i] == myId && curActiveSession != sessionId) { | |||
print('有人@了你'); | |||
ChatDataMgr().groupUnreadProvider.setAlterMe(sessionId); | |||
ChatDataMgr().groupUnreadProvider.setAlterMe(sessionId,msgModel.time); | |||
//to do | |||
} | |||
} | |||