diff --git a/assets/image/2x/icon_gz.webp b/assets/image/2x/icon_gz.webp index e2069d84..f3e96b01 100644 Binary files a/assets/image/2x/icon_gz.webp and b/assets/image/2x/icon_gz.webp differ diff --git a/assets/image/2x/icon_pl.webp b/assets/image/2x/icon_pl.webp index 6d38ebfd..6fbd81f2 100644 Binary files a/assets/image/2x/icon_pl.webp and b/assets/image/2x/icon_pl.webp differ diff --git a/assets/image/2x/icon_system_message_new.webp b/assets/image/2x/icon_system_message_new.webp new file mode 100644 index 00000000..e024425e Binary files /dev/null and b/assets/image/2x/icon_system_message_new.webp differ diff --git a/assets/image/2x/icon_z.webp b/assets/image/2x/icon_z.webp index 65835cb4..d2814065 100644 Binary files a/assets/image/2x/icon_z.webp and b/assets/image/2x/icon_z.webp differ diff --git a/assets/image/3x/icon_gz.webp b/assets/image/3x/icon_gz.webp index 00e33235..41f1ad57 100644 Binary files a/assets/image/3x/icon_gz.webp and b/assets/image/3x/icon_gz.webp differ diff --git a/assets/image/3x/icon_pl.webp b/assets/image/3x/icon_pl.webp index dc69394a..96db2bea 100644 Binary files a/assets/image/3x/icon_pl.webp and b/assets/image/3x/icon_pl.webp differ diff --git a/assets/image/3x/icon_system_message_new.webp b/assets/image/3x/icon_system_message_new.webp new file mode 100644 index 00000000..96ab6a45 Binary files /dev/null and b/assets/image/3x/icon_system_message_new.webp differ diff --git a/assets/image/3x/icon_z.webp b/assets/image/3x/icon_z.webp index 953f1d79..ab5f6f2e 100644 Binary files a/assets/image/3x/icon_z.webp and b/assets/image/3x/icon_z.webp differ diff --git a/assets/image/icon_gz.webp b/assets/image/icon_gz.webp index fbef117c..c0a5ba1b 100644 Binary files a/assets/image/icon_gz.webp and b/assets/image/icon_gz.webp differ diff --git a/assets/image/icon_pl.webp b/assets/image/icon_pl.webp index ad0dde95..c983a728 100644 Binary files a/assets/image/icon_pl.webp and b/assets/image/icon_pl.webp differ diff --git a/assets/image/icon_system_message_new.webp b/assets/image/icon_system_message_new.webp new file mode 100644 index 00000000..f22dd263 Binary files /dev/null and b/assets/image/icon_system_message_new.webp differ diff --git a/assets/image/icon_z.webp b/assets/image/icon_z.webp index 2433add2..6e94b88d 100644 Binary files a/assets/image/icon_z.webp and b/assets/image/icon_z.webp differ diff --git a/lib/im/im_view/im_page.dart b/lib/im/im_view/im_page.dart index f775ae7c..53b2611e 100644 --- a/lib/im/im_view/im_page.dart +++ b/lib/im/im_view/im_page.dart @@ -1,10 +1,11 @@ import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_slidable/flutter_slidable.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:huixiang/constant.dart'; import 'package:huixiang/generated/l10n.dart'; import 'package:huixiang/im/database/message.dart'; +import 'package:huixiang/retrofit/data/msg_stats.dart'; import 'package:huixiang/main.dart'; import 'package:huixiang/retrofit/data/base_data.dart'; import 'package:huixiang/retrofit/retrofit_api.dart'; @@ -16,6 +17,7 @@ import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import '../../retrofit/data/im_user.dart'; +import '../../retrofit/data/page.dart'; import '../../utils/flutter_utils.dart'; import '../../view_widget/custom_image.dart'; import 'on_chat_message.dart'; @@ -49,6 +51,7 @@ class _IMPage extends State implements OnChatMessage { Map contactMap = {}; int insertIndex = 0; String selfUserId; + final RefreshController _refreshController = RefreshController(); @override void onMessage(txt) { @@ -72,7 +75,7 @@ class _IMPage extends State implements OnChatMessage { SharedPreferences.getInstance().then((value) { apiService = ApiService(Dio(), token: value.getString("token"), context: context); - // queryMsgStats(); + queryMsgStats(); }); } @@ -96,7 +99,7 @@ class _IMPage extends State implements OnChatMessage { _refresh() { pageNum = 1; loadMessageList(); - // queryMsgStats(); + queryMsgStats(); } listenerRefresh(Message message) async { @@ -218,7 +221,34 @@ class _IMPage extends State implements OnChatMessage { } } - final RefreshController _refreshController = RefreshController(); + ///App消息 统计各类消息数量 + queryMsgStats() async { + if (apiService == null) { + SharedPreferences value = await SharedPreferences.getInstance(); + apiService = ApiService( + Dio(), + context: context, + token: value.getString("token"), + ); + } + BaseData> baseData = + await apiService.stats().catchError((onError) {}); + if (baseData != null && baseData.isSuccess) { + setState(() { + msgNumber.forEach((key, value) { + msgNumber[key] = 0; + }); + baseData.data.forEach((element) { + if (msgNumber.containsKey(element.name)) { + msgNumber[element.name] = element.number; + } + }); + }); + _refreshController.loadComplete(); + _refreshController.refreshCompleted(); + } + EasyLoading.dismiss(); + } @override Widget build(BuildContext context) { @@ -305,7 +335,56 @@ class _IMPage extends State implements OnChatMessage { ), ), imPageSearch(), + GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: (){ + Navigator.of(context).pushNamed('/router/system_notice').then((value) { + setState(() { + msgNumber["2"] = 0; + msgNumber["3"] = 0; + }); + }); + }, + child:messageItem("assets/image/icon_system_message_new.webp", S.of(context).xitongxiaoxi, (msgNumber["2"]+msgNumber["3"]).toString()), + ), + GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: (){ + Navigator.of(context).pushNamed('/router/system_details', + arguments: {"msgType": 4}).then((value) { + setState(() { + msgNumber["4"] = 0; + }); + }); + }, + child:messageItem("assets/image/icon_gz.webp", S.of(context).guanzhu,msgNumber["4"].toString()), + ), + GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: (){ + Navigator.of(context).pushNamed('/router/system_details', + arguments: {"msgType": 6}).then((value) { + setState(() { + msgNumber["6"] = 0; + }); + }); + }, + child:messageItem("assets/image/icon_pl.webp", S.of(context).pinglun, msgNumber["6"].toString()), + ), + GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: (){ + Navigator.of(context).pushNamed('/router/system_details', + arguments: {"msgType": 5}).then((value) { + setState(() { + msgNumber["5"] = 0; + }); + }); + }, + child: messageItem("assets/image/icon_z.webp", S.of(context).dianzan, msgNumber["5"].toString()), + ), chatList(), + SizedBox(height:100.h) ], ), ), @@ -324,7 +403,7 @@ class _IMPage extends State implements OnChatMessage { }); }, child: Container( - margin: EdgeInsets.fromLTRB(16.w, 0, 16.w, 0), + margin: EdgeInsets.fromLTRB(16.w, 0, 16.w, 16.h), padding: EdgeInsets.symmetric(vertical: 13.h), decoration: BoxDecoration( color: Color(0xFFFDFCFC), @@ -355,67 +434,116 @@ class _IMPage extends State implements OnChatMessage { ); } + bool _isDelEnter = false; + Map idsController = {}; + String lastScrollId; + double lastScrollOffset = 0; + bool _isScrollOpen = false; + ///聊天列表 Widget chatList() { - return Container( - child: SlidableAutoCloseBehavior( - child: ListView( - padding: EdgeInsets.only(top: 16), - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - children: conversationIds.map((e) { - int position = conversationIds.indexOf(e); - return ClipRRect( - // borderRadius: BorderRadius.all(Radius.circular(4)), - child: Slidable( - groupTag: true, - endActionPane: ActionPane( - extentRatio:0.16, - motion: ScrollMotion(), - children: [ - CustomSlidableAction( - onPressed: (bc) { - showDelDialog(conversationIds[position]); - }, - backgroundColor: Color(0xFFFB312B), - foregroundColor: Colors.white, - child: Container( - color: Colors.red, - height: double.infinity, - alignment: Alignment.center, - child: Text( - S.of(context).shanchu, - style: TextStyle( - color: Colors.white, - fontSize: 14.sp, - fontWeight: MyFontWeight.regular, - ), - ), - ), + return ListView( + padding: EdgeInsets.only(top:8.h), + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + children: conversationIds.map((e) { + ScrollController scrollController; + if (idsController.containsKey(e)) + scrollController = idsController[e]; + else { + scrollController = ScrollController(); + idsController[e] = scrollController; + } + scrollController.addListener(() { + if (scrollController.offset > 0) { + if (lastScrollId != null && lastScrollId != e) + idsController[lastScrollId].jumpTo(0); + if(lastScrollOffset < scrollController.offset){ + scrollController.jumpTo(scrollController.position.maxScrollExtent); + _isScrollOpen = true; + }else if(lastScrollOffset > scrollController.offset && _isScrollOpen){ + scrollController.jumpTo(0); + } + lastScrollId = e; + // scrollController.animateTo( + // lastScrollOffset == scrollController.position.maxScrollExtent + // ? 0 + // : scrollController.position.maxScrollExtent, + // duration: Duration(milliseconds: 100), + // curve: Curves.ease); + lastScrollOffset = scrollController.offset; + } else { + if (lastScrollId == e) { + setState(() { + _isDelEnter = false; + _isScrollOpen = false; + }); + } + } + }); + int position = conversationIds.indexOf(e); + return SingleChildScrollView( + physics: ClampingScrollPhysics(), + controller: scrollController, + scrollDirection: Axis.horizontal, + child: Row( + children: [ + GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () { + Navigator.of(context).pushNamed( + '/router/chat_details_page', + arguments: { + "toUser": contactMap[conversationIds[position]], + }, + ).then((value) { + unreadCountMap[conversationIds[position]] = 0; + updateLastMessage(conversationIds[position]); + _refresh(); + }); + }, + child: chatItem(conversationIds[position]), + ), + GestureDetector( + child: Container( + color: Colors.red, + alignment: Alignment.center, + padding: + EdgeInsets.symmetric(vertical: 25.h, horizontal: 14.w), + child: Text( + _isDelEnter && lastScrollId == e + ? "删除并清空" + : S.of(context).shanchu, + style: TextStyle( + color: Colors.white, + fontSize: 14.sp, + fontWeight: MyFontWeight.regular, ), - ], + ), ), - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.of(context).pushNamed( - '/router/chat_details_page', - arguments: { - "toUser": contactMap[conversationIds[position]], - }, - ).then((value) { - unreadCountMap[conversationIds[position]] = 0; - updateLastMessage(conversationIds[position]); - _refresh(); + onTap: () async{ + // showDelDialog(conversationIds[position]); + if (_isDelEnter) { + await hxDatabase.deleteByUser(conversationIds[position]); + lastScrollId = null; + _refresh(); + } else { + Future.delayed(Duration(milliseconds: 100), () { + idsController[lastScrollId].animateTo( + idsController[lastScrollId].position.maxScrollExtent, + duration: Duration(milliseconds: 100), + curve: Curves.ease); }); - }, - child: chatItem(conversationIds[position]), - ), + } + setState(() { + _isDelEnter = !_isDelEnter; + }); + }, ), - ); - }).toList(), - ), - ), + ], + ), + ); + }).toList(), ); } @@ -424,6 +552,7 @@ class _IMPage extends State implements OnChatMessage { padding: EdgeInsets.only( left: 16.w, right: 17.w, bottom: 18.h, ), + width: MediaQuery.of(context).size.width, child: Row( children: [ MImage( @@ -518,6 +647,66 @@ class _IMPage extends State implements OnChatMessage { ); } + Widget messageItem(img, title, messageNum) { + return Container( + padding: EdgeInsets.only(top:8.h,bottom:8.h, left:16.w,right:15.w), + child: Column( + children: [ + Row( + children: [ + Image.asset( + img, + fit: BoxFit.fill, + ), + SizedBox( + width: 12.w, + ), + Text( + title, + style: TextStyle( + fontSize: 14.sp, + color: Color(0xFF060606), + fontWeight: MyFontWeight.semi_bold, + ), + ), + Spacer(), + if(messageNum != "0") + ((double.tryParse(messageNum) < 100)? + Container( + width: 16, + height: 16, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(100), + color: Color(0xFFFF441A), + ), + child: RoundButton( + text:messageNum, + textColor: Colors.white, + fontWeight: MyFontWeight.regular, + backgroup: Color(0xFFFF441A), + fontSize: 10.sp, + radius: 100, + )): + Container( + padding: EdgeInsets.symmetric(horizontal:4.w,vertical:2.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(100), + color: Color(0xFFFF441A), + ), + child: RoundButton( + text:"99+", + textColor: Colors.white, + fontWeight: MyFontWeight.regular, + backgroup: Color(0xFFFF441A), + fontSize: 10.sp, + radius: 100, + ))), + ], + ), + ], + ), + ); + } ///确认删除弹窗 showDelDialog(conversationId) { diff --git a/lib/message/system_message.dart b/lib/message/system_message.dart index 63fd82fe..de0990ac 100644 --- a/lib/message/system_message.dart +++ b/lib/message/system_message.dart @@ -287,7 +287,7 @@ class _SystemMessagePage extends State{ }); }); }, - child:messageItem("assets/image/icon_system_message.webp", S.of(context).xitongxiaoxi, (msgNumber["2"]+msgNumber["3"]).toString()), + child:messageItem("assets/image/icon_system_message_new.webp", S.of(context).xitongxiaoxi, (msgNumber["2"]+msgNumber["3"]).toString()), ), // newsSurvey(), // SizedBox(