From 638dae95846b7b14ef412552cff069e0b6349975 Mon Sep 17 00:00:00 2001 From: Zeew Date: Wed, 13 Aug 2025 15:55:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tim_uikit_conversation.dart | 144 ++++++++++++------ .../tim_uikit_conversation_item.dart | 88 ++++++----- lib/ui/widgets/avatar.dart | 1 + 3 files changed, 149 insertions(+), 84 deletions(-) diff --git a/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation.dart b/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation.dart index 7f49603..a9be768 100644 --- a/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation.dart +++ b/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation.dart @@ -30,9 +30,12 @@ import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart'; import 'package:tencent_cloud_chat_uikit/theme/color.dart'; import 'package:tencent_cloud_chat_uikit/theme/tui_theme_view_model.dart'; -typedef ConversationItemBuilder = Widget Function(V2TimConversation conversationItem, [V2TimUserStatus? onlineStatus]); +typedef ConversationItemBuilder = Widget Function( + V2TimConversation conversationItem, + [V2TimUserStatus? onlineStatus]); -typedef ConversationItemSlideBuilder = List Function(V2TimConversation conversationItem); +typedef ConversationItemSlideBuilder = List + Function(V2TimConversation conversationItem); typedef ConversationItemSecondaryMenuBuilder = Widget Function( V2TimConversation conversationItem, VoidCallback onClose); @@ -149,11 +152,14 @@ class ConversationItemSlidePanel extends TIMUIKitStatelessWidget { } class _TIMUIKitConversationState extends TIMUIKitState { - final TUIConversationViewModel model = serviceLocator(); + final TUIConversationViewModel model = + serviceLocator(); late TIMUIKitConversationController _timuiKitConversationController; final TUIThemeViewModel themeViewModel = serviceLocator(); - final TUIFriendShipViewModel friendShipViewModel = serviceLocator(); - final TUIGroupListenerModel groupListenerModel = serviceLocator(); + final TUIFriendShipViewModel friendShipViewModel = + serviceLocator(); + final TUIGroupListenerModel groupListenerModel = + serviceLocator(); late AutoScrollController _autoScrollController; @override @@ -177,23 +183,30 @@ class _TIMUIKitConversationState extends TIMUIKitState { } _clearHistory(V2TimConversation conversationItem) { - _timuiKitConversationController.clearHistoryMessage(conversation: conversationItem); + _timuiKitConversationController.clearHistoryMessage( + conversation: conversationItem); } _pinConversation(V2TimConversation conversation) { _timuiKitConversationController.pinConversation( - conversationID: conversation.conversationID, isPinned: !conversation.isPinned!); + conversationID: conversation.conversationID, + isPinned: !conversation.isPinned!); } _deleteConversation(V2TimConversation conversation) { - _timuiKitConversationController.deleteConversation(conversationID: conversation.conversationID); + _timuiKitConversationController.deleteConversation( + conversationID: conversation.conversationID); } List getFilteredConversation() { - List filteredConversationList = - model.conversationList.where((element) => (element?.groupID != null || element?.userID != null)).toList(); + List filteredConversationList = model.conversationList + .where( + (element) => (element?.groupID != null || element?.userID != null)) + .toList(); if (widget.conversationCollector != null) { - filteredConversationList = filteredConversationList.where(widget.conversationCollector!).toList(); + filteredConversationList = filteredConversationList + .where(widget.conversationCollector!) + .toList(); } return filteredConversationList; } @@ -219,7 +232,8 @@ class _TIMUIKitConversationState extends TIMUIKitState { } } - Widget _defaultSecondaryMenu(V2TimConversation conversationItem, VoidCallback onClose) { + Widget _defaultSecondaryMenu( + V2TimConversation conversationItem, VoidCallback onClose) { return TUIKitColumnMenu(data: [ if (!PlatformUtils().isWeb) ColumnMenuItem( @@ -231,7 +245,11 @@ class _TIMUIKitConversationState extends TIMUIKitState { }), ColumnMenuItem( label: conversationItem.isPinned! ? TIM_t("取消置顶") : TIM_t("置顶"), - icon: Icon(conversationItem.isPinned! ? Icons.vertical_align_bottom : Icons.vertical_align_top, size: 16), + icon: Icon( + conversationItem.isPinned! + ? Icons.vertical_align_bottom + : Icons.vertical_align_top, + size: 16), onClick: () { onClose(); _pinConversation(conversationItem); @@ -256,7 +274,8 @@ class _TIMUIKitConversationState extends TIMUIKitState { onPressed: (context) { _clearHistory(conversationItem); }, - backgroundColor: theme.conversationItemSliderClearBgColor ?? CommonColor.primaryColor, + backgroundColor: theme.conversationItemSliderClearBgColor ?? + const Color(0xFF0F7FFF), foregroundColor: theme.conversationItemSliderTextColor, label: TIM_t("清除"), spacing: 0, @@ -266,7 +285,8 @@ class _TIMUIKitConversationState extends TIMUIKitState { onPressed: (context) { _pinConversation(conversationItem); }, - backgroundColor: theme.conversationItemSliderPinBgColor ?? CommonColor.infoColor, + backgroundColor: + theme.conversationItemSliderPinBgColor ?? CommonColor.infoColor, foregroundColor: theme.conversationItemSliderTextColor, label: conversationItem.isPinned! ? TIM_t("取消置顶") : TIM_t("置顶"), ), @@ -274,14 +294,16 @@ class _TIMUIKitConversationState extends TIMUIKitState { onPressed: (context) { _deleteConversation(conversationItem); }, - backgroundColor: theme.conversationItemSliderDeleteBgColor ?? Colors.red, + backgroundColor: + theme.conversationItemSliderDeleteBgColor ?? Colors.red, foregroundColor: theme.conversationItemSliderTextColor, label: TIM_t("删除"), ) ]; } - Widget _getSecondaryMenu(V2TimConversation conversation, VoidCallback onClose) { + Widget _getSecondaryMenu( + V2TimConversation conversation, VoidCallback onClose) { if (widget.itemSecondaryMenuBuilder != null) { return widget.itemSecondaryMenuBuilder!(conversation, onClose); } @@ -300,7 +322,8 @@ class _TIMUIKitConversationState extends TIMUIKitState { @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final theme = value.theme; - final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return MultiProvider( providers: [ ChangeNotifierProvider.value(value: model), @@ -310,10 +333,12 @@ class _TIMUIKitConversationState extends TIMUIKitState { builder: (BuildContext context, Widget? w) { final _model = Provider.of(context); bool haveMoreData = _model.haveMoreData; - final _friendShipViewModel = Provider.of(context); + final _friendShipViewModel = + Provider.of(context); _model.lifeCycle = widget.lifeCycle; - final TUIGroupListenerModel groupListenerModel = Provider.of(context, listen: true); + final TUIGroupListenerModel groupListenerModel = + Provider.of(context, listen: true); final NeedUpdate? needUpdate = groupListenerModel.needUpdate; if (needUpdate != null) { groupListenerModel.needUpdate = null; @@ -325,12 +350,14 @@ class _TIMUIKitConversationState extends TIMUIKitState { } else if (needUpdate.updateType == UpdateType.kickedFromGroup) { onTIMCallback(TIMCallback( type: TIMCallbackType.INFO, - infoRecommendText: "${TIM_t("您已被踢出")}${needUpdate!.extraData}", + infoRecommendText: + "${TIM_t("您已被踢出")}${needUpdate!.extraData}", infoCode: 6661402)); } } - List filteredConversationList = getFilteredConversation(); + List filteredConversationList = + getFilteredConversation(); if (TencentUtils.checkString(_model.scrollToConversation) != null) { _onScrollToConversation(_model.scrollToConversation!); @@ -352,17 +379,21 @@ class _TIMUIKitConversationState extends TIMUIKitState { final conversationItem = filteredConversationList[index]; - final V2TimUserStatus? onlineStatus = _friendShipViewModel.userStatusList.firstWhere( - (item) => item.userID == conversationItem?.userID, - orElse: () => V2TimUserStatus(statusType: 0)); + final V2TimUserStatus? onlineStatus = + _friendShipViewModel.userStatusList.firstWhere( + (item) => item.userID == conversationItem?.userID, + orElse: () => V2TimUserStatus(statusType: 0)); if (widget.itemBuilder != null) { - return widget.itemBuilder!(conversationItem!, onlineStatus); + return widget.itemBuilder!( + conversationItem!, onlineStatus); } - final slideChildren = _getSlideBuilder()(conversationItem!); + final slideChildren = + _getSlideBuilder()(conversationItem!); - final isCurrent = conversationItem.conversationID == model.selectedConversation?.conversationID; + final isCurrent = conversationItem.conversationID == + model.selectedConversation?.conversationID; final isPined = conversationItem.isPinned ?? false; @@ -380,10 +411,13 @@ class _TIMUIKitConversationState extends TIMUIKitState { faceUrl: conversationItem.faceUrl ?? "", nickName: conversationItem.showName ?? "", isDisturb: - (conversationItem.groupType == "Meeting" ? false : conversationItem.recvOpt != 0), + (conversationItem.groupType == "Meeting" + ? false + : conversationItem.recvOpt != 0), lastMsg: conversationItem.lastMessage, isPined: isPined, - groupAtInfoList: conversationItem.groupAtInfoList ?? [], + groupAtInfoList: + conversationItem.groupAtInfoList ?? [], unreadCount: conversationItem.unreadCount ?? 0, draftText: conversationItem.draftText, onlineStatus: (widget.isShowOnlineStatus && @@ -407,14 +441,23 @@ class _TIMUIKitConversationState extends TIMUIKitState { child: InkWell( onSecondaryTapDown: (details) { TUIKitWidePopup.showPopupWindow( - operationKey: TUIKitWideModalOperationKey.conversationSecondaryMenu, + operationKey: TUIKitWideModalOperationKey + .conversationSecondaryMenu, isDarkBackground: false, - borderRadius: const BorderRadius.all(Radius.circular(4)), + borderRadius: const BorderRadius.all( + Radius.circular(4)), context: context, offset: Offset( - min(details.globalPosition.dx, MediaQuery.of(context).size.width - 80), - min(details.globalPosition.dy, MediaQuery.of(context).size.height - 130)), - child: (onClose) => _getSecondaryMenu(conversationItem, onClose)); + min( + details.globalPosition.dx, + MediaQuery.of(context).size.width - + 80), + min( + details.globalPosition.dy, + MediaQuery.of(context).size.height - + 130)), + child: (onClose) => _getSecondaryMenu( + conversationItem, onClose)); }, child: conversationLineItem(), ), @@ -427,26 +470,37 @@ class _TIMUIKitConversationState extends TIMUIKitState { groupTag: 'conversation-list', child: conversationLineItem(), endActionPane: ActionPane( - extentRatio: slideChildren.length > 2 ? 0.77 : 0.5, + extentRatio: + slideChildren.length > 2 ? 0.77 : 0.5, motion: const DrawerMotion(), children: slideChildren)), )); }) - : (widget.emptyBuilder != null ? widget.emptyBuilder!() : Container()); + : (widget.emptyBuilder != null + ? widget.emptyBuilder!() + : Container()); } return TUIKitScreenUtils.getDeviceWidget( context: context, - defaultWidget: SlidableAutoCloseBehavior( - child: EasyRefresh( - header: CustomizeBallPulseHeader(color: theme.primaryColor), - onRefresh: () async { - model.refresh(); - }, - child: conversationList(), + defaultWidget: Container( + color: Colors.white, + child: SlidableAutoCloseBehavior( + child: EasyRefresh( + header: CustomizeBallPulseHeader(color: theme.primaryColor), + onRefresh: () async { + model.refresh(); + }, + child: conversationList(), + ), ), ), - desktopWidget: Scrollbar(controller: _autoScrollController, child: conversationList())); + desktopWidget: Container( + color: Colors.white, + child: Scrollbar( + controller: _autoScrollController, + child: conversationList()), + )); }); } } diff --git a/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_item.dart b/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_item.dart index 4e2d944..cfed40d 100644 --- a/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_item.dart +++ b/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_item.dart @@ -18,7 +18,8 @@ import 'package:tencent_cloud_chat_uikit/theme/color.dart'; import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; -typedef LastMessageBuilder = Widget? Function(V2TimMessage? lastMsg, List groupAtInfoList); +typedef LastMessageBuilder = Widget? Function( + V2TimMessage? lastMsg, List groupAtInfoList); class TIMUIKitConversationItem extends TIMUIKitStatelessWidget { final String faceUrl; @@ -53,15 +54,17 @@ class TIMUIKitConversationItem extends TIMUIKitStatelessWidget { }) : super(key: key); Widget _getShowMsgWidget(BuildContext context) { - final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; final isAndroid = PlatformUtils().isAndroid; - + // 针对安卓设备的字体大小调整 - final msgFontSize = isDesktopScreen - ? 12.0 - : (isAndroid ? 13.0 : 14.0); // 安卓设备使用稍小的字体 - - if (lastMsg != null && lastMessageBuilder != null && lastMessageBuilder!(lastMsg, groupAtInfoList) != null) { + final msgFontSize = + isDesktopScreen ? 12.0 : (isAndroid ? 13.0 : 14.0); // 安卓设备使用稍小的字体 + + if (lastMsg != null && + lastMessageBuilder != null && + lastMessageBuilder!(lastMsg, groupAtInfoList) != null) { return lastMessageBuilder!(lastMsg, groupAtInfoList)!; } @@ -91,13 +94,14 @@ class TIMUIKitConversationItem extends TIMUIKitStatelessWidget { if (draftTimestamp != null && draftTimestamp != 0) { return Text(TimeAgo().getTimeStringForChat(draftTimestamp as int) ?? "", style: TextStyle( - fontSize: 12, + fontSize: 14, color: theme.conversationItemTitmeTextColor, )); } else if (lastMsg != null) { - return Text(TimeAgo().getTimeStringForChat(lastMsg!.timestamp as int) ?? "", + return Text( + TimeAgo().getTimeStringForChat(lastMsg!.timestamp as int) ?? "", style: TextStyle( - fontSize: 11, + fontSize: 13, color: theme.conversationItemTitmeTextColor, )); } @@ -109,24 +113,25 @@ class TIMUIKitConversationItem extends TIMUIKitStatelessWidget { @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; - final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; final isAndroid = PlatformUtils().isAndroid; - + // 针对安卓设备的字体大小调整 - final titleFontSize = isDesktopScreen - ? 14.0 - : (isAndroid ? 16.0 : 18.0); // 安卓设备使用稍小的字体 - + final titleFontSize = + isDesktopScreen ? 12.0 : (isAndroid ? 14.0 : 15.0); // 安卓设备使用稍小的字体 + return Container( padding: const EdgeInsets.only(top: 6, bottom: 6, left: 16, right: 16), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: theme.conversationItemBorderColor ?? CommonColor.weakDividerColor, - width: 1, - ), - ), - ), + // decoration: BoxDecoration( + // border: Border( + // bottom: BorderSide( + // color: theme.conversationItemBorderColor ?? Color(0xFFF0F0F0), + // width: 0.5, + // ), + // ), + // ), + decoration: BoxDecoration(), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ @@ -139,7 +144,11 @@ class TIMUIKitConversationItem extends TIMUIKitStatelessWidget { fit: StackFit.expand, clipBehavior: Clip.none, children: [ - Avatar(onlineStatus: onlineStatus, faceUrl: faceUrl, showName: nickName, type: convType), + Avatar( + onlineStatus: onlineStatus, + faceUrl: faceUrl, + showName: nickName, + type: convType), if (unreadCount != 0) Positioned( top: isDisturb ? -2.5 : -4.5, @@ -170,18 +179,18 @@ class TIMUIKitConversationItem extends TIMUIKitStatelessWidget { Flexible( flex: 3, child: Text( - nickName, - softWrap: true, - textAlign: TextAlign.left, - overflow: TextOverflow.ellipsis, - maxLines: 1, - style: TextStyle( - height: 1, - color: theme.conversationItemTitleTextColor, - fontSize: titleFontSize, - fontWeight: FontWeight.w400, - ), - )), + nickName, + softWrap: true, + textAlign: TextAlign.left, + overflow: TextOverflow.ellipsis, + maxLines: 1, + style: TextStyle( + height: 1, + color: theme.conversationItemTitleTextColor, + fontSize: titleFontSize, + fontWeight: FontWeight.w400, + ), + )), Flexible( flex: 1, child: Container( @@ -214,7 +223,8 @@ class TIMUIKitConversationItem extends TIMUIKitStatelessWidget { height: 18, child: Icon( Icons.notifications_off, - color: theme.conversationItemNoNotificationIconColor, + color: + theme.conversationItemNoNotificationIconColor, size: isDesktopScreen ? 14 : 16.0, ), ), diff --git a/lib/ui/widgets/avatar.dart b/lib/ui/widgets/avatar.dart index 2927c9d..8a828fc 100644 --- a/lib/ui/widgets/avatar.dart +++ b/lib/ui/widgets/avatar.dart @@ -72,6 +72,7 @@ class Avatar extends TIMUIKitStatelessWidget { return CachedNetworkImage( imageUrl: faceUrl, fadeInDuration: const Duration(milliseconds: 0), + fit: BoxFit.cover, errorWidget: (BuildContext context, String c, dynamic s) { return defaultAvatar(); },