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/core/controller/im_controller.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'; import 'conversation_logic.dart'; class ConversationPage extends StatelessWidget { final logic = Get.find(); final im = Get.find(); ConversationPage({super.key}); @override Widget build(BuildContext context) { return Obx(() => Scaffold( backgroundColor: Styles.c_F8F9FA, 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: Row( mainAxisSize: MainAxisSize.max, children: [ AvatarView( width: 42.w, height: 42.h, text: im.userInfo.value.nickname, url: im.userInfo.value.faceURL, ), 10.horizontalSpace, if (null != im.userInfo.value.nickname) Flexible( child: im.userInfo.value.nickname!.toText ..style = Styles.ts_0C1C33_17sp ..maxLines = 1 ..overflow = TextOverflow.ellipsis, ), 10.horizontalSpace, if (null != logic.imSdkStatus && (!logic.reInstall || logic.isFailedSdkStatus)) Flexible( child: SyncStatusView( isFailed: logic.isFailedSdkStatus, statusStr: logic.imSdkStatus!, )), ], ), )), body: Column( children: [ Expanded( child: SlidableAutoCloseBehavior( child: ScrollablePositionedList.builder( itemScrollController: logic.itemScrollController, itemBuilder: (_, index) => _buildConversationItemView( 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, ), 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, ), ], ), child: _buildItemView(info), ); Widget _buildItemView(ConversationInfo info) => Ink( child: InkWell( onTap: () => logic.toChat(conversationInfo: info), child: Stack( children: [ Container( height: 68, padding: EdgeInsets.symmetric(horizontal: 16.w), child: Row( children: [ Stack( 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, ), ], ), 12.horizontalSpace, Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Row( children: [ ConstrainedBox( constraints: BoxConstraints(maxWidth: 180.w), child: logic.getShowName(info).toText ..style = Styles.ts_0C1C33_17sp ..maxLines = 1 ..overflow = TextOverflow.ellipsis, ), 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: 68.h, margin: EdgeInsets.only(right: 6.w), foregroundDecoration: RotatedCornerDecoration.withColor( color: Styles.c_0089FF, badgeSize: Size(8.29.w, 8.29.h), ), ) ], ), ), ); }