diff --git a/circle_app/assets/images/msg/CD.png b/circle_app/assets/images/msg/CD.png new file mode 100644 index 0000000..4fc86ef Binary files /dev/null and b/circle_app/assets/images/msg/CD.png differ diff --git a/circle_app/assets/images/msg/FTM.png b/circle_app/assets/images/msg/FTM.png new file mode 100644 index 0000000..b54f34d Binary files /dev/null and b/circle_app/assets/images/msg/FTM.png differ diff --git a/circle_app/assets/images/msg/MTF.png b/circle_app/assets/images/msg/MTF.png new file mode 100644 index 0000000..60016f4 Binary files /dev/null and b/circle_app/assets/images/msg/MTF.png differ diff --git a/circle_app/assets/images/msg/女.png b/circle_app/assets/images/msg/女.png new file mode 100644 index 0000000..97973d8 Binary files /dev/null and b/circle_app/assets/images/msg/女.png differ diff --git a/circle_app/assets/images/msg/男.png b/circle_app/assets/images/msg/男.png new file mode 100644 index 0000000..a3fde53 Binary files /dev/null and b/circle_app/assets/images/msg/男.png differ diff --git a/circle_app/assets/images/msg/酷儿.png b/circle_app/assets/images/msg/酷儿.png new file mode 100644 index 0000000..9b4bcfb Binary files /dev/null and b/circle_app/assets/images/msg/酷儿.png differ diff --git a/circle_app/lib/app/msg/TIMUIKitConversation/tim_uikit_conversation.dart b/circle_app/lib/app/msg/TIMUIKitConversation/tim_uikit_conversation.dart index cb31a2e..1c99535 100644 --- a/circle_app/lib/app/msg/TIMUIKitConversation/tim_uikit_conversation.dart +++ b/circle_app/lib/app/msg/TIMUIKitConversation/tim_uikit_conversation.dart @@ -1,3 +1,4 @@ +import 'dart:convert'; import 'dart:math'; import 'package:flutter/material.dart'; @@ -307,6 +308,36 @@ class _TIMConversationState extends TIMUIKitState { return widget.itemSlideBuilder ?? _defaultSlideBuilder; } + Future> getUserListInfo(List userIdList) async { + + V2TimValueCallback getLoginUserRes = + await TencentImSDKPlugin.v2TIMManager.getLoginUser(); + if (getLoginUserRes.code == 0) { + //获取成功 + userIdList.insert(0, getLoginUserRes.data!);// getLoginUserRes.data为查询到的登录用户的UserID + } + //获取用户资料 + V2TimValueCallback> getUsersInfoRes = + await TencentImSDKPlugin.v2TIMManager.getUsersInfo(userIDList: userIdList);//需要查询的用户id列表 + if (getUsersInfoRes.code == 0) { + // 查询成功 + getUsersInfoRes.data?.forEach((element) { + element.allowType;//用户的好友验证方式 0:允许所有人加我好友 1:不允许所有人加我好友 2:加我好友需我确认 + element.birthday;//用户生日 + element.customInfo;//用户的自定义状态 + element.faceUrl;//用户头像 url + element.gender;//用户的性别 1:男 2:女 + element.level;//用户的等级 + element.nickName;//用户昵称 + element.role;//用户的角色 + element.selfSignature;//用户的签名 + element.userID;//用户 ID + }); + return getUsersInfoRes.data ?? []; + } + return []; + } + @override void dispose() { super.dispose(); @@ -337,111 +368,152 @@ class _TIMConversationState extends TIMUIKitState { _model.clearScrollToConversation(); } + + List userIdList = []; + + + filteredConversationList.forEach((element) { + userIdList.add(element!.userID!); + }); + + Widget conversationList() { return filteredConversationList.isNotEmpty - ? ListView.builder( - controller: _autoScrollController, - shrinkWrap: true, - itemCount: filteredConversationList.length, - itemBuilder: (context, index) { - if (index == filteredConversationList.length - 1) { - if (haveMoreData) { - _timuiKitConversationController.loadData(); + ? FutureBuilder>( + future: getUserListInfo(userIdList), + builder: (BuildContext context, AsyncSnapshot> snapshot) { + return ListView.builder( + controller: _autoScrollController, + shrinkWrap: true, + itemCount: filteredConversationList.length, + itemBuilder: (context, index) { + if (index == filteredConversationList.length - 1) { + if (haveMoreData) { + _timuiKitConversationController.loadData(); + } + } + + final conversationItem = filteredConversationList[index]; + + final V2TimUserStatus? onlineStatus = + _friendShipViewModel.userStatusList.firstWhere( + (item) => item.userID == conversationItem?.userID, + orElse: () => V2TimUserStatus(statusType: 0)); + + if (widget.itemBuilder != null) { + return widget.itemBuilder!( + conversationItem!, onlineStatus); + } + + final slideChildren = + _getSlideBuilder()(conversationItem!); + + final isCurrent = conversationItem.conversationID == + model.selectedConversation?.conversationID; + + final isPined = conversationItem.isPinned ?? false; + + + V2TimUserFullInfo? userFullInfo; + bool isSameCity = false; + if (snapshot.connectionState == ConnectionState.done) { + snapshot.data!.forEach((element) { + if (element.userID == conversationItem.userID) { + userFullInfo = element; + } + }); + + V2TimUserFullInfo myuserFullInfo = snapshot.data!.first; + + if (userFullInfo!.customInfo!.containsKey('Label')) { + var otherInfo = jsonDecode(userFullInfo!.customInfo!['Label'].toString()); + var myInfo = jsonDecode(myuserFullInfo!.customInfo!['Label'].toString()); + if (myInfo['city'].toString().contains(otherInfo['city'].toString())) { + isSameCity = true; } } - final conversationItem = filteredConversationList[index]; + } - final V2TimUserStatus? onlineStatus = - _friendShipViewModel.userStatusList.firstWhere( - (item) => item.userID == conversationItem?.userID, - orElse: () => V2TimUserStatus(statusType: 0)); - if (widget.itemBuilder != null) { - return widget.itemBuilder!( - conversationItem!, onlineStatus); - } - final slideChildren = - _getSlideBuilder()(conversationItem!); - final isCurrent = conversationItem.conversationID == - model.selectedConversation?.conversationID; + Widget conversationLineItem() { - final isPined = conversationItem.isPinned ?? false; + return Material( + color: Colors.transparent, + child: InkWell( + child: TIMConversationItem( + isSameCity: isSameCity, + isCurrent: isCurrent, + userInfo: userFullInfo, + isShowDraft: widget.isShowDraft, + lastMessageBuilder: widget.lastMessageBuilder, + faceUrl: conversationItem.faceUrl ?? "", + nickName: conversationItem.showName ?? "", + isDisturb: conversationItem.recvOpt != 0, + lastMsg: conversationItem.lastMessage, + isPined: isPined, + groupAtInfoList: + conversationItem.groupAtInfoList ?? [], + unreadCount: conversationItem.unreadCount ?? 0, + draftText: conversationItem.draftText, + onlineStatus: (widget.isShowOnlineStatus && + conversationItem.userID != null && + conversationItem.userID!.isNotEmpty) + ? onlineStatus + : null, + draftTimestamp: conversationItem.draftTimestamp, + convType: conversationItem.type), + onTap: () => onTapConvItem(conversationItem), + ), + ); + } - Widget conversationLineItem() { - return Material( - color: Colors.transparent, - child: InkWell( - child: TIMConversationItem( - isCurrent: isCurrent, - isShowDraft: widget.isShowDraft, - lastMessageBuilder: widget.lastMessageBuilder, - faceUrl: conversationItem.faceUrl ?? "", - nickName: conversationItem.showName ?? "", - isDisturb: conversationItem.recvOpt != 0, - lastMsg: conversationItem.lastMessage, - isPined: isPined, - groupAtInfoList: - conversationItem.groupAtInfoList ?? [], - unreadCount: conversationItem.unreadCount ?? 0, - draftText: conversationItem.draftText, - onlineStatus: (widget.isShowOnlineStatus && - conversationItem.userID != null && - conversationItem.userID!.isNotEmpty) - ? onlineStatus - : null, - draftTimestamp: conversationItem.draftTimestamp, - convType: conversationItem.type), - onTap: () => onTapConvItem(conversationItem), + return TUIKitScreenUtils.getDeviceWidget( + desktopWidget: AutoScrollTag( + key: ValueKey(conversationItem.conversationID), + controller: _autoScrollController, + index: index, + child: GestureDetector( + onSecondaryTapDown: (details) { + TUIKitWidePopup.showPopupWindow( + operationKey: TUIKitWideModalOperationKey + .conversationSecondaryMenu, + isDarkBackground: false, + 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)); + }, + child: conversationLineItem(), ), - ); - } - - return TUIKitScreenUtils.getDeviceWidget( - desktopWidget: AutoScrollTag( - key: ValueKey(conversationItem.conversationID), - controller: _autoScrollController, - index: index, - child: GestureDetector( - onSecondaryTapDown: (details) { - TUIKitWidePopup.showPopupWindow( - operationKey: TUIKitWideModalOperationKey - .conversationSecondaryMenu, - isDarkBackground: false, - 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)); - }, + ), + defaultWidget: AutoScrollTag( + key: ValueKey(conversationItem.conversationID), + controller: _autoScrollController, + index: index, + child: Slidable( + groupTag: 'conversation-list', child: conversationLineItem(), - ), - ), - defaultWidget: AutoScrollTag( - key: ValueKey(conversationItem.conversationID), - controller: _autoScrollController, - index: index, - child: Slidable( - groupTag: 'conversation-list', - child: conversationLineItem(), - endActionPane: ActionPane( - extentRatio: - slideChildren.length > 2 ? 0.77 : 0.5, - motion: const DrawerMotion(), - children: slideChildren)), - )); - }) + endActionPane: ActionPane( + extentRatio: + slideChildren.length > 2 ? 0.77 : 0.5, + motion: const DrawerMotion(), + children: slideChildren)), + )); + }); + }) : (widget.emptyBuilder != null ? widget.emptyBuilder!() : Container()); diff --git a/circle_app/lib/app/msg/TIMUIKitConversation/tim_uikit_conversation_item.dart b/circle_app/lib/app/msg/TIMUIKitConversation/tim_uikit_conversation_item.dart index 65e0d3f..1aa93a6 100644 --- a/circle_app/lib/app/msg/TIMUIKitConversation/tim_uikit_conversation_item.dart +++ b/circle_app/lib/app/msg/TIMUIKitConversation/tim_uikit_conversation_item.dart @@ -2,7 +2,9 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:circle_app/app/msg/TIMUIKitConversation/tim_uikit_conversation_last_msg.dart'; +import 'package:circle_app/util/util.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitConversation/tim_uikit_conversation_item.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; @@ -16,7 +18,6 @@ import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/unread_message.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; - class TIMConversationItem extends TIMUIKitStatelessWidget { final String faceUrl; final String nickName; @@ -31,6 +32,8 @@ class TIMConversationItem extends TIMUIKitStatelessWidget { final V2TimUserStatus? onlineStatus; final int? convType; final bool isCurrent; + final bool isSameCity; + final V2TimUserFullInfo? userInfo; /// Control if shows the identifier that the conversation has a draft text, inputted in previous. /// Also, you'd better specifying the `draftText` field for `TIMUIKitChat`, from the `draftText` in `V2TimConversation`, @@ -41,8 +44,10 @@ class TIMConversationItem extends TIMUIKitStatelessWidget { Key? key, required this.isShowDraft, required this.faceUrl, + required this.isSameCity, required this.nickName, required this.lastMsg, + required this.userInfo, this.onlineStatus, required this.isPined, this.isCurrent = false, @@ -56,7 +61,8 @@ class TIMConversationItem extends TIMUIKitStatelessWidget { }) : super(key: key); Widget _getShowMsgWidget(BuildContext context) { - final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; if (isShowDraft && draftText != null && draftText != "") { return TIMUIKitDraftText( context: context, @@ -68,6 +74,28 @@ class TIMConversationItem extends TIMUIKitStatelessWidget { lastMessageBuilder!(lastMsg, groupAtInfoList) != null) { return lastMessageBuilder!(lastMsg, groupAtInfoList)!; } + return Row( + + children: [ + isSameCity + ? const Text('[同城]', + style: TextStyle( + color: Color(0xFF04FDFB), + fontSize: 14 + )) + : Container(), + Expanded( + child: Container( + alignment: Alignment.centerLeft, + padding: EdgeInsets.only(top: 3.sp), + child: TIMLastMsg( + fontSize: isDesktopScreen ? 12 : 14, + groupAtInfoList: groupAtInfoList, + lastMsg: lastMsg, + context: context, + ), + )) + ]); return TIMLastMsg( fontSize: isDesktopScreen ? 12 : 14, groupAtInfoList: groupAtInfoList, @@ -109,14 +137,19 @@ class TIMConversationItem 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; return Container( padding: const EdgeInsets.only(top: 6, bottom: 6, left: 16, right: 16), decoration: BoxDecoration( - color: Colors.transparent, - - - ), + // color: Colors.transparent, + // gl.startPoint = CGPointMake(0.48, 0.48); + // gl.endPoint = CGPointMake(0.52, 0.52); + // Alignment(0.52, 0.52) + gradient: LinearGradient( + colors: isPined + ? [Color(0xFF4B3E5E), Color(0xFF334141)] + : [Colors.transparent, Colors.transparent])), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ @@ -131,9 +164,12 @@ class TIMConversationItem extends TIMUIKitStatelessWidget { clipBehavior: Clip.none, children: [ ClipOval( - child: CachedNetworkImage(imageUrl: faceUrl,fit: BoxFit.cover,width: isDesktopScreen ? 40 : 44, - height: isDesktopScreen ? 40 : 44,) - ), + child: CachedNetworkImage( + imageUrl: faceUrl, + fit: BoxFit.cover, + width: isDesktopScreen ? 40 : 44, + height: isDesktopScreen ? 40 : 44, + )), if (unreadCount != 0) Positioned( top: isDisturb ? -2.5 : -4.5, @@ -144,7 +180,17 @@ class TIMConversationItem extends TIMUIKitStatelessWidget { height: isDisturb ? 10 : 18, unreadCount: isDisturb ? 0 : unreadCount), ), - ) + ), + if (userInfo != null) + Positioned( + bottom: 0, + right: 0, + child: (userInfo!.role ?? 0) > 0 + ? Image.asset( + getMsgImage(getGenderContent(userInfo!.role!)), + height: 13.sp, + ) + : Container()) ], ), ),