diff --git a/CHANGELOG.md b/CHANGELOG.md index 84c20c4..03519bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Improvements * Improved memory usage, enhancing performance. +* Improved the logger storage. # 2.5.0 diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift index 5b2a613..001d40f 100644 --- a/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -20,6 +20,7 @@ import shared_preferences_foundation import sqflite import tencent_cloud_chat_sdk import url_launcher_macos +import wakelock_plus func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) @@ -37,4 +38,5 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) TencentCloudChatSdkPlugin.register(with: registry.registrar(forPlugin: "TencentCloudChatSdkPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) + WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) } diff --git a/example/pubspec.lock b/example/pubspec.lock index 6143fde..1206b4d 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -161,14 +161,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" - chewie_for_us: + chewie: dependency: transitive description: - name: chewie_for_us - sha256: "0307723e811508d361fffa6f8bbd9040b1bfea5536544e4d655e10c27de002ec" + name: chewie + sha256: "8bc4ac4cf3f316e50a25958c0f5eb9bb12cf7e8308bb1d74a43b230da2cfc144" url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "1.7.5" clock: dependency: transitive description: @@ -241,6 +241,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.10" + dbus: + dependency: transitive + description: + name: dbus + sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" + url: "https://pub.dev" + source: hosted + version: "0.7.10" desktop_drop: dependency: transitive description: @@ -1233,33 +1241,33 @@ packages: dependency: transitive description: name: tencent_cloud_chat_sdk - sha256: a78f1f20dc9ebe40aee1bbb47da097780028434d77e97774fbe733debb21e18e + sha256: "358e79b51aba5457418d3bb87e0bbd0f088a1eaf4c4463d09bdda93d1d655aa3" url: "https://pub.dev" source: hosted - version: "7.7.5296" + version: "7.9.5672" tencent_cloud_chat_uikit: dependency: "direct main" description: path: ".." relative: true source: path - version: "2.5.1" + version: "2.5.1+2" tencent_cloud_uikit_core: dependency: transitive description: name: tencent_cloud_uikit_core - sha256: "7ddb2c034e5f832261ba268957e282b7c2e738acb1d21aa40c62dad4eaa433ea" + sha256: "61a5400b3fe75c00252272469f332e7ec07f6d1932ee636a3f2b919cf9805cb8" url: "https://pub.dev" source: hosted - version: "1.5.2" + version: "1.6.0" tencent_im_base: dependency: transitive description: name: tencent_im_base - sha256: "035d97d24bebb87654700d4afc8227de8721a259ef5d0195f3207cb0eb0cdc7a" + sha256: daee1faac70fdf5fa4a53576db4fb7268ba5d897cc036353d3114a31abb76fb1 url: "https://pub.dev" source: hosted - version: "3.3.775296" + version: "3.3.775297" tencent_im_sdk_plugin_desktop: dependency: "direct main" description: @@ -1516,22 +1524,22 @@ packages: url: "https://pub.dev" source: hosted version: "13.0.0" - wakelock_for_us: + wakelock_plus: dependency: transitive description: - name: wakelock_for_us - sha256: a5bdd445e51a617f7c24be8165230391447301f622aacd050038cee7b41989b4 + name: wakelock_plus + sha256: f268ca2116db22e57577fb99d52515a24bdc1d570f12ac18bb762361d43b043d url: "https://pub.dev" source: hosted - version: "0.6.3+1" - wakelock_platform_interface: + version: "1.1.4" + wakelock_plus_platform_interface: dependency: transitive description: - name: wakelock_platform_interface - sha256: "1f4aeb81fb592b863da83d2d0f7b8196067451e4df91046c26b54a403f9de621" + name: wakelock_plus_platform_interface + sha256: "40fabed5da06caff0796dc638e1f07ee395fb18801fbff3255a2372db2d80385" url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "1.1.0" watcher: dependency: transitive description: diff --git a/lib/business_logic/life_cycle/base_life_cycle.dart b/lib/business_logic/life_cycle/base_life_cycle.dart index e7a377a..153f30c 100644 --- a/lib/business_logic/life_cycle/base_life_cycle.dart +++ b/lib/business_logic/life_cycle/base_life_cycle.dart @@ -36,6 +36,10 @@ abstract class DefaultLifeCycle { return message; } + static Future defaultTwoMessagesSolution(V2TimMessage message, [V2TimMessage? repliedMessage]) async { + return message; + } + static Future> defaultMessageListSolution(List list) async { return list; } diff --git a/lib/business_logic/life_cycle/chat_life_cycle.dart b/lib/business_logic/life_cycle/chat_life_cycle.dart index d7d0bea..86f6a2e 100644 --- a/lib/business_logic/life_cycle/chat_life_cycle.dart +++ b/lib/business_logic/life_cycle/chat_life_cycle.dart @@ -11,7 +11,7 @@ class ChatLifeCycle { /// Before a new message will be sent. /// Returns null can block the message from sending. - MessageFunction messageWillSend; + Future Function(V2TimMessage message, [V2TimMessage? repliedMessage]) messageWillSend; /// After a new message been sent. MessageFunctionNullCallback messageDidSend; @@ -43,7 +43,7 @@ class ChatLifeCycle { this.shouldDeleteMessage = DefaultLifeCycle.defaultAsyncBooleanSolution, this.messageDidSend = DefaultLifeCycle.defaultNullCallbackSolution, this.didGetHistoricalMessageList = DefaultLifeCycle.defaultMessageListSolution, - this.messageWillSend = DefaultLifeCycle.defaultMessageSolution, + this.messageWillSend = DefaultLifeCycle.defaultTwoMessagesSolution, this.modifiedMessageWillMount = DefaultLifeCycle.defaultMessageSolution, this.newMessageWillMount = DefaultLifeCycle.defaultMessageSolution, this.messageShouldMount = DefaultLifeCycle.defaultBooleanSolution, diff --git a/lib/business_logic/separate_models/tui_chat_separate_view_model.dart b/lib/business_logic/separate_models/tui_chat_separate_view_model.dart index ee02e0e..83f82f9 100644 --- a/lib/business_logic/separate_models/tui_chat_separate_view_model.dart +++ b/lib/business_logic/separate_models/tui_chat_separate_view_model.dart @@ -26,7 +26,8 @@ import 'package:uuid/uuid.dart'; enum LoadDirection { previous, latest } class TUIChatSeparateViewModel extends ChangeNotifier { - final FriendshipServices _friendshipServices = serviceLocator(); + final FriendshipServices _friendshipServices = + serviceLocator(); final MessageService _messageService = serviceLocator(); final GroupServices _groupServices = serviceLocator(); final TUIChatGlobalModel globalModel = serviceLocator(); @@ -70,112 +71,117 @@ class TUIChatSeparateViewModel extends ChangeNotifier { set groupUserShowName(Map value) { _groupUserShowName = value; - notifyListeners(); + _notify(); } int get activeAtIndex => _activeAtIndex; set activeAtIndex(int value) { _activeAtIndex = value; - notifyListeners(); + _notify(); } List get showAtMemberList => _showAtMemberList; set showAtMemberList(List value) { _showAtMemberList = value; - notifyListeners(); + _notify(); } V2TimGroupInfo? get groupInfo => _groupInfo; set groupInfo(V2TimGroupInfo? value) { _groupInfo = value; - notifyListeners(); + _notify(); } int get totalUnreadCount => _totalUnreadCount; set totalUnreadCount(int value) { _totalUnreadCount = value; - notifyListeners(); + _notify(); } bool get isMultiSelect => _isMultiSelect; set isMultiSelect(bool value) { _isMultiSelect = value; - notifyListeners(); + _notify(); } String get currentPlayedMsgId => _currentPlayedMsgId; set currentPlayedMsgId(String value) { _currentPlayedMsgId = value; - notifyListeners(); + _notify(); } GroupReceiptAllowType? get groupType => _groupType; set groupType(GroupReceiptAllowType? value) { _groupType = value; - notifyListeners(); + _notify(); } List get multiSelectedMessageList => _multiSelectedMessageList; set multiSelectedMessageList(List value) { _multiSelectedMessageList = value; - notifyListeners(); + _notify(); } V2TimMessage? get repliedMessage => _repliedMessage; set repliedMessage(V2TimMessage? value) { _repliedMessage = value; - notifyListeners(); + _notify(); } String get jumpMsgID => _jumpMsgID; set jumpMsgID(String value) { _jumpMsgID = value; - notifyListeners(); + _notify(); } bool get isGroupExist => _isGroupExist; set isGroupExist(bool value) { _isGroupExist = value; - notifyListeners(); + _notify(); } bool get isNotAMember => _isNotAMember; set isNotAMember(bool value) { _isNotAMember = value; - notifyListeners(); + _notify(); } V2TimGroupMemberFullInfo? get currentChatUserInfo => _currentChatUserInfo; set currentChatUserInfo(V2TimGroupMemberFullInfo? value) { _currentChatUserInfo = value; - notifyListeners(); + _notify(); } setLoadingMessageMap(String conversationID, V2TimMessage messageInfo) { if (PlatformUtils().isWeb) { - if (globalModel.loadingMessage[conversationID] != null && globalModel.loadingMessage[conversationID]!.isNotEmpty) { + if (globalModel.loadingMessage[conversationID] != null && + globalModel.loadingMessage[conversationID]!.isNotEmpty) { globalModel.loadingMessage[conversationID]!.add(messageInfo); } else { - globalModel.loadingMessage[conversationID] = [messageInfo]; + globalModel.loadingMessage[conversationID] = [ + messageInfo + ]; } } } void getUserShowName(List userIDs) async { - final List filteredList = userIDs.where((element) => !_groupUserShowName.containsKey(element)).toList(); + final List filteredList = userIDs + .where((element) => !_groupUserShowName.containsKey(element)) + .toList(); for (final element in filteredList) { _groupUserShowName[element] = element; } @@ -183,23 +189,30 @@ class TUIChatSeparateViewModel extends ChangeNotifier { final String groupID = TencentUtils.checkString(_groupID) ?? conversationID; if (filteredList.isNotEmpty) { - final res = await TencentImSDKPlugin.manager?.getGroupManager().getGroupMembersInfo(groupID: groupID, memberList: filteredList); + final res = await TencentImSDKPlugin.manager + ?.getGroupManager() + .getGroupMembersInfo(groupID: groupID, memberList: filteredList); if (res?.code == 0 && res?.data != null) { final data = res!.data; for (final userInfo in data!) { - final showName = TencentUtils.checkString(userInfo.nameCard) ?? TencentUtils.checkString(userInfo.nickName) ?? TencentUtils.checkString(userInfo.userID); + final showName = TencentUtils.checkString(userInfo.nameCard) ?? + TencentUtils.checkString(userInfo.nickName) ?? + TencentUtils.checkString(userInfo.userID); if (TencentUtils.checkString(showName) != null) { _groupUserShowName[userInfo.userID] = showName ?? userInfo.userID; } } if (data.isNotEmpty) { - notifyListeners(); + _notify(); } } } } - void initForEachConversation(ConvType convType, String convID, ValueChanged? onChangeInputField, {String? groupID, List? preGroupMemberList}) async { + void initForEachConversation(ConvType convType, String convID, + ValueChanged? onChangeInputField, + {String? groupID, + List? preGroupMemberList}) async { if (_isInit) { return; } @@ -213,21 +226,24 @@ class TUIChatSeparateViewModel extends ChangeNotifier { groupMemberList = null; selfMemberInfo = null; - globalModel.setCurrentConversation(CurrentConversation(conversationID, conversationType ?? ConvType.c2c)); + globalModel.setCurrentConversation( + CurrentConversation(conversationID, conversationType ?? ConvType.c2c)); globalModel.lifeCycle = lifeCycle; - globalModel.setMessageListPosition(conversationID, HistoryMessagePosition.bottom); + globalModel.setMessageListPosition( + conversationID, HistoryMessagePosition.bottom); globalModel.setChatConfig(chatConfig); globalModel.clearRecivedNewMessageCount(); if (conversationType == ConvType.group) { _groupID = groupID; - notifyListeners(); + _notify(); Future.delayed(const Duration(milliseconds: 10), () async { globalModel.refreshGroupApplicationList(); loadGroupInfo(groupID ?? convID); if (preGroupMemberList != null) { groupMemberList = preGroupMemberList; - selfMemberInfo = preGroupMemberList.firstWhereOrNull((e) => e?.userID == selfModel.loginInfo?.userID); + selfMemberInfo = preGroupMemberList.firstWhereOrNull( + (e) => e?.userID == selfModel.loginInfo?.userID); } else { await loadSelfMemberInfo(groupID: groupID ?? convID); loadGroupMemberList(groupID: groupID ?? convID); @@ -238,13 +254,18 @@ class TUIChatSeparateViewModel extends ChangeNotifier { }); } else { Future.delayed(const Duration(milliseconds: 10), () async { - final List? friendRes = await _friendshipServices.getFriendsInfo(userIDList: [convID]); + final List? friendRes = + await _friendshipServices.getFriendsInfo(userIDList: [convID]); if (friendRes != null && friendRes.isNotEmpty) { final V2TimFriendInfoResult friendInfoResult = friendRes[0]; - currentChatUserInfo = - V2TimGroupMemberFullInfo(userID: convID, faceUrl: friendInfoResult.friendInfo?.userProfile?.faceUrl, nickName: friendInfoResult.friendInfo?.userProfile?.nickName, friendRemark: friendInfoResult.friendInfo?.friendRemark); + currentChatUserInfo = V2TimGroupMemberFullInfo( + userID: convID, + faceUrl: friendInfoResult.friendInfo?.userProfile?.faceUrl, + nickName: friendInfoResult.friendInfo?.userProfile?.nickName, + friendRemark: friendInfoResult.friendInfo?.friendRemark); } else { - final List? userRes = await _friendshipServices.getUsersInfo(userIDList: [convID]); + final List? userRes = + await _friendshipServices.getUsersInfo(userIDList: [convID]); if (userRes != null && userRes.isNotEmpty) { final V2TimUserFullInfo userFullInfo = userRes[0]; currentChatUserInfo = V2TimGroupMemberFullInfo( @@ -254,7 +275,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier { ); } } - notifyListeners(); + _notify(); }); } @@ -270,21 +291,38 @@ class TUIChatSeparateViewModel extends ChangeNotifier { List msgList = []; haveMoreData = false; - final previousResponse = await _messageService.getHistoryMessageListWithComplete( - count: 20, getType: HistoryMsgGetTypeEnum.V2TIM_GET_CLOUD_OLDER_MSG, userID: conversationType == ConvType.c2c ? conversationID : null, groupID: conversationType == ConvType.group ? conversationID : null, lastMsgSeq: max(seq, 0)); + final previousResponse = + await _messageService.getHistoryMessageListWithComplete( + count: 20, + getType: HistoryMsgGetTypeEnum.V2TIM_GET_CLOUD_OLDER_MSG, + userID: conversationType == ConvType.c2c ? conversationID : null, + groupID: conversationType == ConvType.group ? conversationID : null, + lastMsgSeq: max(seq, 0)); msgList = previousResponse?.messageList ?? []; haveMoreData = !(previousResponse?.isFinished ?? false); haveMoreLatestData = true; - globalModel.setMessageListPosition(conversationID, HistoryMessagePosition.notShowLatest); + globalModel.setMessageListPosition( + conversationID, HistoryMessagePosition.notShowLatest); msgList = await lifeCycle?.didGetHistoricalMessageList(msgList) ?? msgList; - msgList.insert(0, V2TimMessage(userID: '', isSelf: false, elemType: 101, msgID: msgList[0].msgID, seq: msgList[0].seq, timestamp: 9999)); - globalModel.setMessageList(conversationID, msgList, needResetNewMessageCount: false); + msgList.insert( + msgList.length - 1, + V2TimMessage( + userID: '', + isSelf: false, + elemType: 101, + msgID: msgList[0].msgID, + seq: msgList[0].seq, + timestamp: 9999)); + globalModel.setMessageList(conversationID, msgList, + needResetNewMessageCount: false); - if (chatConfig.isShowGroupReadingStatus && conversationType == ConvType.group) { + if (chatConfig.isShowGroupReadingStatus && + conversationType == ConvType.group) { _getMsgReadReceipt(msgList); } - if (chatConfig.isReportGroupReadingStatus && conversationType == ConvType.group) { + if (chatConfig.isReportGroupReadingStatus && + conversationType == ConvType.group) { _setMsgReadReceipt(msgList); } @@ -301,7 +339,9 @@ class TUIChatSeparateViewModel extends ChangeNotifier { }) async { try { // 根据加载方向设置是否还能继续加载更多消息 - direction == LoadDirection.latest ? haveMoreLatestData = false : haveMoreData = false; + direction == LoadDirection.latest + ? haveMoreLatestData = false + : haveMoreData = false; // 获取当前聊天对话的历史消息列表 final currentRecordList = globalModel.messageListMap[conversationID]; @@ -309,7 +349,10 @@ class TUIChatSeparateViewModel extends ChangeNotifier { // 调用MessageService获取聊天记录 final response = await _messageService.getHistoryMessageListWithComplete( count: count, - getType: getType ?? (direction == LoadDirection.previous ? HistoryMsgGetTypeEnum.V2TIM_GET_CLOUD_OLDER_MSG : HistoryMsgGetTypeEnum.V2TIM_GET_CLOUD_NEWER_MSG), + getType: getType ?? + (direction == LoadDirection.previous + ? HistoryMsgGetTypeEnum.V2TIM_GET_CLOUD_OLDER_MSG + : HistoryMsgGetTypeEnum.V2TIM_GET_CLOUD_NEWER_MSG), userID: conversationType == ConvType.c2c ? conversationID : null, groupID: conversationType == ConvType.group ? conversationID : null, lastMsgID: lastMsgID, @@ -326,7 +369,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } else { haveMoreData = !response.isFinished; } - notifyListeners(); + _notify(); // 根据lastMsgID判断是否为分页加载 if (lastMsgID != null && currentRecordList != null) { @@ -335,7 +378,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier { // 根据加载方向拼接消息列表 if (direction == LoadDirection.latest) { - globalModel.receivedNewMessageCount = globalModel.receivedMessageListCount + messageList.length; + globalModel.receivedNewMessageCount = + globalModel.receivedMessageListCount + messageList.length; messageList = messageList.reversed.toList(); newList = _combineMessageList(messageList, currentRecordList); } else { @@ -343,7 +387,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } // 处理新获取的消息列表后回调 - final List msgList = await lifeCycle?.didGetHistoricalMessageList(newList) ?? newList; + final List msgList = + await lifeCycle?.didGetHistoricalMessageList(newList) ?? newList; // 更新聊天记录到全局model globalModel.setMessageList( @@ -353,7 +398,9 @@ class TUIChatSeparateViewModel extends ChangeNotifier { ); } else { // 处理新获取的消息列表后回调 - List receivedList = await lifeCycle?.didGetHistoricalMessageList(response.messageList) ?? response.messageList; + List receivedList = await lifeCycle + ?.didGetHistoricalMessageList(response.messageList) ?? + response.messageList; globalModel.loadingMessage.remove(conversationID); // 更新聊天记录到全局model @@ -365,18 +412,23 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } // 获取已读未读状态 - if (chatConfig.isShowGroupReadingStatus && conversationType == ConvType.group && response.messageList.isNotEmpty) { + if (chatConfig.isShowGroupReadingStatus && + conversationType == ConvType.group && + response.messageList.isNotEmpty) { _getMsgReadReceipt(response.messageList); } - if (chatConfig.isReportGroupReadingStatus && conversationType == ConvType.group && response.messageList.isNotEmpty) { + if (chatConfig.isReportGroupReadingStatus && + conversationType == ConvType.group && + response.messageList.isNotEmpty) { _setMsgReadReceipt(response.messageList); } // 根据加载方向更新是否还能继续加载更多消息 if (direction == LoadDirection.latest && !haveMoreLatestData) { - globalModel.setMessageListPosition(conversationID, HistoryMessagePosition.inTwoScreen); + globalModel.setMessageListPosition( + conversationID, HistoryMessagePosition.inTwoScreen); } - notifyListeners(); + _notify(); return haveMoreData; } catch (e) { @@ -387,7 +439,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } // 拼接聊天记录 - List _combineMessageList(List first, List second) { + List _combineMessageList( + List first, List second) { return [...first, ...second]; } @@ -397,12 +450,16 @@ class TUIChatSeparateViewModel extends ChangeNotifier { ); } - Future>> getMessageReadReceipts(List messageIDList) { + Future>> getMessageReadReceipts( + List messageIDList) { return _messageService.getMessageReadReceipts(messageIDList: messageIDList); } _getMsgReadReceipt(List message) async { - final msgID = message.where((e) => (e.isSelf ?? true) && (e.needReadReceipt ?? false)).map((e) => e.msgID ?? '').toList(); + final msgID = message + .where((e) => (e.isSelf ?? true) && (e.needReadReceipt ?? false)) + .map((e) => e.msgID ?? '') + .toList(); if (msgID.isNotEmpty) { final res = await getMessageReadReceipts(msgID); if (res.code == 0) { @@ -413,7 +470,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } } } - notifyListeners(); + _notify(); } } @@ -421,13 +478,16 @@ class TUIChatSeparateViewModel extends ChangeNotifier { final String originText = message.textElem?.text ?? ""; final String deviceLocale = TIM_getCurrentDeviceLocale(); final String targetMessage = deviceLocale.split("-")[0]; - final translatedText = await _messageService.translateText(originText, targetMessage); + final translatedText = + await _messageService.translateText(originText, targetMessage); - final LocalCustomDataModel localCustomData = LocalCustomDataModel.fromMap(json.decode(TencentUtils.checkString(message.localCustomData) ?? "{}")); + final LocalCustomDataModel localCustomData = LocalCustomDataModel.fromMap( + json.decode(TencentUtils.checkString(message.localCustomData) ?? "{}")); localCustomData.translatedText = translatedText; message.localCustomData = json.encode(localCustomData.toMap()); globalModel.onMessageModified(message); - TencentImSDKPlugin.v2TIMManager.v2TIMMessageManager.setLocalCustomData(msgID: message.msgID!, localCustomData: message.localCustomData ?? ""); + TencentImSDKPlugin.v2TIMManager.v2TIMMessageManager.setLocalCustomData( + msgID: message.msgID!, localCustomData: message.localCustomData ?? ""); } _setMsgReadReceipt(List message) async { @@ -435,7 +495,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier { for (var item in message) { final isSelf = item.isSelf ?? true; final needReadReceipt = item.needReadReceipt ?? false; - if (!isSelf && needReadReceipt && item.msgID != null) { + final isRead = item.isRead ?? false; + if (!isRead && !isSelf && needReadReceipt && item.msgID != null) { msgIDList.add(item.msgID!); item.needReadReceipt = false; } @@ -446,7 +507,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } sendMessageReadReceipts(List messageIDList) async { - final res = await _messageService.sendMessageReadReceipts(messageIDList: messageIDList); + final res = await _messageService.sendMessageReadReceipts( + messageIDList: messageIDList); return res; } @@ -456,41 +518,63 @@ class TUIChatSeparateViewModel extends ChangeNotifier { return _messageService.markC2CMessageAsRead(userID: conversationID); } - final res = await _messageService.markGroupMessageAsRead(groupID: conversationID); + final res = + await _messageService.markGroupMessageAsRead(groupID: conversationID); if (res.code == 10015) { isGroupExist = false; } } Future loadSelfMemberInfo({required String groupID}) async { - V2TimValueCallback> getGroupMembersInfoRes = await TencentImSDKPlugin.v2TIMManager.getGroupManager().getGroupMembersInfo( + V2TimValueCallback> getGroupMembersInfoRes = + await TencentImSDKPlugin.v2TIMManager + .getGroupManager() + .getGroupMembersInfo( groupID: groupID, memberList: [selfModel.loginInfo?.userID ?? ""], ); if (getGroupMembersInfoRes.code == 0) { final userList = getGroupMembersInfoRes.data; - selfMemberInfo = userList?.firstWhereOrNull((e) => e.userID == selfModel.loginInfo?.userID); - notifyListeners(); + selfMemberInfo = userList + ?.firstWhereOrNull((e) => e.userID == selfModel.loginInfo?.userID); + _notify(); } return; } - Future loadGroupMemberList({required String groupID, int count = 100, String? seq}) async { - final String? nextSeq = await _loadGroupMemberListFunction(groupID: groupID, seq: seq, count: count); + Future loadGroupMemberList( + {required String groupID, int count = 100, String? seq}) async { + final String? nextSeq = await _loadGroupMemberListFunction( + groupID: groupID, seq: seq, count: count); if (nextSeq != null && nextSeq != "0" && nextSeq != "") { - return await loadGroupMemberList(groupID: groupID, count: count, seq: nextSeq); + return await loadGroupMemberList( + groupID: groupID, count: count, seq: nextSeq); } else { - selfMemberInfo = groupMemberList?.firstWhereOrNull((e) => e?.userID == selfModel.loginInfo?.userID); + selfMemberInfo = groupMemberList + ?.firstWhereOrNull((e) => e?.userID == selfModel.loginInfo?.userID); + _notify(); + } + } + + void _notify(){ + try{ notifyListeners(); + }catch(e){ + debugPrint(e.toString()); } } - Future _loadGroupMemberListFunction({required String groupID, int count = 100, String? seq}) async { + Future _loadGroupMemberListFunction( + {required String groupID, int count = 100, String? seq}) async { if (seq == null || seq == "" || seq == "0") { groupMemberList?.clear(); } try { - final res = await _groupServices.getGroupMemberList(groupID: groupID, filter: GroupMemberFilterTypeEnum.V2TIM_GROUP_MEMBER_FILTER_ALL, count: count, nextSeq: seq ?? groupMemberListSeq); + final res = await _groupServices.getGroupMemberList( + groupID: groupID, + filter: GroupMemberFilterTypeEnum.V2TIM_GROUP_MEMBER_FILTER_ALL, + count: count, + nextSeq: seq ?? groupMemberListSeq); final groupMemberListRes = res.data; if (res.code == 0 && groupMemberListRes != null) { final groupMemberListTemp = groupMemberListRes.memberInfoList ?? []; @@ -507,25 +591,36 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } } - Future<(V2TimGroupInfo?, GroupReceiptAllowType?)> loadGroupInfo(String groupID) async { - final groupInfoList = await _groupServices.getGroupsInfo(groupIDList: [groupID]); + Future<(V2TimGroupInfo?, GroupReceiptAllowType?)> loadGroupInfo( + String groupID) async { + final groupInfoList = + await _groupServices.getGroupsInfo(groupIDList: [groupID]); if (groupInfoList != null && groupInfoList.isNotEmpty) { final groupRes = groupInfoList.first; if (groupRes.resultCode == 0) { _groupInfo = groupRes.groupInfo; - const groupTypeMap = {"Meeting": GroupReceiptAllowType.meeting, "Public": GroupReceiptAllowType.public, "Work": GroupReceiptAllowType.work}; + const groupTypeMap = { + "Meeting": GroupReceiptAllowType.meeting, + "Public": GroupReceiptAllowType.public, + "Work": GroupReceiptAllowType.work + }; _groupType = groupTypeMap[groupRes.groupInfo?.groupType]; - notifyListeners(); + _notify(); return (_groupInfo, _groupType); } } return (null, null); } - Future updateMessageFromController({required String msgID, V2TimMessage? message}) async { - V2TimMessage? newMessage = message ?? await tools.getExistingMessageByID(msgID: msgID, conversationType: conversationType ?? ConvType.c2c, conversationID: conversationID); + Future updateMessageFromController( + {required String msgID, V2TimMessage? message}) async { + V2TimMessage? newMessage = message ?? + await tools.getExistingMessageByID( + msgID: msgID, + conversationType: conversationType ?? ConvType.c2c, + conversationID: conversationID); if (newMessage != null) { globalModel.onMessageModified(newMessage, conversationID); } else { @@ -535,7 +630,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } } - Future?> modifyMessage({required V2TimMessage message}) async { + Future?> modifyMessage( + {required V2TimMessage message}) async { return _messageService.modifyMessage(message: message); } @@ -558,7 +654,9 @@ class TUIChatSeparateViewModel extends ChangeNotifier { if (convType == ConvType.group && _groupType == null) { await loadGroupInfo(groupID); } - final oldGroupType = _groupType != null ? GroupReceptAllowType.values[_groupType!.index] : null; + final oldGroupType = _groupType != null + ? GroupReceptAllowType.values[_groupType!.index] + : null; if (messageInfo != null) { setLoadingMessageMap(convID, messageInfo); } @@ -571,8 +669,12 @@ class TUIChatSeparateViewModel extends ChangeNotifier { needReadReceipt: needReadReceipt ?? chatConfig.isShowGroupReadingStatus && convType == ConvType.group && - ((chatConfig.groupReadReceiptPermissionList != null && chatConfig.groupReadReceiptPermissionList!.contains(_groupType)) || - (chatConfig.groupReadReceiptPermisionList != null && chatConfig.groupReadReceiptPermisionList!.contains(oldGroupType))), + ((chatConfig.groupReadReceiptPermissionList != null && + chatConfig.groupReadReceiptPermissionList! + .contains(_groupType)) || + (chatConfig.groupReadReceiptPermisionList != null && + chatConfig.groupReadReceiptPermisionList! + .contains(oldGroupType))), groupID: groupID, offlinePushInfo: offlinePushInfo, onlineUserOnly: onlineUserOnly ?? false, @@ -586,8 +688,11 @@ class TUIChatSeparateViewModel extends ChangeNotifier { }) : ""), ); - if (isEditStatusMessage == false && globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { - globalModel.updateMessage(sendMsgRes, convID, id, convType, groupType, setInputField); + if (isEditStatusMessage == false && + globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { + globalModel.updateMessage( + sendMsgRes, convID, id, convType, groupType, setInputField); } if (lifeCycle?.messageDidSend != null) { lifeCycle!.messageDidSend(sendMsgRes); @@ -604,15 +709,21 @@ class TUIChatSeparateViewModel extends ChangeNotifier { return globalModel.unreadCountForConversation; } - Future?> sendTextAtMessage({required String text, required String convID, required ConvType convType, required List atUserList}) async { + Future?> sendTextAtMessage( + {required String text, + required String convID, + required ConvType convType, + required List atUserList}) async { if (text.isEmpty) { return null; } - final textATMessageInfo = await _messageService.createTextAtMessage(text: text, atUserList: atUserList); + final textATMessageInfo = await _messageService.createTextAtMessage( + text: text, atUserList: atUserList); List currentHistoryMsgList = getOriginMessageList(); final messageInfo = textATMessageInfo!.messageInfo; if (messageInfo != null) { - final messageInfoWithSender = tools.setUserInfoForMessage(messageInfo, textATMessageInfo.id!); + final messageInfoWithSender = + tools.setUserInfoForMessage(messageInfo, textATMessageInfo.id!); V2TimMessage? lifeCycleMsg; if (lifeCycle?.messageWillSend != null) { lifeCycleMsg = await lifeCycle?.messageWillSend(messageInfoWithSender); @@ -621,64 +732,102 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } } - if (globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { - currentHistoryMsgList = [lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList]; + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { + currentHistoryMsgList = [ + lifeCycleMsg ?? messageInfoWithSender, + ...currentHistoryMsgList + ]; globalModel.setMessageList(conversationID, currentHistoryMsgList); - notifyListeners(); - } - - return _sendMessage(convID: convID, id: textATMessageInfo.id as String, convType: ConvType.group, offlinePushInfo: tools.buildMessagePushInfo(textATMessageInfo.messageInfo!, convID, convType)); - } - return null; - } - - Future?> sendCustomMessage({required String data, required String convID, required ConvType convType}) async { - final textATMessageInfo = await _messageService.createCustomMessage(data: data); - List currentHistoryMsgList = getOriginMessageList(); - final messageInfo = textATMessageInfo!.messageInfo; - if (messageInfo != null) { - final messageInfoWithSender = tools.setUserInfoForMessage(messageInfo, textATMessageInfo.id!); - V2TimMessage? lifeCycleMsg; - if (lifeCycle?.messageWillSend != null) { - lifeCycleMsg = await lifeCycle?.messageWillSend(messageInfoWithSender); - if (lifeCycleMsg == null) { - return null; - } - } - - if (globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { - currentHistoryMsgList = [lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList]; - globalModel.setMessageList(conversationID, currentHistoryMsgList); - notifyListeners(); - } - - return _sendMessage(convID: convID, id: textATMessageInfo.id as String, convType: convType, offlinePushInfo: tools.buildMessagePushInfo(textATMessageInfo.messageInfo!, convID, convType)); - } - return null; - } - - Future?> sendFaceMessage({required int index, required String data, required String convID, required ConvType convType}) async { - final textMessageInfo = await _messageService.createFaceMessage(index: index, data: data); - List currentHistoryMsgList = getOriginMessageList(); - final messageInfo = textMessageInfo!.messageInfo; - if (messageInfo != null) { - final messageInfoWithSender = tools.setUserInfoForMessage(messageInfo, textMessageInfo.id!); - V2TimMessage? lifeCycleMsg; - if (lifeCycle?.messageWillSend != null) { - lifeCycleMsg = await lifeCycle?.messageWillSend(messageInfoWithSender); - if (lifeCycleMsg == null) { - return null; - } - } - - if (globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { - currentHistoryMsgList = [lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList]; - globalModel.setMessageList(conversationID, currentHistoryMsgList); - notifyListeners(); + _notify(); } return _sendMessage( - convID: convID, id: textMessageInfo.id as String, convType: convType, messageInfo: lifeCycleMsg ?? messageInfoWithSender, offlinePushInfo: tools.buildMessagePushInfo(textMessageInfo.messageInfo!, convID, convType)); + convID: convID, + id: textATMessageInfo.id as String, + convType: ConvType.group, + offlinePushInfo: tools.buildMessagePushInfo( + textATMessageInfo.messageInfo!, convID, convType)); + } + return null; + } + + Future?> sendCustomMessage( + {required String data, + required String convID, + required ConvType convType}) async { + final textATMessageInfo = + await _messageService.createCustomMessage(data: data); + List currentHistoryMsgList = getOriginMessageList(); + final messageInfo = textATMessageInfo!.messageInfo; + if (messageInfo != null) { + final messageInfoWithSender = + tools.setUserInfoForMessage(messageInfo, textATMessageInfo.id!); + V2TimMessage? lifeCycleMsg; + if (lifeCycle?.messageWillSend != null) { + lifeCycleMsg = await lifeCycle?.messageWillSend(messageInfoWithSender); + if (lifeCycleMsg == null) { + return null; + } + } + + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { + currentHistoryMsgList = [ + lifeCycleMsg ?? messageInfoWithSender, + ...currentHistoryMsgList + ]; + globalModel.setMessageList(conversationID, currentHistoryMsgList); + _notify(); + } + + return _sendMessage( + convID: convID, + id: textATMessageInfo.id as String, + convType: convType, + offlinePushInfo: tools.buildMessagePushInfo( + textATMessageInfo.messageInfo!, convID, convType)); + } + return null; + } + + Future?> sendFaceMessage( + {required int index, + required String data, + required String convID, + required ConvType convType}) async { + final textMessageInfo = + await _messageService.createFaceMessage(index: index, data: data); + List currentHistoryMsgList = getOriginMessageList(); + final messageInfo = textMessageInfo!.messageInfo; + if (messageInfo != null) { + final messageInfoWithSender = + tools.setUserInfoForMessage(messageInfo, textMessageInfo.id!); + V2TimMessage? lifeCycleMsg; + if (lifeCycle?.messageWillSend != null) { + lifeCycleMsg = await lifeCycle?.messageWillSend(messageInfoWithSender); + if (lifeCycleMsg == null) { + return null; + } + } + + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { + currentHistoryMsgList = [ + lifeCycleMsg ?? messageInfoWithSender, + ...currentHistoryMsgList + ]; + globalModel.setMessageList(conversationID, currentHistoryMsgList); + _notify(); + } + + return _sendMessage( + convID: convID, + id: textMessageInfo.id as String, + convType: convType, + messageInfo: lifeCycleMsg ?? messageInfoWithSender, + offlinePushInfo: tools.buildMessagePushInfo( + textMessageInfo.messageInfo!, convID, convType)); } return null; } @@ -689,11 +838,13 @@ class TUIChatSeparateViewModel extends ChangeNotifier { required String convID, required ConvType convType, }) async { - final soundMessageInfo = await _messageService.createSoundMessage(soundPath: soundPath, duration: duration); + final soundMessageInfo = await _messageService.createSoundMessage( + soundPath: soundPath, duration: duration); List currentHistoryMsgList = getOriginMessageList(); final messageInfo = soundMessageInfo!.messageInfo; if (messageInfo != null) { - final messageInfoWithSender = tools.setUserInfoForMessage(messageInfo, soundMessageInfo.id!); + final messageInfoWithSender = + tools.setUserInfoForMessage(messageInfo, soundMessageInfo.id!); V2TimMessage? lifeCycleMsg; if (lifeCycle?.messageWillSend != null) { lifeCycleMsg = await lifeCycle?.messageWillSend(messageInfoWithSender); @@ -702,17 +853,22 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } } - if (globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { - currentHistoryMsgList = [lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList]; + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { + currentHistoryMsgList = [ + lifeCycleMsg ?? messageInfoWithSender, + ...currentHistoryMsgList + ]; globalModel.setMessageList(conversationID, currentHistoryMsgList); - notifyListeners(); + _notify(); } return _sendMessage( convID: convID, id: soundMessageInfo.id as String, convType: convType, - offlinePushInfo: tools.buildMessagePushInfo(soundMessageInfo.messageInfo!, convID, convType), + offlinePushInfo: tools.buildMessagePushInfo( + soundMessageInfo.messageInfo!, convID, convType), ); } return null; @@ -728,22 +884,31 @@ class TUIChatSeparateViewModel extends ChangeNotifier { return null; } if (_repliedMessage != null) { - V2TimMsgCreateInfoResult? textMessageInfo = await _messageService.createTextMessage(text: text); + V2TimMsgCreateInfoResult? textMessageInfo = + await _messageService.createTextMessage(text: text); if (atUserIDList != null && atUserIDList.isNotEmpty) { - textMessageInfo = await _messageService.createTextAtMessage(text: text, atUserList: atUserIDList); + textMessageInfo = await _messageService.createTextAtMessage( + text: text, atUserList: atUserIDList); } final V2TimMessage? messageInfo = textMessageInfo!.messageInfo; final receiver = convType == ConvType.c2c ? convID : ''; final groupID = convType == ConvType.group ? convID : ''; - final oldGroupType = _groupType != null ? GroupReceptAllowType.values[_groupType!.index] : null; + final oldGroupType = _groupType != null + ? GroupReceptAllowType.values[_groupType!.index] + : null; if (messageInfo != null) { - V2TimMessage messageInfoWithSender = tools.setUserInfoForMessage(messageInfo, textMessageInfo.id!); - final hasNickName = _repliedMessage?.nickName != null && _repliedMessage?.nickName != ""; + V2TimMessage messageInfoWithSender = + tools.setUserInfoForMessage(messageInfo, textMessageInfo.id!); + final hasNickName = _repliedMessage?.nickName != null && + _repliedMessage?.nickName != ""; final cloudCustomData = { "messageReply": { "messageID": _repliedMessage!.msgID, - "messageAbstract": tools.getMessageAbstract(_repliedMessage!, abstractMessageBuilder), - "messageSender": hasNickName ? _repliedMessage!.nickName : _repliedMessage?.sender, + "messageAbstract": tools.getMessageAbstract( + _repliedMessage!, abstractMessageBuilder), + "messageSender": hasNickName + ? _repliedMessage!.nickName + : _repliedMessage?.sender, "messageType": _repliedMessage?.elemType, "version": 1 } @@ -751,28 +916,40 @@ class TUIChatSeparateViewModel extends ChangeNotifier { messageInfoWithSender.cloudCustomData = json.encode(cloudCustomData); V2TimMessage? lifeCycleMsg; if (lifeCycle?.messageWillSend != null) { - lifeCycleMsg = await lifeCycle?.messageWillSend(messageInfoWithSender); + lifeCycleMsg = await lifeCycle?.messageWillSend( + messageInfoWithSender, repliedMessage); if (lifeCycleMsg == null) { return null; } } List currentHistoryMsgList = getOriginMessageList(); - currentHistoryMsgList = [lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList]; + currentHistoryMsgList = [ + lifeCycleMsg ?? messageInfoWithSender, + ...currentHistoryMsgList + ]; globalModel.setMessageList(conversationID, currentHistoryMsgList); _repliedMessage = null; final sendMsgRes = await _messageService.sendMessage( - cloudCustomData: json.encode(cloudCustomData), + cloudCustomData: + TencentUtils.checkString(lifeCycleMsg?.cloudCustomData) ?? + json.encode(cloudCustomData), id: textMessageInfo.id as String, - offlinePushInfo: tools.buildMessagePushInfo(messageInfoWithSender, convID, convType), + offlinePushInfo: tools.buildMessagePushInfo( + messageInfoWithSender, convID, convType), needReadReceipt: chatConfig.isShowGroupReadingStatus && convType == ConvType.group && - ((chatConfig.groupReadReceiptPermissionList != null && chatConfig.groupReadReceiptPermissionList!.contains(_groupType)) || - (chatConfig.groupReadReceiptPermisionList != null && chatConfig.groupReadReceiptPermisionList!.contains(oldGroupType))), + ((chatConfig.groupReadReceiptPermissionList != null && + chatConfig.groupReadReceiptPermissionList! + .contains(_groupType)) || + (chatConfig.groupReadReceiptPermisionList != null && + chatConfig.groupReadReceiptPermisionList! + .contains(oldGroupType))), groupID: groupID, receiver: receiver); - notifyListeners(); - globalModel.updateMessage(sendMsgRes, convID, messageInfoWithSender.id ?? "", convType, groupType, setInputField); + _notify(); + globalModel.updateMessage(sendMsgRes, convID, + messageInfoWithSender.id ?? "", convType, groupType, setInputField); if (lifeCycle?.messageDidSend != null) { lifeCycle!.messageDidSend(sendMsgRes); } @@ -796,25 +973,40 @@ class TUIChatSeparateViewModel extends ChangeNotifier { }); } - Future?> sendImageMessage({String? imagePath, String? imageName, required String convID, dynamic inputElement, required ConvType convType}) async { + Future?> sendImageMessage( + {String? imagePath, + String? imageName, + required String convID, + dynamic inputElement, + required ConvType convType}) async { String? image; - if ((PlatformUtils().isAndroid || PlatformUtils().isIOS) && imagePath != null && imagePath.isNotEmpty) { + if ((PlatformUtils().isAndroid || PlatformUtils().isIOS) && + imagePath != null && + imagePath.isNotEmpty) { try { final size = getFileSize(File(imagePath)); - final format = imagePath.split(".")[imagePath.split(".").length - 1].toLowerCase(); - if (size > 20 || (format != "jpg" && format != "png" && format != "gif")) { + final format = + imagePath.split(".")[imagePath.split(".").length - 1].toLowerCase(); + if (size > 20 || + (format != "jpg" && format != "png" && format != "gif")) { final target = await getTempPath(); - final result = await FlutterImageCompress.compressAndGetFile(imagePath, target, format: CompressFormat.jpeg, quality: 85); + final result = await FlutterImageCompress.compressAndGetFile( + imagePath, target, + format: CompressFormat.jpeg, quality: 85); image = result?.path; } // ignore: empty_catches } catch (e) {} } - final imageMessageInfo = await _messageService.createImageMessage(imageName: imageName, imagePath: image ?? imagePath, inputElement: inputElement); + final imageMessageInfo = await _messageService.createImageMessage( + imageName: imageName, + imagePath: image ?? imagePath, + inputElement: inputElement); List currentHistoryMsgList = getOriginMessageList(); final messageInfo = imageMessageInfo!.messageInfo; if (messageInfo != null) { - final messageInfoWithSender = tools.setUserInfoForMessage(messageInfo, imageMessageInfo.id); + final messageInfoWithSender = + tools.setUserInfoForMessage(messageInfo, imageMessageInfo.id); V2TimMessage? lifeCycleMsg; if (lifeCycle?.messageWillSend != null) { @@ -824,10 +1016,14 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } } - if (globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { - currentHistoryMsgList = [lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList]; + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { + currentHistoryMsgList = [ + lifeCycleMsg ?? messageInfoWithSender, + ...currentHistoryMsgList + ]; globalModel.setMessageList(conversationID, currentHistoryMsgList); - notifyListeners(); + _notify(); } return _sendMessage( @@ -835,19 +1031,33 @@ class TUIChatSeparateViewModel extends ChangeNotifier { messageInfo: lifeCycleMsg ?? messageInfoWithSender, id: imageMessageInfo.id as String, convType: convType, - offlinePushInfo: tools.buildMessagePushInfo(imageMessageInfo.messageInfo!, convID, convType), + offlinePushInfo: tools.buildMessagePushInfo( + imageMessageInfo.messageInfo!, convID, convType), ); } return null; } - Future?> sendVideoMessage({String? videoPath, int? duration, String? snapshotPath, required String convID, required ConvType convType, dynamic inputElement}) async { + Future?> sendVideoMessage( + {String? videoPath, + int? duration, + String? snapshotPath, + required String convID, + required ConvType convType, + dynamic inputElement}) async { List currentHistoryMsgList = getOriginMessageList(); - final videoMessageInfo = - await _messageService.createVideoMessage(videoPath: videoPath, type: videoPath != null ? videoPath.split(".")[videoPath.split(".").length - 1] : 'mp4', duration: duration, inputElement: inputElement, snapshotPath: snapshotPath); + final videoMessageInfo = await _messageService.createVideoMessage( + videoPath: videoPath, + type: videoPath != null + ? videoPath.split(".")[videoPath.split(".").length - 1] + : 'mp4', + duration: duration, + inputElement: inputElement, + snapshotPath: snapshotPath); final messageInfo = videoMessageInfo!.messageInfo; if (messageInfo != null) { - final messageInfoWithSender = tools.setUserInfoForMessage(messageInfo, videoMessageInfo.id); + final messageInfoWithSender = + tools.setUserInfoForMessage(messageInfo, videoMessageInfo.id); V2TimMessage? lifeCycleMsg; if (lifeCycle?.messageWillSend != null) { lifeCycleMsg = await lifeCycle?.messageWillSend(messageInfoWithSender); @@ -856,10 +1066,14 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } } - if (globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { - currentHistoryMsgList = [lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList]; + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { + currentHistoryMsgList = [ + lifeCycleMsg ?? messageInfoWithSender, + ...currentHistoryMsgList + ]; globalModel.setMessageList(conversationID, currentHistoryMsgList); - notifyListeners(); + _notify(); } return _sendMessage( @@ -867,23 +1081,37 @@ class TUIChatSeparateViewModel extends ChangeNotifier { messageInfo: lifeCycleMsg ?? messageInfoWithSender, id: videoMessageInfo.id as String, convType: convType, - offlinePushInfo: tools.buildMessagePushInfo(videoMessageInfo.messageInfo!, convID, convType), + offlinePushInfo: tools.buildMessagePushInfo( + videoMessageInfo.messageInfo!, convID, convType), ); } return null; } - Future?> sendFileMessage({String? filePath, String? fileName, int? size, dynamic inputElement, required String convID, required ConvType convType}) async { + Future?> sendFileMessage( + {String? filePath, + String? fileName, + int? size, + dynamic inputElement, + required String convID, + required ConvType convType}) async { if (await tools.hasZeroSize(filePath ?? "")) { final CoreServicesImpl _coreServices = serviceLocator(); - _coreServices.callOnCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: "不支持 0KB 文件的传输", infoCode: 6660417)); + _coreServices.callOnCallback(TIMCallback( + type: TIMCallbackType.INFO, + infoRecommendText: "不支持 0KB 文件的传输", + infoCode: 6660417)); return null; } - final fileMessageInfo = await _messageService.createFileMessage(inputElement: inputElement, fileName: fileName ?? filePath?.split('/').last ?? "", filePath: filePath); + final fileMessageInfo = await _messageService.createFileMessage( + inputElement: inputElement, + fileName: fileName ?? filePath?.split('/').last ?? "", + filePath: filePath); List currentHistoryMsgList = getOriginMessageList(); final messageInfo = fileMessageInfo!.messageInfo; if (messageInfo != null) { - final messageInfoWithSender = tools.setUserInfoForMessage(messageInfo, fileMessageInfo.id); + final messageInfoWithSender = + tools.setUserInfoForMessage(messageInfo, fileMessageInfo.id); messageInfoWithSender.fileElem!.fileSize = size; V2TimMessage? lifeCycleMsg; if (lifeCycle?.messageWillSend != null) { @@ -893,10 +1121,14 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } } - if (globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { - currentHistoryMsgList = [lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList]; + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { + currentHistoryMsgList = [ + lifeCycleMsg ?? messageInfoWithSender, + ...currentHistoryMsgList + ]; globalModel.setMessageList(conversationID, currentHistoryMsgList); - notifyListeners(); + _notify(); } return _sendMessage( @@ -904,18 +1136,26 @@ class TUIChatSeparateViewModel extends ChangeNotifier { messageInfo: lifeCycleMsg ?? messageInfoWithSender, id: fileMessageInfo.id as String, convType: convType, - offlinePushInfo: tools.buildMessagePushInfo(fileMessageInfo.messageInfo!, convID, convType), + offlinePushInfo: tools.buildMessagePushInfo( + fileMessageInfo.messageInfo!, convID, convType), ); } return null; } - Future?> sendLocationMessage({required String desc, required double longitude, required double latitude, required String convID, required ConvType convType}) async { + Future?> sendLocationMessage( + {required String desc, + required double longitude, + required double latitude, + required String convID, + required ConvType convType}) async { List currentHistoryMsgList = getOriginMessageList(); - final locationMessageInfo = await _messageService.createLocationMessage(desc: desc, longitude: longitude, latitude: latitude); + final locationMessageInfo = await _messageService.createLocationMessage( + desc: desc, longitude: longitude, latitude: latitude); final messageInfo = locationMessageInfo!.messageInfo; if (messageInfo != null) { - final messageInfoWithSender = tools.setUserInfoForMessage(messageInfo, locationMessageInfo.id); + final messageInfoWithSender = + tools.setUserInfoForMessage(messageInfo, locationMessageInfo.id); V2TimMessage? lifeCycleMsg; if (lifeCycle?.messageWillSend != null) { lifeCycleMsg = await lifeCycle?.messageWillSend(messageInfoWithSender); @@ -924,16 +1164,21 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } } - if (globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { - currentHistoryMsgList = [lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList]; + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { + currentHistoryMsgList = [ + lifeCycleMsg ?? messageInfoWithSender, + ...currentHistoryMsgList + ]; globalModel.setMessageList(conversationID, currentHistoryMsgList); - notifyListeners(); + _notify(); } return _sendMessage( convID: convID, id: locationMessageInfo.id as String, convType: convType, - offlinePushInfo: tools.buildMessagePushInfo(locationMessageInfo.messageInfo!, convID, convType), + offlinePushInfo: tools.buildMessagePushInfo( + locationMessageInfo.messageInfo!, convID, convType), ); } return null; @@ -947,13 +1192,16 @@ class TUIChatSeparateViewModel extends ChangeNotifier { final convID = conversation.groupID ?? conversation.userID ?? ""; final convType = conversation.type; for (var message in _multiSelectedMessageList) { - final forwardMessageInfo = await _messageService.createForwardMessage(msgID: message.msgID!); + final forwardMessageInfo = + await _messageService.createForwardMessage(msgID: message.msgID!); final messageInfo = forwardMessageInfo!.messageInfo; if (messageInfo != null) { - final messageInfoWithSender = tools.setUserInfoForMessage(messageInfo, forwardMessageInfo.id); + final messageInfoWithSender = + tools.setUserInfoForMessage(messageInfo, forwardMessageInfo.id); V2TimMessage? lifeCycleMsg; if (lifeCycle?.messageWillSend != null) { - lifeCycleMsg = await lifeCycle?.messageWillSend(messageInfoWithSender); + lifeCycleMsg = + await lifeCycle?.messageWillSend(messageInfoWithSender); if (lifeCycleMsg == null) { return null; } @@ -962,7 +1210,10 @@ class TUIChatSeparateViewModel extends ChangeNotifier { id: forwardMessageInfo.id!, convID: convID, convType: convType == 1 ? ConvType.c2c : ConvType.group, - offlinePushInfo: tools.buildMessagePushInfo(forwardMessageInfo.messageInfo!, convID, convType == 1 ? ConvType.c2c : ConvType.group), + offlinePushInfo: tools.buildMessagePushInfo( + forwardMessageInfo.messageInfo!, + convID, + convType == 1 ? ConvType.c2c : ConvType.group), ); } } @@ -979,15 +1230,24 @@ class TUIChatSeparateViewModel extends ChangeNotifier { for (var conversation in conversationList) { final convID = conversation.groupID ?? conversation.userID ?? ""; final convType = conversation.type; - final List msgIDList = _multiSelectedMessageList.map((e) => e.msgID ?? "").where((element) => element != "").toList(); - final mergerMessageInfo = await _messageService.createMergerMessage(msgIDList: msgIDList, title: title, abstractList: abstractList, compatibleText: TIM_t("该版本不支持此消息")); + final List msgIDList = _multiSelectedMessageList + .map((e) => e.msgID ?? "") + .where((element) => element != "") + .toList(); + final mergerMessageInfo = await _messageService.createMergerMessage( + msgIDList: msgIDList, + title: title, + abstractList: abstractList, + compatibleText: TIM_t("该版本不支持此消息")); final messageInfo = mergerMessageInfo!.messageInfo; if (messageInfo != null) { - final messageInfoWithSender = tools.setUserInfoForMessage(messageInfo, mergerMessageInfo.id); + final messageInfoWithSender = + tools.setUserInfoForMessage(messageInfo, mergerMessageInfo.id); V2TimMessage? lifeCycleMsg; if (lifeCycle?.messageWillSend != null) { - lifeCycleMsg = await lifeCycle?.messageWillSend(messageInfoWithSender); + lifeCycleMsg = + await lifeCycle?.messageWillSend(messageInfoWithSender); if (lifeCycleMsg == null) { continue; } @@ -996,20 +1256,28 @@ class TUIChatSeparateViewModel extends ChangeNotifier { id: mergerMessageInfo.id!, convID: convID, convType: convType == 1 ? ConvType.c2c : ConvType.group, - offlinePushInfo: tools.buildMessagePushInfo(mergerMessageInfo.messageInfo!, convID, convType == 1 ? ConvType.c2c : ConvType.group), + offlinePushInfo: tools.buildMessagePushInfo( + mergerMessageInfo.messageInfo!, + convID, + convType == 1 ? ConvType.c2c : ConvType.group), ); } } return null; } - Future?> reSendMessage({required String msgID, required String convID, bool? onlineUserOnly}) async { - final res = await _messageService.reSendMessage(msgID: msgID, onlineUserOnly: onlineUserOnly ?? false); + Future?> reSendMessage( + {required String msgID, + required String convID, + bool? onlineUserOnly}) async { + final res = await _messageService.reSendMessage( + msgID: msgID, onlineUserOnly: onlineUserOnly ?? false); final messageInfo = res.data; List currentHistoryMsgList = getOriginMessageList(); // final messageInfo = textMessageInfo!.messageInfo; if (messageInfo != null) { - final messageInfoWithSender = tools.setUserInfoForMessage(messageInfo, messageInfo.id!); + final messageInfoWithSender = + tools.setUserInfoForMessage(messageInfo, messageInfo.id!); V2TimMessage? lifeCycleMsg; if (lifeCycle?.messageWillSend != null) { lifeCycleMsg = await lifeCycle?.messageWillSend(messageInfoWithSender); @@ -1017,7 +1285,10 @@ class TUIChatSeparateViewModel extends ChangeNotifier { return null; } } - currentHistoryMsgList = [lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList]; + currentHistoryMsgList = [ + lifeCycleMsg ?? messageInfoWithSender, + ...currentHistoryMsgList + ]; globalModel.setMessageList(convID, currentHistoryMsgList); } return res; @@ -1030,7 +1301,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier { required ConvType convType, List? atUserIDList, }) async { - await deleteMsg(message.msgID ?? "", id: message.id, webMessageInstance: message.messageFromWeb); + await deleteMsg(message.msgID ?? "", + id: message.id, webMessageInstance: message.messageFromWeb); int messageType = message.elemType; V2TimValueCallback? res; if (messageType == MessageElemType.V2TIM_ELEM_TYPE_TEXT) { @@ -1043,37 +1315,53 @@ class TUIChatSeparateViewModel extends ChangeNotifier { atUserIDList: atUserIDList, ); } else { - res = await sendTextMessage(text: text, convID: convID, convType: convType); + res = await sendTextMessage( + text: text, convID: convID, convType: convType); } } if (messageType == MessageElemType.V2TIM_ELEM_TYPE_SOUND) { String soundPath = message.soundElem!.path!; int duration = message.soundElem!.duration!; - res = await sendSoundMessage(soundPath: soundPath, duration: duration, convID: convID, convType: convType); + res = await sendSoundMessage( + soundPath: soundPath, + duration: duration, + convID: convID, + convType: convType); } if (messageType == MessageElemType.V2TIM_ELEM_TYPE_IMAGE) { String imagePath = message.imageElem!.path!; - res = await sendImageMessage(imagePath: imagePath, convID: convID, convType: convType); + res = await sendImageMessage( + imagePath: imagePath, convID: convID, convType: convType); } if (messageType == MessageElemType.V2TIM_ELEM_TYPE_VIDEO) { String videoPath = message.videoElem?.videoPath ?? ""; int duration = message.videoElem?.duration ?? 0; String snapshotPath = message.videoElem?.snapshotPath ?? ""; - res = await sendVideoMessage(videoPath: videoPath, duration: duration, snapshotPath: snapshotPath, convID: convID, convType: convType); + res = await sendVideoMessage( + videoPath: videoPath, + duration: duration, + snapshotPath: snapshotPath, + convID: convID, + convType: convType); } if (messageType == MessageElemType.V2TIM_ELEM_TYPE_FILE) { String filePath = message.fileElem?.path ?? ""; int size = message.fileElem?.fileSize ?? 0; - res = await sendFileMessage(filePath: filePath, size: size, convID: convID, convType: convType); + res = await sendFileMessage( + filePath: filePath, size: size, convID: convID, convType: convType); } if (messageType == MessageElemType.V2TIM_ELEM_TYPE_CUSTOM) { String data = message.customElem?.data ?? ""; - res = await sendCustomMessage(convID: convID, convType: convType, data: data); + res = await sendCustomMessage( + convID: convID, convType: convType, data: data); } return res; } - Future?> sendTextMessage({required String text, required String convID, required ConvType convType}) async { + Future?> sendTextMessage( + {required String text, + required String convID, + required ConvType convType}) async { if (text.isEmpty) { return null; } @@ -1081,7 +1369,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier { List currentHistoryMsgList = getOriginMessageList(); final messageInfo = textMessageInfo!.messageInfo; if (messageInfo != null) { - final messageInfoWithSender = tools.setUserInfoForMessage(messageInfo, textMessageInfo.id!); + final messageInfoWithSender = + tools.setUserInfoForMessage(messageInfo, textMessageInfo.id!); V2TimMessage? lifeCycleMsg; if (lifeCycle?.messageWillSend != null) { lifeCycleMsg = await lifeCycle?.messageWillSend(messageInfoWithSender); @@ -1090,13 +1379,22 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } } - if (globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { - currentHistoryMsgList = [lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList]; + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { + currentHistoryMsgList = [ + lifeCycleMsg ?? messageInfoWithSender, + ...currentHistoryMsgList + ]; globalModel.setMessageList(conversationID, currentHistoryMsgList); - notifyListeners(); + _notify(); } - return _sendMessage(convID: convID, id: textMessageInfo.id as String, convType: convType, offlinePushInfo: tools.buildMessagePushInfo(textMessageInfo.messageInfo!, convID, convType)); + return _sendMessage( + convID: convID, + id: textMessageInfo.id as String, + convType: convType, + offlinePushInfo: tools.buildMessagePushInfo( + textMessageInfo.messageInfo!, convID, convType)); } return null; } @@ -1115,10 +1413,16 @@ class TUIChatSeparateViewModel extends ChangeNotifier { }) { List currentHistoryMsgList = getOriginMessageList(); if (messageInfo != null) { - final messageInfoWithSender = messageInfo.sender == null ? tools.setUserInfoForMessage(messageInfo, messageInfo.id!) : messageInfo; + final messageInfoWithSender = messageInfo.sender == null + ? tools.setUserInfoForMessage(messageInfo, messageInfo.id!) + : messageInfo; - if (globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { - currentHistoryMsgList = [messageInfoWithSender, ...currentHistoryMsgList]; + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { + currentHistoryMsgList = [ + messageInfoWithSender, + ...currentHistoryMsgList + ]; globalModel.setMessageList(conversationID, currentHistoryMsgList); } @@ -1132,18 +1436,22 @@ class TUIChatSeparateViewModel extends ChangeNotifier { convID: conversationID, id: messageInfo.id as String, convType: conversationType ?? ConvType.c2c, - offlinePushInfo: offlinePushInfo ?? tools.buildMessagePushInfo(messageInfo, conversationID, conversationType ?? ConvType.c2c), + offlinePushInfo: offlinePushInfo ?? + tools.buildMessagePushInfo( + messageInfo, conversationID, conversationType ?? ConvType.c2c), ); } return null; } deleteMsg(String msgID, {String? id, Object? webMessageInstance}) async { - if (lifeCycle?.shouldDeleteMessage != null && await lifeCycle!.shouldDeleteMessage(msgID) == false) { + if (lifeCycle?.shouldDeleteMessage != null && + await lifeCycle!.shouldDeleteMessage(msgID) == false) { return; } final messageList = getOriginMessageList(); - final res = await _messageService.deleteMessageFromLocalStorage(msgID: msgID, webMessageInstance: webMessageInstance); + final res = await _messageService.deleteMessageFromLocalStorage( + msgID: msgID, webMessageInstance: webMessageInstance); if (res.code == 0) { messageList.removeWhere((element) { return element.msgID == msgID || (id != null && element.id == id); @@ -1153,28 +1461,35 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } clearHistory() async { - if (lifeCycle?.shouldClearHistoricalMessageList != null && await lifeCycle!.shouldClearHistoricalMessageList(conversationID) == false) { + if (lifeCycle?.shouldClearHistoricalMessageList != null && + await lifeCycle!.shouldClearHistoricalMessageList(conversationID) == + false) { return; } globalModel.setMessageList(conversationID, []); } - Future revokeMsg(String msgID, bool isAdmin, [Object? webMessageInstance]) async { + Future revokeMsg(String msgID, bool isAdmin, + [Object? webMessageInstance]) async { if (chatConfig.isGroupAdminRecallEnabled) { - final V2TimMessage? message = globalModel.messageListMap[conversationID]?.firstWhere((element) => element.msgID == msgID); + final V2TimMessage? message = globalModel.messageListMap[conversationID] + ?.firstWhere((element) => element.msgID == msgID); if (message != null) { if (PlatformUtils().isWeb) { final decodedMessage = jsonDecode(message.messageFromWeb!); - decodedMessage["cloudCustomData"] = jsonEncode({"isRevoke": true, "revokeByAdmin": isAdmin}); + decodedMessage["cloudCustomData"] = + jsonEncode({"isRevoke": true, "revokeByAdmin": isAdmin}); message.messageFromWeb = jsonEncode(decodedMessage); } else { - message.cloudCustomData = jsonEncode({"isRevoke": true, "revokeByAdmin": isAdmin}); + message.cloudCustomData = + jsonEncode({"isRevoke": true, "revokeByAdmin": isAdmin}); } return await modifyMessage(message: message); } } - final res = await _messageService.revokeMessage(msgID: msgID, webMessageInstance: webMessageInstance); + final res = await _messageService.revokeMessage( + msgID: msgID, webMessageInstance: webMessageInstance); if (res.code == 0) { globalModel.onMessageRevoked(msgID, conversationID); } @@ -1183,20 +1498,27 @@ class TUIChatSeparateViewModel extends ChangeNotifier { addToMultiSelectedMessageList(V2TimMessage message) { _multiSelectedMessageList.add(message); - notifyListeners(); + _notify(); } removeFromMultiSelectedMessageList(V2TimMessage message) { _multiSelectedMessageList.remove(message); - notifyListeners(); + _notify(); } deleteSelectedMsg() async { List messageList = getOriginMessageList(); - final msgIDs = _multiSelectedMessageList.map((e) => e.msgID ?? "").where((element) => element != "").toList(); - final webMessageInstanceList = _multiSelectedMessageList.map((e) => e.messageFromWeb).where((element) => element != null).toList(); + final msgIDs = _multiSelectedMessageList + .map((e) => e.msgID ?? "") + .where((element) => element != "") + .toList(); + final webMessageInstanceList = _multiSelectedMessageList + .map((e) => e.messageFromWeb) + .where((element) => element != null) + .toList(); - final res = await _messageService.deleteMessages(msgIDs: msgIDs, webMessageInstanceList: webMessageInstanceList); + final res = await _messageService.deleteMessages( + msgIDs: msgIDs, webMessageInstanceList: webMessageInstanceList); if (res.code == 0) { for (var msgID in msgIDs) { messageList.removeWhere((element) => element.msgID == msgID); @@ -1210,11 +1532,14 @@ class TUIChatSeparateViewModel extends ChangeNotifier { if (!isSelect) { _multiSelectedMessageList.clear(); } - notifyListeners(); + _notify(); } - Future> getGroupMessageReadMemberList(String messageID, GetGroupMessageReadMemberListFilter fileter, int nextSeq) async { - final res = await _messageService.getGroupMessageReadMemberList(nextSeq: nextSeq, messageID: messageID, filter: fileter); + Future> + getGroupMessageReadMemberList(String messageID, + GetGroupMessageReadMemberListFilter fileter, int nextSeq) async { + final res = await _messageService.getGroupMessageReadMemberList( + nextSeq: nextSeq, messageID: messageID, filter: fileter); return res; } @@ -1230,7 +1555,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier { Future findMessage(String msgID) async { List messageList = getOriginMessageList(); - final repliedMessage = messageList.where((element) => element.msgID == msgID).toList(); + final repliedMessage = + messageList.where((element) => element.msgID == msgID).toList(); if (repliedMessage.isNotEmpty) { return repliedMessage.first; } @@ -1243,7 +1569,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier { showLatestUnread() { markMessageAsRead(); - globalModel.setMessageListPosition(conversationID, HistoryMessagePosition.bottom); + globalModel.setMessageListPosition( + conversationID, HistoryMessagePosition.bottom); } @override diff --git a/lib/business_logic/view_models/tui_chat_global_model.dart b/lib/business_logic/view_models/tui_chat_global_model.dart index 9a0b5f6..697dda9 100644 --- a/lib/business_logic/view_models/tui_chat_global_model.dart +++ b/lib/business_logic/view_models/tui_chat_global_model.dart @@ -17,7 +17,6 @@ import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/ui/constants/history_message_constant.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart'; -import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; enum ConvType { none, c2c, group } @@ -504,6 +503,11 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass { } _onReceiveNewMsg(V2TimMessage msgComing) async { + final convID = TencentUtils.checkString(msgComing.userID) ?? msgComing.groupID; + if(convID != currentSelectedConv){ + return; + } + final V2TimMessage? newMsg = _lifeCycle?.newMessageWillMount != null ? await _lifeCycle?.newMessageWillMount(msgComing) : msgComing; if (newMsg == null) { return; @@ -511,13 +515,12 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass { // check the message is editing status msg. and flutter is only support the latest version bool isEditMessage = _editStatusCheck(msgComing); - // if the message is edit status message dont up to screen + // if the message is edit status message don't up to screen if (isEditMessage) { return; } _checkFromUserisActive(msgComing); - final convID = TencentUtils.checkString(newMsg.userID) ?? newMsg.groupID; final convType = TencentUtils.checkString(newMsg.groupID) != null ? ConvType.group : ConvType.c2c; if (convID != null && convID == currentSelectedConv) { final position = getMessageListPosition(convID); @@ -557,7 +560,8 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass { } } } else if (convID != null) { - final currentMsg = _messageListMap[convID] ?? []; + final tempCurrentMsgList = _messageListMap[convID] ?? []; + final currentMsg = tempCurrentMsgList..sublist(max(0, (tempCurrentMsgList.length - 20))); _messageListMap[convID] = [newMsg, ...currentMsg]; notifyListeners(); } @@ -641,6 +645,7 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass { Future onMessageDownloadProgressCallback(V2TimMessageDownloadProgress messageProgress) async { final currentProgress = getMessageProgress(messageProgress.msgID); + print("onMessageDownloadProgressCallback, ${messageProgress.type} - ${messageProgress.isFinish} - ${messageProgress.currentSize} - $currentProgress - "); if (messageProgress.isError || messageProgress.errorCode != 0) { V2TimMessage? message = await _findAndRetrieveMessage(messageProgress.msgID); @@ -666,7 +671,7 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass { if (message != null) { bool isImageType = message.elemType == MessageElemType.V2TIM_ELEM_TYPE_IMAGE; bool isVideoType = message.elemType == MessageElemType.V2TIM_ELEM_TYPE_VIDEO; - final originalImageType = PlatformUtils().isIOS ? 1 : 0; + const originalImageType = 0; if (!isImageType && !isVideoType) { _updateMessageLocationAndDownloadFile(messageProgress); } else if ((isImageType && messageProgress.type == originalImageType) || (isVideoType && !messageProgress.isSnapshot)) { diff --git a/lib/business_logic/view_models/tui_conversation_view_model.dart b/lib/business_logic/view_models/tui_conversation_view_model.dart index eca132d..ed14b23 100644 --- a/lib/business_logic/view_models/tui_conversation_view_model.dart +++ b/lib/business_logic/view_models/tui_conversation_view_model.dart @@ -119,9 +119,9 @@ class TUIConversationViewModel extends ChangeNotifier { notifyListeners(); }, onSyncServerFinish: () { // Remove the process to load such a many of conversations after launching - // if (!PlatformUtils().isWeb) { - // loadInitConversation(); - // } + if (!PlatformUtils().isWeb) { + loadInitConversation(); + } }); } diff --git a/lib/data_services/core/core_services_implements.dart b/lib/data_services/core/core_services_implements.dart index 7021c53..317c171 100644 --- a/lib/data_services/core/core_services_implements.dart +++ b/lib/data_services/core/core_services_implements.dart @@ -95,9 +95,6 @@ class CoreServicesImpl implements CoreServices { if (platform != null) { TUIKitScreenUtils.deviceType = platform; } - if (TencentUtils.checkString(uikitLogPath) != null) { - logOutputGenerator(uikitLogPath!); - } addIdentifier(); if (extraLanguage != null) { Future.delayed(const Duration(milliseconds: 1), () { diff --git a/lib/data_services/message/message_service_implement.dart b/lib/data_services/message/message_service_implement.dart index 02cadc2..bf496ba 100644 --- a/lib/data_services/message/message_service_implement.dart +++ b/lib/data_services/message/message_service_implement.dart @@ -16,7 +16,8 @@ class MessageServiceImpl extends MessageService { @override Future getHistoryMessageListV2({ - HistoryMsgGetTypeEnum getType = HistoryMsgGetTypeEnum.V2TIM_GET_LOCAL_OLDER_MSG, + HistoryMsgGetTypeEnum getType = + HistoryMsgGetTypeEnum.V2TIM_GET_LOCAL_OLDER_MSG, String? userID, String? groupID, int lastMsgSeq = -1, @@ -25,8 +26,16 @@ class MessageServiceImpl extends MessageService { List? messageTypeList, }) async { bool haveMoreData = true; - final res = - await TencentImSDKPlugin.v2TIMManager.getMessageManager().getHistoryMessageList(count: count, getType: getType, userID: userID, groupID: groupID, lastMsgID: lastMsgID, lastMsgSeq: lastMsgSeq, messageTypeList: messageTypeList); + final res = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .getHistoryMessageList( + count: count, + getType: getType, + userID: userID, + groupID: groupID, + lastMsgID: lastMsgID, + lastMsgSeq: lastMsgSeq, + messageTypeList: messageTypeList); final List responseMessageList = res.data ?? []; final conversationID = userID ?? groupID; final cachedMessageList = messageListMap[conversationID]; @@ -36,29 +45,41 @@ class MessageServiceImpl extends MessageService { combinedMessageList = [...cachedMessageList, ...responseMessageList]; // 首次加载 } else { - final bool existSendingMessage = sendingMessage[conversationID] != null && sendingMessage[conversationID]!.isNotEmpty; + final bool existSendingMessage = sendingMessage[conversationID] != null && + sendingMessage[conversationID]!.isNotEmpty; // 存在未发送完成的消息 if (existSendingMessage) { - combinedMessageList = [...sendingMessage[conversationID]!, ...responseMessageList]; + combinedMessageList = [ + ...sendingMessage[conversationID]!, + ...responseMessageList + ]; } else { sendingMessage.remove(conversationID); combinedMessageList = responseMessageList; } } if (res.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: res.desc, + errorCode: res.code)); } - if (responseMessageList.isEmpty || (!PlatformUtils().isWeb && responseMessageList.length < count) || (PlatformUtils().isWeb && responseMessageList.length < min(count, 20))) { + if (responseMessageList.isEmpty || + (!PlatformUtils().isWeb && responseMessageList.length < count) || + (PlatformUtils().isWeb && + responseMessageList.length < min(count, 20))) { haveMoreData = false; } else { haveMoreData = true; } - return MessageListResponse(haveMoreData: haveMoreData, data: combinedMessageList); + return MessageListResponse( + haveMoreData: haveMoreData, data: combinedMessageList); } @override Future> getHistoryMessageList({ - HistoryMsgGetTypeEnum getType = HistoryMsgGetTypeEnum.V2TIM_GET_LOCAL_OLDER_MSG, + HistoryMsgGetTypeEnum getType = + HistoryMsgGetTypeEnum.V2TIM_GET_LOCAL_OLDER_MSG, String? userID, String? groupID, int lastMsgSeq = -1, @@ -66,30 +87,53 @@ class MessageServiceImpl extends MessageService { String? lastMsgID, List? messageTypeList, }) async { - final res = - await TencentImSDKPlugin.v2TIMManager.getMessageManager().getHistoryMessageList(count: count, getType: getType, userID: userID, groupID: groupID, lastMsgID: lastMsgID, lastMsgSeq: lastMsgSeq, messageTypeList: messageTypeList); + final res = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .getHistoryMessageList( + count: count, + getType: getType, + userID: userID, + groupID: groupID, + lastMsgID: lastMsgID, + lastMsgSeq: lastMsgSeq, + messageTypeList: messageTypeList); final reponseMessageList = res.data ?? []; if (res.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: res.desc, + errorCode: res.code)); } return reponseMessageList; } @override Future getHistoryMessageListWithComplete({ - HistoryMsgGetTypeEnum getType = HistoryMsgGetTypeEnum.V2TIM_GET_LOCAL_OLDER_MSG, + HistoryMsgGetTypeEnum getType = + HistoryMsgGetTypeEnum.V2TIM_GET_LOCAL_OLDER_MSG, String? userID, String? groupID, - int lastMsgSeq = -1, + int lastMsgSeq = 0, required int count, String? lastMsgID, List? messageTypeList, }) async { - final res = - await TencentImSDKPlugin.v2TIMManager.getMessageManager().getHistoryMessageListV2(count: count, getType: getType, userID: userID, groupID: groupID, lastMsgID: lastMsgID, lastMsgSeq: lastMsgSeq, messageTypeList: messageTypeList); + final res = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .getHistoryMessageListV2( + count: count, + getType: getType, + userID: userID, + groupID: groupID, + lastMsgID: lastMsgID, + lastMsgSeq: lastMsgSeq, + messageTypeList: messageTypeList); final responseMessageList = res.data; if (res.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: res.desc, + errorCode: res.code)); } return responseMessageList; } @@ -98,31 +142,45 @@ class MessageServiceImpl extends MessageService { Future addSimpleMsgListener({ required V2TimSimpleMsgListener listener, }) async { - return TencentImSDKPlugin.v2TIMManager.addSimpleMsgListener(listener: listener); + return TencentImSDKPlugin.v2TIMManager + .addSimpleMsgListener(listener: listener); } @override Future removeSimpleMsgListener({V2TimSimpleMsgListener? listener}) { - return TencentImSDKPlugin.v2TIMManager.removeSimpleMsgListener(listener: listener); + return TencentImSDKPlugin.v2TIMManager + .removeSimpleMsgListener(listener: listener); } @override Future addAdvancedMsgListener({ required V2TimAdvancedMsgListener listener, }) { - return TencentImSDKPlugin.v2TIMManager.getMessageManager().addAdvancedMsgListener(listener: listener); + return TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .addAdvancedMsgListener(listener: listener); } @override - Future> getGroupMessageReadMemberList({ + Future> + getGroupMessageReadMemberList({ required String messageID, required GetGroupMessageReadMemberListFilter filter, int nextSeq = 0, int count = 100, }) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().getGroupMessageReadMemberList(messageID: messageID, filter: filter, nextSeq: nextSeq, count: count); + final result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .getGroupMessageReadMemberList( + messageID: messageID, + filter: filter, + nextSeq: nextSeq, + count: count); if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); } return result; } @@ -131,9 +189,14 @@ class MessageServiceImpl extends MessageService { Future>> getMessageReadReceipts({ required List messageIDList, }) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().getMessageReadReceipts(messageIDList: messageIDList); + final result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .getMessageReadReceipts(messageIDList: messageIDList); if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); } return result; } @@ -142,43 +205,61 @@ class MessageServiceImpl extends MessageService { Future sendMessageReadReceipts({ required List messageIDList, }) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessageReadReceipts(messageIDList: messageIDList); - if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); - } - return result; + return _retryMarkMessageAsRead(action: (){ + return TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .sendMessageReadReceipts(messageIDList: messageIDList); + }); } @override - Future createTextMessage({required String text}) async { - final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createTextMessage(text: text); + Future createTextMessage( + {required String text}) async { + final res = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .createTextMessage(text: text); if (res.code == 0) { final messageResult = res.data; return messageResult; } - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: res.desc, + errorCode: res.code)); return null; } @override - Future createCustomMessage({required String data}) async { - final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createCustomMessage(data: data); + Future createCustomMessage( + {required String data}) async { + final res = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .createCustomMessage(data: data); if (res.code == 0) { final messageResult = res.data; return messageResult; } - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: res.desc, + errorCode: res.code)); return null; } @override - Future createFaceMessage({required int index, required String data}) async { - final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createFaceMessage(index: index, data: data); + Future createFaceMessage( + {required int index, required String data}) async { + final res = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .createFaceMessage(index: index, data: data); if (res.code == 0) { final messageResult = res.data; return messageResult; } - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: res.desc, + errorCode: res.code)); return null; } @@ -186,31 +267,51 @@ class MessageServiceImpl extends MessageService { Future> reSendMessage( {required String msgID, // 自己创建的ID bool? onlineUserOnly}) async { - final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().reSendMessage(msgID: msgID, onlineUserOnly: onlineUserOnly ?? false); + final res = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .reSendMessage(msgID: msgID, onlineUserOnly: onlineUserOnly ?? false); if (res.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: res.desc, + errorCode: res.code)); } return res; } @override - Future createTextAtMessage({required String text, required List atUserList}) async { - final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createTextAtMessage(text: text, atUserList: atUserList); + Future createTextAtMessage( + {required String text, required List atUserList}) async { + final res = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .createTextAtMessage(text: text, atUserList: atUserList); if (res.code == 0) { final messageResult = res.data; return messageResult; } - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: res.desc, + errorCode: res.code)); return null; } @override - Future createImageMessage({String? imageName, String? imagePath, dynamic inputElement}) async { - final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createImageMessage(imageName: imageName, imagePath: imagePath ?? "", inputElement: inputElement); + Future createImageMessage( + {String? imageName, String? imagePath, dynamic inputElement}) async { + final res = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .createImageMessage( + imageName: imageName, + imagePath: imagePath ?? "", + inputElement: inputElement); if (res.code == 0) { return res.data; } - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: res.desc, + errorCode: res.code)); return null; } @@ -219,11 +320,16 @@ class MessageServiceImpl extends MessageService { required String soundPath, required int duration, }) async { - final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createSoundMessage(soundPath: soundPath, duration: duration); + final res = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .createSoundMessage(soundPath: soundPath, duration: duration); if (res.code == 0) { return res.data; } - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: res.desc, + errorCode: res.code)); return null; } @@ -240,19 +346,23 @@ class MessageServiceImpl extends MessageService { String? cloudCustomData, String? localCustomData, }) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessage( - id: id, - receiver: receiver, - groupID: groupID, - priority: priority, - onlineUserOnly: onlineUserOnly, - offlinePushInfo: offlinePushInfo, - needReadReceipt: needReadReceipt, - localCustomData: localCustomData, - cloudCustomData: cloudCustomData, - ); + final result = + await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessage( + id: id, + receiver: receiver, + groupID: groupID, + priority: priority, + onlineUserOnly: onlineUserOnly, + offlinePushInfo: offlinePushInfo, + needReadReceipt: needReadReceipt, + localCustomData: localCustomData, + cloudCustomData: cloudCustomData, + ); if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); } return result; } @@ -264,22 +374,36 @@ class MessageServiceImpl extends MessageService { }) async { V2TimCallback result; if (kIsWeb) { - result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().deleteMessages(msgIDs: [], webMessageInstanceList: [webMessageInstance]); + result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .deleteMessages( + msgIDs: [], webMessageInstanceList: [webMessageInstance]); } else { - result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().deleteMessageFromLocalStorage(msgID: msgID); + result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .deleteMessageFromLocalStorage(msgID: msgID); } if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); } return result; } @override - Future revokeMessage({required String msgID, Object? webMessageInstance}) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().revokeMessage(msgID: msgID, webMessageInstatnce: webMessageInstance); + Future revokeMessage( + {required String msgID, Object? webMessageInstance}) async { + final result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .revokeMessage(msgID: msgID, webMessageInstatnce: webMessageInstance); if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); } return result; } @@ -288,9 +412,14 @@ class MessageServiceImpl extends MessageService { Future clearC2CHistoryMessage({ required String userID, }) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().clearC2CHistoryMessage(userID: userID); + final result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .clearC2CHistoryMessage(userID: userID); if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); } return result; } @@ -299,38 +428,77 @@ class MessageServiceImpl extends MessageService { Future clearGroupHistoryMessage({ required String groupID, }) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().clearGroupHistoryMessage(groupID: groupID); + final result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .clearGroupHistoryMessage(groupID: groupID); if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); } return result; } + Future _retryMarkMessageAsRead({ + required Future Function() action, + int retries = 3, + }) async { + V2TimCallback result; + int attempts = 0; + do { + result = await action(); + if (result.code == 0) { + return result; + } + attempts++; + await Future.delayed(const Duration(milliseconds: 500)); + } while (attempts < retries); + + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); + + return result; + } + @override Future markC2CMessageAsRead({ required String userID, - }) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().markC2CMessageAsRead(userID: userID); - if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); - } - return result; + }) { + return _retryMarkMessageAsRead(action: () { + return TencentImSDKPlugin.v2TIMManager + .getConversationManager() + .cleanConversationUnreadMessageCount( + conversationID: "c2c_$userID", + cleanTimestamp: 0, + cleanSequence: 0, + ); + }); } @override Future markGroupMessageAsRead({ required String groupID, - }) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().markGroupMessageAsRead(groupID: groupID); - if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); - } - return result; + }) { + return _retryMarkMessageAsRead(action: () { + return TencentImSDKPlugin.v2TIMManager + .getConversationManager() + .cleanConversationUnreadMessageCount( + conversationID: "group_$groupID", + cleanTimestamp: 0, + cleanSequence: 0, + ); + }); } @override - Future removeAdvancedMsgListener({V2TimAdvancedMsgListener? listener}) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().removeAdvancedMsgListener(listener: listener); + Future removeAdvancedMsgListener( + {V2TimAdvancedMsgListener? listener}) async { + final result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .removeAdvancedMsgListener(listener: listener); return result; } @@ -338,11 +506,16 @@ class MessageServiceImpl extends MessageService { Future?> downloadMergerMessage({ required String msgID, }) async { - final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().downloadMergerMessage(msgID: msgID); + final res = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .downloadMergerMessage(msgID: msgID); if (res.code == 0) { return res.data; } - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: res.desc, + errorCode: res.code)); return null; } @@ -350,11 +523,16 @@ class MessageServiceImpl extends MessageService { Future createForwardMessage({ required String msgID, }) async { - final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createForwardMessage(msgID: msgID); + final res = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .createForwardMessage(msgID: msgID); if (res.code == 0) { return res.data; } - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: res.desc, + errorCode: res.code)); return null; } @@ -365,30 +543,62 @@ class MessageServiceImpl extends MessageService { required List abstractList, required String compatibleText, }) async { - final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createMergerMessage(msgIDList: msgIDList, title: title, abstractList: abstractList, compatibleText: compatibleText); + final res = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .createMergerMessage( + msgIDList: msgIDList, + title: title, + abstractList: abstractList, + compatibleText: compatibleText); if (res.code == 0) { return res.data; } - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: res.desc, + errorCode: res.code)); return null; } @override - Future deleteMessages({required List msgIDs, List? webMessageInstanceList}) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().deleteMessages(msgIDs: msgIDs, webMessageInstanceList: webMessageInstanceList); + Future deleteMessages( + {required List msgIDs, + List? webMessageInstanceList}) async { + final result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .deleteMessages( + msgIDs: msgIDs, webMessageInstanceList: webMessageInstanceList); if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); } return result; } @override - Future createVideoMessage({String? videoPath, String? type, int? duration, String? snapshotPath, dynamic inputElement}) async { - final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createVideoMessage(videoFilePath: videoPath ?? "", type: type ?? "", duration: duration ?? 1, snapshotPath: snapshotPath ?? "", inputElement: inputElement); + Future createVideoMessage( + {String? videoPath, + String? type, + int? duration, + String? snapshotPath, + dynamic inputElement}) async { + final res = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .createVideoMessage( + videoFilePath: videoPath ?? "", + type: type ?? "", + duration: duration ?? 1, + snapshotPath: snapshotPath ?? "", + inputElement: inputElement); if (res.code == 0) { return res.data; } - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: res.desc, + errorCode: res.code)); return null; } @@ -401,38 +611,75 @@ class MessageServiceImpl extends MessageService { bool needReadReceipt = false, required V2TimMessage replyMessage, // 被回复的消息 }) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendReplyMessage(id: id, receiver: receiver, offlinePushInfo: offlinePushInfo, groupID: groupID, needReadReceipt: needReadReceipt, replyMessage: replyMessage); + final result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .sendReplyMessage( + id: id, + receiver: receiver, + offlinePushInfo: offlinePushInfo, + groupID: groupID, + needReadReceipt: needReadReceipt, + replyMessage: replyMessage); if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); } return result; } @override - Future createFileMessage({String? filePath, required String fileName, dynamic inputElement}) async { - final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createFileMessage(filePath: filePath ?? "", fileName: fileName, inputElement: inputElement); + Future createFileMessage( + {String? filePath, + required String fileName, + dynamic inputElement}) async { + final res = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .createFileMessage( + filePath: filePath ?? "", + fileName: fileName, + inputElement: inputElement); if (res.code == 0) { return res.data; } - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: res.desc, + errorCode: res.code)); return null; } @override - Future createLocationMessage({required String desc, required double longitude, required double latitude}) async { - final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createLocationMessage(desc: desc, longitude: longitude, latitude: latitude); + Future createLocationMessage( + {required String desc, + required double longitude, + required double latitude}) async { + final res = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .createLocationMessage( + desc: desc, longitude: longitude, latitude: latitude); if (res.code == 0) { return res.data; } - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: res.desc, + errorCode: res.code)); return null; } @override - Future> searchLocalMessages({required V2TimMessageSearchParam searchParam}) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().searchLocalMessages(searchParam: searchParam); + Future> searchLocalMessages( + {required V2TimMessageSearchParam searchParam}) async { + final result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .searchLocalMessages(searchParam: searchParam); if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); } return result; } @@ -441,19 +688,30 @@ class MessageServiceImpl extends MessageService { Future?> findMessages({ required List messageIDList, }) async { - final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().findMessages(messageIDList: messageIDList); + final res = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .findMessages(messageIDList: messageIDList); if (res.code == 0) { return res.data; } - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: res.desc, + errorCode: res.code)); return null; } @override - Future setLocalCustomInt({required String msgID, required int localCustomInt}) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().setLocalCustomInt(msgID: msgID, localCustomInt: localCustomInt); + Future setLocalCustomInt( + {required String msgID, required int localCustomInt}) async { + final result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .setLocalCustomInt(msgID: msgID, localCustomInt: localCustomInt); if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); } return result; } @@ -463,9 +721,14 @@ class MessageServiceImpl extends MessageService { required List userIDList, required ReceiveMsgOptEnum opt, }) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().setC2CReceiveMessageOpt(userIDList: userIDList, opt: opt); + final result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .setC2CReceiveMessageOpt(userIDList: userIDList, opt: opt); if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); } return result; } @@ -475,55 +738,96 @@ class MessageServiceImpl extends MessageService { required String groupID, required ReceiveMsgOptEnum opt, }) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().setGroupReceiveMessageOpt(groupID: groupID, opt: opt); + final result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .setGroupReceiveMessageOpt(groupID: groupID, opt: opt); if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); } return result; } @override - Future> modifyMessage({required V2TimMessage message}) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().modifyMessage(message: message); + Future> modifyMessage( + {required V2TimMessage message}) async { + final result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .modifyMessage(message: message); if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); } return result; } @override - Future setLocalCustomData({required String msgID, required String localCustomData}) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().setLocalCustomData(msgID: msgID, localCustomData: localCustomData); + Future setLocalCustomData( + {required String msgID, required String localCustomData}) async { + final result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .setLocalCustomData(msgID: msgID, localCustomData: localCustomData); if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); } return result; } @override - Future> getMessageOnlineUrl({required String msgID}) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().getMessageOnlineUrl(msgID: msgID); + Future> getMessageOnlineUrl( + {required String msgID}) async { + final result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .getMessageOnlineUrl(msgID: msgID); if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); } return result; } @override - Future downloadMessage({required String msgID, required int messageType, required int imageType, required bool isSnapshot}) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().downloadMessage(msgID: msgID, messageType: messageType, imageType: imageType, isSnapshot: isSnapshot); + Future downloadMessage( + {required String msgID, + required int messageType, + required int imageType, + required bool isSnapshot}) async { + final result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .downloadMessage( + msgID: msgID, + messageType: messageType, + imageType: imageType, + isSnapshot: isSnapshot); if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); } return result; } @override Future translateText(String text, String target) async { - final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().translateText(texts: [text], targetLanguage: target); + final result = await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .translateText(texts: [text], targetLanguage: target); if (result.code != 0) { - _coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code)); + _coreService.callOnCallback(TIMCallback( + type: TIMCallbackType.API_ERROR, + errorMsg: result.desc, + errorCode: result.code)); } return result.data?[text] ?? ""; } diff --git a/lib/ui/utils/logger.dart b/lib/ui/utils/logger.dart index 249c65c..1a637b6 100644 --- a/lib/ui/utils/logger.dart +++ b/lib/ui/utils/logger.dart @@ -1,107 +1,15 @@ -import 'dart:convert'; -import 'dart:io'; -import 'package:logger/logger.dart'; -import 'package:package_info_plus/package_info_plus.dart'; -import 'package:path/path.dart' as p; + + import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; -final outputLogger = Logger( - output: _outputLogger ?? logOutputGenerator(null), -); +final outputLogger = TencentCloudChatLog(); -TUIKitOutput? _outputLogger; - -TUIKitOutput logOutputGenerator(String? path) { - _outputLogger = TUIKitOutput(path); - return _outputLogger!; -} - -class TUIKitOutput extends LogOutput { - Future createDirectoryIfNotExists(String path) async { - final directory = Directory(p.dirname(path)); - - if (await directory.exists() == false) { - await directory.create(recursive: true); +class TencentCloudChatLog{ + void i(String text){ + if(!PlatformUtils().isWeb){ + TencentImSDKPlugin.v2TIMManager + .uikitTrace(trace: text); } } - - Future deleteFilesOlderThanDays(String directoryPath, int days) async { - final directory = Directory(directoryPath); - final threshold = DateTime.now().subtract(Duration(days: days)); - - await for (var fileEntity in directory.list(followLinks: false)) { - if (fileEntity is File) { - final lastModified = await fileEntity.lastModified(); - if (lastModified.isBefore(threshold)) { - await fileEntity.delete(); - } - } - } - } - - Future getPlatformLogPath({String? path}) async { - if (TencentUtils.checkString(path) != null) { - print("The path to local log: $path"); - return path!; - } - - final String documentsDirectoryPath = - "${Platform.environment['USERPROFILE']}"; - PackageInfo packageInfo = await PackageInfo.fromPlatform(); - String pkgName = packageInfo.packageName; - var timeName = - "${DateTime.now().year}-${DateTime.now().month}-${DateTime.now().day}"; - final logPath = p.join(documentsDirectoryPath, "Documents", ".TencentCloudChat", - pkgName, "uikit_log", 'Flutter-TUIKit-$timeName.log'); - print("The path to local log: $logPath"); - - return logPath; - } - - File? logFile; - - TUIKitOutput(String? path) { - if (!PlatformUtils().isWeb) { - getPlatformLogPath(path: path).then((logFilePath) async { - await createDirectoryIfNotExists(logFilePath); - deleteFilesOlderThanDays(p.dirname(logFilePath), 7); - logFile = File(logFilePath); - if (logFile != null) { - if (!logFile!.existsSync()) { - logFile!.createSync(recursive: true); - } - } - }); - } - } - - @override - void output(OutputEvent event) { - var msg = "\n"; - for (var line in event.lines) { - msg += "$line \n"; - } - if (!PlatformUtils().isWeb) { - if (logFile != null) { - final sink = logFile!.openWrite( - mode: FileMode.append, - encoding: const SystemEncoding(), - ); - sink.write(utf8.decode(utf8.encode(msg))); - sink.close(); - } else { - Future.delayed(const Duration(seconds: 1)).then((value) { - if (logFile != null) { - final sink = logFile!.openWrite( - mode: FileMode.append, - encoding: const SystemEncoding(), - ); - sink.write(msg); - sink.close(); - } - }); - } - } - } -} +} \ No newline at end of file diff --git a/lib/ui/utils/sound_record.dart b/lib/ui/utils/sound_record.dart index f8121c6..6ec80b8 100644 --- a/lib/ui/utils/sound_record.dart +++ b/lib/ui/utils/sound_record.dart @@ -32,11 +32,13 @@ class SoundPlayer { _soundInterruptListener!(); } await _audioPlayer.setUrl(url); + await _audioPlayer.play(); } static stop() { _audioPlayer.stop(); + } static dispose() { diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue_container.dart b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue_container.dart index 321c8f9..f4a628a 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue_container.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue_container.dart @@ -1,19 +1,18 @@ import 'package:flutter/cupertino.dart'; import 'package:provider/provider.dart'; import 'package:scroll_to_index/scroll_to_index.dart'; -import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart'; -import 'package:tencent_im_base/tencent_im_base.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/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; -import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue.dart'; +import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tuple/tuple.dart'; class TIMUIKitHistoryMessageListTongueContainer extends StatefulWidget { - final Widget Function(void Function(), MessageListTongueType, int)? - tongueItemBuilder; + final Widget Function(void Function(), MessageListTongueType, int)? tongueItemBuilder; final List? groupAtInfoList; final Function(String targetSeq) scrollToIndexBySeq; final AutoScrollController scrollController; @@ -31,12 +30,10 @@ class TIMUIKitHistoryMessageListTongueContainer extends StatefulWidget { }) : super(key: key); @override - State createState() => - _TIMUIKitHistoryMessageListTongueContainerState(); + State createState() => _TIMUIKitHistoryMessageListTongueContainerState(); } -class _TIMUIKitHistoryMessageListTongueContainerState - extends TIMUIKitState { +class _TIMUIKitHistoryMessageListTongueContainerState extends TIMUIKitState { bool isFinishJumpToAt = false; List? groupAtInfoList = []; final TUIChatGlobalModel globalModel = serviceLocator(); @@ -50,10 +47,8 @@ class _TIMUIKitHistoryMessageListTongueContainerState } void changePositionState(HistoryMessagePosition newPosition) { - if (globalModel.getMessageListPosition(widget.model.conversationID) != - newPosition) { - globalModel.setMessageListPosition( - widget.model.conversationID, newPosition); + if (globalModel.getMessageListPosition(widget.model.conversationID) != newPosition) { + globalModel.setMessageListPosition(widget.model.conversationID, newPosition); } } @@ -64,19 +59,11 @@ class _TIMUIKitHistoryMessageListTongueContainerState if (offset <= 0.0 && conversationUnreadCount != 0) { widget.model.showLatestUnread(); } - if (widget.scrollController.offset <= - widget.scrollController.position.minScrollExtent && - !widget.scrollController.position.outOfRange && - !widget.model.haveMoreLatestData) { + if (widget.scrollController.offset <= widget.scrollController.position.minScrollExtent && !widget.scrollController.position.outOfRange && !widget.model.haveMoreLatestData) { changePositionState(HistoryMessagePosition.bottom); - } else if (widget.scrollController.offset <= screenHeight * 1.6 && - widget.scrollController.offset > 0 && - !widget.scrollController.position.outOfRange && - !widget.model.haveMoreLatestData) { + } else if (widget.scrollController.offset <= screenHeight * 1.6 && widget.scrollController.offset > 0 && !widget.scrollController.position.outOfRange && !widget.model.haveMoreLatestData) { changePositionState(HistoryMessagePosition.inTwoScreen); - } else if (widget.scrollController.offset > screenHeight * 1.6 && - !widget.scrollController.position.outOfRange && - !widget.model.haveMoreLatestData) { + } else if (widget.scrollController.offset > screenHeight * 1.6 && !widget.scrollController.position.outOfRange && !widget.model.haveMoreLatestData) { changePositionState(HistoryMessagePosition.awayTwoScreen); } } @@ -85,15 +72,11 @@ class _TIMUIKitHistoryMessageListTongueContainerState widget.scrollController.addListener(scrollHandler); } - MessageListTongueType _getTongueValueType( - List? groupAtInfoList) { - if (globalModel.getMessageListPosition(widget.model.conversationID) == - HistoryMessagePosition.notShowLatest) { + MessageListTongueType _getTongueValueType(List? groupAtInfoList) { + if (globalModel.getMessageListPosition(widget.model.conversationID) == HistoryMessagePosition.notShowLatest) { return MessageListTongueType.none; } - if (groupAtInfoList != null && - groupAtInfoList.isNotEmpty && - !isFinishJumpToAt) { + if (groupAtInfoList != null && groupAtInfoList.isNotEmpty && !isFinishJumpToAt) { if (groupAtInfoList[0]!.atType == 1) { return MessageListTongueType.atMe; } else { @@ -109,8 +92,7 @@ class _TIMUIKitHistoryMessageListTongueContainerState return MessageListTongueType.showUnread; } - if (globalModel.getMessageListPosition(widget.model.conversationID) == - HistoryMessagePosition.awayTwoScreen) { + if (globalModel.getMessageListPosition(widget.model.conversationID) == HistoryMessagePosition.awayTwoScreen) { return MessageListTongueType.toLatest; } @@ -128,14 +110,8 @@ class _TIMUIKitHistoryMessageListTongueContainerState return Selector>( builder: (context, value, child) { return Positioned( - bottom: _getTongueValueType(groupAtInfoList) != - MessageListTongueType.showPrevious - ? 16 - : null, - top: _getTongueValueType(groupAtInfoList) == - MessageListTongueType.showPrevious - ? 16 - : null, + bottom: _getTongueValueType(groupAtInfoList) != MessageListTongueType.showPrevious ? 16 : null, + top: _getTongueValueType(groupAtInfoList) == MessageListTongueType.showPrevious ? 16 : null, right: 16, child: TIMUIKitHistoryMessageListTongue( previousCount: widget.conversation.unreadCount ?? 0, @@ -153,29 +129,24 @@ class _TIMUIKitHistoryMessageListTongueContainerState } else { widget.scrollToIndexBySeq(groupAtInfoList!.removeAt(0)!.seq); } - } else if ((widget.conversation.unreadCount ?? 0) > 20 && - !isClickShowPrevious) { + } else if ((widget.conversation.unreadCount ?? 0) > 20 && !isClickShowPrevious) { try { isClickShowPrevious = true; - final String? lastSeqString = - widget.conversation.lastMessage?.seq; - final int? lastSeq = - TencentUtils.checkString(lastSeqString) != null - ? int.parse(lastSeqString!) - : null; + final String? lastSeqString = widget.conversation.lastMessage?.seq; + final int? lastSeq = TencentUtils.checkString(lastSeqString) != null ? int.parse(lastSeqString!) : null; final int? previousCount = widget.conversation.unreadCount; if (lastSeq != null && previousCount != null) { final targetSeq = lastSeq - previousCount; - await widget.model - .loadListForSpecificMessage(seq: targetSeq); - // widget.scrollToIndexBySeq((targetSeq + 1).toString()); + await widget.model.loadListForSpecificMessage(seq: targetSeq); + // Future.delayed(const Duration(milliseconds: 100), () { + // widget.scrollToIndexBySeq((targetSeq).toString()); + // }); } } catch (e) { // TODO: 这里后续加个弹窗提示客户,找消息失败了 } // widget.model.loadListForSpecificMessage(seq: count); - } else if (value.item1 == HistoryMessagePosition.awayTwoScreen || - globalModel.unreadCountForConversation > 0) { + } else if (value.item1 == HistoryMessagePosition.awayTwoScreen || globalModel.unreadCountForConversation > 0) { widget.model.showLatestUnread(); widget.scrollController.animateTo( widget.scrollController.position.minScrollExtent, @@ -191,8 +162,7 @@ class _TIMUIKitHistoryMessageListTongueContainerState ); }, selector: (c, model) { - final mesageListPosition = - model.getMessageListPosition(widget.model.conversationID); + final mesageListPosition = model.getMessageListPosition(widget.model.conversationID); final unreadCountForConversation = model.unreadCountForConversation; return Tuple2(mesageListPosition, unreadCountForConversation); }, diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart index 5f0eecf..1dbffdf 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart @@ -646,7 +646,7 @@ class _TIMUIKItHistoryMessageListItemState extends TIMUIKitState defaultTipsList = [ if (fileBeenDownloaded) MessageToolTipItem( @@ -240,7 +243,8 @@ class TIMUIKitMessageTooltipState onClick: () => _onTap("forwardMessage", model)), if (shouldShowReplyAction) MessageToolTipItem( - label: TIM_t(model.chatConfig.isAtWhenReply ? "回复" : "引用"), + label: TIM_t( + (dynamicQuote ?? model.chatConfig.isAtWhenReply) ? "回复" : "引用"), id: "replyMessage", iconImageAsset: "images/reply_message.png", onClick: () => _onTap("replyMessage", model)), @@ -502,7 +506,7 @@ class TIMUIKitMessageTooltipState } else if (widget.message.elemType == MessageElemType.V2TIM_ELEM_TYPE_IMAGE) { final savePath = (TencentUtils.checkString( - widget.message.imageElem!.imageList?[0]?.localUrl) ?? + widget.message.imageElem!.imageList?[0]?.localUrl) ?? TencentUtils.checkString(widget.message.imageElem?.path) ?? ""); copyImageToClipboard(savePath); @@ -510,12 +514,14 @@ class TIMUIKitMessageTooltipState break; case "replyMessage": model.repliedMessage = widget.message; + final dynamicQuote = + model.chatConfig.isAtWhenReplyDynamic?.call(widget.message); final isSelf = widget.message.isSelf ?? true; final isGroup = TencentUtils.checkString(widget.message.groupID) != null; final isAtWhenReply = !isSelf && isGroup && - widget.allowAtUserWhenReply && + (dynamicQuote ?? widget.allowAtUserWhenReply) && widget.onLongPressForOthersHeadPortrait != null; /// If replying to a self message, do not add a at tag, only requestFocus. diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_file_elem.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_file_elem.dart index 41e7f1f..f1dba03 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_file_elem.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_file_elem.dart @@ -32,7 +32,16 @@ class TIMUIKitFileElem extends StatefulWidget { final bool? isShowMessageReaction; final TUIChatSeparateViewModel chatModel; - const TIMUIKitFileElem({Key? key, required this.chatModel, required this.messageID, required this.fileElem, required this.isSelf, required this.isShowJump, this.clearJump, required this.message, this.isShowMessageReaction}) + const TIMUIKitFileElem( + {Key? key, + required this.chatModel, + required this.messageID, + required this.fileElem, + required this.isSelf, + required this.isShowJump, + this.clearJump, + required this.message, + this.isShowMessageReaction}) : super(key: key); @override @@ -44,14 +53,19 @@ class _TIMUIKitFileElemState extends TIMUIKitState { bool isWebDownloading = false; final TUIChatGlobalModel model = serviceLocator(); int downloadProgress = 0; - late V2TimAdvancedMsgListener advancedMsgListener; + V2TimAdvancedMsgListener? advancedMsgListener; final GlobalKey containerKey = GlobalKey(); double? containerHeight; bool? _downloadFailed = false; @override void dispose() { - TencentImSDKPlugin.v2TIMManager.getMessageManager().removeAdvancedMsgListener(listener: advancedMsgListener); + if (advancedMsgListener != null) { + TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .removeAdvancedMsgListener(listener: advancedMsgListener); + advancedMsgListener = null; + } super.dispose(); } @@ -63,8 +77,15 @@ class _TIMUIKitFileElemState extends TIMUIKitState { hasFile(); }); } + } + + Future addAdvancedMsgListenerForDownload() async { + if(advancedMsgListener != null){ + return false; + } advancedMsgListener = V2TimAdvancedMsgListener( - onMessageDownloadProgressCallback: (V2TimMessageDownloadProgress messageProgress) async { + onMessageDownloadProgressCallback: + (V2TimMessageDownloadProgress messageProgress) async { if (messageProgress.msgID == widget.message.msgID) { if (messageProgress.isError || messageProgress.errorCode != 0) { setState(() { @@ -79,12 +100,17 @@ class _TIMUIKitFileElemState extends TIMUIKitState { downloadProgress = 100; }); - TencentImSDKPlugin.v2TIMManager.getMessageManager().removeAdvancedMsgListener( - listener: advancedMsgListener, - ); + if (advancedMsgListener != null) { + TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .removeAdvancedMsgListener(listener: advancedMsgListener); + advancedMsgListener = null; + } } } else { - final currentProgress = (messageProgress.currentSize / messageProgress.totalSize * 100).floor(); + final currentProgress = + (messageProgress.currentSize / messageProgress.totalSize * 100) + .floor(); if (mounted && currentProgress > downloadProgress) { setState(() { downloadProgress = currentProgress; @@ -94,11 +120,17 @@ class _TIMUIKitFileElemState extends TIMUIKitState { } }, ); - TencentImSDKPlugin.v2TIMManager.getMessageManager().addAdvancedMsgListener(listener: advancedMsgListener); + await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .addAdvancedMsgListener(listener: advancedMsgListener!); + return true; } Future getSavePath() async { - String savePathWithAppPath = '/storage/emulated/0/Android/data/com.tencent.flutter.tuikit/cache/' + (widget.message.msgID ?? "") + widget.fileElem!.fileName!; + String savePathWithAppPath = + '/storage/emulated/0/Android/data/com.tencent.flutter.tuikit/cache/' + + (widget.message.msgID ?? "") + + widget.fileElem!.fileName!; return savePathWithAppPath; } @@ -106,7 +138,11 @@ class _TIMUIKitFileElemState extends TIMUIKitState { if (PlatformUtils().isWeb) { return true; } - String savePath = TencentUtils.checkString(model.getFileMessageLocation(widget.messageID)) ?? TencentUtils.checkString(widget.message.fileElem!.localUrl) ?? widget.message.fileElem?.path ?? ''; + String savePath = TencentUtils.checkString( + model.getFileMessageLocation(widget.messageID)) ?? + TencentUtils.checkString(widget.message.fileElem!.localUrl) ?? + widget.message.fileElem?.path ?? + ''; File f = File(savePath); if (f.existsSync() && widget.messageID != null) { filePath = savePath; @@ -118,6 +154,12 @@ class _TIMUIKitFileElemState extends TIMUIKitState { if (model.getMessageProgress(widget.messageID) != 100) { model.setMessageProgress(widget.messageID!, 100); } + if (advancedMsgListener != null) { + TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .removeAdvancedMsgListener(listener: advancedMsgListener); + advancedMsgListener = null; + } return true; } return false; @@ -159,7 +201,8 @@ class _TIMUIKitFileElemState extends TIMUIKitState { downloadFile(TUITheme theme) async { if (PlatformUtils().isMobile) { if (PlatformUtils().isIOS) { - if (!await Permissions.checkPermission(context, Permission.photosAddOnly.value, theme, false)) { + if (!await Permissions.checkPermission( + context, Permission.photosAddOnly.value, theme, false)) { return; } } else { @@ -191,13 +234,18 @@ class _TIMUIKitFileElemState extends TIMUIKitState { } tryOpenFile(context, theme) async { - if (!PlatformUtils().isWeb && (await hasZeroSize(filePath) || widget.message.status == 3)) { - onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: "不支持 0KB 文件的传输", infoCode: 6660417)); + if (!PlatformUtils().isWeb && + (await hasZeroSize(filePath) || widget.message.status == 3)) { + onTIMCallback(TIMCallback( + type: TIMCallbackType.INFO, + infoRecommendText: "不支持 0KB 文件的传输", + infoCode: 6660417)); return; } if (PlatformUtils().isMobile) { if (PlatformUtils().isIOS) { - if (!await Permissions.checkPermission(context, Permission.photosAddOnly.value, theme!, false)) { + if (!await Permissions.checkPermission( + context, Permission.photosAddOnly.value, theme!, false)) { return; } } else { @@ -241,7 +289,8 @@ class _TIMUIKitFileElemState extends TIMUIKitState { headers: {'Content-Type': 'application/x-www-form-urlencoded'}, ); - final html.AnchorElement downloadAnchor = html.document.createElement('a') as html.AnchorElement; + final html.AnchorElement downloadAnchor = + html.document.createElement('a') as html.AnchorElement; final html.Blob blob = html.Blob([response.bodyBytes]); @@ -253,7 +302,8 @@ class _TIMUIKitFileElemState extends TIMUIKitState { html.AnchorElement( href: widget.fileElem?.path ?? "", ) - ..setAttribute("download", widget.message.fileElem?.fileName ?? fileName) + ..setAttribute( + "download", widget.message.fileElem?.fileName ?? fileName) ..setAttribute("target", '_blank') ..style.display = "none" ..click(); @@ -272,14 +322,24 @@ class _TIMUIKitFileElemState extends TIMUIKitState { final fileName = widget.fileElem!.fileName ?? ""; final fileSize = widget.fileElem!.fileSize; final borderRadius = widget.isSelf - ? const BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(2), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)) - : const BorderRadius.only(topLeft: Radius.circular(2), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)); + ? const BorderRadius.only( + topLeft: Radius.circular(10), + topRight: Radius.circular(2), + bottomLeft: Radius.circular(10), + bottomRight: Radius.circular(10)) + : const BorderRadius.only( + topLeft: Radius.circular(2), + topRight: Radius.circular(10), + bottomLeft: Radius.circular(10), + bottomRight: Radius.circular(10)); String? fileFormat; - if (widget.fileElem?.fileName != null && widget.fileElem!.fileName!.isNotEmpty) { + if (widget.fileElem?.fileName != null && + widget.fileElem!.fileName!.isNotEmpty) { final String fileName = widget.fileElem!.fileName!; fileFormat = fileName.split(".")[max(fileName.split(".").length - 1, 0)]; } - final RenderBox? containerRenderBox = containerKey.currentContext?.findRenderObject() as RenderBox?; + final RenderBox? containerRenderBox = + containerKey.currentContext?.findRenderObject() as RenderBox?; if (containerRenderBox != null) { containerHeight = containerRenderBox.size.height; } @@ -312,6 +372,8 @@ class _TIMUIKitFileElemState extends TIMUIKitState { } return; } + + await addAdvancedMsgListenerForDownload(); if (await hasFile()) { if (received == 100) { tryOpenFile(context, theme); @@ -328,14 +390,20 @@ class _TIMUIKitFileElemState extends TIMUIKitState { } if (checkIsWaiting()) { onTIMCallback( - TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("已加入待下载队列,其他文件下载中"), infoCode: 6660413), + TIMCallback( + type: TIMCallbackType.INFO, + infoRecommendText: TIM_t("已加入待下载队列,其他文件下载中"), + infoCode: 6660413), ); return; } else { await addUrlToWaitingPath(theme); } } catch (e) { - onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: "文件处理异常", infoCode: 6660416)); + onTIMCallback(TIMCallback( + type: TIMCallbackType.INFO, + infoRecommendText: "文件处理异常", + infoCode: 6660416)); } }, child: ConstrainedBox( @@ -344,7 +412,8 @@ class _TIMUIKitFileElemState extends TIMUIKitState { width: 237, decoration: BoxDecoration( border: Border.all( - color: theme.weakDividerColor ?? CommonColor.weakDividerColor, + color: theme.weakDividerColor ?? + CommonColor.weakDividerColor, ), borderRadius: borderRadius), child: Stack(children: [ @@ -353,44 +422,55 @@ class _TIMUIKitFileElemState extends TIMUIKitState { child: LinearProgressIndicator( minHeight: ((containerHeight) ?? 72) - 6, value: (received == 100 ? 0 : received) / 100, - backgroundColor: received == 100 ? theme.weakBackgroundColor : Colors.white, - valueColor: AlwaysStoppedAnimation(theme.lightPrimaryMaterialColor.shade50), + backgroundColor: received == 100 + ? theme.weakBackgroundColor + : Colors.white, + valueColor: AlwaysStoppedAnimation( + theme.lightPrimaryMaterialColor.shade50), ), ), Padding( - padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12), - child: Row(mainAxisAlignment: widget.isSelf ? MainAxisAlignment.end : MainAxisAlignment.start, children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 12), + child: Row( + mainAxisAlignment: widget.isSelf + ? MainAxisAlignment.end + : MainAxisAlignment.start, children: [ - Container( - constraints: const BoxConstraints(maxWidth: 160), - child: LayoutBuilder( - builder: (buildContext, boxConstraints) { - return CustomText( - fileName, - width: boxConstraints.maxWidth, - maxLines: 1, + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + constraints: + const BoxConstraints(maxWidth: 160), + child: LayoutBuilder( + builder: (buildContext, boxConstraints) { + return CustomText( + fileName, + width: boxConstraints.maxWidth, + maxLines: 1, + style: TextStyle( + color: theme.darkTextColor, + fontSize: 16, + ), + ); + }, + ), + ), + if (fileSize != null) + Text( + showFileSize(fileSize), style: TextStyle( - color: theme.darkTextColor, - fontSize: 16, - ), - ); - }, - ), + fontSize: 14, + color: theme.weakTextColor), + ) + ], + )), + TIMUIKitFileIcon( + fileFormat: fileFormat, ), - if (fileSize != null) - Text( - showFileSize(fileSize), - style: TextStyle(fontSize: 14, color: theme.weakTextColor), - ) - ], - )), - TIMUIKitFileIcon( - fileFormat: fileFormat, - ), - ])), + ])), ]), ), ), diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_image_elem.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_image_elem.dart index 2036954..f88d078 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_image_elem.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_image_elem.dart @@ -45,7 +45,15 @@ class TIMUIKitImageElem extends StatefulWidget { final bool? isShowMessageReaction; final TUIChatSeparateViewModel chatModel; - const TIMUIKitImageElem({required this.message, this.isShowJump = false, required this.chatModel, this.clearJump, this.isFrom, Key? key, this.isShowMessageReaction}) : super(key: key); + const TIMUIKitImageElem( + {required this.message, + this.isShowJump = false, + required this.chatModel, + this.clearJump, + this.isFrom, + Key? key, + this.isShowMessageReaction}) + : super(key: key); @override State createState() => _TIMUIKitImageElem(); @@ -65,7 +73,9 @@ class _TIMUIKitImageElem extends TIMUIKitState { String getOriginImgURL() { // 实际拿的是原图 - V2TimImage? img = MessageUtils.getImageFromImgList(widget.message.imageElem!.imageList, HistoryMessageDartConstant.oriImgPrior); + V2TimImage? img = MessageUtils.getImageFromImgList( + widget.message.imageElem!.imageList, + HistoryMessageDartConstant.oriImgPrior); return img == null ? widget.message.imageElem!.path! : img.url!; } @@ -114,7 +124,8 @@ class _TIMUIKitImageElem extends TIMUIKitState { final http.Response r = await http.get(Uri.parse(imageUrl)); final data = r.bodyBytes; final base64data = base64Encode(data); - final a = html.AnchorElement(href: 'data:image/jpeg;base64,$base64data'); + final a = + html.AnchorElement(href: 'data:image/jpeg;base64,$base64data'); a.download = md5.convert(utf8.encode(imageUrl)).toString(); a.click(); a.remove(); @@ -125,7 +136,8 @@ class _TIMUIKitImageElem extends TIMUIKitState { } if (PlatformUtils().isIOS) { - if (!await Permissions.checkPermission(context, Permission.photosAddOnly.value, theme!, false)) { + if (!await Permissions.checkPermission( + context, Permission.photosAddOnly.value, theme!, false)) { return; } } else { @@ -160,7 +172,8 @@ class _TIMUIKitImageElem extends TIMUIKitState { if (model.getMessageProgress(widget.message.msgID) == 100) { String savePath; - if (widget.message.imageElem!.path != null && widget.message.imageElem!.path != '') { + if (widget.message.imageElem!.path != null && + widget.message.imageElem!.path != '') { savePath = widget.message.imageElem!.path!; } else { savePath = model.getFileMessageLocation(widget.message.msgID); @@ -171,21 +184,36 @@ class _TIMUIKitImageElem extends TIMUIKitState { if (PlatformUtils().isIOS) { if (result['isSuccess']) { - onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存成功"), infoCode: 6660406)); + onTIMCallback(TIMCallback( + type: TIMCallbackType.INFO, + infoRecommendText: TIM_t("图片保存成功"), + infoCode: 6660406)); } else { - onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存失败"), infoCode: 6660407)); + onTIMCallback(TIMCallback( + type: TIMCallbackType.INFO, + infoRecommendText: TIM_t("图片保存失败"), + infoCode: 6660407)); } } else { if (result != null) { - onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存成功"), infoCode: 6660406)); + onTIMCallback(TIMCallback( + type: TIMCallbackType.INFO, + infoRecommendText: TIM_t("图片保存成功"), + infoCode: 6660406)); } else { - onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存失败"), infoCode: 6660407)); + onTIMCallback(TIMCallback( + type: TIMCallbackType.INFO, + infoRecommendText: TIM_t("图片保存失败"), + infoCode: 6660407)); } } return; } } 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; } @@ -194,15 +222,27 @@ class _TIMUIKitImageElem extends TIMUIKitState { if (PlatformUtils().isIOS) { if (result['isSuccess']) { - onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存成功"), infoCode: 6660406)); + onTIMCallback(TIMCallback( + type: TIMCallbackType.INFO, + infoRecommendText: TIM_t("图片保存成功"), + infoCode: 6660406)); } else { - onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存失败"), infoCode: 6660407)); + onTIMCallback(TIMCallback( + type: TIMCallbackType.INFO, + infoRecommendText: TIM_t("图片保存失败"), + infoCode: 6660407)); } } else { if (result != null) { - onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存成功"), infoCode: 6660406)); + onTIMCallback(TIMCallback( + type: TIMCallbackType.INFO, + infoRecommendText: TIM_t("图片保存成功"), + infoCode: 6660406)); } else { - onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存失败"), infoCode: 6660407)); + onTIMCallback(TIMCallback( + type: TIMCallbackType.INFO, + infoRecommendText: TIM_t("图片保存失败"), + infoCode: 6660407)); } } return; @@ -223,7 +263,8 @@ class _TIMUIKitImageElem extends TIMUIKitState { if (!isWeb && filePath != null && File(filePath).existsSync()) { imageUrl = filePath; isAssetBool = true; - } else if (localUrl != null && (!isWeb && File(localUrl).existsSync())) { + } else if (localUrl != null && + (!isWeb && File(localUrl).existsSync())) { imageUrl = localUrl; isAssetBool = true; } else { @@ -241,13 +282,19 @@ class _TIMUIKitImageElem extends TIMUIKitState { ); } } catch (e) { - onTIMCallback(TIMCallback(infoCode: 6660414, infoRecommendText: TIM_t("正在下载中"), type: TIMCallbackType.INFO)); + onTIMCallback(TIMCallback( + infoCode: 6660414, + infoRecommendText: TIM_t("正在下载中"), + type: TIMCallbackType.INFO)); return; } } V2TimImage? getImageFromList(V2TimImageTypesEnum imgType) { - V2TimImage? img = MessageUtils.getImageFromImgList(widget.message.imageElem!.imageList, HistoryMessageDartConstant.imgPriorMap[imgType] ?? HistoryMessageDartConstant.oriImgPrior); + V2TimImage? img = MessageUtils.getImageFromImgList( + widget.message.imageElem!.imageList, + HistoryMessageDartConstant.imgPriorMap[imgType] ?? + HistoryMessageDartConstant.oriImgPrior); return img; } @@ -271,18 +318,26 @@ class _TIMUIKitImageElem extends TIMUIKitState { )); bool checkIfDownloadSuccess() { - final localUrl = TencentUtils.checkString(model.getFileMessageLocation(widget.message.msgID)) ?? widget.message.imageElem!.imageList![0]!.localUrl; - return TencentUtils.checkString(localUrl) != null && File(localUrl!).existsSync(); + final localUrl = TencentUtils.checkString( + model.getFileMessageLocation(widget.message.msgID)) ?? + widget.message.imageElem!.imageList![0]!.localUrl; + return TencentUtils.checkString(localUrl) != null && + File(localUrl!).existsSync(); } _onClickOpenImageInNewWindow() { - final localUrl = TencentUtils.checkString(model.getFileMessageLocation(widget.message.msgID)) ?? widget.message.imageElem!.imageList![0]!.localUrl; + final localUrl = TencentUtils.checkString( + model.getFileMessageLocation(widget.message.msgID)) ?? + widget.message.imageElem!.imageList![0]!.localUrl; Future.delayed(const Duration(milliseconds: 0), () async { final isDownloaded = checkIfDownloadSuccess(); if (isDownloaded) { launchDesktopFile(localUrl ?? ""); } else { - onTIMCallback(TIMCallback(infoCode: 6660414, infoRecommendText: TIM_t("正在下载原始资源,请稍候..."), type: TIMCallbackType.INFO)); + onTIMCallback(TIMCallback( + infoCode: 6660414, + infoRecommendText: TIM_t("正在下载原始资源,请稍候..."), + type: TIMCallbackType.INFO)); } }); } @@ -291,14 +346,27 @@ class _TIMUIKitImageElem extends TIMUIKitState { double? positionRadio, String? originImgUrl, }) { - final localUrl = TencentUtils.checkString(model.getFileMessageLocation(widget.message.msgID)) ?? widget.message.imageElem!.imageList![0]!.localUrl; + final localUrl = TencentUtils.checkString( + model.getFileMessageLocation(widget.message.msgID)) ?? + widget.message.imageElem!.imageList![0]!.localUrl; if (checkIfDownloadSuccess()) { - TUIKitWidePopup.showMedia(aspectRatio: positionRadio, context: context, mediaLocalPath: localUrl ?? "", onClickOrigin: () => _onClickOpenImageInNewWindow()); + TUIKitWidePopup.showMedia( + aspectRatio: positionRadio, + context: context, + mediaLocalPath: localUrl ?? "", + onClickOrigin: () => _onClickOpenImageInNewWindow()); } else { if (TencentUtils.checkString(originImgUrl) != null) { - TUIKitWidePopup.showMedia(aspectRatio: positionRadio, context: context, mediaURL: originImgUrl, onClickOrigin: () => _onClickOpenImageInNewWindow()); + TUIKitWidePopup.showMedia( + aspectRatio: positionRadio, + context: context, + mediaURL: originImgUrl, + onClickOrigin: () => _onClickOpenImageInNewWindow()); } else { - onTIMCallback(TIMCallback(infoCode: 6660414, infoRecommendText: TIM_t("正在下载中"), type: TIMCallbackType.INFO)); + onTIMCallback(TIMCallback( + infoCode: 6660414, + infoRecommendText: TIM_t("正在下载中"), + type: TIMCallbackType.INFO)); } } } @@ -365,7 +433,10 @@ class _TIMUIKitImageElem extends TIMUIKitState { } } else { if (PlatformUtils().isDesktop) { - TUIKitWidePopup.showMedia(mediaLocalPath: imgPath, context: context, onClickOrigin: () => launchDesktopFile(imgPath ?? "")); + TUIKitWidePopup.showMedia( + mediaLocalPath: imgPath, + context: context, + onClickOrigin: () => launchDesktopFile(imgPath ?? "")); } else { Navigator.of(context).push( PageRouteBuilder( @@ -383,56 +454,134 @@ class _TIMUIKitImageElem extends TIMUIKitState { } } - Widget _renderAllImage({dynamic heroTag, required TUITheme theme, bool isNetworkImage = false, String? webPath, V2TimImage? originalImg, V2TimImage? smallImg, String? smallLocalPath, String? originLocalPath}) { + Widget _renderAllImage( + {dynamic heroTag, + double? positionRadio, + required TUITheme theme, + bool isNetworkImage = false, + String? webPath, + V2TimImage? originalImg, + V2TimImage? smallImg, + String? smallLocalPath, + String? originLocalPath}) { Widget getImageWidget() { if (isNetworkImage) { return Hero( tag: heroTag, child: PlatformUtils().isWeb - ? Image.network(webPath ?? smallImg?.url ?? originalImg!.url!, fit: BoxFit.contain) + ? Image.network(webPath ?? smallImg?.url ?? originalImg!.url!, + fit: BoxFit.contain) : CachedNetworkImage( alignment: Alignment.topCenter, imageUrl: webPath ?? smallImg?.url ?? originalImg!.url!, - errorWidget: (context, error, stackTrace) => errorPage(theme), + errorWidget: (context, error, stackTrace) => + errorPage(theme), fit: BoxFit.contain, cacheKey: smallImg?.uuid ?? originalImg!.uuid, - placeholder: (context, url) => Image(image: MemoryImage(kTransparentImage)), + placeholder: (context, url) => + Image(image: MemoryImage(kTransparentImage)), fadeInDuration: const Duration(milliseconds: 0), )); } else { - final imgPath = (TencentUtils.checkString(smallLocalPath) != null ? smallLocalPath : originLocalPath)!; - return Hero(tag: heroTag, child: Image.file(File(imgPath), fit: BoxFit.contain)); + final imgPath = (TencentUtils.checkString(smallLocalPath) != null + ? smallLocalPath + : originLocalPath)!; + return Hero( + tag: heroTag, + child: Image.file(File(imgPath), fit: BoxFit.contain)); } } + double? currentPositionRadio; + // File imgF = File((TencentUtils.checkString(originLocalPath) != null + // ? originLocalPath + // : smallLocalPath) ?? + // ""); + // bool isExist = imgF.existsSync(); + // + // if (!isExist) { + // return errorDisplay(context, theme); + // } + // Image image = Image.file(imgF); + // + // image.image + // .resolve(const ImageConfiguration()) + // .addListener(ImageStreamListener((image, synchronousCall) { + // if (image.image.width != 0 && image.image.height != 0) { + // currentPositionRadio = image.image.width / image.image.height; + // } + // })); + return GestureDetector( onTap: () => onClickImage( - theme: theme, heroTag: heroTag, isNetworkImage: isNetworkImage, imgUrl: webPath ?? smallImg?.url ?? originalImg?.url ?? "", imgPath: (TencentUtils.checkString(originLocalPath) != null ? originLocalPath : smallLocalPath) ?? ""), - child: getImageWidget(), + theme: theme, + heroTag: heroTag, + isNetworkImage: isNetworkImage, + imgUrl: webPath ?? smallImg?.url ?? originalImg?.url ?? "", + imgPath: (TencentUtils.checkString(originLocalPath) != null + ? originLocalPath + : smallLocalPath) ?? + ""), + child: Stack( + children: [ + if (currentPositionRadio != null || positionRadio != null) + AspectRatio( + aspectRatio: (currentPositionRadio ?? positionRadio)!, + child: Container( + decoration: const BoxDecoration(color: Colors.transparent), + ), + ), + getImageWidget(), + ], + ), ); } void initImages() async { - final zeroImageLocal = TencentUtils.checkString(widget.message.imageElem?.imageList?.firstWhereOrNull((element) => element?.type == 0)?.localUrl); - final oneImageLocal = TencentUtils.checkString(widget.message.imageElem?.imageList?.firstWhereOrNull((element) => element?.type == 1)?.localUrl); - final twoImageLocal = TencentUtils.checkString(widget.message.imageElem?.imageList?.firstWhereOrNull((element) => element?.type == 2)?.localUrl); + final zeroImageLocal = TencentUtils.checkString(widget + .message.imageElem?.imageList + ?.firstWhereOrNull((element) => element?.type == 0) + ?.localUrl); + final oneImageLocal = TencentUtils.checkString(widget + .message.imageElem?.imageList + ?.firstWhereOrNull((element) => element?.type == 1) + ?.localUrl); + final twoImageLocal = TencentUtils.checkString(widget + .message.imageElem?.imageList + ?.firstWhereOrNull((element) => element?.type == 2) + ?.localUrl); - if (!PlatformUtils().isWeb && TencentUtils.checkString(widget.message.msgID) != null) { - if ((widget.message.imageElem?.imageList) == null || widget.message.imageElem!.imageList!.isEmpty) { - final response = await _messageService.getMessageOnlineUrl(msgID: widget.message.msgID!); + if (!PlatformUtils().isWeb && + TencentUtils.checkString(widget.message.msgID) != null) { + if ((widget.message.imageElem?.imageList) == null || + widget.message.imageElem!.imageList!.isEmpty) { + final response = await _messageService.getMessageOnlineUrl( + msgID: widget.message.msgID!); final elem = response.data; if (elem != null && elem.imageElem != null) { widget.message.imageElem = elem.imageElem; } } if (oneImageLocal == null || !File(oneImageLocal).existsSync()) { - _messageService.downloadMessage(msgID: widget.message.msgID!, messageType: 3, imageType: 1, isSnapshot: false); + _messageService.downloadMessage( + msgID: widget.message.msgID!, + messageType: 3, + imageType: 1, + isSnapshot: false); } if (twoImageLocal == null || !File(twoImageLocal).existsSync()) { - _messageService.downloadMessage(msgID: widget.message.msgID!, messageType: 3, imageType: 2, isSnapshot: false); + _messageService.downloadMessage( + msgID: widget.message.msgID!, + messageType: 3, + imageType: 2, + isSnapshot: false); } if (zeroImageLocal == null || !File(zeroImageLocal).existsSync()) { - _messageService.downloadMessage(msgID: widget.message.msgID!, messageType: 3, imageType: 0, isSnapshot: false); + _messageService.downloadMessage( + msgID: widget.message.msgID!, + messageType: 3, + imageType: 0, + isSnapshot: false); } } } @@ -446,36 +595,83 @@ class _TIMUIKitImageElem extends TIMUIKitState { bool isNeedShowLocalPath() { final current = (DateTime.now().millisecondsSinceEpoch / 1000).ceil(); final timeStamp = widget.message.timestamp ?? current; - return (widget.message.isSelf ?? true) && (isSent || current - timeStamp < 300); + return (widget.message.isSelf ?? true) && + (isSent || current - timeStamp < 300); } - Widget? _renderImage(dynamic heroTag, TUITheme theme, {V2TimImage? originalImg, V2TimImage? smallImg}) { + Widget? _renderImage(dynamic heroTag, TUITheme theme, + {V2TimImage? originalImg, V2TimImage? smallImg}) { + + double positionRadio = 1.0; + if (smallImg?.width != null && + smallImg?.height != null && + smallImg?.width != 0 && + smallImg?.height != 0) { + positionRadio = (smallImg!.width! / smallImg.height!); + } + if (PlatformUtils().isWeb && widget.message.imageElem!.path != null) { // Displaying on Web only - return _renderAllImage(heroTag: heroTag, theme: theme, isNetworkImage: true, smallImg: smallImg, originalImg: originalImg, webPath: widget.message.imageElem!.path); + return _renderAllImage( + heroTag: heroTag, + theme: theme, + isNetworkImage: true, + smallImg: smallImg, + originalImg: originalImg, + positionRadio: positionRadio, + webPath: widget.message.imageElem!.path); } try { - if ((isNeedShowLocalPath() && widget.message.imageElem!.path != null && widget.message.imageElem!.path!.isNotEmpty && File(widget.message.imageElem!.path!).existsSync())) { - return _renderAllImage(smallLocalPath: widget.message.imageElem!.path!, heroTag: heroTag, theme: theme, originLocalPath: widget.message.imageElem!.path!); + if ((isNeedShowLocalPath() && + widget.message.imageElem!.path != null && + widget.message.imageElem!.path!.isNotEmpty && + File(widget.message.imageElem!.path!).existsSync())) { + return _renderAllImage( + smallLocalPath: widget.message.imageElem!.path!, + heroTag: heroTag, + theme: theme, + positionRadio: positionRadio, + originLocalPath: widget.message.imageElem!.path!); } } catch (e) { // ignore: avoid_print - outputLogger.i(e); + outputLogger.i(e.toString()); } try { - if ((TencentUtils.checkString(smallImg?.localUrl) != null && File((smallImg?.localUrl!)!).existsSync()) || (TencentUtils.checkString(originalImg?.localUrl) != null && File((originalImg?.localUrl!)!).existsSync())) { - return _renderAllImage(smallLocalPath: smallImg?.localUrl ?? "", heroTag: heroTag, theme: theme, originLocalPath: originalImg?.localUrl); + if ((TencentUtils.checkString(smallImg?.localUrl) != null && + File((smallImg?.localUrl!)!).existsSync()) || + (TencentUtils.checkString(originalImg?.localUrl) != null && + File((originalImg?.localUrl!)!).existsSync())) { + return _renderAllImage( + smallLocalPath: smallImg?.localUrl ?? "", + heroTag: heroTag, + theme: theme, + positionRadio: positionRadio, + originLocalPath: originalImg?.localUrl); } } catch (e) { // ignore: avoid_print - outputLogger.i(e); - return _renderAllImage(heroTag: heroTag, theme: theme, isNetworkImage: true, smallImg: smallImg, originalImg: originalImg); + outputLogger.i(e.toString()); + return _renderAllImage( + heroTag: heroTag, + theme: theme, + isNetworkImage: true, + smallImg: smallImg, + positionRadio: positionRadio, + originalImg: originalImg); } - if ((smallImg?.url ?? originalImg?.url) != null && (smallImg?.url ?? originalImg?.url)!.isNotEmpty) { - return _renderAllImage(heroTag: heroTag, theme: theme, isNetworkImage: true, smallImg: smallImg, originalImg: originalImg); + if ((smallImg?.url ?? originalImg?.url) != null && + (smallImg?.url ?? originalImg?.url)!.isNotEmpty) { + return _renderAllImage( + heroTag: heroTag, + theme: theme, + isNetworkImage: true, + positionRadio: positionRadio, + smallImg: smallImg, + originalImg: originalImg); } return errorDisplay(context, theme); @@ -487,8 +683,10 @@ class _TIMUIKitImageElem extends TIMUIKitState { if (widget.message.status == MessageStatus.V2TIM_MSG_STATUS_SENDING) { isSent = true; } - final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; - final heroTag = "${widget.message.msgID ?? widget.message.id ?? widget.message.timestamp ?? DateTime.now().millisecondsSinceEpoch}${widget.isFrom}"; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + final heroTag = + "${widget.message.msgID ?? widget.message.id ?? widget.message.timestamp ?? DateTime.now().millisecondsSinceEpoch}${widget.isFrom}"; V2TimImage? originalImg = getImageFromList(V2TimImageTypesEnum.original); V2TimImage? smallImg = getImageFromList(V2TimImageTypesEnum.small); @@ -499,14 +697,16 @@ class _TIMUIKitImageElem extends TIMUIKitState { isFromSelf: widget.message.isSelf ?? true, isShowMessageReaction: widget.isShowMessageReaction ?? true, message: widget.message, - child: LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) { + child: LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { return ConstrainedBox( constraints: BoxConstraints( maxWidth: constraints.maxWidth * (isDesktopScreen ? 0.4 : 0.5), minWidth: 64, maxHeight: 256, ), - child: _renderImage(heroTag, theme, originalImg: originalImg, smallImg: smallImg), + child: _renderImage(heroTag, theme, + originalImg: originalImg, smallImg: smallImg), ); })); } @@ -515,7 +715,9 @@ class _TIMUIKitImageElem extends TIMUIKitState { class ImageClipper extends CustomClipper { @override RRect getClip(Size size) { - return RRect.fromRectAndRadius(Rect.fromLTWH(0, 0, size.width, min(size.height, 256)), const Radius.circular(5)); + return RRect.fromRectAndRadius( + Rect.fromLTWH(0, 0, size.width, min(size.height, 256)), + const Radius.circular(5)); } @override diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_reply_elem.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_reply_elem.dart index 53e4f75..0dc3c91 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_reply_elem.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_reply_elem.dart @@ -5,6 +5,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_model_tools.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart'; import 'package:extended_text/extended_text.dart'; @@ -93,6 +94,9 @@ class _TIMUIKitReplyElemState extends TIMUIKitState { } final messageID = cloudCustomData.messageID; + if(PlatformUtils().isWeb){ + return; + } V2TimMessage? message = await widget.chatModel.findMessage(messageID); if (message == null) { try { @@ -168,7 +172,7 @@ class _TIMUIKitReplyElemState extends TIMUIKitState { } if (message == null) { if (repliedMessage?.messageAbstract != null) { - _renderMessageSummary(theme); + return _renderMessageSummary(theme); } return const SizedBox(width: 0, height: 12); } diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_send_sound_message.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_send_sound_message.dart index 4c557da..98d9aef 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_send_sound_message.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_send_sound_message.dart @@ -261,7 +261,7 @@ class _SendSoundMessageState extends TIMUIKitState { isRecording = true; }); } else { - outputLogger.i(status); + outputLogger.i(status.toString()); } }); final amplitudesResponseSubscription = diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/wide.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/wide.dart index 84efff1..38a3331 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/wide.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/wide.dart @@ -222,7 +222,7 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState { axis: Axis.vertical, ); + Widget? joinInGroupCallWidget; + @override void initState() { super.initState(); @@ -346,12 +348,21 @@ class _TUIChatState extends TIMUIKitState { return widget.conversation.type == 1 ? ConvType.c2c : ConvType.group; } + _updateJoinInGroupCallWidget() async { + if (_getConvType() != ConvType.group) { + return; + } + joinInGroupCallWidget = await TUICore.instance.raiseExtension(TUIExtensionID.joinInGroup, {GROUP_ID: widget.conversationID!}); + setState(() {}); + } + @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; final closePanel = OptimizeUtils.throttle((_) => textFieldController.hideAllPanel(), 60); final isBuild = isInit; isInit = true; + _updateJoinInGroupCallWidget(); return TIMUIKitChatProviderScope( model: model, @@ -450,6 +461,7 @@ class _TUIChatState extends TIMUIKitState { if (widget.customAppBar != null) widget.customAppBar!, if (filteredApplicationList.isNotEmpty) _renderJoinGroupApplication(filteredApplicationList.length, theme), if (widget.topFixWidget != null) widget.topFixWidget!, + if (joinInGroupCallWidget != null) Center(child: joinInGroupCallWidget!), Expanded( child: Container( color: theme.chatBgColor, diff --git a/lib/ui/views/TIMUIKitChat/tim_uikit_chat_config.dart b/lib/ui/views/TIMUIKitChat/tim_uikit_chat_config.dart index a73eed1..763e264 100644 --- a/lib/ui/views/TIMUIKitChat/tim_uikit_chat_config.dart +++ b/lib/ui/views/TIMUIKitChat/tim_uikit_chat_config.dart @@ -96,6 +96,10 @@ class TIMUIKitChatConfig { /// [Default]: true. final bool isAtWhenReply; + /// Control if allowed to at when reply automatically. + /// [Default]: true. + final bool Function(V2TimMessage message)? isAtWhenReplyDynamic; + /// The main switch of the group read receipt. final bool isShowGroupMessageReadReceipt; @@ -258,6 +262,7 @@ class TIMUIKitChatConfig { this.isUseMessageReaction = true, this.isShowAvatar = true, this.isShowSelfNameInGroup = false, + this.isAtWhenReplyDynamic, this.offlinePushInfo, @Deprecated("Please use [isShowGroupReadingStatus] instead") this.isShowGroupMessageReadReceipt = true, diff --git a/lib/ui/views/TIMUIKitGroup/tim_uikit_group_application_list.dart b/lib/ui/views/TIMUIKitGroup/tim_uikit_group_application_list.dart index 63850cd..2c004ed 100644 --- a/lib/ui/views/TIMUIKitGroup/tim_uikit_group_application_list.dart +++ b/lib/ui/views/TIMUIKitGroup/tim_uikit_group_application_list.dart @@ -1,21 +1,15 @@ import 'package:flutter/material.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'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; - - import 'package:tencent_cloud_chat_uikit/data_services/group/group_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; - - import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; - -import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; -typedef GroupApplicationItemBuilder = Widget Function( - BuildContext context, V2TimGroupApplication applicationInfo, int index); +typedef GroupApplicationItemBuilder = Widget Function(BuildContext context, V2TimGroupApplication applicationInfo, int index); enum ApplicationStatus { none, @@ -30,16 +24,13 @@ class TIMUIKitGroupApplicationList extends StatefulWidget { /// group ID final String groupID; - const TIMUIKitGroupApplicationList( - {Key? key, this.itemBuilder, required this.groupID}) - : super(key: key); + const TIMUIKitGroupApplicationList({Key? key, this.itemBuilder, required this.groupID}) : super(key: key); @override State createState() => TIMUIKitGroupApplicationListState(); } -class TIMUIKitGroupApplicationListState - extends TIMUIKitState { +class TIMUIKitGroupApplicationListState extends TIMUIKitState { final TUIChatGlobalModel model = serviceLocator(); final GroupServices _groupServices = serviceLocator(); List groupApplicationList = []; @@ -48,26 +39,20 @@ class TIMUIKitGroupApplicationListState @override void initState() { super.initState(); - groupApplicationList = model.groupApplicationList - .where((item) => (item.groupID == widget.groupID)) - .toList(); - applicationStatusList = - groupApplicationList.map((item) => ApplicationStatus.none).toList(); + groupApplicationList = model.groupApplicationList.where((item) => (item.groupID == widget.groupID)).toList(); + applicationStatusList = groupApplicationList.map((item) => ApplicationStatus.none).toList(); } GroupApplicationItemBuilder _getItemBuilder() { return widget.itemBuilder ?? _defaultItemBuilder; } - Widget _defaultItemBuilder( - BuildContext context, V2TimGroupApplication applicationInfo, int index) { + Widget _defaultItemBuilder(BuildContext context, V2TimGroupApplication applicationInfo, int index) { final theme = Provider.of(context).theme; final ApplicationStatus currentStatus = applicationStatusList[index]; String _getUserName() { - if (applicationInfo.fromUserNickName != null && - applicationInfo.fromUserNickName!.isNotEmpty && - applicationInfo.fromUserNickName != applicationInfo.fromUser) { + if (applicationInfo.fromUserNickName != null && applicationInfo.fromUserNickName!.isNotEmpty && applicationInfo.fromUserNickName != applicationInfo.fromUser) { return "${applicationInfo.fromUserNickName} (${applicationInfo.fromUser})"; } else { return "${applicationInfo.fromUser}"; @@ -76,17 +61,14 @@ class TIMUIKitGroupApplicationListState String _getRequestMessage() { String option2 = applicationInfo.requestMsg ?? ""; - return TIM_t_para("验证消息: {{option2}}", "验证消息: $option2")( - option2: option2); + return TIM_t_para("验证消息: {{option2}}", "验证消息: $option2")(option2: option2); } return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, - border: Border( - bottom: BorderSide( - color: theme.weakDividerColor ?? const Color(0xFFDBDBDB))), + border: Border(bottom: BorderSide(color: theme.weakDividerColor ?? const Color(0xFFDBDBDB))), ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, @@ -96,11 +78,7 @@ class TIMUIKitGroupApplicationListState child: SizedBox( height: 40, width: 40, - child: Avatar( - faceUrl: applicationInfo.fromUserFaceUrl ?? "", - showName: applicationInfo.fromUserNickName ?? - applicationInfo.fromUser ?? - ""), + child: Avatar(faceUrl: applicationInfo.fromUserFaceUrl ?? "", showName: applicationInfo.fromUserNickName ?? applicationInfo.fromUser ?? ""), ), ), Expanded( @@ -109,10 +87,7 @@ class TIMUIKitGroupApplicationListState children: [ Text( _getUserName(), - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: theme.darkTextColor), + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: theme.darkTextColor), ), Text( _getRequestMessage(), @@ -120,21 +95,13 @@ class TIMUIKitGroupApplicationListState ), ], )), - if (currentStatus == ApplicationStatus.none && - applicationInfo.handleStatus == 0) + if (currentStatus == ApplicationStatus.none && applicationInfo.handleStatus == 0) Container( margin: const EdgeInsets.only(left: 8, right: 8), child: InkWell( child: Container( - padding: - const EdgeInsets.symmetric(horizontal: 10, vertical: 4), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(4), - color: theme.primaryColor, - border: Border.all( - width: 1, - color: theme.weakTextColor ?? - CommonColor.weakTextColor)), + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(4), color: theme.primaryColor, border: Border.all(width: 1, color: theme.weakTextColor ?? CommonColor.weakTextColor)), child: Text( TIM_t("同意"), // agree style: const TextStyle( @@ -160,19 +127,11 @@ class TIMUIKitGroupApplicationListState } }), ), - if (currentStatus == ApplicationStatus.none && - applicationInfo.handleStatus == 0) + if (currentStatus == ApplicationStatus.none && applicationInfo.handleStatus == 0) InkWell( child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(4), - color: Colors.white, - border: Border.all( - width: 1, - color: - theme.weakTextColor ?? CommonColor.weakTextColor)), - padding: - const EdgeInsets.symmetric(horizontal: 10, vertical: 4), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(4), color: Colors.white, border: Border.all(width: 1, color: theme.weakTextColor ?? CommonColor.weakTextColor)), + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), child: Text( TIM_t("拒绝"), // reject style: TextStyle( @@ -182,12 +141,7 @@ class TIMUIKitGroupApplicationListState ), onTap: () async { final res = await _groupServices.refuseGroupApplication( - addTime: applicationInfo.addTime!, - groupID: applicationInfo.groupID, - fromUser: applicationInfo.fromUser!, - toUser: applicationInfo.toUser!, - type: - GroupApplicationTypeEnum.values[applicationInfo.type]); + addTime: applicationInfo.addTime!, groupID: applicationInfo.groupID, fromUser: applicationInfo.fromUser!, toUser: applicationInfo.toUser!, type: GroupApplicationTypeEnum.values[applicationInfo.type]); if (res.code == 0) { setState(() { applicationStatusList[index] = ApplicationStatus.reject; @@ -198,8 +152,7 @@ class TIMUIKitGroupApplicationListState } }, ), - if (currentStatus == ApplicationStatus.accept || - applicationInfo.handleStatus == 1) + if (currentStatus == ApplicationStatus.accept || applicationInfo.handleResult == 1) Container( margin: const EdgeInsets.only(left: 8), child: Text( @@ -207,8 +160,7 @@ class TIMUIKitGroupApplicationListState style: TextStyle(fontSize: 15, color: theme.weakTextColor), ), ), - if (currentStatus == ApplicationStatus.reject || - applicationInfo.handleStatus == 2) + if (currentStatus == ApplicationStatus.reject || applicationInfo.handleResult == 2) Container( margin: const EdgeInsets.only(left: 8), child: Text( @@ -228,8 +180,7 @@ class TIMUIKitGroupApplicationListState return MultiProvider( providers: [ChangeNotifierProvider.value(value: model)], builder: (context, w) { - final isDesktopScreen = - TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return Container( decoration: isDesktopScreen ? null : BoxDecoration(color: theme.weakBackgroundColor), child: ListView.builder( diff --git a/lib/ui/widgets/video_custom_control.dart b/lib/ui/widgets/video_custom_control.dart index a55a493..f82c7fa 100644 --- a/lib/ui/widgets/video_custom_control.dart +++ b/lib/ui/widgets/video_custom_control.dart @@ -2,10 +2,10 @@ import 'dart:async'; -import 'package:chewie_for_us/chewie_for_us.dart'; -import 'package:chewie_for_us/src/animated_play_pause.dart'; -import 'package:chewie_for_us/src/helpers/utils.dart'; -import 'package:chewie_for_us/src/material/material_progress_bar.dart'; +import 'package:chewie/chewie.dart'; +import 'package:chewie/src/animated_play_pause.dart'; +import 'package:chewie/src/helpers/utils.dart'; +import 'package:chewie/src/material/material_progress_bar.dart'; import 'package:flutter/material.dart'; import 'package:loading_animation_widget/loading_animation_widget.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; @@ -380,8 +380,7 @@ class _VideoCustomControlsState extends TIMUIKitState with _startHideTimer(); }, - colors: chewieController.materialProgressColors ?? - ChewieProgressColors(playedColor: Colors.white, handleColor: Colors.white, bufferedColor: Colors.white38, backgroundColor: Colors.white24), + colors: chewieController.materialProgressColors ?? ChewieProgressColors(playedColor: Colors.white, handleColor: Colors.white, bufferedColor: Colors.white38, backgroundColor: Colors.white24), ), ), ); diff --git a/lib/ui/widgets/video_screen.dart b/lib/ui/widgets/video_screen.dart index 8c926bc..20e5da3 100644 --- a/lib/ui/widgets/video_screen.dart +++ b/lib/ui/widgets/video_screen.dart @@ -1,30 +1,27 @@ import 'dart:convert'; import 'dart:io'; import 'dart:math'; + +import 'package:chewie/chewie.dart'; import 'package:crypto/crypto.dart'; import 'package:device_info_plus/device_info_plus.dart'; -import 'package:image_gallery_saver/image_gallery_saver.dart'; -import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.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: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'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; -import 'package:universal_html/html.dart' as html; -import 'package:chewie_for_us/chewie_for_us.dart'; -import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/permission.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/video_custom_control.dart'; +import 'package:universal_html/html.dart' as html; import 'package:video_player/video_player.dart'; -import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.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; @@ -37,8 +34,7 @@ class VideoScreen extends StatefulWidget { class _VideoScreenState extends TIMUIKitState { late VideoPlayerController videoPlayerController; late ChewieController chewieController; - GlobalKey slidePagekey = - GlobalKey(); + GlobalKey slidePagekey = GlobalKey(); final TUIChatGlobalModel model = serviceLocator(); bool isInit = false; @@ -56,22 +52,19 @@ class _VideoScreenState extends TIMUIKitState { } //保存网络视频到本地 - Future _saveNetworkVideo(context, - String videoUrl, { - bool isAsset = true, - }) async { + Future _saveNetworkVideo( + context, + String videoUrl, { + bool isAsset = true, + }) async { if (PlatformUtils().isWeb) { RegExp exp = RegExp(r"((\.){1}[^?]{2,4})"); - String? suffix = exp - .allMatches(videoUrl) - .last - .group(0); + String? suffix = exp.allMatches(videoUrl).last.group(0); var xhr = html.HttpRequest(); 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(); @@ -92,7 +85,8 @@ class _VideoScreenState extends TIMUIKitState { AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; if ((androidInfo.version.sdkInt) >= 33) { final videos = await Permissions.checkPermission( - context, Permission.videos.value, + context, + Permission.videos.value, ); if (!videos) { @@ -100,7 +94,8 @@ class _VideoScreenState extends TIMUIKitState { } } else { final storage = await Permissions.checkPermission( - context, Permission.storage.value, + context, + Permission.storage.value, ); if (!storage) { return; @@ -115,8 +110,7 @@ class _VideoScreenState extends TIMUIKitState { } 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); @@ -126,62 +120,35 @@ class _VideoScreenState extends TIMUIKitState { 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; @@ -195,8 +162,7 @@ class _VideoScreenState extends TIMUIKitState { isAsset: true, ); } - if (widget.videoElement.videoPath != '' && - widget.videoElement.videoPath != null) { + if (widget.videoElement.videoPath != '' && widget.videoElement.videoPath != null) { File f = File(widget.videoElement.videoPath!); if (f.existsSync()) { return await _saveNetworkVideo( @@ -206,8 +172,7 @@ class _VideoScreenState extends TIMUIKitState { ); } } - 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( @@ -246,8 +211,7 @@ class _VideoScreenState extends TIMUIKitState { 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()) { @@ -257,28 +221,26 @@ class _VideoScreenState extends TIMUIKitState { } VideoPlayerController player = PlatformUtils().isWeb - ? ((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) - ? 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) - ? VideoPlayerController.file(File(widget.videoElement.videoPath!)) - : (TencentUtils.checkString(widget.videoElement.localVideoUrl) == null) - ? VideoPlayerController.networkUrl( - Uri.parse(widget.videoElement.videoUrl!), - ) - : VideoPlayerController.file(File( - widget.videoElement.localVideoUrl!, - )); + ? ((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) + ? 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) + ? VideoPlayerController.file(File(widget.videoElement.videoPath!)) + : (TencentUtils.checkString(widget.videoElement.localVideoUrl) == null) + ? VideoPlayerController.networkUrl( + Uri.parse(widget.videoElement.videoUrl!), + ) + : VideoPlayerController.file(File( + widget.videoElement.localVideoUrl!, + )); await player.initialize(); WidgetsBinding.instance.addPostFrameCallback((_) { double w = getVideoWidth(); @@ -303,8 +265,7 @@ class _VideoScreenState extends TIMUIKitState { @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); @@ -330,10 +291,7 @@ class _VideoScreenState extends TIMUIKitState { child: Container( color: Colors.transparent, constraints: BoxConstraints.expand( - height: MediaQuery - .of(context) - .size - .height, + height: MediaQuery.of(context).size.height, ), child: ExtendedImageSlidePage( key: slidePagekey, @@ -342,13 +300,12 @@ class _VideoScreenState extends TIMUIKitState { 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: (Offset offset, { + slideEndHandler: ( + Offset offset, { ExtendedImageSlidePageState? state, ScaleEndDetails? details, }) { @@ -364,24 +321,15 @@ class _VideoScreenState extends TIMUIKitState { color: Colors.black, child: isInit ? Chewie( - controller: chewieController, - ) - : const Center( - child: - CircularProgressIndicator(color: Colors.white))), + controller: chewieController, + ) + : const Center(child: CircularProgressIndicator(color: Colors.white))), heroBuilderForSlidingPage: (Widget result) { return Hero( tag: widget.heroTag, child: result, - flightShuttleBuilder: (BuildContext flightContext, - Animation animation, - HeroFlightDirection flightDirection, - BuildContext fromHeroContext, - BuildContext toHeroContext) { - final Hero hero = - (flightDirection == HeroFlightDirection.pop - ? fromHeroContext.widget - : toHeroContext.widget) as Hero; + flightShuttleBuilder: (BuildContext flightContext, Animation animation, HeroFlightDirection flightDirection, BuildContext fromHeroContext, BuildContext toHeroContext) { + final Hero hero = (flightDirection == HeroFlightDirection.pop ? fromHeroContext.widget : toHeroContext.widget) as Hero; return hero.child; }, diff --git a/lib/ui/widgets/wide_popup.dart b/lib/ui/widgets/wide_popup.dart index fe85ba8..5fda41b 100644 --- a/lib/ui/widgets/wide_popup.dart +++ b/lib/ui/widgets/wide_popup.dart @@ -2,15 +2,15 @@ import 'dart:io'; -import 'package:chewie_for_us/chewie_for_us.dart'; +import 'package:chewie/chewie.dart'; import 'package:flutter/material.dart'; +import 'package:path/path.dart' as p; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; 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'; import 'package:tencent_cloud_chat_uikit/ui/widgets/drag_widget.dart'; -import 'package:path/path.dart' as p; import 'package:video_player/video_player.dart'; class TUIKitWidePopup { @@ -70,26 +70,10 @@ class TUIKitWidePopup { } isShow = true; - final TUISelfInfoViewModel selfInfoViewModel = - serviceLocator(); + final TUISelfInfoViewModel selfInfoViewModel = serviceLocator(); if (selfInfoViewModel.globalConfig?.showDesktopModalFunc != null) { - final res = await selfInfoViewModel.globalConfig!.showDesktopModalFunc!( - operationKey, - context, - child, - theme, - width, - height, - offset, - initText, - borderRadius, - isDarkBackground, - title, - onSubmit, - submitWidget, - onConfirm, - onCancel); + final res = await selfInfoViewModel.globalConfig!.showDesktopModalFunc!(operationKey, context, child, theme, width, height, offset, initText, borderRadius, isDarkBackground, title, onSubmit, submitWidget, onConfirm, onCancel); if (res == true) { return; @@ -102,8 +86,7 @@ class TUIKitWidePopup { width: width, height: height, decoration: BoxDecoration( - borderRadius: - borderRadius ?? const BorderRadius.all(Radius.circular(16)), + borderRadius: borderRadius ?? const BorderRadius.all(Radius.circular(16)), color: theme?.wideBackgroundColor ?? const Color(0xFFffffff), border: isDarkBackground ? Border.all( @@ -129,9 +112,7 @@ class TUIKitWidePopup { padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: hexToColor("f5f6f7"), - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(16), - topRight: Radius.circular(16)), + borderRadius: const BorderRadius.only(topLeft: Radius.circular(16), topRight: Radius.circular(16)), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -139,9 +120,7 @@ class TUIKitWidePopup { children: [ Text( title, - style: TextStyle( - fontSize: 18, - color: theme?.darkTextColor ?? const Color(0xFF444444)), + style: TextStyle(fontSize: 18, color: theme?.darkTextColor ?? const Color(0xFF444444)), ), InkWell( onTap: () { @@ -156,9 +135,7 @@ class TUIKitWidePopup { entry = null; } }, - child: onSubmit != null - ? (submitWidget ?? const Icon(Icons.check)) - : const Icon(Icons.close), + child: onSubmit != null ? (submitWidget ?? const Icon(Icons.check)) : const Icon(Icons.close), ) ], ), @@ -212,8 +189,7 @@ class TUIKitWidePopup { }, child: Text( TIM_t("取消"), - style: TextStyle( - color: theme?.weakTextColor ?? Colors.black), + style: TextStyle(color: theme?.weakTextColor ?? Colors.black), )), ), if (onConfirm != null) @@ -293,8 +269,7 @@ class TUIKitWidePopup { required VoidCallback onClickOrigin, double? aspectRatio, }) async { - assert((mediaLocalPath != null) || (mediaURL != null), - "At least one of mediaLocalPath or mediaURL must be provided."); + assert((mediaLocalPath != null) || (mediaURL != null), "At least one of mediaLocalPath or mediaURL must be provided."); String _removeQueryString(String urlString) { Uri uri = Uri.parse(urlString); @@ -310,10 +285,8 @@ class TUIKitWidePopup { final String mediaPath = mediaLocalPath ?? mediaURL ?? ""; final isLocalResource = mediaLocalPath != null; - String fileExtension = p - .extension(isLocalResource ? mediaPath : _removeQueryString(mediaPath)); - bool isVideo = - ['.mp4', '.avi', '.mov', '.flv', '.wmv'].contains(fileExtension); + String fileExtension = p.extension(isLocalResource ? mediaPath : _removeQueryString(mediaPath)); + bool isVideo = ['.mp4', '.avi', '.mov', '.flv', '.wmv'].contains(fileExtension); VideoPlayerController? videoController; ChewieController? chewieController; @@ -324,8 +297,7 @@ class TUIKitWidePopup { if (isLocalResource) { videoController = VideoPlayerController.file(File(mediaPath)); } else { - videoController = - VideoPlayerController.networkUrl(Uri.parse(mediaPath)); + videoController = VideoPlayerController.networkUrl(Uri.parse(mediaPath)); } await videoController.initialize(); @@ -342,9 +314,7 @@ class TUIKitWidePopup { mediaWidget = Chewie(controller: chewieController); } else { - mediaWidget = isLocalResource - ? Image.file(File(mediaPath), fit: BoxFit.contain) - : Image.network(mediaPath, fit: BoxFit.contain); + mediaWidget = isLocalResource ? Image.file(File(mediaPath), fit: BoxFit.contain) : Image.network(mediaPath, fit: BoxFit.contain); } showDialog( @@ -373,11 +343,7 @@ class TUIKitWidePopup { maxWidth: MediaQuery.of(context).size.width * 0.85, maxHeight: MediaQuery.of(context).size.height * 0.82, ), - child: aspectRatioFinal != null - ? AspectRatio( - aspectRatio: aspectRatioFinal, - child: mediaWidget) - : mediaWidget, + child: aspectRatioFinal != null ? AspectRatio(aspectRatio: aspectRatioFinal, child: mediaWidget) : mediaWidget, ), const SizedBox(height: 10), InkWell( diff --git a/pubspec.lock b/pubspec.lock index 4fe8ebf..6441e8e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -217,14 +217,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.3" - chewie_for_us: + chewie: dependency: "direct main" description: - name: chewie_for_us - sha256: "0307723e811508d361fffa6f8bbd9040b1bfea5536544e4d655e10c27de002ec" + name: chewie + sha256: "8bc4ac4cf3f316e50a25958c0f5eb9bb12cf7e8308bb1d74a43b230da2cfc144" url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "1.7.5" clock: dependency: transitive description: @@ -313,6 +313,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.2" + dbus: + dependency: transitive + description: + name: dbus + sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" + url: "https://pub.dev" + source: hosted + version: "0.7.10" desktop_drop: dependency: "direct main" description: @@ -1308,26 +1316,26 @@ packages: dependency: transitive description: name: tencent_cloud_chat_sdk - sha256: a78f1f20dc9ebe40aee1bbb47da097780028434d77e97774fbe733debb21e18e + sha256: "358e79b51aba5457418d3bb87e0bbd0f088a1eaf4c4463d09bdda93d1d655aa3" url: "https://pub.dev" source: hosted - version: "7.7.5296" + version: "7.9.5672" tencent_cloud_uikit_core: dependency: "direct main" description: name: tencent_cloud_uikit_core - sha256: "7ddb2c034e5f832261ba268957e282b7c2e738acb1d21aa40c62dad4eaa433ea" + sha256: "61a5400b3fe75c00252272469f332e7ec07f6d1932ee636a3f2b919cf9805cb8" url: "https://pub.dev" source: hosted - version: "1.5.2" + version: "1.6.0" tencent_im_base: dependency: "direct main" description: name: tencent_im_base - sha256: "035d97d24bebb87654700d4afc8227de8721a259ef5d0195f3207cb0eb0cdc7a" + sha256: daee1faac70fdf5fa4a53576db4fb7268ba5d897cc036353d3114a31abb76fb1 url: "https://pub.dev" source: hosted - version: "3.3.775296" + version: "3.3.775297" tencent_keyboard_visibility: dependency: "direct main" description: @@ -1560,22 +1568,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.16" - wakelock_for_us: + wakelock_plus: dependency: transitive description: - name: wakelock_for_us - sha256: a5bdd445e51a617f7c24be8165230391447301f622aacd050038cee7b41989b4 + name: wakelock_plus + sha256: f268ca2116db22e57577fb99d52515a24bdc1d570f12ac18bb762361d43b043d url: "https://pub.dev" source: hosted - version: "0.6.3+1" - wakelock_platform_interface: + version: "1.1.4" + wakelock_plus_platform_interface: dependency: transitive description: - name: wakelock_platform_interface - sha256: "1f4aeb81fb592b863da83d2d0f7b8196067451e4df91046c26b54a403f9de621" + name: wakelock_plus_platform_interface + sha256: "40fabed5da06caff0796dc638e1f07ee395fb18801fbff3255a2372db2d80385" url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "1.1.0" watcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index e0d092c..a77d32c 100644 --- a/pubspec.yaml +++ b/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: 2.5.1 +version: 2.5.1+4 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 @@ -29,7 +29,7 @@ dependencies: file_picker: ^5.3.0 tencent_super_tooltip: ^0.0.1 video_player: ^2.7.0 - chewie_for_us: ^1.5.0 + chewie: ^1.7.5 flutter_slidable: ^3.0.1 flutter_plugin_record_plus: ^0.0.16 azlistview_all_platforms: ^2.1.2 @@ -62,10 +62,10 @@ dependencies: open_file: ^3.3.2 tencent_keyboard_visibility: ^1.0.1 tim_ui_kit_sticker_plugin: ^3.1.0 - tencent_im_base: ^3.3.775296 + tencent_im_base: ^3.3.775297 fc_native_video_thumbnail: any path: ^1.8.1 - tencent_cloud_uikit_core: ^1.2.1 + tencent_cloud_uikit_core: ^1.6.0 pasteboard: ^0.2.0 desktop_drop: ^0.4.4 device_info_plus: any @@ -82,6 +82,11 @@ dev_dependencies: build_runner: any lints: ^1.0.1 +dependency_overrides: + + # tencent_chat_i18n_tool: + # path: D:\Project\tencent-chat-i18n-tool + # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec