tencent_cloud_chat_uikit source code update to version 3.1.0+2
This commit is contained in:
parent
5700746752
commit
e7c38ef149
64
README_ZH.md
64
README_ZH.md
|
|
@ -112,38 +112,38 @@ _coreInstance.login(
|
|||
|
||||
全部场景码清单如下:
|
||||
|
||||
| 场景码 `infoCode` | 推荐提示语 `infoRecommendText` | 场景描述 |
|
||||
| ----------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
|
||||
| 6660101 | 好友申请已发送 | 用户申请添加其他用户为联系人 |
|
||||
| 6660102 | 该用户已是好友 | 用户申请添加其他已是好友的用户为好友时,触发 `onTapAlreadyFriendsItem` 回调 |
|
||||
| 6660201 | 群申请已发送 | 用户申请加入需要管理员审批的群聊 |
|
||||
| 6660202 | 您已是群成员 | 用户申请加群时,判断用户已经是当前群成员,触发 `onTapExistGroup` 回调 |
|
||||
| 6660401 | 无法定位到原消息 | 当用户需要跳转至@消息或者是引用消息时,在消息列表中查不到目标消息 |
|
||||
| 6660402 | 视频保存成功 | 用户在消息列表,点开视频消息后,选择保存视频 |
|
||||
| 6660403 | 视频保存失败 | 用户在消息列表,点开视频消息后,选择保存视频 |
|
||||
| 6660404 | 说话时间太短 | 用户发送了过短的语音消息 |
|
||||
| 6660405 | 发送失败,视频不能大于 100MB | 用户试图发送大于 100MB 的视频 |
|
||||
| 6660406 | 图片保存成功 | 用户在消息列表,点开图片大图后,选择保存图片 |
|
||||
| 6660407 | 图片保存失败 | 用户在消息列表,点开图片大图后,选择保存图片 |
|
||||
| 6660408 | 已复制 | 用户在弹窗内选择复制文字消息 |
|
||||
| 6660409 | 暂未实现 | 用户在弹窗内选择非标功能 |
|
||||
| 6660410 | 其他文件正在接收中 | 用户点击下载文件消息时,前序下载任务还未完成 |
|
||||
| 6660411 | 正在接收中 | 用户点击下载文件消息 |
|
||||
| 6660412 | 视频消息仅限 mp4 格式 | 用户发送了一条非 mp4 格式的视频消息 |
|
||||
| 6660413 | 已加入待下载队列,其他文件下载中 | 已加入待下载队列,其他文件下载中 |
|
||||
| 6661001 | 无网络连接,无法修改 | 当用户试图在无网络环境下,修改群资料 |
|
||||
| 6661002 | 无网络连接,无法查看群成员 | 当用户试图在无网络环境下,修改群资料 |
|
||||
| 6661003 | 成功取消管理员身份 | 用户将群内其他用户移除管理员 |
|
||||
| 6661201 | 无网络连接,无法修改 | 当用户试图在无网络环境下,修改自己或联系人的资料 |
|
||||
| 6661202 | 好友添加成功 | 在资料页添加其他用户为好友,并自动添加成功,无需验证 |
|
||||
| 6661203 | 好友申请已发出 | 在资料页添加其他用户为好友,对方设置需要验证 |
|
||||
| 6661204 | 当前用户在黑名单 | 在资料页添加其他用户为好友,对方在自己的黑名单内 |
|
||||
| 6661205 | 好友添加失败 | 在资料页添加其他用户为好友,添加失败,可能是由于对方禁止加好友 |
|
||||
| 6661206 | 好友删除成功 | 在资料页删除其他用户为好友,成功 |
|
||||
| 6661207 | 好友删除失败 | 在资料页删除其他用户为好友,失败 |
|
||||
| 6661401 | 输入不能为空 | 当用户在录入信息时,输入了空字符串 |
|
||||
| 6661402 | 请传入离开群组生命周期函数,提供返回首页或其他页面的导航方法 | 用户退出群或解散群时,为提供返回首页办法 |
|
||||
| 6661403 | 设备存储空间不足,建议清理,以获得更好使用体验 | 在login成功后,会自动检测设备存储空间,如果不足1GB,会提示存储空间不足 |
|
||||
| 场景码 `infoCode` | 推荐提示语 `infoRecommendText` | 场景描述 |
|
||||
|------------------| ------------------------------------------------------------ | ------------------------------------------------------------ |
|
||||
| 6660101(3.0.1废弃)| 好友申请已发送 | 用户申请添加其他用户为联系人 |
|
||||
| 6660102(3.0.1废弃)| 该用户已是好友 | 用户申请添加其他已是好友的用户为好友时,触发 `onTapAlreadyFriendsItem` 回调 |
|
||||
| 6660201 | 群申请已发送 | 用户申请加入需要管理员审批的群聊 |
|
||||
| 6660202 | 您已是群成员 | 用户申请加群时,判断用户已经是当前群成员,触发 `onTapExistGroup` 回调 |
|
||||
| 6660401(3.0.1废弃)| 无法定位到原消息 | 当用户需要跳转至@消息或者是引用消息时,在消息列表中查不到目标消息 |
|
||||
| 6660402 | 视频保存成功 | 用户在消息列表,点开视频消息后,选择保存视频 |
|
||||
| 6660403 | 视频保存失败 | 用户在消息列表,点开视频消息后,选择保存视频 |
|
||||
| 6660404 | 说话时间太短 | 用户发送了过短的语音消息 |
|
||||
| 6660405(3.0.1废弃)| 发送失败,视频不能大于 100MB | 用户试图发送大于 100MB 的视频 |
|
||||
| 6660406 | 图片保存成功 | 用户在消息列表,点开图片大图后,选择保存图片 |
|
||||
| 6660407 | 图片保存失败 | 用户在消息列表,点开图片大图后,选择保存图片 |
|
||||
| 6660408 | 已复制 | 用户在弹窗内选择复制文字消息 |
|
||||
| 6660409 | 暂未实现 | 用户在弹窗内选择非标功能 |
|
||||
| 6660410 | 其他文件正在接收中 | 用户点击下载文件消息时,前序下载任务还未完成 |
|
||||
| 6660411 | 正在接收中 | 用户点击下载文件消息 |
|
||||
| 6660412 | 视频消息仅限 mp4 格式 | 用户发送了一条非 mp4 格式的视频消息 |
|
||||
| 6660413 | 已加入待下载队列,其他文件下载中 | 已加入待下载队列,其他文件下载中 |
|
||||
| 6661001 | 无网络连接,无法修改 | 当用户试图在无网络环境下,修改群资料 |
|
||||
| 6661002 | 无网络连接,无法查看群成员 | 当用户试图在无网络环境下,修改群资料 |
|
||||
| 6661003 | 成功取消管理员身份 | 用户将群内其他用户移除管理员 |
|
||||
| 6661201 | 无网络连接,无法修改 | 当用户试图在无网络环境下,修改自己或联系人的资料 |
|
||||
| 6661202(3.0.1废弃)| 好友添加成功 | 在资料页添加其他用户为好友,并自动添加成功,无需验证 |
|
||||
| 6661203(3.0.1废弃)| 好友申请已发出 | 在资料页添加其他用户为好友,对方设置需要验证 |
|
||||
| 6661204(3.0.1废弃)| 当前用户在黑名单 | 在资料页添加其他用户为好友,对方在自己的黑名单内 |
|
||||
| 6661205(3.0.1废弃)| 好友添加失败 | 在资料页添加其他用户为好友,添加失败,可能是由于对方禁止加好友 |
|
||||
| 6661206(3.0.1废弃)| 好友删除成功 | 在资料页删除其他用户为好友,成功 |
|
||||
| 6661207(3.0.1废弃)| 好友删除失败 | 在资料页删除其他用户为好友,失败 |
|
||||
| 6661401 | 输入不能为空 | 当用户在录入信息时,输入了空字符串 |
|
||||
| 6661402(3.0.1废弃)| 请传入离开群组生命周期函数,提供返回首页或其他页面的导航方法 | 用户退出群或解散群时,为提供返回首页办法 |
|
||||
| 6661403 | 设备存储空间不足,建议清理,以获得更好使用体验 | 在login成功后,会自动检测设备存储空间,如果不足1GB,会提示存储空间不足 |
|
||||
|
||||
## TIMUIKitConversation
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
final TUIChatGlobalModel globalModel = serviceLocator<TUIChatGlobalModel>();
|
||||
final TUIChatModelTools tools = serviceLocator<TUIChatModelTools>();
|
||||
final TUISelfInfoViewModel selfModel = serviceLocator<TUISelfInfoViewModel>();
|
||||
final TUIConversationViewModel conversationViewModel = serviceLocator<TUIConversationViewModel>();
|
||||
final TUIConversationViewModel conversationViewModel =
|
||||
serviceLocator<TUIConversationViewModel>();
|
||||
final _uuid = const Uuid();
|
||||
|
||||
ChatLifeCycle? lifeCycle;
|
||||
|
|
@ -135,7 +136,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
|
||||
List<V2TimMessage> currentHistoryMsgList = getOriginMessageList();
|
||||
for (var v2TimMessage in currentHistoryMsgList) {
|
||||
if (_selectedPositions.containsKey(v2TimMessage.msgID) && _selectedPositions[v2TimMessage.msgID]!) {
|
||||
if (_selectedPositions.containsKey(v2TimMessage.msgID) &&
|
||||
_selectedPositions[v2TimMessage.msgID]!) {
|
||||
selectList.add(v2TimMessage);
|
||||
}
|
||||
}
|
||||
|
|
@ -368,7 +370,6 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
? haveMoreLatestData = false
|
||||
: tempHaveMoreData = false;
|
||||
|
||||
|
||||
// 获取当前聊天对话的历史消息列表
|
||||
final currentRecordList = globalModel.messageListMap[conversationID];
|
||||
|
||||
|
|
@ -478,7 +479,10 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
|
||||
_getMsgReadReceipt(List<V2TimMessage> message) async {
|
||||
final msgID = message
|
||||
.where((e) => (e.isSelf ?? true) && (e.needReadReceipt ?? false) && (e.status == MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC))
|
||||
.where((e) =>
|
||||
(e.isSelf ?? true) &&
|
||||
(e.needReadReceipt ?? false) &&
|
||||
(e.status == MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC))
|
||||
.map((e) => e.msgID ?? '')
|
||||
.toList();
|
||||
if (msgID.isNotEmpty) {
|
||||
|
|
@ -587,12 +591,12 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
_notify();
|
||||
}
|
||||
}
|
||||
|
||||
void _notify(){
|
||||
try{
|
||||
|
||||
void _notify() {
|
||||
try {
|
||||
notifyListeners();
|
||||
}catch(e){
|
||||
debugPrint(e.toString());
|
||||
} catch (e) {
|
||||
debugPrint(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -920,9 +924,9 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
|
||||
_repliedMessage = null;
|
||||
final sendMsgRes = await _messageService.sendMessage(
|
||||
cloudCustomData:
|
||||
TencentUtils.checkString(messageInfoWithSender?.cloudCustomData) ??
|
||||
json.encode(cloudCustomData),
|
||||
cloudCustomData: TencentUtils.checkString(
|
||||
messageInfoWithSender?.cloudCustomData) ??
|
||||
json.encode(cloudCustomData),
|
||||
id: textMessageInfo.id as String,
|
||||
offlinePushInfo: tools.buildMessagePushInfo(
|
||||
messageInfoWithSender, convID, convType),
|
||||
|
|
@ -1149,9 +1153,11 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
for (var conversation in conversationList) {
|
||||
final convID = conversation.groupID ?? conversation.userID ?? "";
|
||||
final convType = conversation.type;
|
||||
List<V2TimMessage> currentHistoryMsgList = globalModel.messageListMap[conversationID] ?? [];
|
||||
List<V2TimMessage> currentHistoryMsgList =
|
||||
globalModel.messageListMap[conversationID] ?? [];
|
||||
for (var message in selectedMessages) {
|
||||
final forwardMessageInfo = await _messageService.createForwardMessage(msgID: message.msgID!);
|
||||
final forwardMessageInfo =
|
||||
await _messageService.createForwardMessage(msgID: message.msgID!);
|
||||
final messageInfo = forwardMessageInfo!.messageInfo;
|
||||
if (messageInfo != null) {
|
||||
tools.setUserInfoForMessage(messageInfo, forwardMessageInfo.id);
|
||||
|
|
@ -1159,11 +1165,9 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
addSendingMessageID(messageInfo.id);
|
||||
// 如果转发的会话是当前会话,则直接添加到当前会话的消息列表中
|
||||
if (convID == conversationID) {
|
||||
if (globalModel.getMessageListPosition(convID) != HistoryMessagePosition.notShowLatest) {
|
||||
currentHistoryMsgList = [
|
||||
messageInfo,
|
||||
...currentHistoryMsgList
|
||||
];
|
||||
if (globalModel.getMessageListPosition(convID) !=
|
||||
HistoryMessagePosition.notShowLatest) {
|
||||
currentHistoryMsgList = [messageInfo, ...currentHistoryMsgList];
|
||||
globalModel.setMessageList(conversationID, currentHistoryMsgList);
|
||||
_notify();
|
||||
}
|
||||
|
|
@ -1198,7 +1202,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
for (var conversation in conversationList) {
|
||||
final convID = conversation.groupID ?? conversation.userID ?? "";
|
||||
final convType = conversation.type;
|
||||
List<V2TimMessage> currentHistoryMsgList = globalModel.messageListMap[conversationID] ?? [];
|
||||
List<V2TimMessage> currentHistoryMsgList =
|
||||
globalModel.messageListMap[conversationID] ?? [];
|
||||
final mergerMessageInfo = await _messageService.createMergerMessage(
|
||||
msgIDList: msgIDList,
|
||||
title: title,
|
||||
|
|
@ -1211,11 +1216,9 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
addSendingMessageID(messageInfo.id);
|
||||
// 如果转发的会话是当前会话,则直接添加到当前会话的消息列表中
|
||||
if (convID == conversationID) {
|
||||
if (globalModel.getMessageListPosition(convID) != HistoryMessagePosition.notShowLatest) {
|
||||
currentHistoryMsgList = [
|
||||
messageInfo,
|
||||
...currentHistoryMsgList
|
||||
];
|
||||
if (globalModel.getMessageListPosition(convID) !=
|
||||
HistoryMessagePosition.notShowLatest) {
|
||||
currentHistoryMsgList = [messageInfo, ...currentHistoryMsgList];
|
||||
globalModel.setMessageList(conversationID, currentHistoryMsgList);
|
||||
_notify();
|
||||
}
|
||||
|
|
@ -1244,16 +1247,14 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
return null;
|
||||
}
|
||||
|
||||
currentHistoryMsgList.removeWhere((element) => element.msgID == message.msgID);
|
||||
currentHistoryMsgList
|
||||
.removeWhere((element) => element.msgID == message.msgID);
|
||||
message.status = MessageStatus.V2TIM_MSG_STATUS_SENDING;
|
||||
addSendingMessageID(message.msgID);
|
||||
globalModel.setMessageList(convID, currentHistoryMsgList);
|
||||
if (globalModel.getMessageListPosition(conversationID) !=
|
||||
HistoryMessagePosition.notShowLatest) {
|
||||
currentHistoryMsgList = [
|
||||
message,
|
||||
...currentHistoryMsgList
|
||||
];
|
||||
currentHistoryMsgList = [message, ...currentHistoryMsgList];
|
||||
globalModel.setMessageList(conversationID, currentHistoryMsgList);
|
||||
_notify();
|
||||
}
|
||||
|
|
@ -1263,7 +1264,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
msgID: message.msgID ?? "", onlineUserOnly: false);
|
||||
removeSendingMessageID(message.msgID ?? "");
|
||||
if (globalModel.getMessageListPosition(conversationID) !=
|
||||
HistoryMessagePosition.notShowLatest) {
|
||||
HistoryMessagePosition.notShowLatest) {
|
||||
globalModel.updateMessage(
|
||||
res, convID, message.msgID!, convType, groupType, setInputField);
|
||||
}
|
||||
|
|
@ -1426,7 +1427,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
for (var msgID in msgIDs) {
|
||||
messageList.removeWhere((element) => element.msgID == msgID);
|
||||
}
|
||||
globalModel.setMessageList(conversationID, messageList, isDeleteMsg: true);
|
||||
globalModel.setMessageList(conversationID, messageList,
|
||||
isDeleteMsg: true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1492,10 +1494,9 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
// 是否已经延迟渲染
|
||||
bool? hasDelayedRenderSendingStatus(String id) {
|
||||
if (_sendingMessageIDMap.containsKey(id)) {
|
||||
return _sendingMessageIDMap[id];
|
||||
return _sendingMessageIDMap[id];
|
||||
}
|
||||
|
||||
print("sending test, hasDelayedRenderSendingStatus false:${id}");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
// ignore_for_file: unnecessary_getters_setters
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/conversation_life_cycle.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
|
||||
|
|
@ -11,7 +12,8 @@ import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
|
|||
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
|
||||
|
||||
List<T> removeDuplicates<T>(List<T> list, bool Function(T first, T second) isEqual) {
|
||||
List<T> removeDuplicates<T>(
|
||||
List<T> list, bool Function(T first, T second) isEqual) {
|
||||
List<T> output = [];
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
bool found = false;
|
||||
|
|
@ -32,10 +34,14 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
static const String conversationC2CPrefix = "c2c_";
|
||||
static const String conversationGroupPrefix = "group_";
|
||||
|
||||
final TUISelfInfoViewModel selfInfoViewModel = serviceLocator<TUISelfInfoViewModel>();
|
||||
final ConversationService _conversationService = serviceLocator<ConversationService>();
|
||||
final FriendshipServices _friendshipServices = serviceLocator<FriendshipServices>();
|
||||
final TUIChatGlobalModel _chatGlobalModel = serviceLocator<TUIChatGlobalModel>();
|
||||
final TUISelfInfoViewModel selfInfoViewModel =
|
||||
serviceLocator<TUISelfInfoViewModel>();
|
||||
final ConversationService _conversationService =
|
||||
serviceLocator<ConversationService>();
|
||||
final FriendshipServices _friendshipServices =
|
||||
serviceLocator<FriendshipServices>();
|
||||
final TUIChatGlobalModel _chatGlobalModel =
|
||||
serviceLocator<TUIChatGlobalModel>();
|
||||
final MessageService _messageService = serviceLocator<MessageService>();
|
||||
late V2TimConversationListener _conversationListener;
|
||||
List<V2TimConversation?> _conversationList = [];
|
||||
|
|
@ -45,7 +51,8 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
bool _haveMoreData = true;
|
||||
int _totalUnReadCount = 0;
|
||||
String? _scrollToConversation;
|
||||
final TUIChatGlobalModel globalChatModel = serviceLocator<TUIChatGlobalModel>();
|
||||
final TUIChatGlobalModel globalChatModel =
|
||||
serviceLocator<TUIChatGlobalModel>();
|
||||
|
||||
String _nextSeq = "0";
|
||||
ConversationLifeCycle? _lifeCycle;
|
||||
|
|
@ -54,10 +61,13 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
if (PlatformUtils().isWeb) {
|
||||
try {
|
||||
_conversationList.sort((a, b) {
|
||||
return b!.lastMessage!.timestamp!.compareTo(a!.lastMessage!.timestamp!);
|
||||
return b!.lastMessage!.timestamp!
|
||||
.compareTo(a!.lastMessage!.timestamp!);
|
||||
});
|
||||
|
||||
final pinnedConversation = _conversationList.where((element) => element?.isPinned == true).toList();
|
||||
final pinnedConversation = _conversationList
|
||||
.where((element) => element?.isPinned == true)
|
||||
.toList();
|
||||
_conversationList.removeWhere((element) => element?.isPinned == true);
|
||||
_conversationList = [...pinnedConversation, ..._conversationList];
|
||||
// ignore: empty_catches
|
||||
|
|
@ -69,7 +79,8 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
}
|
||||
|
||||
V2TimConversation? getConversation(String conversationID) {
|
||||
return _conversationList.firstWhere((element) => element?.conversationID == conversationID);
|
||||
return _conversationList.firstWhereOrNull(
|
||||
(element) => element?.conversationID == conversationID);
|
||||
}
|
||||
|
||||
String? get scrollToConversation => _scrollToConversation;
|
||||
|
|
@ -116,7 +127,8 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
}
|
||||
|
||||
TUIConversationViewModel() {
|
||||
_conversationListener = V2TimConversationListener(onConversationChanged: (conversationList) {
|
||||
_conversationListener =
|
||||
V2TimConversationListener(onConversationChanged: (conversationList) {
|
||||
_onConversationListChanged(conversationList);
|
||||
}, onNewConversation: (conversationList) {
|
||||
_addNewConversation(conversationList);
|
||||
|
|
@ -129,7 +141,7 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
if (!PlatformUtils().isWeb) {
|
||||
loadInitConversation();
|
||||
}
|
||||
}, onConversationDeleted:(List<String> conversationIDList) {
|
||||
}, onConversationDeleted: (List<String> conversationIDList) {
|
||||
_onConversationDeleted(conversationIDList);
|
||||
for (var conversationID in conversationIDList) {
|
||||
String resultID = "";
|
||||
|
|
@ -162,7 +174,8 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
Future<void> loadData({required int count}) async {
|
||||
_haveMoreData = true;
|
||||
final isRefresh = _nextSeq == "0";
|
||||
final conversationResult = await _conversationService.getConversationList(nextSeq: _nextSeq, count: count);
|
||||
final conversationResult = await _conversationService.getConversationList(
|
||||
nextSeq: _nextSeq, count: count);
|
||||
_nextSeq = conversationResult?.nextSeq ?? "";
|
||||
final conversationList = conversationResult?.conversationList;
|
||||
if (conversationList != null) {
|
||||
|
|
@ -175,8 +188,12 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
} else {
|
||||
combinedConversationList = [..._conversationList, ...conversationList];
|
||||
}
|
||||
final List<V2TimConversation?> finalConversationList = await _lifeCycle?.conversationListWillMount(combinedConversationList) ?? combinedConversationList;
|
||||
_conversationList = removeDuplicates<V2TimConversation?>(finalConversationList, (item1, item2) => item1?.conversationID == item2?.conversationID);
|
||||
final List<V2TimConversation?> finalConversationList = await _lifeCycle
|
||||
?.conversationListWillMount(combinedConversationList) ??
|
||||
combinedConversationList;
|
||||
_conversationList = removeDuplicates<V2TimConversation?>(
|
||||
finalConversationList,
|
||||
(item1, item2) => item1?.conversationID == item2?.conversationID);
|
||||
notifyListeners();
|
||||
}
|
||||
_totalUnReadCount = await _conversationService.getTotalUnreadCount();
|
||||
|
|
@ -193,11 +210,15 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
required String conversationID,
|
||||
required bool isPinned,
|
||||
}) {
|
||||
return _conversationService.pinConversation(conversationID: conversationID, isPinned: isPinned);
|
||||
return _conversationService.pinConversation(
|
||||
conversationID: conversationID, isPinned: isPinned);
|
||||
}
|
||||
|
||||
Future<V2TimCallback?> clearHistoryMessage({required String convID, required int convType}) async {
|
||||
if (_lifeCycle?.shouldClearHistoricalMessageForConversation != null && await _lifeCycle!.shouldClearHistoricalMessageForConversation(convID) == false) {
|
||||
Future<V2TimCallback?> clearHistoryMessage(
|
||||
{required String convID, required int convType}) async {
|
||||
if (_lifeCycle?.shouldClearHistoricalMessageForConversation != null &&
|
||||
await _lifeCycle!.shouldClearHistoricalMessageForConversation(convID) ==
|
||||
false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -211,17 +232,22 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
}
|
||||
|
||||
searchFriends(String searchKey) async {
|
||||
final res = await _friendshipServices.searchFriends(searchParam: V2TimFriendSearchParam(keywordList: [searchKey]));
|
||||
final res = await _friendshipServices.searchFriends(
|
||||
searchParam: V2TimFriendSearchParam(keywordList: [searchKey]));
|
||||
return res;
|
||||
}
|
||||
|
||||
Future<V2TimCallback?> deleteConversation({required String conversationID}) async {
|
||||
if (_lifeCycle?.shouldDeleteConversation != null && await _lifeCycle!.shouldDeleteConversation(conversationID) == false) {
|
||||
Future<V2TimCallback?> deleteConversation(
|
||||
{required String conversationID}) async {
|
||||
if (_lifeCycle?.shouldDeleteConversation != null &&
|
||||
await _lifeCycle!.shouldDeleteConversation(conversationID) == false) {
|
||||
return null;
|
||||
}
|
||||
final res = await _conversationService.deleteConversation(conversationID: conversationID);
|
||||
final res = await _conversationService.deleteConversation(
|
||||
conversationID: conversationID);
|
||||
if (res.code == 0) {
|
||||
_conversationList.removeWhere((element) => element?.conversationID == conversationID);
|
||||
_conversationList
|
||||
.removeWhere((element) => element?.conversationID == conversationID);
|
||||
notifyListeners();
|
||||
}
|
||||
return res;
|
||||
|
|
@ -229,9 +255,11 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
|
||||
_onConversationListChanged(List<V2TimConversation> list) {
|
||||
for (int element = 0; element < list.length; element++) {
|
||||
int index = _conversationList.indexWhere((item) => item!.conversationID == list[element].conversationID);
|
||||
int index = _conversationList.indexWhere(
|
||||
(item) => item!.conversationID == list[element].conversationID);
|
||||
if (index > -1) {
|
||||
_conversationList.setAll(index, [list[element]] as List<V2TimConversation?>);
|
||||
_conversationList.setAll(
|
||||
index, [list[element]] as List<V2TimConversation?>);
|
||||
} else {
|
||||
_conversationList.add(list[element]);
|
||||
}
|
||||
|
|
@ -242,10 +270,13 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
|
||||
_onConversationDeleted(List<String> list) {
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
int index = _conversationList.indexWhere((item) => item!.conversationID == list[i]);
|
||||
int index = _conversationList
|
||||
.indexWhere((item) => item!.conversationID == list[i]);
|
||||
if (index > -1) {
|
||||
_conversationList.removeAt(index);
|
||||
_conversationList = removeDuplicates<V2TimConversation?>(_conversationList, (item1, item2) => item1?.conversationID == item2?.conversationID);
|
||||
_conversationList = removeDuplicates<V2TimConversation?>(
|
||||
_conversationList,
|
||||
(item1, item2) => item1?.conversationID == item2?.conversationID);
|
||||
}
|
||||
}
|
||||
notifyListeners();
|
||||
|
|
@ -253,16 +284,19 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
|
||||
_addNewConversation(List<V2TimConversation> list) {
|
||||
_conversationList.addAll(list);
|
||||
_conversationList = removeDuplicates<V2TimConversation?>(_conversationList, (item1, item2) => item1?.conversationID == item2?.conversationID);
|
||||
_conversationList = removeDuplicates<V2TimConversation?>(_conversationList,
|
||||
(item1, item2) => item1?.conversationID == item2?.conversationID);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
setConversationListener() {
|
||||
_conversationService.addConversationListener(listener: _conversationListener);
|
||||
_conversationService.addConversationListener(
|
||||
listener: _conversationListener);
|
||||
}
|
||||
|
||||
removeConversationListener() {
|
||||
_conversationService.removeConversationListener(listener: _conversationListener);
|
||||
_conversationService.removeConversationListener(
|
||||
listener: _conversationListener);
|
||||
}
|
||||
|
||||
Future<V2TimCallback> setConversationDraft({
|
||||
|
|
@ -272,19 +306,25 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
String? groupID,
|
||||
bool isAllowWeb = true,
|
||||
}) async {
|
||||
assert(!isTopic || (groupID != null && groupID.isNotEmpty), "When 'isTopic' is true, 'groupID' must not be null or empty.");
|
||||
assert(!isTopic || (groupID != null && groupID.isNotEmpty),
|
||||
"When 'isTopic' is true, 'groupID' must not be null or empty.");
|
||||
if (PlatformUtils().isWeb && isAllowWeb) {
|
||||
webDraftMap[conversationID] = draftText ?? "";
|
||||
return V2TimCallback(code: 0, desc: "");
|
||||
} else {
|
||||
if (isTopic) {
|
||||
final topicInfoList = await TencentImSDKPlugin.v2TIMManager.getGroupManager().getTopicInfoList(groupID: groupID!, topicIDList: [conversationID]);
|
||||
final topicInfoList = await TencentImSDKPlugin.v2TIMManager
|
||||
.getGroupManager()
|
||||
.getTopicInfoList(groupID: groupID!, topicIDList: [conversationID]);
|
||||
final topicInfo = topicInfoList.data?.first.topicInfo;
|
||||
topicInfo?.draftText = draftText;
|
||||
final res = await TencentImSDKPlugin.v2TIMManager.getGroupManager().setTopicInfo(groupID: groupID, topicInfo: topicInfo!);
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getGroupManager()
|
||||
.setTopicInfo(groupID: groupID, topicInfo: topicInfo!);
|
||||
return res;
|
||||
} else {
|
||||
return _conversationService.setConversationDraft(conversationID: conversationID, draftText: draftText);
|
||||
return _conversationService.setConversationDraft(
|
||||
conversationID: conversationID, draftText: draftText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||
import 'package:flutter_slidable_plus_plus/flutter_slidable_plus_plus.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/block_list_life_cycle.dart';
|
||||
|
|
@ -88,7 +88,8 @@ class _TIMUIKitBlackListState extends TIMUIKitState<TIMUIKitBlackList> {
|
|||
child: Text(
|
||||
showName,
|
||||
style: TextStyle(
|
||||
color: theme.black, fontSize: isDesktopScreen ? 14 : 18),
|
||||
color: theme.black,
|
||||
fontSize: isDesktopScreen ? 14 : 18),
|
||||
),
|
||||
)),
|
||||
if (isDesktopScreen)
|
||||
|
|
@ -132,7 +133,6 @@ class _TIMUIKitBlackListState extends TIMUIKitState<TIMUIKitBlackList> {
|
|||
return widget.itemBuilder ?? _itemBuilder;
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
return MultiProvider(
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -5,7 +5,6 @@ import 'dart:io';
|
|||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:image_clipboard/image_clipboard.dart';
|
||||
import 'package:open_file/open_file.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart';
|
||||
|
|
@ -196,13 +195,15 @@ class TIMUIKitMessageTooltipState
|
|||
bool showTranslation = true;
|
||||
if (widget.message.localCustomData != null) {
|
||||
final LocalCustomDataModel localCustomData = LocalCustomDataModel.fromMap(
|
||||
json.decode(TencentUtils.checkString(widget.message.localCustomData) ?? "{}"));
|
||||
if (localCustomData.translatedText != null && localCustomData.translatedText != "") {
|
||||
json.decode(
|
||||
TencentUtils.checkString(widget.message.localCustomData) ??
|
||||
"{}"));
|
||||
if (localCustomData.translatedText != null &&
|
||||
localCustomData.translatedText != "") {
|
||||
showTranslation = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final dynamicQuote =
|
||||
model.chatConfig.isAtWhenReplyDynamic?.call(widget.message);
|
||||
|
||||
|
|
@ -405,12 +406,6 @@ class TIMUIKitMessageTooltipState
|
|||
} catch (e) {}
|
||||
}
|
||||
|
||||
Future<void> copyImageToClipboard(String imagePath) async {
|
||||
ImageClipboard().copyImage(imagePath);
|
||||
// final DesktopClipboard desktopClipboard = DesktopClipboard();
|
||||
// desktopClipboard.copyImage(imagePath);
|
||||
}
|
||||
|
||||
_onTap(String operation, TUIChatSeparateViewModel model) async {
|
||||
final messageItem = widget.message;
|
||||
final msgID = messageItem.msgID as String;
|
||||
|
|
@ -494,13 +489,6 @@ class TIMUIKitMessageTooltipState
|
|||
infoCode: 6660408));
|
||||
// ignore: empty_catches
|
||||
} catch (e) {}
|
||||
} else if (widget.message.elemType ==
|
||||
MessageElemType.V2TIM_ELEM_TYPE_IMAGE) {
|
||||
final savePath = (TencentUtils.checkString(
|
||||
widget.message.imageElem!.imageList?[0]?.localUrl) ??
|
||||
TencentUtils.checkString(widget.message.imageElem?.path) ??
|
||||
"");
|
||||
copyImageToClipboard(savePath);
|
||||
}
|
||||
break;
|
||||
case "replyMessage":
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import 'package:crypto/crypto.dart';
|
|||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:image_gallery_saver/image_gallery_saver.dart';
|
||||
import 'package:image_gallery_saver_plus/image_gallery_saver_plus.dart';
|
||||
import 'package:loading_animation_widget/loading_animation_widget.dart';
|
||||
import 'package:open_file/open_file.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
|
@ -172,7 +172,8 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
if (model.getMessageProgress(widget.message.msgID) == 100) {
|
||||
String savePath;
|
||||
if (widget.message.imageElem!.path != null &&
|
||||
widget.message.imageElem!.path != '' && File(widget.message.imageElem!.path!).existsSync()) {
|
||||
widget.message.imageElem!.path != '' &&
|
||||
File(widget.message.imageElem!.path!).existsSync()) {
|
||||
savePath = widget.message.imageElem!.path!;
|
||||
} else {
|
||||
savePath = model.getFileMessageLocation(widget.message.msgID);
|
||||
|
|
@ -593,7 +594,6 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
|
||||
Widget? _renderImage(dynamic heroTag, TUITheme theme,
|
||||
{V2TimImage? originalImg, V2TimImage? smallImg}) {
|
||||
|
||||
double positionRadio = 1.0;
|
||||
if (smallImg?.width != null &&
|
||||
smallImg?.height != null &&
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import 'dart:math';
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_easyrefresh/easy_refresh.dart';
|
||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||
import 'package:flutter_slidable_plus_plus/flutter_slidable_plus_plus.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:scroll_to_index/scroll_to_index.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
|
|
@ -22,11 +22,15 @@ import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitConversation/tim_uikit
|
|||
import 'package:tencent_cloud_chat_uikit/ui/widgets/customize_ball_pulse_header.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart';
|
||||
|
||||
typedef ConversationItemBuilder = Widget Function(V2TimConversation conversationItem, [V2TimUserStatus? onlineStatus]);
|
||||
typedef ConversationItemBuilder = Widget Function(
|
||||
V2TimConversation conversationItem,
|
||||
[V2TimUserStatus? onlineStatus]);
|
||||
|
||||
typedef ConversationItemSlideBuilder = List<ConversationItemSlidePanel> Function(V2TimConversation conversationItem);
|
||||
typedef ConversationItemSlideBuilder = List<ConversationItemSlidePanel>
|
||||
Function(V2TimConversation conversationItem);
|
||||
|
||||
typedef ConversationItemSecondaryMenuBuilder = Widget Function(V2TimConversation conversationItem, VoidCallback onClose);
|
||||
typedef ConversationItemSecondaryMenuBuilder = Widget Function(
|
||||
V2TimConversation conversationItem, VoidCallback onClose);
|
||||
|
||||
class TIMUIKitConversation extends StatefulWidget {
|
||||
/// the callback after clicking conversation item
|
||||
|
|
@ -140,11 +144,14 @@ class ConversationItemSlidePanel extends TIMUIKitStatelessWidget {
|
|||
}
|
||||
|
||||
class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
||||
final TUIConversationViewModel model = serviceLocator<TUIConversationViewModel>();
|
||||
final TUIConversationViewModel model =
|
||||
serviceLocator<TUIConversationViewModel>();
|
||||
late TIMUIKitConversationController _timuiKitConversationController;
|
||||
final TUIThemeViewModel themeViewModel = serviceLocator<TUIThemeViewModel>();
|
||||
final TUIFriendShipViewModel friendShipViewModel = serviceLocator<TUIFriendShipViewModel>();
|
||||
final TUIGroupListenerModel groupListenerModel = serviceLocator<TUIGroupListenerModel>();
|
||||
final TUIFriendShipViewModel friendShipViewModel =
|
||||
serviceLocator<TUIFriendShipViewModel>();
|
||||
final TUIGroupListenerModel groupListenerModel =
|
||||
serviceLocator<TUIGroupListenerModel>();
|
||||
late AutoScrollController _autoScrollController;
|
||||
|
||||
@override
|
||||
|
|
@ -168,21 +175,30 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
}
|
||||
|
||||
_clearHistory(V2TimConversation conversationItem) {
|
||||
_timuiKitConversationController.clearHistoryMessage(conversation: conversationItem);
|
||||
_timuiKitConversationController.clearHistoryMessage(
|
||||
conversation: conversationItem);
|
||||
}
|
||||
|
||||
_pinConversation(V2TimConversation conversation) {
|
||||
_timuiKitConversationController.pinConversation(conversationID: conversation.conversationID, isPinned: !conversation.isPinned!);
|
||||
_timuiKitConversationController.pinConversation(
|
||||
conversationID: conversation.conversationID,
|
||||
isPinned: !conversation.isPinned!);
|
||||
}
|
||||
|
||||
_deleteConversation(V2TimConversation conversation) {
|
||||
_timuiKitConversationController.deleteConversation(conversationID: conversation.conversationID);
|
||||
_timuiKitConversationController.deleteConversation(
|
||||
conversationID: conversation.conversationID);
|
||||
}
|
||||
|
||||
List<V2TimConversation?> getFilteredConversation() {
|
||||
List<V2TimConversation?> filteredConversationList = model.conversationList.where((element) => (element?.groupID != null || element?.userID != null)).toList();
|
||||
List<V2TimConversation?> 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;
|
||||
}
|
||||
|
|
@ -208,7 +224,8 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
}
|
||||
}
|
||||
|
||||
Widget _defaultSecondaryMenu(V2TimConversation conversationItem, VoidCallback onClose) {
|
||||
Widget _defaultSecondaryMenu(
|
||||
V2TimConversation conversationItem, VoidCallback onClose) {
|
||||
return TUIKitColumnMenu(data: [
|
||||
if (!PlatformUtils().isWeb)
|
||||
ColumnMenuItem(
|
||||
|
|
@ -220,7 +237,11 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
}),
|
||||
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);
|
||||
|
|
@ -245,7 +266,8 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
onPressed: (context) {
|
||||
_clearHistory(conversationItem);
|
||||
},
|
||||
backgroundColor: theme.conversationItemSliderClearBgColor ?? CommonColor.primaryColor,
|
||||
backgroundColor: theme.conversationItemSliderClearBgColor ??
|
||||
CommonColor.primaryColor,
|
||||
foregroundColor: theme.conversationItemSliderTextColor,
|
||||
label: TIM_t("清除"),
|
||||
spacing: 0,
|
||||
|
|
@ -255,7 +277,8 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
onPressed: (context) {
|
||||
_pinConversation(conversationItem);
|
||||
},
|
||||
backgroundColor: theme.conversationItemSliderPinBgColor ?? CommonColor.infoColor,
|
||||
backgroundColor:
|
||||
theme.conversationItemSliderPinBgColor ?? CommonColor.infoColor,
|
||||
foregroundColor: theme.conversationItemSliderTextColor,
|
||||
label: conversationItem.isPinned! ? TIM_t("取消置顶") : TIM_t("置顶"),
|
||||
),
|
||||
|
|
@ -263,14 +286,16 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
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);
|
||||
}
|
||||
|
|
@ -289,19 +314,23 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
@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),
|
||||
ChangeNotifierProvider.value(value: friendShipViewModel),
|
||||
ChangeNotifierProvider.value(value: groupListenerModel)],
|
||||
ChangeNotifierProvider.value(value: groupListenerModel)
|
||||
],
|
||||
builder: (BuildContext context, Widget? w) {
|
||||
final _model = Provider.of<TUIConversationViewModel>(context);
|
||||
bool haveMoreData = _model.haveMoreData;
|
||||
final _friendShipViewModel = Provider.of<TUIFriendShipViewModel>(context);
|
||||
final _friendShipViewModel =
|
||||
Provider.of<TUIFriendShipViewModel>(context);
|
||||
_model.lifeCycle = widget.lifeCycle;
|
||||
|
||||
final TUIGroupListenerModel groupListenerModel = Provider.of<TUIGroupListenerModel>(context, listen: true);
|
||||
final TUIGroupListenerModel groupListenerModel =
|
||||
Provider.of<TUIGroupListenerModel>(context, listen: true);
|
||||
final NeedUpdate? needUpdate = groupListenerModel.needUpdate;
|
||||
if (needUpdate != null) {
|
||||
groupListenerModel.needUpdate = null;
|
||||
|
|
@ -313,12 +342,14 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
} else if (needUpdate.updateType == UpdateType.kickedFromGroup) {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: "${TIM_t("您已被踢出")}${needUpdate!.extraData}",
|
||||
infoRecommendText:
|
||||
"${TIM_t("您已被踢出")}${needUpdate!.extraData}",
|
||||
infoCode: 6661402));
|
||||
}
|
||||
}
|
||||
|
||||
List<V2TimConversation?> filteredConversationList = getFilteredConversation();
|
||||
List<V2TimConversation?> filteredConversationList =
|
||||
getFilteredConversation();
|
||||
|
||||
if (TencentUtils.checkString(_model.scrollToConversation) != null) {
|
||||
_onScrollToConversation(_model.scrollToConversation!);
|
||||
|
|
@ -340,15 +371,21 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
|
||||
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;
|
||||
|
||||
|
|
@ -365,14 +402,21 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
lastMessageBuilder: widget.lastMessageBuilder,
|
||||
faceUrl: conversationItem.faceUrl ?? "",
|
||||
nickName: conversationItem.showName ?? "",
|
||||
isDisturb: (conversationItem.groupType == "Meeting" ? false : conversationItem
|
||||
.recvOpt != 0),
|
||||
isDisturb:
|
||||
(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 && conversationItem.userID != null && conversationItem.userID!.isNotEmpty) ? onlineStatus : null,
|
||||
onlineStatus: (widget.isShowOnlineStatus &&
|
||||
conversationItem.userID != null &&
|
||||
conversationItem.userID!.isNotEmpty)
|
||||
? onlineStatus
|
||||
: null,
|
||||
draftTimestamp: conversationItem.draftTimestamp,
|
||||
convType: conversationItem.type),
|
||||
onTap: () => onTapConvItem(conversationItem),
|
||||
|
|
@ -389,12 +433,23 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
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));
|
||||
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(),
|
||||
),
|
||||
|
|
@ -403,10 +458,19 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
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)),
|
||||
child: Slidable(
|
||||
groupTag: 'conversation-list',
|
||||
child: conversationLineItem(),
|
||||
endActionPane: ActionPane(
|
||||
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(
|
||||
|
|
@ -420,7 +484,9 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
child: conversationList(),
|
||||
),
|
||||
),
|
||||
desktopWidget: Scrollbar(controller: _autoScrollController, child: conversationList()));
|
||||
desktopWidget: Scrollbar(
|
||||
controller: _autoScrollController,
|
||||
child: conversationList()));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import 'dart:math';
|
|||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||
import 'package:flutter_slidable_plus_plus/flutter_slidable_plus_plus.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
|
|
@ -26,23 +26,34 @@ class GroupProfileGroupManage extends StatefulWidget {
|
|||
State<StatefulWidget> createState() => GroupProfileGroupManageState();
|
||||
}
|
||||
|
||||
class GroupProfileGroupManageState extends TIMUIKitState<GroupProfileGroupManage> {
|
||||
class GroupProfileGroupManageState
|
||||
extends TIMUIKitState<GroupProfileGroupManage> {
|
||||
bool isShowManageBox = false;
|
||||
|
||||
@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 model = Provider.of<TUIGroupProfileModel>(context);
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
decoration: BoxDecoration(color: Colors.white, border: isDesktopScreen ? null : Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: isDesktopScreen
|
||||
? null
|
||||
: Border(
|
||||
bottom: BorderSide(
|
||||
color: theme.weakDividerColor ??
|
||||
CommonColor.weakDividerColor))),
|
||||
child: Column(
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) ==
|
||||
DeviceType.Desktop;
|
||||
if (!isDesktopScreen) {
|
||||
Navigator.push(
|
||||
context,
|
||||
|
|
@ -61,12 +72,15 @@ class GroupProfileGroupManageState extends TIMUIKitState<GroupProfileGroupManage
|
|||
children: [
|
||||
Text(
|
||||
TIM_t("群管理"),
|
||||
style: TextStyle(fontSize: isDesktopScreen ? 14 : 16, color: theme.darkTextColor),
|
||||
style: TextStyle(
|
||||
fontSize: isDesktopScreen ? 14 : 16,
|
||||
color: theme.darkTextColor),
|
||||
),
|
||||
AnimatedRotation(
|
||||
turns: isShowManageBox ? 0.25 : 0,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: Icon(Icons.keyboard_arrow_right, color: theme.weakTextColor),
|
||||
child: Icon(Icons.keyboard_arrow_right,
|
||||
color: theme.weakTextColor),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
|
@ -94,7 +108,8 @@ class GroupProfileGroupManagePage extends StatefulWidget {
|
|||
State<StatefulWidget> createState() => _GroupProfileGroupManagePageState();
|
||||
}
|
||||
|
||||
class _GroupProfileGroupManagePageState extends TIMUIKitState<GroupProfileGroupManagePage> {
|
||||
class _GroupProfileGroupManagePageState
|
||||
extends TIMUIKitState<GroupProfileGroupManagePage> {
|
||||
int? serverTime;
|
||||
|
||||
@override
|
||||
|
|
@ -113,20 +128,38 @@ class _GroupProfileGroupManagePageState extends TIMUIKitState<GroupProfileGroupM
|
|||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
return MultiProvider(
|
||||
providers: [ChangeNotifierProvider.value(value: widget.model), ChangeNotifierProvider.value(value: serviceLocator<TUIThemeViewModel>())],
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: widget.model),
|
||||
ChangeNotifierProvider.value(
|
||||
value: serviceLocator<TUIThemeViewModel>())
|
||||
],
|
||||
builder: (context, w) {
|
||||
final memberList = Provider.of<TUIGroupProfileModel>(context).groupMemberList;
|
||||
final memberList =
|
||||
Provider.of<TUIGroupProfileModel>(context).groupMemberList;
|
||||
final theme = Provider.of<TUIThemeViewModel>(context).theme;
|
||||
final isAllMuted = widget.model.groupInfo?.isAllMuted ?? false;
|
||||
final bool isAllowMuteMember = (widget.model.groupInfo?.groupType ?? "") != GroupType.Work;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final bool isAllowMuteMember =
|
||||
(widget.model.groupInfo?.groupType ?? "") != GroupType.Work;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
|
||||
Widget managePage() {
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 12, left: isDesktopScreen ? 0 : 16, bottom: isDesktopScreen ? 0 : 12, right: isDesktopScreen ? 0 : 12),
|
||||
decoration: BoxDecoration(color: Colors.white, border: isDesktopScreen ? null : Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
padding: EdgeInsets.only(
|
||||
top: 12,
|
||||
left: isDesktopScreen ? 0 : 16,
|
||||
bottom: isDesktopScreen ? 0 : 12,
|
||||
right: isDesktopScreen ? 0 : 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: isDesktopScreen
|
||||
? null
|
||||
: Border(
|
||||
bottom: BorderSide(
|
||||
color: theme.weakDividerColor ??
|
||||
CommonColor.weakDividerColor))),
|
||||
child: InkWell(
|
||||
onTap: isDesktopScreen
|
||||
? null
|
||||
|
|
@ -134,7 +167,8 @@ class _GroupProfileGroupManagePageState extends TIMUIKitState<GroupProfileGroupM
|
|||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => GroupProfileSetManagerPage(
|
||||
builder: (context) =>
|
||||
GroupProfileSetManagerPage(
|
||||
model: widget.model,
|
||||
),
|
||||
));
|
||||
|
|
@ -143,12 +177,22 @@ class _GroupProfileGroupManagePageState extends TIMUIKitState<GroupProfileGroupM
|
|||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(TIM_t("群管理员"), style: TextStyle(fontSize: 14, color: theme.darkTextColor)),
|
||||
Text(TIM_t("群管理员"),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: theme.darkTextColor)),
|
||||
],
|
||||
)
|
||||
: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [Text(TIM_t("设置管理员"), style: TextStyle(fontSize: isDesktopScreen ? 14 : 16, color: theme.darkTextColor)), Icon(Icons.keyboard_arrow_right, color: theme.weakTextColor)],
|
||||
children: [
|
||||
Text(TIM_t("设置管理员"),
|
||||
style: TextStyle(
|
||||
fontSize: isDesktopScreen ? 14 : 16,
|
||||
color: theme.darkTextColor)),
|
||||
Icon(Icons.keyboard_arrow_right,
|
||||
color: theme.weakTextColor)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -158,14 +202,21 @@ class _GroupProfileGroupManagePageState extends TIMUIKitState<GroupProfileGroupM
|
|||
),
|
||||
if (!isDesktopScreen)
|
||||
Container(
|
||||
padding: const EdgeInsets.only(top: 12, left: 16, bottom: 12, right: 12),
|
||||
decoration: BoxDecoration(color: Colors.white, border: Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
padding: const EdgeInsets.only(
|
||||
top: 12, left: 16, bottom: 12, right: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: theme.weakDividerColor ??
|
||||
CommonColor.weakDividerColor))),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
TIM_t("全员禁言"),
|
||||
style: TextStyle(fontSize: 16, color: theme.darkTextColor),
|
||||
style: TextStyle(
|
||||
fontSize: 16, color: theme.darkTextColor),
|
||||
),
|
||||
CupertinoSwitch(
|
||||
value: isAllMuted,
|
||||
|
|
@ -180,7 +231,9 @@ class _GroupProfileGroupManagePageState extends TIMUIKitState<GroupProfileGroupM
|
|||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(TIM_t("禁言"), style: TextStyle(fontSize: 14, color: theme.darkTextColor)),
|
||||
Text(TIM_t("禁言"),
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: theme.darkTextColor)),
|
||||
],
|
||||
),
|
||||
if (isDesktopScreen)
|
||||
|
|
@ -200,12 +253,14 @@ class _GroupProfileGroupManagePageState extends TIMUIKitState<GroupProfileGroupM
|
|||
),
|
||||
if (!isDesktopScreen)
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10, horizontal: 16),
|
||||
color: theme.weakBackgroundColor,
|
||||
alignment: Alignment.topLeft,
|
||||
child: Text(
|
||||
TIM_t("全员禁言开启后,只允许群主和管理员发言。"),
|
||||
style: TextStyle(fontSize: 12, color: theme.weakTextColor),
|
||||
style:
|
||||
TextStyle(fontSize: 12, color: theme.weakTextColor),
|
||||
),
|
||||
),
|
||||
if (!isAllMuted && isAllowMuteMember)
|
||||
|
|
@ -221,7 +276,14 @@ class _GroupProfileGroupManagePageState extends TIMUIKitState<GroupProfileGroupM
|
|||
: const EdgeInsets.only(
|
||||
bottom: 4,
|
||||
),
|
||||
decoration: isDesktopScreen ? null : BoxDecoration(color: Colors.white, border: Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
decoration: isDesktopScreen
|
||||
? null
|
||||
: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: theme.weakDividerColor ??
|
||||
CommonColor.weakDividerColor))),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
|
|
@ -242,15 +304,21 @@ class _GroupProfileGroupManagePageState extends TIMUIKitState<GroupProfileGroupM
|
|||
key: groupProfileAddAdminKey,
|
||||
appbarTitle: TIM_t("设置禁言"),
|
||||
memberList: memberList.where((element) {
|
||||
final isMute = (serverTime != null ? (element?.muteUntil ?? 0) > serverTime! : false);
|
||||
final isMember = element!.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_MEMBER;
|
||||
final isMute = (serverTime != null
|
||||
? (element?.muteUntil ?? 0) > serverTime!
|
||||
: false);
|
||||
final isMember = element!.role ==
|
||||
GroupMemberRoleType
|
||||
.V2TIM_GROUP_MEMBER_ROLE_MEMBER;
|
||||
return !isMute && isMember;
|
||||
}).toList(),
|
||||
selectCompletedHandler: (context, selectedMember) async {
|
||||
selectCompletedHandler:
|
||||
(context, selectedMember) async {
|
||||
if (selectedMember.isNotEmpty) {
|
||||
for (var member in selectedMember) {
|
||||
final userID = member!.userID;
|
||||
widget.model.muteGroupMember(userID, true, serverTime);
|
||||
widget.model
|
||||
.muteGroupMember(userID, true, serverTime);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -269,29 +337,48 @@ class _GroupProfileGroupManagePageState extends TIMUIKitState<GroupProfileGroupM
|
|||
},
|
||||
child: (onClose) => muteMember());
|
||||
} else {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => muteMember()));
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => muteMember()));
|
||||
}
|
||||
},
|
||||
),
|
||||
if (!isAllMuted && isAllowMuteMember)
|
||||
...memberList
|
||||
.where((element) => (serverTime != null ? (element?.muteUntil ?? 0) > serverTime! : false))
|
||||
.where((element) => (serverTime != null
|
||||
? (element?.muteUntil ?? 0) > serverTime!
|
||||
: false))
|
||||
.map((e) => Container(
|
||||
padding: isDesktopScreen ? const EdgeInsets.only(left: 16) : null,
|
||||
padding: isDesktopScreen
|
||||
? const EdgeInsets.only(left: 16)
|
||||
: null,
|
||||
child: GestureDetector(
|
||||
onSecondaryTapDown: (details) {
|
||||
TUIKitWidePopup.showPopupWindow(
|
||||
operationKey: TUIKitWideModalOperationKey.setUnmute,
|
||||
operationKey:
|
||||
TUIKitWideModalOperationKey.setUnmute,
|
||||
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), details.globalPosition.dy),
|
||||
offset: Offset(
|
||||
min(
|
||||
details.globalPosition.dx,
|
||||
MediaQuery.of(context).size.width -
|
||||
80),
|
||||
details.globalPosition.dy),
|
||||
child: (onClose) => TUIKitColumnMenu(data: [
|
||||
ColumnMenuItem(
|
||||
label: TIM_t("删除"),
|
||||
icon: const Icon(Icons.remove_circle_outline, size: 16),
|
||||
icon: const Icon(
|
||||
Icons.remove_circle_outline,
|
||||
size: 16),
|
||||
onClick: () {
|
||||
widget.model.muteGroupMember(e.userID, false, serverTime);
|
||||
widget.model.muteGroupMember(
|
||||
e.userID,
|
||||
false,
|
||||
serverTime);
|
||||
onClose();
|
||||
}),
|
||||
]));
|
||||
|
|
@ -299,17 +386,21 @@ class _GroupProfileGroupManagePageState extends TIMUIKitState<GroupProfileGroupM
|
|||
child: _buildListItem(
|
||||
context,
|
||||
e!,
|
||||
ActionPane(motion: const DrawerMotion(), children: [
|
||||
SlidableAction(
|
||||
onPressed: (_) {
|
||||
widget.model.muteGroupMember(e.userID, false, serverTime);
|
||||
},
|
||||
flex: 1,
|
||||
backgroundColor: theme.cautionColor ?? CommonColor.cautionColor,
|
||||
autoClose: true,
|
||||
label: TIM_t("删除"),
|
||||
)
|
||||
])),
|
||||
ActionPane(
|
||||
motion: const DrawerMotion(),
|
||||
children: [
|
||||
SlidableAction(
|
||||
onPressed: (_) {
|
||||
widget.model.muteGroupMember(
|
||||
e.userID, false, serverTime);
|
||||
},
|
||||
flex: 1,
|
||||
backgroundColor: theme.cautionColor ??
|
||||
CommonColor.cautionColor,
|
||||
autoClose: true,
|
||||
label: TIM_t("删除"),
|
||||
)
|
||||
])),
|
||||
),
|
||||
))
|
||||
.toList()
|
||||
|
|
@ -324,7 +415,8 @@ class _GroupProfileGroupManagePageState extends TIMUIKitState<GroupProfileGroupM
|
|||
appBar: AppBar(
|
||||
title: Text(
|
||||
TIM_t("群管理"),
|
||||
style: TextStyle(color: theme.appbarTextColor, fontSize: 17),
|
||||
style:
|
||||
TextStyle(color: theme.appbarTextColor, fontSize: 17),
|
||||
),
|
||||
backgroundColor: theme.appbarBgColor ?? theme.primaryColor,
|
||||
shadowColor: theme.weakDividerColor,
|
||||
|
|
@ -369,9 +461,11 @@ _getShowName(V2TimGroupMemberFullInfo? item) {
|
|||
: userID;
|
||||
}
|
||||
|
||||
Widget _buildListItem(BuildContext context, V2TimGroupMemberFullInfo memberInfo, ActionPane? endActionPane) {
|
||||
Widget _buildListItem(BuildContext context, V2TimGroupMemberFullInfo memberInfo,
|
||||
ActionPane? endActionPane) {
|
||||
final theme = Provider.of<TUIThemeViewModel>(context).theme;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
|
||||
Widget nameItem() {
|
||||
return Container(
|
||||
|
|
@ -390,42 +484,67 @@ Widget _buildListItem(BuildContext context, V2TimGroupMemberFullInfo memberInfo,
|
|||
),
|
||||
title: Row(
|
||||
children: [
|
||||
Text(_getShowName(memberInfo), style: TextStyle(fontSize: isDesktopScreen ? 14 : 16)),
|
||||
Text(_getShowName(memberInfo),
|
||||
style: TextStyle(fontSize: isDesktopScreen ? 14 : 16)),
|
||||
],
|
||||
),
|
||||
onTap: () {},
|
||||
),
|
||||
if (!isDesktopScreen) Divider(thickness: 1, indent: 74, endIndent: 0, color: theme.weakDividerColor, height: 0)
|
||||
if (!isDesktopScreen)
|
||||
Divider(
|
||||
thickness: 1,
|
||||
indent: 74,
|
||||
endIndent: 0,
|
||||
color: theme.weakDividerColor,
|
||||
height: 0)
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
return TUIKitScreenUtils.getDeviceWidget(context: context, desktopWidget: nameItem(), defaultWidget: SingleChildScrollView(child: Slidable(endActionPane: endActionPane, child: nameItem())));
|
||||
return TUIKitScreenUtils.getDeviceWidget(
|
||||
context: context,
|
||||
desktopWidget: nameItem(),
|
||||
defaultWidget: SingleChildScrollView(
|
||||
child: Slidable(endActionPane: endActionPane, child: nameItem())));
|
||||
}
|
||||
|
||||
/// 选择管理员
|
||||
class GroupProfileSetManagerPage extends StatefulWidget {
|
||||
final TUIGroupProfileModel model;
|
||||
|
||||
const GroupProfileSetManagerPage({Key? key, required this.model}) : super(key: key);
|
||||
const GroupProfileSetManagerPage({Key? key, required this.model})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _GroupProfileSetManagerPageState();
|
||||
}
|
||||
|
||||
class _GroupProfileSetManagerPageState extends TIMUIKitState<GroupProfileSetManagerPage> {
|
||||
List<V2TimGroupMemberFullInfo?> _getAdminMemberList(List<V2TimGroupMemberFullInfo?> memberList) {
|
||||
return memberList.where((member) => member?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN).toList();
|
||||
class _GroupProfileSetManagerPageState
|
||||
extends TIMUIKitState<GroupProfileSetManagerPage> {
|
||||
List<V2TimGroupMemberFullInfo?> _getAdminMemberList(
|
||||
List<V2TimGroupMemberFullInfo?> memberList) {
|
||||
return memberList
|
||||
.where((member) =>
|
||||
member?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN)
|
||||
.toList();
|
||||
}
|
||||
|
||||
List<V2TimGroupMemberFullInfo?> _getOwnerList(List<V2TimGroupMemberFullInfo?> memberList) {
|
||||
return memberList.where((member) => member?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER).toList();
|
||||
List<V2TimGroupMemberFullInfo?> _getOwnerList(
|
||||
List<V2TimGroupMemberFullInfo?> memberList) {
|
||||
return memberList
|
||||
.where((member) =>
|
||||
member?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER)
|
||||
.toList();
|
||||
}
|
||||
|
||||
_removeAdmin(BuildContext context, V2TimGroupMemberFullInfo memberFullInfo) async {
|
||||
_removeAdmin(
|
||||
BuildContext context, V2TimGroupMemberFullInfo memberFullInfo) async {
|
||||
final res = await widget.model.setMemberToNormal(memberFullInfo.userID);
|
||||
if (res.code == 0) {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("成功取消管理员身份"), infoCode: 6661003));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("成功取消管理员身份"),
|
||||
infoCode: 6661003));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -441,7 +560,8 @@ class _GroupProfileSetManagerPageState extends TIMUIKitState<GroupProfileSetMana
|
|||
final adminList = _getAdminMemberList(memberList);
|
||||
final ownerList = _getOwnerList(memberList);
|
||||
final String option2 = adminList.length.toString();
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
|
||||
Widget adminPage() {
|
||||
return SingleChildScrollView(
|
||||
|
|
@ -451,7 +571,8 @@ class _GroupProfileSetManagerPageState extends TIMUIKitState<GroupProfileSetMana
|
|||
Container(
|
||||
alignment: Alignment.topLeft,
|
||||
color: theme.weakDividerColor,
|
||||
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 16),
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 6, horizontal: 16),
|
||||
child: Text(
|
||||
TIM_t("群主"),
|
||||
style: TextStyle(fontSize: 14, color: theme.weakTextColor),
|
||||
|
|
@ -469,7 +590,9 @@ class _GroupProfileSetManagerPageState extends TIMUIKitState<GroupProfileSetMana
|
|||
...ownerList
|
||||
.map(
|
||||
(e) => Container(
|
||||
padding: isDesktopScreen ? const EdgeInsets.only(left: 16) : null,
|
||||
padding: isDesktopScreen
|
||||
? const EdgeInsets.only(left: 16)
|
||||
: null,
|
||||
child: _buildListItem(context, e!, null),
|
||||
),
|
||||
)
|
||||
|
|
@ -478,9 +601,11 @@ class _GroupProfileSetManagerPageState extends TIMUIKitState<GroupProfileSetMana
|
|||
Container(
|
||||
alignment: Alignment.topLeft,
|
||||
color: theme.weakDividerColor,
|
||||
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 16),
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 6, horizontal: 16),
|
||||
child: Text(
|
||||
TIM_t_para("管理员 ({{option2}}/10)", "管理员 ($option2/10)")(option2: option2),
|
||||
TIM_t_para("管理员 ({{option2}}/10)", "管理员 ($option2/10)")(
|
||||
option2: option2),
|
||||
style: TextStyle(fontSize: 14, color: theme.weakTextColor),
|
||||
),
|
||||
),
|
||||
|
|
@ -489,7 +614,8 @@ class _GroupProfileSetManagerPageState extends TIMUIKitState<GroupProfileSetMana
|
|||
alignment: Alignment.topLeft,
|
||||
padding: const EdgeInsets.only(top: 10, bottom: 4, left: 16),
|
||||
child: Text(
|
||||
TIM_t_para("管理员 ({{option2}}/10)", "管理员 ($option2/10)")(option2: option2),
|
||||
TIM_t_para("管理员 ({{option2}}/10)", "管理员 ($option2/10)")(
|
||||
option2: option2),
|
||||
style: TextStyle(fontSize: 14, color: theme.primaryColor),
|
||||
),
|
||||
),
|
||||
|
|
@ -501,7 +627,14 @@ class _GroupProfileSetManagerPageState extends TIMUIKitState<GroupProfileSetMana
|
|||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 12,
|
||||
),
|
||||
decoration: isDesktopScreen ? null : BoxDecoration(color: Colors.white, border: Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
decoration: isDesktopScreen
|
||||
? null
|
||||
: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: theme.weakDividerColor ??
|
||||
CommonColor.weakDividerColor))),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
|
|
@ -529,9 +662,15 @@ class _GroupProfileSetManagerPageState extends TIMUIKitState<GroupProfileSetMana
|
|||
},
|
||||
child: (onClose) => GroupProfileAddAdmin(
|
||||
key: groupProfileAddAdminKey,
|
||||
memberList: memberList.where((element) => element?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_MEMBER).toList(),
|
||||
memberList: memberList
|
||||
.where((element) =>
|
||||
element?.role ==
|
||||
GroupMemberRoleType
|
||||
.V2TIM_GROUP_MEMBER_ROLE_MEMBER)
|
||||
.toList(),
|
||||
appbarTitle: TIM_t("设置管理员"),
|
||||
selectCompletedHandler: (context, selectedMember) async {
|
||||
selectCompletedHandler:
|
||||
(context, selectedMember) async {
|
||||
if (selectedMember.isNotEmpty) {
|
||||
for (var member in selectedMember) {
|
||||
final userID = member!.userID;
|
||||
|
|
@ -546,9 +685,15 @@ class _GroupProfileSetManagerPageState extends TIMUIKitState<GroupProfileSetMana
|
|||
MaterialPageRoute(
|
||||
builder: (context) => GroupProfileAddAdmin(
|
||||
key: groupProfileAddAdminKey,
|
||||
memberList: memberList.where((element) => element?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_MEMBER).toList(),
|
||||
memberList: memberList
|
||||
.where((element) =>
|
||||
element?.role ==
|
||||
GroupMemberRoleType
|
||||
.V2TIM_GROUP_MEMBER_ROLE_MEMBER)
|
||||
.toList(),
|
||||
appbarTitle: TIM_t("设置管理员"),
|
||||
selectCompletedHandler: (context, selectedMember) async {
|
||||
selectCompletedHandler:
|
||||
(context, selectedMember) async {
|
||||
if (selectedMember.isNotEmpty) {
|
||||
for (var member in selectedMember) {
|
||||
final userID = member!.userID;
|
||||
|
|
@ -564,15 +709,22 @@ class _GroupProfileSetManagerPageState extends TIMUIKitState<GroupProfileSetMana
|
|||
.map((e) => GestureDetector(
|
||||
onSecondaryTapDown: (details) {
|
||||
TUIKitWidePopup.showPopupWindow(
|
||||
operationKey: TUIKitWideModalOperationKey.deleteAdmin,
|
||||
operationKey:
|
||||
TUIKitWideModalOperationKey.deleteAdmin,
|
||||
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), details.globalPosition.dy),
|
||||
offset: Offset(
|
||||
min(details.globalPosition.dx,
|
||||
MediaQuery.of(context).size.width - 80),
|
||||
details.globalPosition.dy),
|
||||
child: (onClose) => TUIKitColumnMenu(data: [
|
||||
ColumnMenuItem(
|
||||
label: TIM_t("删除"),
|
||||
icon: const Icon(Icons.remove_circle_outline, size: 16),
|
||||
icon: const Icon(
|
||||
Icons.remove_circle_outline,
|
||||
size: 16),
|
||||
onClick: () {
|
||||
_removeAdmin(context, e);
|
||||
onClose();
|
||||
|
|
@ -580,21 +732,26 @@ class _GroupProfileSetManagerPageState extends TIMUIKitState<GroupProfileSetMana
|
|||
]));
|
||||
},
|
||||
child: Container(
|
||||
padding: isDesktopScreen ? const EdgeInsets.only(left: 16) : null,
|
||||
padding: isDesktopScreen
|
||||
? const EdgeInsets.only(left: 16)
|
||||
: null,
|
||||
child: _buildListItem(
|
||||
context,
|
||||
e!,
|
||||
ActionPane(motion: const DrawerMotion(), children: [
|
||||
SlidableAction(
|
||||
onPressed: (_) {
|
||||
_removeAdmin(context, e);
|
||||
},
|
||||
flex: 1,
|
||||
backgroundColor: theme.cautionColor ?? CommonColor.cautionColor,
|
||||
autoClose: true,
|
||||
label: TIM_t("删除"),
|
||||
)
|
||||
])),
|
||||
ActionPane(
|
||||
motion: const DrawerMotion(),
|
||||
children: [
|
||||
SlidableAction(
|
||||
onPressed: (_) {
|
||||
_removeAdmin(context, e);
|
||||
},
|
||||
flex: 1,
|
||||
backgroundColor: theme.cautionColor ??
|
||||
CommonColor.cautionColor,
|
||||
autoClose: true,
|
||||
label: TIM_t("删除"),
|
||||
)
|
||||
])),
|
||||
),
|
||||
))
|
||||
.toList(),
|
||||
|
|
@ -628,9 +785,16 @@ class _GroupProfileSetManagerPageState extends TIMUIKitState<GroupProfileSetMana
|
|||
class GroupProfileAddAdmin extends StatefulWidget {
|
||||
final List<V2TimGroupMemberFullInfo?> memberList;
|
||||
final String appbarTitle;
|
||||
final void Function(BuildContext context, List<V2TimGroupMemberFullInfo?> selectedMemberList)? selectCompletedHandler;
|
||||
final void Function(BuildContext context,
|
||||
List<V2TimGroupMemberFullInfo?> selectedMemberList)?
|
||||
selectCompletedHandler;
|
||||
|
||||
const GroupProfileAddAdmin({Key? key, required this.memberList, this.selectCompletedHandler, required this.appbarTitle}) : super(key: key);
|
||||
const GroupProfileAddAdmin(
|
||||
{Key? key,
|
||||
required this.memberList,
|
||||
this.selectCompletedHandler,
|
||||
required this.appbarTitle})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _GroupProfileAddAdminState();
|
||||
|
|
@ -664,8 +828,14 @@ class _GroupProfileAddAdminState extends TIMUIKitState<GroupProfileAddAdmin> {
|
|||
),
|
||||
...widget.memberList
|
||||
.map((e) => Container(
|
||||
decoration: BoxDecoration(color: Colors.white, border: Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: theme.weakDividerColor ??
|
||||
CommonColor.weakDividerColor))),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10, horizontal: 16),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
final isChecked = selectedMemberList.contains(e);
|
||||
|
|
@ -697,7 +867,8 @@ class _GroupProfileAddAdminState extends TIMUIKitState<GroupProfileAddAdmin> {
|
|||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Text(_getShowName(e), style: const TextStyle(fontSize: 16))
|
||||
Text(_getShowName(e),
|
||||
style: const TextStyle(fontSize: 16))
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import 'package:azlistview_all_platforms/azlistview_all_platforms.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||
import 'package:flutter_slidable_plus_plus/flutter_slidable_plus_plus.dart';
|
||||
import 'package:lpinyin/lpinyin.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
|
|
@ -24,9 +24,12 @@ class GroupProfileMemberList extends StatefulWidget {
|
|||
|
||||
// when the @ need filter some group types
|
||||
final String? groupType;
|
||||
final Function(List<V2TimGroupMemberFullInfo> selectedMember)? onSelectedMemberChange;
|
||||
final Function(List<V2TimGroupMemberFullInfo> selectedMember)?
|
||||
onSelectedMemberChange;
|
||||
// notice: onTapMemberItem and onSelectedMemberChange use together will triger together
|
||||
final Function(V2TimGroupMemberFullInfo memberInfo, TapDownDetails? tapDetails)? onTapMemberItem;
|
||||
final Function(
|
||||
V2TimGroupMemberFullInfo memberInfo, TapDownDetails? tapDetails)?
|
||||
onTapMemberItem;
|
||||
// When sliding to the bottom bar callBack
|
||||
final Function()? touchBottomCallBack;
|
||||
|
||||
|
|
@ -53,7 +56,8 @@ class GroupProfileMemberList extends StatefulWidget {
|
|||
State<StatefulWidget> createState() => _GroupProfileMemberListState();
|
||||
}
|
||||
|
||||
class _GroupProfileMemberListState extends TIMUIKitState<GroupProfileMemberList> {
|
||||
class _GroupProfileMemberListState
|
||||
extends TIMUIKitState<GroupProfileMemberList> {
|
||||
List<V2TimGroupMemberFullInfo> selectedMemberList = [];
|
||||
|
||||
_getShowName(V2TimGroupMemberFullInfo? item) {
|
||||
|
|
@ -70,12 +74,14 @@ class _GroupProfileMemberListState extends TIMUIKitState<GroupProfileMemberList>
|
|||
: userID;
|
||||
}
|
||||
|
||||
List<ISuspensionBeanImpl> _getShowList(List<V2TimGroupMemberFullInfo?> memberList) {
|
||||
List<ISuspensionBeanImpl> _getShowList(
|
||||
List<V2TimGroupMemberFullInfo?> memberList) {
|
||||
final List<ISuspensionBeanImpl> showList = List.empty(growable: true);
|
||||
for (var i = 0; i < memberList.length; i++) {
|
||||
final item = memberList[i];
|
||||
final showName = _getShowName(item);
|
||||
if (item?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER || item?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN) {
|
||||
if (item?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER ||
|
||||
item?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN) {
|
||||
showList.add(ISuspensionBeanImpl(memberInfo: item, tagIndex: "@"));
|
||||
} else {
|
||||
String pinyin = PinyinHelper.getPinyinE(showName);
|
||||
|
|
@ -94,17 +100,26 @@ class _GroupProfileMemberListState extends TIMUIKitState<GroupProfileMemberList>
|
|||
if (widget.canAtAll) {
|
||||
final canAtGroupType = ["Work", "Public", "Meeting"];
|
||||
if (canAtGroupType.contains(widget.groupType)) {
|
||||
showList.insert(0, ISuspensionBeanImpl(memberInfo: V2TimGroupMemberFullInfo(userID: GroupProfileMemberList.AT_ALL_USER_ID, nickName: TIM_t("所有人")), tagIndex: ""));
|
||||
showList.insert(
|
||||
0,
|
||||
ISuspensionBeanImpl(
|
||||
memberInfo: V2TimGroupMemberFullInfo(
|
||||
userID: GroupProfileMemberList.AT_ALL_USER_ID,
|
||||
nickName: TIM_t("所有人")),
|
||||
tagIndex: ""));
|
||||
}
|
||||
}
|
||||
|
||||
return showList;
|
||||
}
|
||||
|
||||
Widget _buildListItem(BuildContext context, V2TimGroupMemberFullInfo memberInfo) {
|
||||
Widget _buildListItem(
|
||||
BuildContext context, V2TimGroupMemberFullInfo memberInfo) {
|
||||
final theme = Provider.of<TUIThemeViewModel>(context).theme;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor() == DeviceType.Desktop;
|
||||
final isGroupMember = memberInfo.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_MEMBER;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor() == DeviceType.Desktop;
|
||||
final isGroupMember =
|
||||
memberInfo.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_MEMBER;
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: Slidable(
|
||||
|
|
@ -117,7 +132,8 @@ class _GroupProfileMemberListState extends TIMUIKitState<GroupProfileMemberList>
|
|||
}
|
||||
},
|
||||
flex: 1,
|
||||
backgroundColor: theme.cautionColor ?? CommonColor.cautionColor,
|
||||
backgroundColor:
|
||||
theme.cautionColor ?? CommonColor.cautionColor,
|
||||
autoClose: true,
|
||||
label: TIM_t("删除"),
|
||||
)
|
||||
|
|
@ -134,21 +150,28 @@ class _GroupProfileMemberListState extends TIMUIKitState<GroupProfileMemberList>
|
|||
child: CheckBoxButton(
|
||||
onChanged: (isChecked) {
|
||||
if (isChecked) {
|
||||
if (widget.maxSelectNum != null && selectedMemberList.length >= widget.maxSelectNum!) {
|
||||
if (widget.maxSelectNum != null &&
|
||||
selectedMemberList.length >=
|
||||
widget.maxSelectNum!) {
|
||||
return;
|
||||
}
|
||||
selectedMemberList.add(memberInfo);
|
||||
} else {
|
||||
selectedMemberList.removeWhere((element) => element.userID == memberInfo.userID);
|
||||
selectedMemberList.removeWhere((element) =>
|
||||
element.userID == memberInfo.userID);
|
||||
}
|
||||
|
||||
if (widget.onSelectedMemberChange != null) {
|
||||
widget.onSelectedMemberChange!(selectedMemberList);
|
||||
widget.onSelectedMemberChange!(
|
||||
selectedMemberList);
|
||||
}
|
||||
setState(() {});
|
||||
},
|
||||
isChecked: selectedMemberList.where((element) => element.userID == memberInfo.userID).toList().isNotEmpty
|
||||
),
|
||||
isChecked: selectedMemberList
|
||||
.where((element) =>
|
||||
element.userID == memberInfo.userID)
|
||||
.toList()
|
||||
.isNotEmpty),
|
||||
),
|
||||
Container(
|
||||
width: isDesktopScreen ? 30 : 36,
|
||||
|
|
@ -160,8 +183,10 @@ class _GroupProfileMemberListState extends TIMUIKitState<GroupProfileMemberList>
|
|||
type: 1,
|
||||
),
|
||||
),
|
||||
Text(_getShowName(memberInfo), style: TextStyle(fontSize: isDesktopScreen ? 14 : 16)),
|
||||
memberInfo.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER
|
||||
Text(_getShowName(memberInfo),
|
||||
style: TextStyle(fontSize: isDesktopScreen ? 14 : 16)),
|
||||
memberInfo.role ==
|
||||
GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER
|
||||
? Container(
|
||||
margin: const EdgeInsets.only(left: 5),
|
||||
child: Text(TIM_t("群主"),
|
||||
|
|
@ -171,11 +196,17 @@ class _GroupProfileMemberListState extends TIMUIKitState<GroupProfileMemberList>
|
|||
)),
|
||||
padding: const EdgeInsets.fromLTRB(5, 0, 5, 0),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: theme.ownerColor ?? CommonColor.ownerColor, width: 1),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(4.0)),
|
||||
border: Border.all(
|
||||
color: theme.ownerColor ??
|
||||
CommonColor.ownerColor,
|
||||
width: 1),
|
||||
borderRadius:
|
||||
const BorderRadius.all(Radius.circular(4.0)),
|
||||
),
|
||||
)
|
||||
: memberInfo.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN
|
||||
: memberInfo.role ==
|
||||
GroupMemberRoleType
|
||||
.V2TIM_GROUP_MEMBER_ROLE_ADMIN
|
||||
? Container(
|
||||
margin: const EdgeInsets.only(left: 5),
|
||||
child: Text(TIM_t("管理员"),
|
||||
|
|
@ -185,8 +216,12 @@ class _GroupProfileMemberListState extends TIMUIKitState<GroupProfileMemberList>
|
|||
)),
|
||||
padding: const EdgeInsets.fromLTRB(5, 0, 5, 0),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: theme.adminColor ?? CommonColor.adminColor, width: 1),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(4.0)),
|
||||
border: Border.all(
|
||||
color: theme.adminColor ??
|
||||
CommonColor.adminColor,
|
||||
width: 1),
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.circular(4.0)),
|
||||
),
|
||||
)
|
||||
: Container()
|
||||
|
|
@ -201,7 +236,8 @@ class _GroupProfileMemberListState extends TIMUIKitState<GroupProfileMemberList>
|
|||
if (isChecked) {
|
||||
selectedMemberList.remove(memberInfo);
|
||||
} else {
|
||||
if (widget.maxSelectNum != null && selectedMemberList.length >= widget.maxSelectNum!) {
|
||||
if (widget.maxSelectNum != null &&
|
||||
selectedMemberList.length >= widget.maxSelectNum!) {
|
||||
return;
|
||||
}
|
||||
selectedMemberList.add(memberInfo);
|
||||
|
|
@ -213,11 +249,17 @@ class _GroupProfileMemberListState extends TIMUIKitState<GroupProfileMemberList>
|
|||
}
|
||||
},
|
||||
),
|
||||
Divider(thickness: 1, indent: 74, endIndent: 0, color: theme.weakBackgroundColor, height: 0)
|
||||
Divider(
|
||||
thickness: 1,
|
||||
indent: 74,
|
||||
endIndent: 0,
|
||||
color: theme.weakBackgroundColor,
|
||||
height: 0)
|
||||
])));
|
||||
}
|
||||
|
||||
static Widget getSusItem(BuildContext context, TUITheme theme, String tag, {double susHeight = 40}) {
|
||||
static Widget getSusItem(BuildContext context, TUITheme theme, String tag,
|
||||
{double susHeight = 40}) {
|
||||
if (tag == '@') {
|
||||
tag = TIM_t("群主、管理员");
|
||||
}
|
||||
|
|
@ -242,9 +284,11 @@ class _GroupProfileMemberListState extends TIMUIKitState<GroupProfileMemberList>
|
|||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor() == DeviceType.Desktop;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor() == DeviceType.Desktop;
|
||||
|
||||
final throteFunction = OptimizeUtils.throttle((ScrollNotification notification) {
|
||||
final throteFunction =
|
||||
OptimizeUtils.throttle((ScrollNotification notification) {
|
||||
final pixels = notification.metrics.pixels;
|
||||
// 总像素高度
|
||||
final maxScrollExtent = notification.metrics.maxScrollExtent;
|
||||
|
|
@ -272,15 +316,19 @@ class _GroupProfileMemberListState extends TIMUIKitState<GroupProfileMemberList>
|
|||
child: Text(TIM_t("暂无群成员")),
|
||||
)
|
||||
: Container(
|
||||
padding: isDesktopScreen ? const EdgeInsets.symmetric(horizontal: 16) : null,
|
||||
padding: isDesktopScreen
|
||||
? const EdgeInsets.symmetric(horizontal: 16)
|
||||
: null,
|
||||
child: AZListViewContainer(
|
||||
memberList: showList,
|
||||
susItemBuilder: (context, index) {
|
||||
final model = showList[index];
|
||||
return getSusItem(context, theme, model.getSuspensionTag());
|
||||
return getSusItem(
|
||||
context, theme, model.getSuspensionTag());
|
||||
},
|
||||
itemBuilder: (context, index) {
|
||||
final memberInfo = showList[index].memberInfo as V2TimGroupMemberFullInfo;
|
||||
final memberInfo = showList[index].memberInfo
|
||||
as V2TimGroupMemberFullInfo;
|
||||
|
||||
return _buildListItem(context, memberInfo);
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import 'package:device_info_plus/device_info_plus.dart';
|
|||
import 'package:extended_image/extended_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:image_gallery_saver/image_gallery_saver.dart';
|
||||
import 'package:image_gallery_saver_plus/image_gallery_saver_plus.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
|
||||
|
|
@ -21,7 +21,12 @@ import 'package:universal_html/html.dart' as html;
|
|||
import 'package:video_player/video_player.dart';
|
||||
|
||||
class VideoScreen extends StatefulWidget {
|
||||
const VideoScreen({required this.message, required this.heroTag, required this.videoElement, Key? key}) : super(key: key);
|
||||
const VideoScreen(
|
||||
{required this.message,
|
||||
required this.heroTag,
|
||||
required this.videoElement,
|
||||
Key? key})
|
||||
: super(key: key);
|
||||
|
||||
final V2TimMessage message;
|
||||
final dynamic heroTag;
|
||||
|
|
@ -34,7 +39,8 @@ class VideoScreen extends StatefulWidget {
|
|||
class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
||||
late VideoPlayerController videoPlayerController;
|
||||
late ChewieController chewieController;
|
||||
GlobalKey<ExtendedImageSlidePageState> slidePagekey = GlobalKey<ExtendedImageSlidePageState>();
|
||||
GlobalKey<ExtendedImageSlidePageState> slidePagekey =
|
||||
GlobalKey<ExtendedImageSlidePageState>();
|
||||
final TUIChatGlobalModel model = serviceLocator<TUIChatGlobalModel>();
|
||||
bool isInit = false;
|
||||
|
||||
|
|
@ -64,7 +70,8 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
xhr.open('get', videoUrl);
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.onLoad.listen((event) {
|
||||
final a = html.AnchorElement(href: html.Url.createObjectUrl(html.Blob([xhr.response])));
|
||||
final a = html.AnchorElement(
|
||||
href: html.Url.createObjectUrl(html.Blob([xhr.response])));
|
||||
a.download = '${md5.convert(utf8.encode(videoUrl)).toString()}$suffix';
|
||||
a.click();
|
||||
a.remove();
|
||||
|
|
@ -110,7 +117,8 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
}
|
||||
if (model.getMessageProgress(widget.message.msgID) == 100) {
|
||||
String savePath;
|
||||
if (widget.message.videoElem!.localVideoUrl != null && widget.message.videoElem!.localVideoUrl != '') {
|
||||
if (widget.message.videoElem!.localVideoUrl != null &&
|
||||
widget.message.videoElem!.localVideoUrl != '') {
|
||||
savePath = widget.message.videoElem!.localVideoUrl!;
|
||||
} else {
|
||||
savePath = model.getFileMessageLocation(widget.message.msgID);
|
||||
|
|
@ -120,35 +128,62 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
var result = await ImageGallerySaver.saveFile(savePath);
|
||||
if (PlatformUtils().isIOS) {
|
||||
if (result['isSuccess']) {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频保存成功"), infoCode: 6660402));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("视频保存成功"),
|
||||
infoCode: 6660402));
|
||||
} else {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频保存失败"), infoCode: 6660403));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("视频保存失败"),
|
||||
infoCode: 6660403));
|
||||
}
|
||||
} else {
|
||||
if (result != null) {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频保存成功"), infoCode: 6660402));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("视频保存成功"),
|
||||
infoCode: 6660402));
|
||||
} else {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频保存失败"), infoCode: 6660403));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("视频保存失败"),
|
||||
infoCode: 6660403));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("the message is downloading"), infoCode: -1));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("the message is downloading"),
|
||||
infoCode: -1));
|
||||
}
|
||||
return;
|
||||
}
|
||||
var result = await ImageGallerySaver.saveFile(savePath);
|
||||
if (PlatformUtils().isIOS) {
|
||||
if (result['isSuccess']) {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频保存成功"), infoCode: 6660402));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("视频保存成功"),
|
||||
infoCode: 6660402));
|
||||
} else {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频保存失败"), infoCode: 6660403));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("视频保存失败"),
|
||||
infoCode: 6660403));
|
||||
}
|
||||
} else {
|
||||
if (result != null) {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频保存成功"), infoCode: 6660402));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("视频保存成功"),
|
||||
infoCode: 6660402));
|
||||
} else {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频保存失败"), infoCode: 6660403));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("视频保存失败"),
|
||||
infoCode: 6660403));
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
@ -162,7 +197,9 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
isAsset: true,
|
||||
);
|
||||
}
|
||||
if (widget.videoElement.videoPath != '' && widget.videoElement.videoPath != null && File(widget.videoElement.videoPath!).existsSync()) {
|
||||
if (widget.videoElement.videoPath != '' &&
|
||||
widget.videoElement.videoPath != null &&
|
||||
File(widget.videoElement.videoPath!).existsSync()) {
|
||||
File f = File(widget.videoElement.videoPath!);
|
||||
if (f.existsSync()) {
|
||||
return await _saveNetworkVideo(
|
||||
|
|
@ -172,7 +209,8 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
);
|
||||
}
|
||||
}
|
||||
if (widget.videoElement.localVideoUrl != '' && widget.videoElement.localVideoUrl != null) {
|
||||
if (widget.videoElement.localVideoUrl != '' &&
|
||||
widget.videoElement.localVideoUrl != null) {
|
||||
File f = File(widget.videoElement.localVideoUrl!);
|
||||
if (f.existsSync()) {
|
||||
return await _saveNetworkVideo(
|
||||
|
|
@ -211,7 +249,8 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
|
||||
setVideoPlayerController() async {
|
||||
if (!PlatformUtils().isWeb) {
|
||||
if (TencentUtils.checkString(widget.message.msgID) != null && widget.videoElement.localVideoUrl == null) {
|
||||
if (TencentUtils.checkString(widget.message.msgID) != null &&
|
||||
widget.videoElement.localVideoUrl == null) {
|
||||
String savePath = model.getFileMessageLocation(widget.message.msgID);
|
||||
File f = File(savePath);
|
||||
if (f.existsSync()) {
|
||||
|
|
@ -221,20 +260,26 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
}
|
||||
|
||||
VideoPlayerController player = PlatformUtils().isWeb
|
||||
? ((TencentUtils.checkString(widget.videoElement.videoPath) != null) || widget.message.status == MessageStatus.V2TIM_MSG_STATUS_SENDING
|
||||
? ((TencentUtils.checkString(widget.videoElement.videoPath) != null) ||
|
||||
widget.message.status == MessageStatus.V2TIM_MSG_STATUS_SENDING
|
||||
? VideoPlayerController.networkUrl(
|
||||
Uri.parse(widget.videoElement.videoPath!),
|
||||
)
|
||||
: (TencentUtils.checkString(widget.videoElement.localVideoUrl) == null)
|
||||
: (TencentUtils.checkString(widget.videoElement.localVideoUrl) ==
|
||||
null)
|
||||
? VideoPlayerController.networkUrl(
|
||||
Uri.parse(widget.videoElement.videoUrl!),
|
||||
)
|
||||
: VideoPlayerController.networkUrl(
|
||||
Uri.parse(widget.videoElement.localVideoUrl!),
|
||||
))
|
||||
: ((TencentUtils.checkString(widget.videoElement.videoPath) != null || widget.message.status == MessageStatus.V2TIM_MSG_STATUS_SENDING) && File(widget.videoElement.videoPath!).existsSync())
|
||||
: ((TencentUtils.checkString(widget.videoElement.videoPath) != null ||
|
||||
widget.message.status ==
|
||||
MessageStatus.V2TIM_MSG_STATUS_SENDING) &&
|
||||
File(widget.videoElement.videoPath!).existsSync())
|
||||
? VideoPlayerController.file(File(widget.videoElement.videoPath!))
|
||||
: (TencentUtils.checkString(widget.videoElement.localVideoUrl) == null)
|
||||
: (TencentUtils.checkString(widget.videoElement.localVideoUrl) ==
|
||||
null)
|
||||
? VideoPlayerController.networkUrl(
|
||||
Uri.parse(widget.videoElement.videoUrl!),
|
||||
)
|
||||
|
|
@ -264,7 +309,8 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
|
||||
@override
|
||||
didUpdateWidget(oldWidget) {
|
||||
if (oldWidget.videoElement.videoUrl != widget.videoElement.videoUrl || oldWidget.videoElement.videoPath != widget.videoElement.videoPath) {
|
||||
if (oldWidget.videoElement.videoUrl != widget.videoElement.videoUrl ||
|
||||
oldWidget.videoElement.videoPath != widget.videoElement.videoPath) {
|
||||
setVideoPlayerController();
|
||||
}
|
||||
super.didUpdateWidget(oldWidget);
|
||||
|
|
@ -299,8 +345,10 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
return Colors.black;
|
||||
}
|
||||
double opacity = 0.0;
|
||||
opacity = offset.distance / (Offset(size.width, size.height).distance / 2.0);
|
||||
return Colors.black.withOpacity(min(1.0, max(1.0 - opacity, 0.0)));
|
||||
opacity = offset.distance /
|
||||
(Offset(size.width, size.height).distance / 2.0);
|
||||
return Colors.black
|
||||
.withOpacity(min(1.0, max(1.0 - opacity, 0.0)));
|
||||
},
|
||||
slideType: SlideType.onlyImage,
|
||||
slideEndHandler: (
|
||||
|
|
@ -322,13 +370,22 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
? Chewie(
|
||||
controller: chewieController,
|
||||
)
|
||||
: const Center(child: CircularProgressIndicator(color: Colors.white))),
|
||||
: const Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: Colors.white))),
|
||||
heroBuilderForSlidingPage: (Widget result) {
|
||||
return Hero(
|
||||
tag: widget.heroTag,
|
||||
child: result,
|
||||
flightShuttleBuilder: (BuildContext flightContext, Animation<double> animation, HeroFlightDirection flightDirection, BuildContext fromHeroContext, BuildContext toHeroContext) {
|
||||
final Hero hero = (flightDirection == HeroFlightDirection.pop ? fromHeroContext.widget : toHeroContext.widget) as Hero;
|
||||
flightShuttleBuilder: (BuildContext flightContext,
|
||||
Animation<double> animation,
|
||||
HeroFlightDirection flightDirection,
|
||||
BuildContext fromHeroContext,
|
||||
BuildContext toHeroContext) {
|
||||
final Hero hero =
|
||||
(flightDirection == HeroFlightDirection.pop
|
||||
? fromHeroContext.widget
|
||||
: toHeroContext.widget) as Hero;
|
||||
|
||||
return hero.child;
|
||||
},
|
||||
|
|
|
|||
11
pubspec.yaml
11
pubspec.yaml
|
|
@ -1,6 +1,6 @@
|
|||
name: tencent_cloud_chat_uikit
|
||||
description: A powerful chat UI component library and business logic for Tencent Cloud Chat, creating seamless in-app chat modules for delightful user experiences.
|
||||
version: 3.1.0
|
||||
version: 3.1.0+2
|
||||
homepage: https://trtc.io/products/chat?utm_source=gfs&utm_medium=link&utm_campaign=%E6%B8%A0%E9%81%93&_channel_track_key=k6WgfCKn
|
||||
repository: https://github.com/TencentCloud/chat-uikit-flutter
|
||||
documentation: https://comm.qq.com/im/doc/flutter/en/TUIKit/readme.html
|
||||
|
|
@ -30,12 +30,12 @@ dependencies:
|
|||
tencent_super_tooltip: ^0.0.1
|
||||
video_player: ^2.9.0
|
||||
chewie: ^1.8.5
|
||||
flutter_slidable: ^3.0.1
|
||||
flutter_plugin_record_plus: ^0.0.17
|
||||
flutter_slidable_plus_plus: ^0.1.0
|
||||
flutter_plugin_record_plus: ^0.0.19
|
||||
azlistview_all_platforms: ^2.1.2
|
||||
lpinyin: ^2.0.3
|
||||
transparent_image: ^2.0.0
|
||||
image_gallery_saver: ^2.0.1
|
||||
image_gallery_saver_plus: ^3.0.5
|
||||
path_provider: ^2.0.8
|
||||
cached_network_image: ^3.3.0
|
||||
shared_preferences: ^2.0.13
|
||||
|
|
@ -57,7 +57,7 @@ dependencies:
|
|||
http: ^1.0.0
|
||||
crypto: ^3.0.2
|
||||
collection: ^1.15.0
|
||||
flutter_image_compress: ^1.1.3
|
||||
flutter_image_compress: ^2.3.0
|
||||
uuid: ^3.0.6
|
||||
open_file: ^3.3.2
|
||||
tencent_keyboard_visibility: ^1.0.1
|
||||
|
|
@ -75,7 +75,6 @@ dependencies:
|
|||
just_audio: ^0.9.34
|
||||
markdown: ^7.1.0
|
||||
logger: ^2.0.1
|
||||
image_clipboard: ^1.0.0+2
|
||||
visibility_detector: ^0.4.0+2
|
||||
|
||||
dev_dependencies:
|
||||
|
|
|
|||
Loading…
Reference in New Issue