diff --git a/mobile-next/lib/pages/conversation/conversation_view.dart b/mobile-next/lib/pages/conversation/conversation_view.dart index 7fb4fd6..59507c2 100644 --- a/mobile-next/lib/pages/conversation/conversation_view.dart +++ b/mobile-next/lib/pages/conversation/conversation_view.dart @@ -1,10 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_openim_sdk/flutter_openim_sdk.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:flutter_slidable/flutter_slidable.dart'; import 'package:get/get.dart'; import 'package:openim_common/openim_common.dart'; -import 'package:rotated_corner_decoration/rotated_corner_decoration.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; import 'package:sprintf/sprintf.dart'; @@ -21,51 +19,75 @@ class ConversationPage extends StatelessWidget { Widget build(BuildContext context) { return Obx(() => Scaffold( backgroundColor: AppColors.pageBg, - appBar: TitleBar.conversation( - statusStr: logic.imSdkStatus, - isFailed: logic.isFailedSdkStatus, - popCtrl: logic.popCtrl, - onScan: logic.scan, - onAddFriend: logic.addFriend, - onAddGroup: logic.addGroup, - onCreateGroup: logic.createGroup, - left: Expanded( - flex: 2, - child: Align( - alignment: Alignment.centerLeft, - child: const Text( - '消息', - style: TextStyle( - fontSize: AppFont.title, - fontWeight: FontWeight.w700, - color: AppColors.textPrimary, - ), + appBar: TitleBar( + height: 56, + backgroundColor: AppColors.pageBg, + left: const Expanded( + child: Align( + alignment: Alignment.centerLeft, + child: Text( + '消息', + style: TextStyle( + fontSize: AppFont.title, + fontWeight: FontWeight.w700, + color: AppColors.textPrimary, ), ), - )), + ), + ), + right: PopButton( + popCtrl: logic.popCtrl, + bgRadius: AppRadius.modal, + menus: [ + PopMenuInfo( + text: '发起群聊', + iconWidget: const Icon(Icons.group_outlined, + size: AppIconSize.sm, color: AppColors.textPrimary), + onTap: logic.createGroup, + ), + PopMenuInfo( + text: '添加同事', + iconWidget: const Icon(Icons.person_add_alt, + size: AppIconSize.sm, color: AppColors.textPrimary), + onTap: logic.addFriend, + ), + ], + child: const Padding( + padding: EdgeInsets.all(AppGap.x1), + child: Icon(Icons.add, + size: AppIconSize.md, color: AppColors.textPrimary), + ), + ), + ), body: Column( children: [ Padding( padding: const EdgeInsets.fromLTRB( AppGap.x4, 0, AppGap.x4, AppGap.x2), - child: Container( - height: 36, - decoration: BoxDecoration( - color: AppColors.searchBg, - borderRadius: BorderRadius.circular(AppRadius.control), - ), - padding: const EdgeInsets.symmetric(horizontal: AppGap.x3), - alignment: Alignment.centerLeft, - child: const Row( - children: [ - Icon(Icons.search, - size: AppIconSize.sm, color: AppColors.textSecondary), - SizedBox(width: AppGap.x2), - Text('搜索', - style: TextStyle( - fontSize: AppFont.sub, - color: AppColors.textSecondary)), - ], + child: GestureDetector( + onTap: logic.globalSearch, + behavior: HitTestBehavior.opaque, + child: Container( + height: 36, + decoration: BoxDecoration( + color: AppColors.searchBg, + borderRadius: BorderRadius.circular(AppRadius.control), + ), + padding: + const EdgeInsets.symmetric(horizontal: AppGap.x3), + alignment: Alignment.centerLeft, + child: const Row( + children: [ + Icon(Icons.search, + size: AppIconSize.sm, + color: AppColors.textSecondary), + SizedBox(width: AppGap.x2), + Text('搜索', + style: TextStyle( + fontSize: AppFont.sub, + color: AppColors.textSecondary)), + ], + ), ), ), ), @@ -89,155 +111,162 @@ class ConversationPage extends StatelessWidget { subtitle: '去通讯录找个同事聊聊吧', ); } - return SlidableAutoCloseBehavior( - child: ScrollablePositionedList.builder( - itemScrollController: logic.itemScrollController, - itemBuilder: (_, index) => _buildConversationItemView( - logic.list.elementAt(index), - ), - itemCount: logic.list.length, - itemPositionsListener: logic.itemPositionsListener, - ), + return ScrollablePositionedList.builder( + itemScrollController: logic.itemScrollController, + itemBuilder: (_, index) => + _buildItemView(logic.list.elementAt(index)), + itemCount: logic.list.length, + itemPositionsListener: logic.itemPositionsListener, ); } - Widget _buildConversationItemView(ConversationInfo info) => Slidable( - endActionPane: ActionPane( - motion: const ScrollMotion(), - extentRatio: logic.existUnreadMsg(info) - ? 0.7 - : (logic.isPinned(info) ? 0.5 : 0.4), - children: [ - CustomSlidableAction( - onPressed: (_) => logic.pinConversation(info), - flex: logic.isPinned(info) ? 3 : 2, - backgroundColor: Styles.c_0089FF, - padding: const EdgeInsets.all(1), - child: - (logic.isPinned(info) ? StrRes.cancelTop : StrRes.top).toText - ..style = Styles.ts_FFFFFF_14sp, + void _showConversationMenu(BuildContext context, ConversationInfo info) { + showModalBottomSheet( + context: context, + backgroundColor: Colors.transparent, + builder: (ctx) { + return Padding( + padding: const EdgeInsets.fromLTRB(AppGap.x4, 0, AppGap.x4, AppGap.x6), + child: Material( + color: AppColors.pageBg, + elevation: 0, + shadowColor: Colors.transparent, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(AppRadius.modal), ), - if (logic.existUnreadMsg(info)) - CustomSlidableAction( - onPressed: (_) => logic.markMessageHasRead(info), - flex: 3, - backgroundColor: Styles.c_8E9AB0, - padding: const EdgeInsets.all(1), - child: StrRes.markHasRead.toText - ..style = Styles.ts_FFFFFF_14sp - ..maxLines = 1, - ), - CustomSlidableAction( - onPressed: (_) => logic.deleteConversation(info), - flex: 2, - backgroundColor: Styles.c_FF381F, - padding: const EdgeInsets.all(1), - child: StrRes.delete.toText..style = Styles.ts_FFFFFF_14sp, + clipBehavior: Clip.antiAlias, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ListTile( + title: Text( + logic.isPinned(info) ? '取消置顶' : '置顶', + style: const TextStyle( + fontSize: AppFont.body, color: AppColors.textPrimary), + ), + onTap: () { + Navigator.pop(ctx); + logic.pinConversation(info); + }, + ), + const Divider(height: 0.5, color: AppColors.divider), + ListTile( + title: const Text( + '删除', + style: TextStyle( + fontSize: AppFont.body, color: AppColors.danger), + ), + onTap: () { + Navigator.pop(ctx); + logic.deleteConversation(info); + }, + ), + ], ), - ], - ), - child: _buildItemView(info), - ); + ), + ); + }, + ); + } - Widget _buildItemView(ConversationInfo info) => Ink( - child: InkWell( - onTap: () => logic.toChat(conversationInfo: info), - child: Stack( - children: [ - Container( - height: 72, - padding: EdgeInsets.symmetric(horizontal: 16.w), - child: Row( - children: [ - Stack( + Widget _buildItemView(ConversationInfo info) => Builder( + builder: (context) { + return InkWell( + onTap: () => logic.toChat(conversationInfo: info), + onLongPress: () => _showConversationMenu(context, info), + splashColor: AppColors.chatBg, + highlightColor: AppColors.chatBg, + child: Container( + height: 72, + padding: const EdgeInsets.symmetric(horizontal: AppGap.x4), + child: Row( + children: [ + AvatarView( + width: 48.w, + height: 48.h, + text: logic.getShowName(info), + url: info.faceURL, + isGroup: logic.isGroupChat(info), + textStyle: Styles.ts_FFFFFF_14sp_medium, + ), + const SizedBox(width: AppGap.x3), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, children: [ - AvatarView( - width: 48.w, - height: 48.h, - text: logic.getShowName(info), - url: info.faceURL, - isGroup: logic.isGroupChat(info), - textStyle: Styles.ts_FFFFFF_14sp_medium, + Row( + children: [ + ConstrainedBox( + constraints: BoxConstraints(maxWidth: 180.w), + child: Text( + logic.getShowName(info), + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontSize: AppFont.body, + fontWeight: FontWeight.w700, + color: AppColors.textPrimary, + ), + ), + ), + const Spacer(), + Text( + logic.getTime(info), + style: const TextStyle( + fontSize: AppFont.small, + color: AppColors.textSecondary), + ), + ], + ), + const SizedBox(height: AppGap.x1), + Row( + children: [ + MatchTextView( + text: logic.getContent(info), + textStyle: const TextStyle( + fontSize: AppFont.sub, + color: AppColors.textSecondary), + prefixSpan: TextSpan( + text: '', + children: [ + if (logic.isNotDisturb(info) && + logic.getUnreadCount(info) > 0) + TextSpan( + text: '[${sprintf(StrRes.nPieces, [ + logic.getUnreadCount(info) + ])}] ', + style: const TextStyle( + fontSize: AppFont.sub, + color: AppColors.textSecondary), + ), + TextSpan( + text: logic.getPrefixTag(info), + style: const TextStyle( + fontSize: AppFont.sub, + color: AppColors.primary), + ), + ], + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + const Spacer(), + if (logic.isNotDisturb(info)) + const Icon(Icons.notifications_off_outlined, + size: AppIconSize.sm, + color: AppColors.textSecondary) + else + UnreadCountView( + count: logic.getUnreadCount(info)), + ], ), ], ), - 12.horizontalSpace, - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Row( - children: [ - ConstrainedBox( - constraints: BoxConstraints(maxWidth: 180.w), - child: Text( - logic.getShowName(info), - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: const TextStyle( - fontSize: AppFont.body, - color: AppColors.textPrimary, - ), - ), - ), - const Spacer(), - logic.getTime(info).toText - ..style = Styles.ts_8E9AB0_12sp, - ], - ), - 3.verticalSpace, - Row( - children: [ - MatchTextView( - text: logic.getContent(info), - textStyle: Styles.ts_8E9AB0_14sp, - prefixSpan: TextSpan( - text: '', - children: [ - if (logic.isNotDisturb(info) && - logic.getUnreadCount(info) > 0) - TextSpan( - text: '[${sprintf(StrRes.nPieces, [ - logic.getUnreadCount(info) - ])}] ', - style: Styles.ts_8E9AB0_14sp, - ), - TextSpan( - text: logic.getPrefixTag(info), - style: Styles.ts_0089FF_14sp, - ), - ], - ), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - const Spacer(), - if (logic.isNotDisturb(info)) - ImageRes.notDisturb.toImage - ..width = 13.63.w - ..height = 14.07.h - else - UnreadCountView( - count: logic.getUnreadCount(info)), - ], - ), - ], - ), - ), - ], - ), - ), - if (logic.isPinned(info)) - Container( - height: 72, - margin: EdgeInsets.only(right: 6.w), - foregroundDecoration: RotatedCornerDecoration.withColor( - color: Styles.c_0089FF, - badgeSize: Size(8.29.w, 8.29.h), ), - ) - ], - ), - ), + ], + ), + ), + ); + }, ); }