feat: Upgrade to V2.5.1
This commit is contained in:
parent
8d34acf282
commit
da84ca9bc6
|
|
@ -1,3 +1,9 @@
|
||||||
|
# 2.5.1
|
||||||
|
|
||||||
|
## Improvements
|
||||||
|
|
||||||
|
* Improved memory usage, enhancing performance.
|
||||||
|
|
||||||
# 2.5.0
|
# 2.5.0
|
||||||
|
|
||||||
## Breaking Changes
|
## Breaking Changes
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import path_provider_foundation
|
||||||
import photo_manager
|
import photo_manager
|
||||||
import shared_preferences_foundation
|
import shared_preferences_foundation
|
||||||
import sqflite
|
import sqflite
|
||||||
|
import tencent_cloud_chat_sdk
|
||||||
import url_launcher_macos
|
import url_launcher_macos
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
|
@ -34,5 +35,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
PhotoManagerPlugin.register(with: registry.registrar(forPlugin: "PhotoManagerPlugin"))
|
PhotoManagerPlugin.register(with: registry.registrar(forPlugin: "PhotoManagerPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||||
|
TencentCloudChatSdkPlugin.register(with: registry.registrar(forPlugin: "TencentCloudChatSdkPlugin"))
|
||||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -648,14 +648,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.7"
|
version: "0.6.7"
|
||||||
json_annotation:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: json_annotation
|
|
||||||
sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "4.8.1"
|
|
||||||
just_audio:
|
just_audio:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -884,50 +876,50 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider
|
name: path_provider
|
||||||
sha256: "3087813781ab814e4157b172f1a11c46be20179fcc9bea043e0fba36bc0acaa2"
|
sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.15"
|
version: "2.1.2"
|
||||||
path_provider_android:
|
path_provider_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86"
|
sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.27"
|
version: "2.2.2"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_foundation
|
name: path_provider_foundation
|
||||||
sha256: "1995d88ec2948dac43edf8fe58eb434d35d22a2940ecee1a9fefcd62beee6eb3"
|
sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.3"
|
version: "2.3.2"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_linux
|
name: path_provider_linux
|
||||||
sha256: ffbb8cc9ed2c9ec0e4b7a541e56fd79b138e8f47d2fb86815f15358a349b3b57
|
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.11"
|
version: "2.2.1"
|
||||||
path_provider_platform_interface:
|
path_provider_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_platform_interface
|
name: path_provider_platform_interface
|
||||||
sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec"
|
sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.6"
|
version: "2.1.1"
|
||||||
path_provider_windows:
|
path_provider_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_windows
|
name: path_provider_windows
|
||||||
sha256: "1cb68ba4cd3a795033de62ba1b7b4564dace301f952de6bfb3cd91b202b6ee96"
|
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.7"
|
version: "2.2.1"
|
||||||
permission_handler:
|
permission_handler:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -1233,41 +1225,41 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: tencent_chat_i18n_tool
|
name: tencent_chat_i18n_tool
|
||||||
sha256: "0ee982e814bedd0aea4751b972901c6cfcfb224cfeb8e13ae02e43c0b8a58bbc"
|
sha256: d1e68f06a0cf8372eebd9a6b0f01f57e68b569cf909756ee6bdbbe625688debd
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.0"
|
version: "2.3.0"
|
||||||
tencent_cloud_chat_sdk:
|
tencent_cloud_chat_sdk:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: tencent_cloud_chat_sdk
|
name: tencent_cloud_chat_sdk
|
||||||
sha256: "7dbb354209eca61f2c816c8ba7c1b1282dd5fb7e090135186bde56c89d976110"
|
sha256: a78f1f20dc9ebe40aee1bbb47da097780028434d77e97774fbe733debb21e18e
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.2"
|
version: "7.7.5296"
|
||||||
tencent_cloud_chat_uikit:
|
tencent_cloud_chat_uikit:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: ".."
|
path: ".."
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "2.5.0"
|
version: "2.5.1"
|
||||||
tencent_cloud_uikit_core:
|
tencent_cloud_uikit_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: tencent_cloud_uikit_core
|
name: tencent_cloud_uikit_core
|
||||||
sha256: "60779d81e5e2591f2f637fb52388baaf004a8966005d1cbb9aab89efbd1945b9"
|
sha256: "7ddb2c034e5f832261ba268957e282b7c2e738acb1d21aa40c62dad4eaa433ea"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.5.2"
|
||||||
tencent_im_base:
|
tencent_im_base:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: tencent_im_base
|
name: tencent_im_base
|
||||||
sha256: "52a99ef1c9dbd219530cf6f96a9891ab316f789b9b2c11634e0002d0a0f0f63c"
|
sha256: "035d97d24bebb87654700d4afc8227de8721a259ef5d0195f3207cb0eb0cdc7a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.3.775296"
|
||||||
tencent_im_sdk_plugin_desktop:
|
tencent_im_sdk_plugin_desktop:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#include <image_clipboard/image_clipboard_plugin_c_api.h>
|
#include <image_clipboard/image_clipboard_plugin_c_api.h>
|
||||||
#include <pasteboard/pasteboard_plugin.h>
|
#include <pasteboard/pasteboard_plugin.h>
|
||||||
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
||||||
|
#include <tencent_cloud_chat_sdk/tencent_cloud_chat_sdk_plugin_c_api.h>
|
||||||
#include <url_launcher_windows/url_launcher_windows.h>
|
#include <url_launcher_windows/url_launcher_windows.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
|
@ -27,6 +28,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
registry->GetRegistrarForPlugin("PasteboardPlugin"));
|
registry->GetRegistrarForPlugin("PasteboardPlugin"));
|
||||||
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
|
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
|
||||||
|
TencentCloudChatSdkPluginCApiRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("TencentCloudChatSdkPluginCApi"));
|
||||||
UrlLauncherWindowsRegisterWithRegistrar(
|
UrlLauncherWindowsRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
image_clipboard
|
image_clipboard
|
||||||
pasteboard
|
pasteboard
|
||||||
permission_handler_windows
|
permission_handler_windows
|
||||||
|
tencent_cloud_chat_sdk
|
||||||
url_launcher_windows
|
url_launcher_windows
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import 'dart:math';
|
||||||
|
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
||||||
// ignore: unnecessary_import
|
// ignore: unnecessary_import
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter_image_compress/flutter_image_compress.dart';
|
import 'package:flutter_image_compress/flutter_image_compress.dart';
|
||||||
|
|
@ -183,7 +182,6 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
||||||
|
|
||||||
final String groupID = TencentUtils.checkString(_groupID) ?? conversationID;
|
final String groupID = TencentUtils.checkString(_groupID) ?? conversationID;
|
||||||
|
|
||||||
|
|
||||||
if (filteredList.isNotEmpty) {
|
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) {
|
if (res?.code == 0 && res?.data != null) {
|
||||||
|
|
@ -199,11 +197,9 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void initForEachConversation(ConvType convType, String convID, ValueChanged<String>? onChangeInputField,
|
void initForEachConversation(ConvType convType, String convID, ValueChanged<String>? onChangeInputField, {String? groupID, List<V2TimGroupMemberFullInfo?>? preGroupMemberList}) async {
|
||||||
{String? groupID, List<V2TimGroupMemberFullInfo?>? preGroupMemberList}) async {
|
|
||||||
if (_isInit) {
|
if (_isInit) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -217,8 +213,16 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
||||||
groupMemberList = null;
|
groupMemberList = null;
|
||||||
selfMemberInfo = null;
|
selfMemberInfo = null;
|
||||||
|
|
||||||
|
globalModel.setCurrentConversation(CurrentConversation(conversationID, conversationType ?? ConvType.c2c));
|
||||||
|
globalModel.lifeCycle = lifeCycle;
|
||||||
|
globalModel.setMessageListPosition(conversationID, HistoryMessagePosition.bottom);
|
||||||
|
globalModel.setChatConfig(chatConfig);
|
||||||
|
globalModel.clearRecivedNewMessageCount();
|
||||||
|
|
||||||
if (conversationType == ConvType.group) {
|
if (conversationType == ConvType.group) {
|
||||||
_groupID = groupID;
|
_groupID = groupID;
|
||||||
|
notifyListeners();
|
||||||
|
Future.delayed(const Duration(milliseconds: 10), () async {
|
||||||
globalModel.refreshGroupApplicationList();
|
globalModel.refreshGroupApplicationList();
|
||||||
loadGroupInfo(groupID ?? convID);
|
loadGroupInfo(groupID ?? convID);
|
||||||
if (preGroupMemberList != null) {
|
if (preGroupMemberList != null) {
|
||||||
|
|
@ -231,18 +235,14 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
||||||
if (selfMemberInfo == null) {
|
if (selfMemberInfo == null) {
|
||||||
await loadSelfMemberInfo(groupID: groupID ?? convID);
|
await loadSelfMemberInfo(groupID: groupID ?? convID);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
notifyListeners();
|
Future.delayed(const Duration(milliseconds: 10), () async {
|
||||||
}
|
|
||||||
if (conversationType == ConvType.c2c) {
|
|
||||||
final List<V2TimFriendInfoResult>? friendRes = await _friendshipServices.getFriendsInfo(userIDList: [convID]);
|
final List<V2TimFriendInfoResult>? friendRes = await _friendshipServices.getFriendsInfo(userIDList: [convID]);
|
||||||
if (friendRes != null && friendRes.isNotEmpty) {
|
if (friendRes != null && friendRes.isNotEmpty) {
|
||||||
final V2TimFriendInfoResult friendInfoResult = friendRes[0];
|
final V2TimFriendInfoResult friendInfoResult = friendRes[0];
|
||||||
currentChatUserInfo = V2TimGroupMemberFullInfo(
|
currentChatUserInfo =
|
||||||
userID: convID,
|
V2TimGroupMemberFullInfo(userID: convID, faceUrl: friendInfoResult.friendInfo?.userProfile?.faceUrl, nickName: friendInfoResult.friendInfo?.userProfile?.nickName, friendRemark: friendInfoResult.friendInfo?.friendRemark);
|
||||||
faceUrl: friendInfoResult.friendInfo?.userProfile?.faceUrl,
|
|
||||||
nickName: friendInfoResult.friendInfo?.userProfile?.nickName,
|
|
||||||
friendRemark: friendInfoResult.friendInfo?.friendRemark);
|
|
||||||
} else {
|
} else {
|
||||||
final List<V2TimUserFullInfo>? userRes = await _friendshipServices.getUsersInfo(userIDList: [convID]);
|
final List<V2TimUserFullInfo>? userRes = await _friendshipServices.getUsersInfo(userIDList: [convID]);
|
||||||
if (userRes != null && userRes.isNotEmpty) {
|
if (userRes != null && userRes.isNotEmpty) {
|
||||||
|
|
@ -254,12 +254,10 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
notifyListeners();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
globalModel.lifeCycle = lifeCycle;
|
|
||||||
globalModel.setCurrentConversation(CurrentConversation(conversationID, conversationType ?? ConvType.c2c));
|
|
||||||
globalModel.setMessageListPosition(conversationID, HistoryMessagePosition.bottom);
|
|
||||||
globalModel.setChatConfig(chatConfig);
|
|
||||||
globalModel.clearRecivedNewMessageCount();
|
|
||||||
_isInit = true;
|
_isInit = true;
|
||||||
Future.delayed(const Duration(milliseconds: 300), () {
|
Future.delayed(const Duration(milliseconds: 300), () {
|
||||||
markMessageAsRead();
|
markMessageAsRead();
|
||||||
|
|
@ -273,11 +271,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
||||||
haveMoreData = false;
|
haveMoreData = false;
|
||||||
|
|
||||||
final previousResponse = await _messageService.getHistoryMessageListWithComplete(
|
final previousResponse = await _messageService.getHistoryMessageListWithComplete(
|
||||||
count: 20,
|
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));
|
||||||
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 ?? [];
|
msgList = previousResponse?.messageList ?? [];
|
||||||
haveMoreData = !(previousResponse?.isFinished ?? false);
|
haveMoreData = !(previousResponse?.isFinished ?? false);
|
||||||
haveMoreLatestData = true;
|
haveMoreLatestData = true;
|
||||||
|
|
@ -496,8 +490,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
||||||
groupMemberList?.clear();
|
groupMemberList?.clear();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final res = await _groupServices.getGroupMemberList(
|
final res = await _groupServices.getGroupMemberList(groupID: groupID, filter: GroupMemberFilterTypeEnum.V2TIM_GROUP_MEMBER_FILTER_ALL, count: count, nextSeq: seq ?? groupMemberListSeq);
|
||||||
groupID: groupID, filter: GroupMemberFilterTypeEnum.V2TIM_GROUP_MEMBER_FILTER_ALL, count: count, nextSeq: seq ?? groupMemberListSeq);
|
|
||||||
final groupMemberListRes = res.data;
|
final groupMemberListRes = res.data;
|
||||||
if (res.code == 0 && groupMemberListRes != null) {
|
if (res.code == 0 && groupMemberListRes != null) {
|
||||||
final groupMemberListTemp = groupMemberListRes.memberInfoList ?? [];
|
final groupMemberListTemp = groupMemberListRes.memberInfoList ?? [];
|
||||||
|
|
@ -634,11 +627,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _sendMessage(
|
return _sendMessage(convID: convID, id: textATMessageInfo.id as String, convType: ConvType.group, offlinePushInfo: tools.buildMessagePushInfo(textATMessageInfo.messageInfo!, convID, convType));
|
||||||
convID: convID,
|
|
||||||
id: textATMessageInfo.id as String,
|
|
||||||
convType: ConvType.group,
|
|
||||||
offlinePushInfo: tools.buildMessagePushInfo(textATMessageInfo.messageInfo!, convID, convType));
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -663,8 +652,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _sendMessage(
|
return _sendMessage(convID: convID, id: textATMessageInfo.id as String, convType: convType, offlinePushInfo: tools.buildMessagePushInfo(textATMessageInfo.messageInfo!, convID, convType));
|
||||||
convID: convID, id: textATMessageInfo.id as String, convType: convType, offlinePushInfo: tools.buildMessagePushInfo(textATMessageInfo.messageInfo!, convID, convType));
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -690,11 +678,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
return _sendMessage(
|
return _sendMessage(
|
||||||
convID: convID,
|
convID: convID, id: textMessageInfo.id as String, convType: convType, messageInfo: lifeCycleMsg ?? messageInfoWithSender, offlinePushInfo: tools.buildMessagePushInfo(textMessageInfo.messageInfo!, convID, convType));
|
||||||
id: textMessageInfo.id as String,
|
|
||||||
convType: convType,
|
|
||||||
messageInfo: lifeCycleMsg ?? messageInfoWithSender,
|
|
||||||
offlinePushInfo: tools.buildMessagePushInfo(textMessageInfo.messageInfo!, convID, convType));
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -812,8 +796,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<V2TimValueCallback<V2TimMessage>?> sendImageMessage(
|
Future<V2TimValueCallback<V2TimMessage>?> sendImageMessage({String? imagePath, String? imageName, required String convID, dynamic inputElement, required ConvType convType}) async {
|
||||||
{String? imagePath, String? imageName, required String convID, dynamic inputElement, required ConvType convType}) async {
|
|
||||||
String? image;
|
String? image;
|
||||||
if ((PlatformUtils().isAndroid || PlatformUtils().isIOS) && imagePath != null && imagePath.isNotEmpty) {
|
if ((PlatformUtils().isAndroid || PlatformUtils().isIOS) && imagePath != null && imagePath.isNotEmpty) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -858,15 +841,10 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<V2TimValueCallback<V2TimMessage>?> sendVideoMessage(
|
Future<V2TimValueCallback<V2TimMessage>?> sendVideoMessage({String? videoPath, int? duration, String? snapshotPath, required String convID, required ConvType convType, dynamic inputElement}) async {
|
||||||
{String? videoPath, int? duration, String? snapshotPath, required String convID, required ConvType convType, dynamic inputElement}) async {
|
|
||||||
List<V2TimMessage> currentHistoryMsgList = getOriginMessageList();
|
List<V2TimMessage> currentHistoryMsgList = getOriginMessageList();
|
||||||
final videoMessageInfo = await _messageService.createVideoMessage(
|
final videoMessageInfo =
|
||||||
videoPath: videoPath,
|
await _messageService.createVideoMessage(videoPath: videoPath, type: videoPath != null ? videoPath.split(".")[videoPath.split(".").length - 1] : 'mp4', duration: duration, inputElement: inputElement, snapshotPath: snapshotPath);
|
||||||
type: videoPath != null ? videoPath.split(".")[videoPath.split(".").length - 1] : 'mp4',
|
|
||||||
duration: duration,
|
|
||||||
inputElement: inputElement,
|
|
||||||
snapshotPath: snapshotPath);
|
|
||||||
final messageInfo = videoMessageInfo!.messageInfo;
|
final messageInfo = videoMessageInfo!.messageInfo;
|
||||||
if (messageInfo != null) {
|
if (messageInfo != null) {
|
||||||
final messageInfoWithSender = tools.setUserInfoForMessage(messageInfo, videoMessageInfo.id);
|
final messageInfoWithSender = tools.setUserInfoForMessage(messageInfo, videoMessageInfo.id);
|
||||||
|
|
@ -895,8 +873,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<V2TimValueCallback<V2TimMessage>?> sendFileMessage(
|
Future<V2TimValueCallback<V2TimMessage>?> sendFileMessage({String? filePath, String? fileName, int? size, dynamic inputElement, required String convID, required ConvType convType}) async {
|
||||||
{String? filePath, String? fileName, int? size, dynamic inputElement, required String convID, required ConvType convType}) async {
|
|
||||||
if (await tools.hasZeroSize(filePath ?? "")) {
|
if (await tools.hasZeroSize(filePath ?? "")) {
|
||||||
final CoreServicesImpl _coreServices = serviceLocator<CoreServicesImpl>();
|
final CoreServicesImpl _coreServices = serviceLocator<CoreServicesImpl>();
|
||||||
_coreServices.callOnCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: "不支持 0KB 文件的传输", infoCode: 6660417));
|
_coreServices.callOnCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: "不支持 0KB 文件的传输", infoCode: 6660417));
|
||||||
|
|
@ -933,8 +910,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<V2TimValueCallback<V2TimMessage>?> sendLocationMessage(
|
Future<V2TimValueCallback<V2TimMessage>?> sendLocationMessage({required String desc, required double longitude, required double latitude, required String convID, required ConvType convType}) async {
|
||||||
{required String desc, required double longitude, required double latitude, required String convID, required ConvType convType}) async {
|
|
||||||
List<V2TimMessage> currentHistoryMsgList = getOriginMessageList();
|
List<V2TimMessage> 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;
|
final messageInfo = locationMessageInfo!.messageInfo;
|
||||||
|
|
@ -1120,8 +1096,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _sendMessage(
|
return _sendMessage(convID: convID, id: textMessageInfo.id as String, convType: convType, offlinePushInfo: tools.buildMessagePushInfo(textMessageInfo.messageInfo!, convID, convType));
|
||||||
convID: convID, id: textMessageInfo.id as String, convType: convType, offlinePushInfo: tools.buildMessagePushInfo(textMessageInfo.messageInfo!, convID, convType));
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
// ignore_for_file: unnecessary_getters_setters, avoid_print
|
// ignore_for_file: unnecessary_getters_setters, avoid_print
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart';
|
|
||||||
import 'package:tencent_im_base/tencent_im_base.dart';
|
|
||||||
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/group_profile_life_cycle.dart';
|
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/group_profile_life_cycle.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/data_services/conversation/conversation_services.dart';
|
import 'package:tencent_cloud_chat_uikit/data_services/conversation/conversation_services.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart';
|
import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart';
|
||||||
|
|
@ -10,15 +8,15 @@ import 'package:tencent_cloud_chat_uikit/data_services/friendShip/friendship_ser
|
||||||
import 'package:tencent_cloud_chat_uikit/data_services/group/group_services.dart';
|
import 'package:tencent_cloud_chat_uikit/data_services/group/group_services.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart';
|
import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
|
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
|
||||||
|
import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart';
|
||||||
|
import 'package:tencent_im_base/tencent_im_base.dart';
|
||||||
|
|
||||||
class TUIGroupProfileModel extends ChangeNotifier {
|
class TUIGroupProfileModel extends ChangeNotifier {
|
||||||
final CoreServicesImpl _coreServices = serviceLocator<CoreServicesImpl>();
|
final CoreServicesImpl _coreServices = serviceLocator<CoreServicesImpl>();
|
||||||
final GroupServices _groupServices = serviceLocator<GroupServices>();
|
final GroupServices _groupServices = serviceLocator<GroupServices>();
|
||||||
final ConversationService _conversationService =
|
final ConversationService _conversationService = serviceLocator<ConversationService>();
|
||||||
serviceLocator<ConversationService>();
|
|
||||||
final MessageService _messageService = serviceLocator<MessageService>();
|
final MessageService _messageService = serviceLocator<MessageService>();
|
||||||
final FriendshipServices _friendshipServices =
|
final FriendshipServices _friendshipServices = serviceLocator<FriendshipServices>();
|
||||||
serviceLocator<FriendshipServices>();
|
|
||||||
GroupProfileLifeCycle? _lifeCycle;
|
GroupProfileLifeCycle? _lifeCycle;
|
||||||
|
|
||||||
V2TimConversation? _conversation;
|
V2TimConversation? _conversation;
|
||||||
|
|
@ -74,8 +72,7 @@ class TUIGroupProfileModel extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
loadGroupInfo(String groupID) async {
|
loadGroupInfo(String groupID) async {
|
||||||
final groupInfo =
|
final groupInfo = await _groupServices.getGroupsInfo(groupIDList: [groupID]);
|
||||||
await _groupServices.getGroupsInfo(groupIDList: [groupID]);
|
|
||||||
if (groupInfo != null) {
|
if (groupInfo != null) {
|
||||||
final groupRes = groupInfo.first;
|
final groupRes = groupInfo.first;
|
||||||
if (groupRes.resultCode == 0) {
|
if (groupRes.resultCode == 0) {
|
||||||
|
|
@ -85,34 +82,25 @@ class TUIGroupProfileModel extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> loadGroupMemberList(
|
Future<void> loadGroupMemberList({required String groupID, int count = 100, String? seq}) async {
|
||||||
{required String groupID, int count = 100, String? seq}) async {
|
final String? nextSeq = await _loadGroupMemberListFunction(groupID: groupID, seq: seq, count: count);
|
||||||
final String? nextSeq = await _loadGroupMemberListFunction(
|
|
||||||
groupID: groupID, seq: seq, count: count);
|
|
||||||
if (nextSeq != null && nextSeq != "0" && nextSeq != "") {
|
if (nextSeq != null && nextSeq != "0" && nextSeq != "") {
|
||||||
return await loadGroupMemberList(
|
return await loadGroupMemberList(groupID: groupID, count: count, seq: nextSeq);
|
||||||
groupID: groupID, count: count, seq: nextSeq);
|
|
||||||
} else {
|
} else {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> _loadGroupMemberListFunction(
|
Future<String?> _loadGroupMemberListFunction({required String groupID, int count = 100, String? seq}) async {
|
||||||
{required String groupID, int count = 100, String? seq}) async {
|
|
||||||
if (seq == null || seq == "" || seq == "0") {
|
if (seq == null || seq == "" || seq == "0") {
|
||||||
_groupMemberList?.clear();
|
_groupMemberList?.clear();
|
||||||
}
|
}
|
||||||
final res = await _groupServices.getGroupMemberList(
|
final res = await _groupServices.getGroupMemberList(groupID: groupID, filter: GroupMemberFilterTypeEnum.V2TIM_GROUP_MEMBER_FILTER_ALL, count: count, nextSeq: seq ?? _groupMemberListSeq);
|
||||||
groupID: groupID,
|
|
||||||
filter: GroupMemberFilterTypeEnum.V2TIM_GROUP_MEMBER_FILTER_ALL,
|
|
||||||
count: count,
|
|
||||||
nextSeq: seq ?? _groupMemberListSeq);
|
|
||||||
final groupMemberListRes = res.data;
|
final groupMemberListRes = res.data;
|
||||||
if (res.code == 0 && groupMemberListRes != null) {
|
if (res.code == 0 && groupMemberListRes != null) {
|
||||||
final groupMemberListTemp = groupMemberListRes.memberInfoList ?? [];
|
final groupMemberListTemp = groupMemberListRes.memberInfoList ?? [];
|
||||||
// TODO
|
// TODO
|
||||||
outputLogger.i(
|
outputLogger.i("loadGroupMemberListfinish,groupMemberListTemp, ${groupMemberListRes.nextSeq}, ${groupMemberListTemp.length}");
|
||||||
"loadGroupMemberListfinish,groupMemberListTemp, ${groupMemberListRes.nextSeq}, ${groupMemberListTemp.length}");
|
|
||||||
_groupMemberList = [...?_groupMemberList, ...groupMemberListTemp];
|
_groupMemberList = [...?_groupMemberList, ...groupMemberListTemp];
|
||||||
_groupMemberListSeq = groupMemberListRes.nextSeq ?? "0";
|
_groupMemberListSeq = groupMemberListRes.nextSeq ?? "0";
|
||||||
}
|
}
|
||||||
|
|
@ -120,8 +108,7 @@ class TUIGroupProfileModel extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
_loadConversation() async {
|
_loadConversation() async {
|
||||||
conversation = await _conversationService.getConversation(
|
conversation = await _conversationService.getConversation(conversationID: "group_$_groupID");
|
||||||
conversationID: "group_$_groupID");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_loadContactList() async {
|
_loadContactList() async {
|
||||||
|
|
@ -130,31 +117,21 @@ class TUIGroupProfileModel extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
pinedConversation(bool isPined) async {
|
pinedConversation(bool isPined) async {
|
||||||
await _conversationService.pinConversation(
|
await _conversationService.pinConversation(conversationID: "group_$_groupID", isPinned: isPined);
|
||||||
conversationID: "group_$_groupID", isPinned: isPined);
|
|
||||||
conversation?.isPinned = isPined;
|
conversation?.isPinned = isPined;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
setMessageDisturb(bool value) async {
|
setMessageDisturb(bool value) async {
|
||||||
final res = await _messageService.setGroupReceiveMessageOpt(
|
final res = await _messageService.setGroupReceiveMessageOpt(groupID: _groupID, opt: value ? ReceiveMsgOptEnum.V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE : ReceiveMsgOptEnum.V2TIM_RECEIVE_MESSAGE);
|
||||||
groupID: _groupID,
|
|
||||||
opt: value
|
|
||||||
? ReceiveMsgOptEnum.V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE
|
|
||||||
: ReceiveMsgOptEnum.V2TIM_RECEIVE_MESSAGE);
|
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
conversation?.recvOpt = (value
|
conversation?.recvOpt = (value ? ReceiveMsgOptEnum.V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE : ReceiveMsgOptEnum.V2TIM_RECEIVE_MESSAGE).index;
|
||||||
? ReceiveMsgOptEnum.V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE
|
|
||||||
: ReceiveMsgOptEnum.V2TIM_RECEIVE_MESSAGE)
|
|
||||||
.index;
|
|
||||||
}
|
}
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<V2TimValueCallback<V2GroupMemberInfoSearchResult>> searchGroupMember(
|
Future<V2TimValueCallback<V2GroupMemberInfoSearchResult>> searchGroupMember(V2TimGroupMemberSearchParam searchParam) async {
|
||||||
V2TimGroupMemberSearchParam searchParam) async {
|
final res = await _groupServices.searchGroupMembers(searchParam: searchParam);
|
||||||
final res =
|
|
||||||
await _groupServices.searchGroupMembers(searchParam: searchParam);
|
|
||||||
|
|
||||||
if (res.code == 0) {}
|
if (res.code == 0) {}
|
||||||
return res;
|
return res;
|
||||||
|
|
@ -164,12 +141,7 @@ class TUIGroupProfileModel extends ChangeNotifier {
|
||||||
if (_groupInfo != null) {
|
if (_groupInfo != null) {
|
||||||
String? originalGroupName = _groupInfo?.groupName;
|
String? originalGroupName = _groupInfo?.groupName;
|
||||||
_groupInfo?.groupName = groupName;
|
_groupInfo?.groupName = groupName;
|
||||||
final response = await _groupServices.setGroupInfo(
|
final response = await _groupServices.setGroupInfo(info: V2TimGroupInfo.fromJson({"groupID": _groupID, "groupType": _groupInfo!.groupType, "groupName": groupName}));
|
||||||
info: V2TimGroupInfo.fromJson({
|
|
||||||
"groupID": _groupID,
|
|
||||||
"groupType": _groupInfo!.groupType,
|
|
||||||
"groupName": groupName
|
|
||||||
}));
|
|
||||||
if (response.code != 0) {
|
if (response.code != 0) {
|
||||||
_groupInfo?.groupName = originalGroupName;
|
_groupInfo?.groupName = originalGroupName;
|
||||||
}
|
}
|
||||||
|
|
@ -181,12 +153,7 @@ class TUIGroupProfileModel extends ChangeNotifier {
|
||||||
|
|
||||||
setGroupNotification(String notification) async {
|
setGroupNotification(String notification) async {
|
||||||
if (_groupInfo != null) {
|
if (_groupInfo != null) {
|
||||||
final response = await _groupServices.setGroupInfo(
|
final response = await _groupServices.setGroupInfo(info: V2TimGroupInfo.fromJson({"groupID": _groupID, "groupType": _groupInfo!.groupType, "notification": notification}));
|
||||||
info: V2TimGroupInfo.fromJson({
|
|
||||||
"groupID": _groupID,
|
|
||||||
"groupType": _groupInfo!.groupType,
|
|
||||||
"notification": notification
|
|
||||||
}));
|
|
||||||
if (response.code == 0) {
|
if (response.code == 0) {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
_groupInfo?.notification = notification;
|
_groupInfo?.notification = notification;
|
||||||
|
|
@ -199,10 +166,7 @@ class TUIGroupProfileModel extends ChangeNotifier {
|
||||||
final loginUserID = _coreServices.loginUserInfo?.userID;
|
final loginUserID = _coreServices.loginUserInfo?.userID;
|
||||||
String nameCard = "";
|
String nameCard = "";
|
||||||
if (_groupMemberList != null) {
|
if (_groupMemberList != null) {
|
||||||
nameCard = groupMemberList
|
nameCard = groupMemberList.firstWhere((element) => element?.userID == loginUserID)?.nameCard ?? "";
|
||||||
.firstWhere((element) => element?.userID == loginUserID)
|
|
||||||
?.nameCard ??
|
|
||||||
"";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nameCard;
|
return nameCard;
|
||||||
|
|
@ -214,11 +178,9 @@ class TUIGroupProfileModel extends ChangeNotifier {
|
||||||
Future<V2TimCallback?> setNameCard(String nameCard) async {
|
Future<V2TimCallback?> setNameCard(String nameCard) async {
|
||||||
final loginUserID = _coreServices.loginUserInfo?.userID;
|
final loginUserID = _coreServices.loginUserInfo?.userID;
|
||||||
if (loginUserID != null) {
|
if (loginUserID != null) {
|
||||||
final res = await _groupServices.setGroupMemberInfo(
|
final res = await _groupServices.setGroupMemberInfo(groupID: _groupID, userID: loginUserID, nameCard: nameCard);
|
||||||
groupID: _groupID, userID: loginUserID, nameCard: nameCard);
|
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
final targetIndex = _groupMemberList
|
final targetIndex = _groupMemberList?.indexWhere((element) => element?.userID == loginUserID);
|
||||||
?.indexWhere((element) => element?.userID == loginUserID);
|
|
||||||
if (targetIndex != -1) {
|
if (targetIndex != -1) {
|
||||||
_groupMemberList![targetIndex!]!.nameCard = nameCard;
|
_groupMemberList![targetIndex!]!.nameCard = nameCard;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
@ -233,12 +195,7 @@ class TUIGroupProfileModel extends ChangeNotifier {
|
||||||
if (_groupInfo != null) {
|
if (_groupInfo != null) {
|
||||||
int? originalAddopt = _groupInfo?.groupAddOpt;
|
int? originalAddopt = _groupInfo?.groupAddOpt;
|
||||||
_groupInfo?.groupAddOpt = addOpt;
|
_groupInfo?.groupAddOpt = addOpt;
|
||||||
final response = await _groupServices.setGroupInfo(
|
final response = await _groupServices.setGroupInfo(info: V2TimGroupInfo.fromJson({"groupID": _groupID, "groupType": _groupInfo!.groupType, "groupAddOpt": addOpt}));
|
||||||
info: V2TimGroupInfo.fromJson({
|
|
||||||
"groupID": _groupID,
|
|
||||||
"groupType": _groupInfo!.groupType,
|
|
||||||
"groupAddOpt": addOpt
|
|
||||||
}));
|
|
||||||
if (response.code != 0) {
|
if (response.code != 0) {
|
||||||
_groupInfo?.groupAddOpt = originalAddopt;
|
_groupInfo?.groupAddOpt = originalAddopt;
|
||||||
}
|
}
|
||||||
|
|
@ -249,13 +206,9 @@ class TUIGroupProfileModel extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<V2TimCallback> setMemberToNormal(String userID) async {
|
Future<V2TimCallback> setMemberToNormal(String userID) async {
|
||||||
final res = await _groupServices.setGroupMemberRole(
|
final res = await _groupServices.setGroupMemberRole(groupID: _groupID, userID: userID, role: GroupMemberRoleTypeEnum.V2TIM_GROUP_MEMBER_ROLE_MEMBER);
|
||||||
groupID: _groupID,
|
|
||||||
userID: userID,
|
|
||||||
role: GroupMemberRoleTypeEnum.V2TIM_GROUP_MEMBER_ROLE_MEMBER);
|
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
final targetIndex =
|
final targetIndex = _groupMemberList!.indexWhere((e) => e!.userID == userID);
|
||||||
_groupMemberList!.indexWhere((e) => e!.userID == userID);
|
|
||||||
if (targetIndex != -1) {
|
if (targetIndex != -1) {
|
||||||
final targetElem = _groupMemberList![targetIndex];
|
final targetElem = _groupMemberList![targetIndex];
|
||||||
targetElem?.role = GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_MEMBER;
|
targetElem?.role = GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_MEMBER;
|
||||||
|
|
@ -267,13 +220,9 @@ class TUIGroupProfileModel extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<V2TimCallback> setMemberToAdmin(String userID) async {
|
Future<V2TimCallback> setMemberToAdmin(String userID) async {
|
||||||
final res = await _groupServices.setGroupMemberRole(
|
final res = await _groupServices.setGroupMemberRole(groupID: _groupID, userID: userID, role: GroupMemberRoleTypeEnum.V2TIM_GROUP_MEMBER_ROLE_ADMIN);
|
||||||
groupID: _groupID,
|
|
||||||
userID: userID,
|
|
||||||
role: GroupMemberRoleTypeEnum.V2TIM_GROUP_MEMBER_ROLE_ADMIN);
|
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
final targetIndex =
|
final targetIndex = _groupMemberList!.indexWhere((e) => e!.userID == userID);
|
||||||
_groupMemberList!.indexWhere((e) => e!.userID == userID);
|
|
||||||
if (targetIndex != -1) {
|
if (targetIndex != -1) {
|
||||||
final targetElem = _groupMemberList![targetIndex];
|
final targetElem = _groupMemberList![targetIndex];
|
||||||
targetElem?.role = GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN;
|
targetElem?.role = GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN;
|
||||||
|
|
@ -286,21 +235,18 @@ class TUIGroupProfileModel extends ChangeNotifier {
|
||||||
|
|
||||||
bool canInviteMember() {
|
bool canInviteMember() {
|
||||||
final groupType = _groupInfo?.groupType;
|
final groupType = _groupInfo?.groupType;
|
||||||
return groupType == GroupType.Work;
|
return groupType == GroupType.Work || groupType == "Private";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool canKickOffMember() {
|
bool canKickOffMember() {
|
||||||
final isGroupOwner =
|
final isGroupOwner = _groupInfo?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER;
|
||||||
_groupInfo?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER;
|
final isAdmin = _groupInfo?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN;
|
||||||
final isAdmin =
|
|
||||||
_groupInfo?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN;
|
|
||||||
if (_groupInfo?.groupType == GroupType.Work) {
|
if (_groupInfo?.groupType == GroupType.Work) {
|
||||||
/// work 群主才能踢人
|
/// work 群主才能踢人
|
||||||
return isGroupOwner;
|
return isGroupOwner;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_groupInfo?.groupType == GroupType.Public ||
|
if (_groupInfo?.groupType == GroupType.Public || _groupInfo?.groupType == GroupType.Meeting) {
|
||||||
_groupInfo?.groupType == GroupType.Meeting) {
|
|
||||||
/// public || meeting 群主和管理员可以踢人
|
/// public || meeting 群主和管理员可以踢人
|
||||||
return isGroupOwner || isAdmin;
|
return isGroupOwner || isAdmin;
|
||||||
}
|
}
|
||||||
|
|
@ -311,12 +257,7 @@ class TUIGroupProfileModel extends ChangeNotifier {
|
||||||
Future<V2TimCallback?> setMuteAll(bool muteAll) async {
|
Future<V2TimCallback?> setMuteAll(bool muteAll) async {
|
||||||
if (_groupInfo != null) {
|
if (_groupInfo != null) {
|
||||||
_groupInfo?.isAllMuted = muteAll;
|
_groupInfo?.isAllMuted = muteAll;
|
||||||
final response = await _groupServices.setGroupInfo(
|
final response = await _groupServices.setGroupInfo(info: V2TimGroupInfo.fromJson({"groupID": _groupInfo!.groupID, "groupType": _groupInfo!.groupType, "isAllMuted": muteAll}));
|
||||||
info: V2TimGroupInfo.fromJson({
|
|
||||||
"groupID": _groupInfo!.groupID,
|
|
||||||
"groupType": _groupInfo!.groupType,
|
|
||||||
"isAllMuted": muteAll
|
|
||||||
}));
|
|
||||||
if (response.code != 0) {
|
if (response.code != 0) {
|
||||||
_groupInfo?.isAllMuted = muteAll;
|
_groupInfo?.isAllMuted = muteAll;
|
||||||
}
|
}
|
||||||
|
|
@ -326,14 +267,11 @@ class TUIGroupProfileModel extends ChangeNotifier {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<V2TimCallback?> muteGroupMember(
|
Future<V2TimCallback?> muteGroupMember(String userID, bool isMute, int? serverTime) async {
|
||||||
String userID, bool isMute, int? serverTime) async {
|
|
||||||
const muteTime = 315360000;
|
const muteTime = 315360000;
|
||||||
final res = await _groupServices.muteGroupMember(
|
final res = await _groupServices.muteGroupMember(groupID: _groupID, userID: userID, seconds: isMute ? muteTime : 0);
|
||||||
groupID: _groupID, userID: userID, seconds: isMute ? muteTime : 0);
|
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
final targetIndex =
|
final targetIndex = _groupMemberList!.indexWhere((e) => e!.userID == userID);
|
||||||
_groupMemberList!.indexWhere((e) => e!.userID == userID);
|
|
||||||
if (targetIndex != -1) {
|
if (targetIndex != -1) {
|
||||||
final targetElem = _groupMemberList![targetIndex];
|
final targetElem = _groupMemberList![targetIndex];
|
||||||
targetElem?.muteUntil = isMute ? (serverTime ?? 0) + muteTime : 0;
|
targetElem?.muteUntil = isMute ? (serverTime ?? 0) + muteTime : 0;
|
||||||
|
|
@ -345,15 +283,12 @@ class TUIGroupProfileModel extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<V2TimCallback> kickOffMember(List<String> userIDs) async {
|
Future<V2TimCallback> kickOffMember(List<String> userIDs) async {
|
||||||
final res = await _groupServices.kickGroupMember(
|
final res = await _groupServices.kickGroupMember(groupID: _groupID, memberList: userIDs);
|
||||||
groupID: _groupID, memberList: userIDs);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<V2TimValueCallback<List<V2TimGroupMemberOperationResult>>>
|
Future<V2TimValueCallback<List<V2TimGroupMemberOperationResult>>> inviteUserToGroup(List<String> userIDS) async {
|
||||||
inviteUserToGroup(List<String> userIDS) async {
|
final res = await _groupServices.inviteUserToGroup(groupID: _groupID, userList: userIDS);
|
||||||
final res = await _groupServices.inviteUserToGroup(
|
|
||||||
groupID: _groupID, userList: userIDS);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -198,7 +198,7 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass {
|
||||||
|
|
||||||
clearCurrentConversation() {
|
clearCurrentConversation() {
|
||||||
// Only keep the last 20 messages when existing a chat.
|
// Only keep the last 20 messages when existing a chat.
|
||||||
_messageListMap[currentSelectedConv] = (_messageListMap[currentSelectedConv] ?? []).sublist(max(0, ((_messageListMap[currentSelectedConv] ?? []).length - 20)));
|
_messageListMap[currentSelectedConv] = (_messageListMap[currentSelectedConv] ?? []).sublist(max(0, ((_messageListMap[currentSelectedConv] ?? []).length - 10)));
|
||||||
if (_currentConversationList.isNotEmpty) {
|
if (_currentConversationList.isNotEmpty) {
|
||||||
_currentConversationList.removeLast();
|
_currentConversationList.removeLast();
|
||||||
}
|
}
|
||||||
|
|
@ -271,7 +271,7 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass {
|
||||||
if (conversationItem == null || conversationItem.type == null) {
|
if (conversationItem == null || conversationItem.type == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final conversationID = conversationItem.userID ?? conversationItem.groupID ?? conversationItem.conversationID;
|
final conversationID = TencentUtils.checkString(conversationItem.userID) ?? TencentUtils.checkString(conversationItem.groupID) ?? conversationItem.conversationID;
|
||||||
if (messageListMap[conversationID] == null || messageListMap[conversationID]!.isEmpty) {
|
if (messageListMap[conversationID] == null || messageListMap[conversationID]!.isEmpty) {
|
||||||
index++;
|
index++;
|
||||||
Future.delayed(Duration(milliseconds: 500 * index), () {
|
Future.delayed(Duration(milliseconds: 500 * index), () {
|
||||||
|
|
@ -535,7 +535,8 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_receivedNewMessageCount = 0;
|
_receivedNewMessageCount = 0;
|
||||||
final currentMsg = _messageListMap[convID] ?? [];
|
final tempCurrentMsgList = _messageListMap[convID] ?? [];
|
||||||
|
final currentMsg = tempCurrentMsgList..sublist(max(0, (tempCurrentMsgList.length - 30)));
|
||||||
_messageListMap[convID] = [newMsg, ...currentMsg];
|
_messageListMap[convID] = [newMsg, ...currentMsg];
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
final messageID = newMsg.msgID;
|
final messageID = newMsg.msgID;
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,17 @@
|
||||||
// ignore_for_file: unnecessary_getters_setters
|
// ignore_for_file: unnecessary_getters_setters
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart';
|
|
||||||
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
|
|
||||||
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/conversation_life_cycle.dart';
|
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/conversation_life_cycle.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
|
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
|
||||||
|
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/data_services/conversation/conversation_services.dart';
|
import 'package:tencent_cloud_chat_uikit/data_services/conversation/conversation_services.dart';
|
||||||
|
import 'package:tencent_cloud_chat_uikit/data_services/friendShip/friendship_services.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart';
|
import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
|
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/data_services/friendShip/friendship_services.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/utils/platform.dart';
|
||||||
|
|
||||||
List<T> removeDuplicates<T>(
|
List<T> removeDuplicates<T>(List<T> list, bool Function(T first, T second) isEqual) {
|
||||||
List<T> list, bool Function(T first, T second) isEqual) {
|
|
||||||
List<T> output = [];
|
List<T> output = [];
|
||||||
for (var i = 0; i < list.length; i++) {
|
for (var i = 0; i < list.length; i++) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
@ -30,14 +29,10 @@ List<T> removeDuplicates<T>(
|
||||||
}
|
}
|
||||||
|
|
||||||
class TUIConversationViewModel extends ChangeNotifier {
|
class TUIConversationViewModel extends ChangeNotifier {
|
||||||
final TUISelfInfoViewModel selfInfoViewModel =
|
final TUISelfInfoViewModel selfInfoViewModel = serviceLocator<TUISelfInfoViewModel>();
|
||||||
serviceLocator<TUISelfInfoViewModel>();
|
final ConversationService _conversationService = serviceLocator<ConversationService>();
|
||||||
final ConversationService _conversationService =
|
final FriendshipServices _friendshipServices = serviceLocator<FriendshipServices>();
|
||||||
serviceLocator<ConversationService>();
|
final TUIChatGlobalModel _chatGlobalModel = serviceLocator<TUIChatGlobalModel>();
|
||||||
final FriendshipServices _friendshipServices =
|
|
||||||
serviceLocator<FriendshipServices>();
|
|
||||||
final TUIChatGlobalModel _chatGlobalModel =
|
|
||||||
serviceLocator<TUIChatGlobalModel>();
|
|
||||||
final MessageService _messageService = serviceLocator<MessageService>();
|
final MessageService _messageService = serviceLocator<MessageService>();
|
||||||
late V2TimConversationListener _conversationListener;
|
late V2TimConversationListener _conversationListener;
|
||||||
List<V2TimConversation?> _conversationList = [];
|
List<V2TimConversation?> _conversationList = [];
|
||||||
|
|
@ -47,8 +42,7 @@ class TUIConversationViewModel extends ChangeNotifier {
|
||||||
bool _haveMoreData = true;
|
bool _haveMoreData = true;
|
||||||
int _totalUnReadCount = 0;
|
int _totalUnReadCount = 0;
|
||||||
String? _scrollToConversation;
|
String? _scrollToConversation;
|
||||||
final TUIChatGlobalModel globalChatModel =
|
final TUIChatGlobalModel globalChatModel = serviceLocator<TUIChatGlobalModel>();
|
||||||
serviceLocator<TUIChatGlobalModel>();
|
|
||||||
|
|
||||||
String _nextSeq = "0";
|
String _nextSeq = "0";
|
||||||
ConversationLifeCycle? _lifeCycle;
|
ConversationLifeCycle? _lifeCycle;
|
||||||
|
|
@ -57,13 +51,10 @@ class TUIConversationViewModel extends ChangeNotifier {
|
||||||
if (PlatformUtils().isWeb) {
|
if (PlatformUtils().isWeb) {
|
||||||
try {
|
try {
|
||||||
_conversationList.sort((a, b) {
|
_conversationList.sort((a, b) {
|
||||||
return b!.lastMessage!.timestamp!
|
return b!.lastMessage!.timestamp!.compareTo(a!.lastMessage!.timestamp!);
|
||||||
.compareTo(a!.lastMessage!.timestamp!);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final pinnedConversation = _conversationList
|
final pinnedConversation = _conversationList.where((element) => element?.isPinned == true).toList();
|
||||||
.where((element) => element?.isPinned == true)
|
|
||||||
.toList();
|
|
||||||
_conversationList.removeWhere((element) => element?.isPinned == true);
|
_conversationList.removeWhere((element) => element?.isPinned == true);
|
||||||
_conversationList = [...pinnedConversation, ..._conversationList];
|
_conversationList = [...pinnedConversation, ..._conversationList];
|
||||||
// ignore: empty_catches
|
// ignore: empty_catches
|
||||||
|
|
@ -118,8 +109,7 @@ class TUIConversationViewModel extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
TUIConversationViewModel() {
|
TUIConversationViewModel() {
|
||||||
_conversationListener =
|
_conversationListener = V2TimConversationListener(onConversationChanged: (conversationList) {
|
||||||
V2TimConversationListener(onConversationChanged: (conversationList) {
|
|
||||||
_onConversationListChanged(conversationList);
|
_onConversationListChanged(conversationList);
|
||||||
}, onNewConversation: (conversationList) {
|
}, onNewConversation: (conversationList) {
|
||||||
_addNewConversation(conversationList);
|
_addNewConversation(conversationList);
|
||||||
|
|
@ -128,17 +118,19 @@ class TUIConversationViewModel extends ChangeNotifier {
|
||||||
_chatGlobalModel.totalUnReadCount = totalUnread;
|
_chatGlobalModel.totalUnReadCount = totalUnread;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}, onSyncServerFinish: () {
|
}, onSyncServerFinish: () {
|
||||||
if (!PlatformUtils().isWeb) {
|
// Remove the process to load such a many of conversations after launching
|
||||||
loadInitConversation();
|
// if (!PlatformUtils().isWeb) {
|
||||||
}
|
// loadInitConversation();
|
||||||
|
// }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadInitConversation() async {
|
loadInitConversation() async {
|
||||||
await loadData(count: 40);
|
await loadData(count: 40);
|
||||||
if (selfInfoViewModel.globalConfig?.isPreloadMessagesAfterInit ?? true) {
|
// Remove the process to load such a many of conversations after launching
|
||||||
_chatGlobalModel.initMessageMapFromLocalDatabase(_conversationList);
|
// if (selfInfoViewModel.globalConfig?.isPreloadMessagesAfterInit ?? true) {
|
||||||
}
|
// _chatGlobalModel.initMessageMapFromLocalDatabase(_conversationList);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
initConversation() async {
|
initConversation() async {
|
||||||
|
|
@ -149,8 +141,7 @@ class TUIConversationViewModel extends ChangeNotifier {
|
||||||
Future<void> loadData({required int count}) async {
|
Future<void> loadData({required int count}) async {
|
||||||
_haveMoreData = true;
|
_haveMoreData = true;
|
||||||
final isRefresh = _nextSeq == "0";
|
final isRefresh = _nextSeq == "0";
|
||||||
final conversationResult = await _conversationService.getConversationList(
|
final conversationResult = await _conversationService.getConversationList(nextSeq: _nextSeq, count: count);
|
||||||
nextSeq: _nextSeq, count: count);
|
|
||||||
_nextSeq = conversationResult?.nextSeq ?? "";
|
_nextSeq = conversationResult?.nextSeq ?? "";
|
||||||
final conversationList = conversationResult?.conversationList;
|
final conversationList = conversationResult?.conversationList;
|
||||||
if (conversationList != null) {
|
if (conversationList != null) {
|
||||||
|
|
@ -163,12 +154,8 @@ class TUIConversationViewModel extends ChangeNotifier {
|
||||||
} else {
|
} else {
|
||||||
combinedConversationList = [..._conversationList, ...conversationList];
|
combinedConversationList = [..._conversationList, ...conversationList];
|
||||||
}
|
}
|
||||||
final List<V2TimConversation?> finalConversationList = await _lifeCycle
|
final List<V2TimConversation?> finalConversationList = await _lifeCycle?.conversationListWillMount(combinedConversationList) ?? combinedConversationList;
|
||||||
?.conversationListWillMount(combinedConversationList) ??
|
_conversationList = removeDuplicates<V2TimConversation?>(finalConversationList, (item1, item2) => item1?.conversationID == item2?.conversationID);
|
||||||
combinedConversationList;
|
|
||||||
_conversationList = removeDuplicates<V2TimConversation?>(
|
|
||||||
finalConversationList,
|
|
||||||
(item1, item2) => item1?.conversationID == item2?.conversationID);
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
_totalUnReadCount = await _conversationService.getTotalUnreadCount();
|
_totalUnReadCount = await _conversationService.getTotalUnreadCount();
|
||||||
|
|
@ -185,15 +172,11 @@ class TUIConversationViewModel extends ChangeNotifier {
|
||||||
required String conversationID,
|
required String conversationID,
|
||||||
required bool isPinned,
|
required bool isPinned,
|
||||||
}) {
|
}) {
|
||||||
return _conversationService.pinConversation(
|
return _conversationService.pinConversation(conversationID: conversationID, isPinned: isPinned);
|
||||||
conversationID: conversationID, isPinned: isPinned);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<V2TimCallback?> clearHistoryMessage(
|
Future<V2TimCallback?> clearHistoryMessage({required String convID, required int convType}) async {
|
||||||
{required String convID, required int convType}) async {
|
if (_lifeCycle?.shouldClearHistoricalMessageForConversation != null && await _lifeCycle!.shouldClearHistoricalMessageForConversation(convID) == false) {
|
||||||
if (_lifeCycle?.shouldClearHistoricalMessageForConversation != null &&
|
|
||||||
await _lifeCycle!.shouldClearHistoricalMessageForConversation(convID) ==
|
|
||||||
false) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -207,22 +190,17 @@ class TUIConversationViewModel extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
searchFriends(String searchKey) async {
|
searchFriends(String searchKey) async {
|
||||||
final res = await _friendshipServices.searchFriends(
|
final res = await _friendshipServices.searchFriends(searchParam: V2TimFriendSearchParam(keywordList: [searchKey]));
|
||||||
searchParam: V2TimFriendSearchParam(keywordList: [searchKey]));
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<V2TimCallback?> deleteConversation(
|
Future<V2TimCallback?> deleteConversation({required String conversationID}) async {
|
||||||
{required String conversationID}) async {
|
if (_lifeCycle?.shouldDeleteConversation != null && await _lifeCycle!.shouldDeleteConversation(conversationID) == false) {
|
||||||
if (_lifeCycle?.shouldDeleteConversation != null &&
|
|
||||||
await _lifeCycle!.shouldDeleteConversation(conversationID) == false) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final res = await _conversationService.deleteConversation(
|
final res = await _conversationService.deleteConversation(conversationID: conversationID);
|
||||||
conversationID: conversationID);
|
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
_conversationList
|
_conversationList.removeWhere((element) => element?.conversationID == conversationID);
|
||||||
.removeWhere((element) => element?.conversationID == conversationID);
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
|
@ -230,8 +208,7 @@ class TUIConversationViewModel extends ChangeNotifier {
|
||||||
|
|
||||||
_onConversationListChanged(List<V2TimConversation> list) {
|
_onConversationListChanged(List<V2TimConversation> list) {
|
||||||
for (int element = 0; element < list.length; element++) {
|
for (int element = 0; element < list.length; element++) {
|
||||||
int index = _conversationList.indexWhere(
|
int index = _conversationList.indexWhere((item) => item!.conversationID == list[element].conversationID);
|
||||||
(item) => item!.conversationID == list[element].conversationID);
|
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
_conversationList.setAll(index, [list[element]]);
|
_conversationList.setAll(index, [list[element]]);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -244,19 +221,16 @@ class TUIConversationViewModel extends ChangeNotifier {
|
||||||
|
|
||||||
_addNewConversation(List<V2TimConversation> list) {
|
_addNewConversation(List<V2TimConversation> list) {
|
||||||
_conversationList.addAll(list);
|
_conversationList.addAll(list);
|
||||||
_conversationList = removeDuplicates<V2TimConversation?>(_conversationList,
|
_conversationList = removeDuplicates<V2TimConversation?>(_conversationList, (item1, item2) => item1?.conversationID == item2?.conversationID);
|
||||||
(item1, item2) => item1?.conversationID == item2?.conversationID);
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
setConversationListener() {
|
setConversationListener() {
|
||||||
_conversationService.addConversationListener(
|
_conversationService.addConversationListener(listener: _conversationListener);
|
||||||
listener: _conversationListener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
removeConversationListener() {
|
removeConversationListener() {
|
||||||
_conversationService.removeConversationListener(
|
_conversationService.removeConversationListener(listener: _conversationListener);
|
||||||
listener: _conversationListener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<V2TimCallback> setConversationDraft({
|
Future<V2TimCallback> setConversationDraft({
|
||||||
|
|
@ -266,25 +240,19 @@ class TUIConversationViewModel extends ChangeNotifier {
|
||||||
String? groupID,
|
String? groupID,
|
||||||
bool isAllowWeb = true,
|
bool isAllowWeb = true,
|
||||||
}) async {
|
}) async {
|
||||||
assert(!isTopic || (groupID != null && groupID.isNotEmpty),
|
assert(!isTopic || (groupID != null && groupID.isNotEmpty), "When 'isTopic' is true, 'groupID' must not be null or empty.");
|
||||||
"When 'isTopic' is true, 'groupID' must not be null or empty.");
|
|
||||||
if (PlatformUtils().isWeb && isAllowWeb) {
|
if (PlatformUtils().isWeb && isAllowWeb) {
|
||||||
webDraftMap[conversationID] = draftText ?? "";
|
webDraftMap[conversationID] = draftText ?? "";
|
||||||
return V2TimCallback(code: 0, desc: "");
|
return V2TimCallback(code: 0, desc: "");
|
||||||
} else {
|
} else {
|
||||||
if (isTopic) {
|
if (isTopic) {
|
||||||
final topicInfoList = await TencentImSDKPlugin.v2TIMManager
|
final topicInfoList = await TencentImSDKPlugin.v2TIMManager.getGroupManager().getTopicInfoList(groupID: groupID!, topicIDList: [conversationID]);
|
||||||
.getGroupManager()
|
|
||||||
.getTopicInfoList(groupID: groupID!, topicIDList: [conversationID]);
|
|
||||||
final topicInfo = topicInfoList.data?.first.topicInfo;
|
final topicInfo = topicInfoList.data?.first.topicInfo;
|
||||||
topicInfo?.draftText = draftText;
|
topicInfo?.draftText = draftText;
|
||||||
final res = await TencentImSDKPlugin.v2TIMManager
|
final res = await TencentImSDKPlugin.v2TIMManager.getGroupManager().setTopicInfo(groupID: groupID, topicInfo: topicInfo!);
|
||||||
.getGroupManager()
|
|
||||||
.setTopicInfo(groupID: groupID, topicInfo: topicInfo!);
|
|
||||||
return res;
|
return res;
|
||||||
} else {
|
} else {
|
||||||
return _conversationService.setConversationDraft(
|
return _conversationService.setConversationDraft(conversationID: conversationID, draftText: draftText);
|
||||||
conversationID: conversationID, draftText: draftText);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import 'package:tencent_im_base/tencent_im_base.dart';
|
||||||
|
|
||||||
class MessageServiceImpl extends MessageService {
|
class MessageServiceImpl extends MessageService {
|
||||||
final CoreServicesImpl _coreService = serviceLocator<CoreServicesImpl>();
|
final CoreServicesImpl _coreService = serviceLocator<CoreServicesImpl>();
|
||||||
final Map<String, List<V2TimMessage>> messgaeListMap = {};
|
final Map<String, List<V2TimMessage>> messageListMap = {};
|
||||||
final Map<String, List<V2TimMessage>> sendingMessage = {};
|
final Map<String, List<V2TimMessage>> sendingMessage = {};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -27,28 +27,28 @@ class MessageServiceImpl extends MessageService {
|
||||||
bool haveMoreData = true;
|
bool haveMoreData = true;
|
||||||
final res =
|
final res =
|
||||||
await TencentImSDKPlugin.v2TIMManager.getMessageManager().getHistoryMessageList(count: count, getType: getType, userID: userID, groupID: groupID, lastMsgID: lastMsgID, lastMsgSeq: lastMsgSeq, messageTypeList: messageTypeList);
|
await TencentImSDKPlugin.v2TIMManager.getMessageManager().getHistoryMessageList(count: count, getType: getType, userID: userID, groupID: groupID, lastMsgID: lastMsgID, lastMsgSeq: lastMsgSeq, messageTypeList: messageTypeList);
|
||||||
final List<V2TimMessage> responsedMessageList = res.data ?? [];
|
final List<V2TimMessage> responseMessageList = res.data ?? [];
|
||||||
final conversationID = userID ?? groupID;
|
final conversationID = userID ?? groupID;
|
||||||
final cachedMessageList = messgaeListMap[conversationID];
|
final cachedMessageList = messageListMap[conversationID];
|
||||||
List<V2TimMessage> combinedMessageList = [];
|
List<V2TimMessage> combinedMessageList = [];
|
||||||
// 加载更多
|
// 加载更多
|
||||||
if (lastMsgID != null && cachedMessageList != null) {
|
if (lastMsgID != null && cachedMessageList != null) {
|
||||||
combinedMessageList = [...cachedMessageList, ...responsedMessageList];
|
combinedMessageList = [...cachedMessageList, ...responseMessageList];
|
||||||
// 首次加载
|
// 首次加载
|
||||||
} else {
|
} else {
|
||||||
final bool existSendingMessage = sendingMessage[conversationID] != null && sendingMessage[conversationID]!.isNotEmpty;
|
final bool existSendingMessage = sendingMessage[conversationID] != null && sendingMessage[conversationID]!.isNotEmpty;
|
||||||
// 存在未发送完成的消息
|
// 存在未发送完成的消息
|
||||||
if (existSendingMessage) {
|
if (existSendingMessage) {
|
||||||
combinedMessageList = [...sendingMessage[conversationID]!, ...responsedMessageList];
|
combinedMessageList = [...sendingMessage[conversationID]!, ...responseMessageList];
|
||||||
} else {
|
} else {
|
||||||
sendingMessage.remove(conversationID);
|
sendingMessage.remove(conversationID);
|
||||||
combinedMessageList = responsedMessageList;
|
combinedMessageList = responseMessageList;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (res.code != 0) {
|
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 (responsedMessageList.isEmpty || (!PlatformUtils().isWeb && responsedMessageList.length < count) || (PlatformUtils().isWeb && responsedMessageList.length < min(count, 20))) {
|
if (responseMessageList.isEmpty || (!PlatformUtils().isWeb && responseMessageList.length < count) || (PlatformUtils().isWeb && responseMessageList.length < min(count, 20))) {
|
||||||
haveMoreData = false;
|
haveMoreData = false;
|
||||||
} else {
|
} else {
|
||||||
haveMoreData = true;
|
haveMoreData = true;
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -334,7 +334,7 @@ class _TIMUIKitHistoryMessageListState extends TIMUIKitState<TIMUIKitHistoryMess
|
||||||
}
|
}
|
||||||
|
|
||||||
String getMessageIdentifier(V2TimMessage? message, int index) {
|
String getMessageIdentifier(V2TimMessage? message, int index) {
|
||||||
return "${message?.msgID} - ${message?.timestamp} - ${message?.seq} -${message?.id}";
|
return "${message?.msgID} - ${message?.timestamp} - ${message?.seq} -${message?.id ?? ""}";
|
||||||
}
|
}
|
||||||
|
|
||||||
return Stack(
|
return Stack(
|
||||||
|
|
|
||||||
|
|
@ -6,23 +6,20 @@ import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:loading_animation_widget/loading_animation_widget.dart';
|
import 'package:loading_animation_widget/loading_animation_widget.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart';
|
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_translate_elem.dart';
|
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/forward_message_screen.dart';
|
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart';
|
|
||||||
import 'package:tencent_super_tooltip/tencent_super_tooltip.dart';
|
|
||||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
|
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.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/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/business_logic/view_models/tui_chat_global_model.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart';
|
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/message/message_services.dart';
|
import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.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/tencent_cloud_chat_uikit.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/constants/history_message_constant.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/constants/history_message_constant.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.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/utils/time_ago.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/utils/time_ago.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_message_tooltip.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_message_tooltip.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_message_read_receipt.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_message_read_receipt.dart';
|
||||||
|
|
@ -30,10 +27,13 @@ import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageIt
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/main.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/main.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_custom_elem.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_custom_elem.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_face_elem.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_face_elem.dart';
|
||||||
|
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_translate_elem.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/tim_uikit_cloud_custom_data.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/tim_uikit_cloud_custom_data.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart';
|
||||||
|
import 'package:tencent_cloud_chat_uikit/ui/widgets/forward_message_screen.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/radio_button.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/widgets/radio_button.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart';
|
||||||
|
import 'package:tencent_super_tooltip/tencent_super_tooltip.dart';
|
||||||
|
|
||||||
import '../TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_select_emoji.dart';
|
import '../TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_select_emoji.dart';
|
||||||
|
|
||||||
|
|
@ -57,8 +57,7 @@ typedef MessageRowBuilder = Widget? Function(
|
||||||
Function onScrollToIndexBegin,
|
Function onScrollToIndexBegin,
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef MessageNickNameBuilder = Widget Function(
|
typedef MessageNickNameBuilder = Widget Function(BuildContext context, V2TimMessage message, TUIChatSeparateViewModel model);
|
||||||
BuildContext context, V2TimMessage message, TUIChatSeparateViewModel model);
|
|
||||||
|
|
||||||
typedef MessageItemContent = Widget? Function(
|
typedef MessageItemContent = Widget? Function(
|
||||||
V2TimMessage message,
|
V2TimMessage message,
|
||||||
|
|
@ -71,8 +70,7 @@ class MessageHoverControlItem {
|
||||||
Widget icon;
|
Widget icon;
|
||||||
ValueChanged<TapDownDetails> onClick;
|
ValueChanged<TapDownDetails> onClick;
|
||||||
|
|
||||||
MessageHoverControlItem(
|
MessageHoverControlItem({required this.name, required this.icon, required this.onClick});
|
||||||
{required this.name, required this.icon, required this.onClick});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MessageItemBuilder {
|
class MessageItemBuilder {
|
||||||
|
|
@ -140,11 +138,7 @@ class MessageToolTipItem {
|
||||||
final String iconImageAsset;
|
final String iconImageAsset;
|
||||||
final VoidCallback onClick;
|
final VoidCallback onClick;
|
||||||
|
|
||||||
MessageToolTipItem(
|
MessageToolTipItem({required this.label, required this.id, required this.iconImageAsset, required this.onClick});
|
||||||
{required this.label,
|
|
||||||
required this.id,
|
|
||||||
required this.iconImageAsset,
|
|
||||||
required this.onClick});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ToolTipsConfig {
|
class ToolTipsConfig {
|
||||||
|
|
@ -170,12 +164,10 @@ class ToolTipsConfig {
|
||||||
final bool showTranslation;
|
final bool showTranslation;
|
||||||
|
|
||||||
/// A builder for additional custom items. We recommend using `additionalMessageToolTips` instead of this field since version 2.0, as you only need to provide the data rather than the whole widget. This makes usage easier and you don't need to worry about the UI display.
|
/// A builder for additional custom items. We recommend using `additionalMessageToolTips` instead of this field since version 2.0, as you only need to provide the data rather than the whole widget. This makes usage easier and you don't need to worry about the UI display.
|
||||||
final Widget? Function(V2TimMessage message, Function() closeTooltip,
|
final Widget? Function(V2TimMessage message, Function() closeTooltip, [Key? key, BuildContext? context])? additionalItemBuilder;
|
||||||
[Key? key, BuildContext? context])? additionalItemBuilder;
|
|
||||||
|
|
||||||
/// A list of additional message tooltip menu items, provided with the data only. We recommend using this field instead of the previous `additionalItemBuilder`.
|
/// A list of additional message tooltip menu items, provided with the data only. We recommend using this field instead of the previous `additionalItemBuilder`.
|
||||||
List<MessageToolTipItem> Function(
|
List<MessageToolTipItem> Function(V2TimMessage message, Function() closeTooltip)? additionalMessageToolTips;
|
||||||
V2TimMessage message, Function() closeTooltip)? additionalMessageToolTips;
|
|
||||||
|
|
||||||
ToolTipsConfig(
|
ToolTipsConfig(
|
||||||
{this.showDeleteMessage = true,
|
{this.showDeleteMessage = true,
|
||||||
|
|
@ -186,8 +178,7 @@ class ToolTipsConfig {
|
||||||
this.showCopyMessage = true,
|
this.showCopyMessage = true,
|
||||||
this.showForwardMessage = true,
|
this.showForwardMessage = true,
|
||||||
this.additionalMessageToolTips,
|
this.additionalMessageToolTips,
|
||||||
@Deprecated(
|
@Deprecated("Please use `additionalMessageToolTips` instead. You are now only expected to specify the data, rather than providing a whole widget. This makes usage easier, as you no longer need to worry about the UI display.")
|
||||||
"Please use `additionalMessageToolTips` instead. You are now only expected to specify the data, rather than providing a whole widget. This makes usage easier, as you no longer need to worry about the UI display.")
|
|
||||||
this.additionalItemBuilder});
|
this.additionalItemBuilder});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,12 +187,10 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget {
|
||||||
final V2TimMessage message;
|
final V2TimMessage message;
|
||||||
|
|
||||||
/// tap remote user avatar callback function
|
/// tap remote user avatar callback function
|
||||||
final void Function(String userID, TapDownDetails tapDetails)?
|
final void Function(String userID, TapDownDetails tapDetails)? onTapForOthersPortrait;
|
||||||
onTapForOthersPortrait;
|
|
||||||
|
|
||||||
/// secondary tap remote user avatar callback function
|
/// secondary tap remote user avatar callback function
|
||||||
final void Function(String userID, TapDownDetails tapDetails)?
|
final void Function(String userID, TapDownDetails tapDetails)? onSecondaryTapForOthersPortrait;
|
||||||
onSecondaryTapForOthersPortrait;
|
|
||||||
|
|
||||||
/// the function use for reply message, when click replied message can scroll to it.
|
/// the function use for reply message, when click replied message can scroll to it.
|
||||||
final Function? onScrollToIndex;
|
final Function? onScrollToIndex;
|
||||||
|
|
@ -210,8 +199,7 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget {
|
||||||
final Function? onScrollToIndexBegin;
|
final Function? onScrollToIndexBegin;
|
||||||
|
|
||||||
/// the callback for long press event, except myself avatar
|
/// the callback for long press event, except myself avatar
|
||||||
final Function(String? userId, String? nickName)?
|
final Function(String? userId, String? nickName)? onLongPressForOthersHeadPortrait;
|
||||||
onLongPressForOthersHeadPortrait;
|
|
||||||
|
|
||||||
/// message item builder, works for customize all message types and row layout.
|
/// message item builder, works for customize all message types and row layout.
|
||||||
final MessageItemBuilder? messageItemBuilder;
|
final MessageItemBuilder? messageItemBuilder;
|
||||||
|
|
@ -237,8 +225,7 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget {
|
||||||
/// Auto mention user when send reply message
|
/// Auto mention user when send reply message
|
||||||
final bool allowAtUserWhenReply;
|
final bool allowAtUserWhenReply;
|
||||||
|
|
||||||
@Deprecated(
|
@Deprecated("Nickname will not show in one-to-one chat, if you tend to control it in group chat, please use `isShowSelfNameInGroup` and `isShowOthersNameInGroup` from `config: TIMUIKitChatConfig` instead")
|
||||||
"Nickname will not show in one-to-one chat, if you tend to control it in group chat, please use `isShowSelfNameInGroup` and `isShowOthersNameInGroup` from `config: TIMUIKitChatConfig` instead")
|
|
||||||
|
|
||||||
/// allow show user nick name
|
/// allow show user nick name
|
||||||
final bool showNickName;
|
final bool showNickName;
|
||||||
|
|
@ -259,19 +246,16 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget {
|
||||||
final EdgeInsetsGeometry? textPadding;
|
final EdgeInsetsGeometry? textPadding;
|
||||||
|
|
||||||
/// avatar builder
|
/// avatar builder
|
||||||
final Widget Function(BuildContext context, V2TimMessage message)?
|
final Widget Function(BuildContext context, V2TimMessage message)? userAvatarBuilder;
|
||||||
userAvatarBuilder;
|
|
||||||
|
|
||||||
/// theme info for message and avatar
|
/// theme info for message and avatar
|
||||||
final MessageThemeData? themeData;
|
final MessageThemeData? themeData;
|
||||||
|
|
||||||
/// builder for nick name row
|
/// builder for nick name row
|
||||||
final Widget Function(BuildContext context, V2TimMessage message)?
|
final Widget Function(BuildContext context, V2TimMessage message)? topRowBuilder;
|
||||||
topRowBuilder;
|
|
||||||
|
|
||||||
/// builder for bottom raw which under message content
|
/// builder for bottom raw which under message content
|
||||||
final Widget Function(BuildContext context, V2TimMessage message)?
|
final Widget Function(BuildContext context, V2TimMessage message)? bottomRowBuilder;
|
||||||
bottomRowBuilder;
|
|
||||||
|
|
||||||
// open MessageReaction
|
// open MessageReaction
|
||||||
final bool? isUseMessageReaction;
|
final bool? isUseMessageReaction;
|
||||||
|
|
@ -292,9 +276,7 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget {
|
||||||
const TIMUIKitHistoryMessageListItem(
|
const TIMUIKitHistoryMessageListItem(
|
||||||
{Key? key,
|
{Key? key,
|
||||||
required this.message,
|
required this.message,
|
||||||
@Deprecated(
|
@Deprecated("Nickname will not show in one-to-one chat, if you tend to control it in group chat, please use `isShowSelfNameInGroup` and `isShowOthersNameInGroup` from `config: TIMUIKitChatConfig` instead") this.showNickName = false,
|
||||||
"Nickname will not show in one-to-one chat, if you tend to control it in group chat, please use `isShowSelfNameInGroup` and `isShowOthersNameInGroup` from `config: TIMUIKitChatConfig` instead")
|
|
||||||
this.showNickName = false,
|
|
||||||
this.onScrollToIndex,
|
this.onScrollToIndex,
|
||||||
this.onScrollToIndexBegin,
|
this.onScrollToIndexBegin,
|
||||||
this.onTapForOthersPortrait,
|
this.onTapForOthersPortrait,
|
||||||
|
|
@ -333,9 +315,7 @@ class TipsActionItem extends TIMUIKitStatelessWidget {
|
||||||
final String icon;
|
final String icon;
|
||||||
final String? package;
|
final String? package;
|
||||||
|
|
||||||
TipsActionItem(
|
TipsActionItem({Key? key, required this.label, required this.icon, this.package}) : super(key: key);
|
||||||
{Key? key, required this.label, required this.icon, this.package})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||||
|
|
@ -363,15 +343,12 @@ class TipsActionItem extends TIMUIKitStatelessWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TIMUIKItHistoryMessageListItemState
|
class _TIMUIKItHistoryMessageListItemState extends TIMUIKitState<TIMUIKitHistoryMessageListItem> with TickerProviderStateMixin {
|
||||||
extends TIMUIKitState<TIMUIKitHistoryMessageListItem>
|
|
||||||
with TickerProviderStateMixin {
|
|
||||||
SuperTooltip? tooltip;
|
SuperTooltip? tooltip;
|
||||||
|
|
||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final MessageService _messageService = serviceLocator<MessageService>();
|
final MessageService _messageService = serviceLocator<MessageService>();
|
||||||
final TUISelfInfoViewModel selfInfoModel =
|
final TUISelfInfoViewModel selfInfoModel = serviceLocator<TUISelfInfoViewModel>();
|
||||||
serviceLocator<TUISelfInfoViewModel>();
|
|
||||||
final TUIThemeViewModel themeModel = serviceLocator<TUIThemeViewModel>();
|
final TUIThemeViewModel themeModel = serviceLocator<TUIThemeViewModel>();
|
||||||
|
|
||||||
// bool isChecked = false;
|
// bool isChecked = false;
|
||||||
|
|
@ -384,15 +361,10 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isReplyMessage(V2TimMessage message) {
|
bool isReplyMessage(V2TimMessage message) {
|
||||||
final hasCustomData =
|
final hasCustomData = message.cloudCustomData != null && message.cloudCustomData != "";
|
||||||
message.cloudCustomData != null && message.cloudCustomData != "";
|
|
||||||
if (hasCustomData) {
|
if (hasCustomData) {
|
||||||
try {
|
try {
|
||||||
final CloudCustomData messageCloudCustomData = CloudCustomData.fromJson(
|
final CloudCustomData messageCloudCustomData = CloudCustomData.fromJson(json.decode(TencentUtils.checkString(message.cloudCustomData) != null ? message.cloudCustomData! : "{}"));
|
||||||
json.decode(
|
|
||||||
TencentUtils.checkString(message.cloudCustomData) != null
|
|
||||||
? message.cloudCustomData!
|
|
||||||
: "{}"));
|
|
||||||
if (messageCloudCustomData.messageReply != null) {
|
if (messageCloudCustomData.messageReply != null) {
|
||||||
MessageRepliedData.fromJson(messageCloudCustomData.messageReply!);
|
MessageRepliedData.fromJson(messageCloudCustomData.messageReply!);
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -405,8 +377,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
(bool isRevoke, bool isRevokeByAdmin) isRevokeMessage(
|
(bool isRevoke, bool isRevokeByAdmin) isRevokeMessage(V2TimMessage message, TUIChatSeparateViewModel model) {
|
||||||
V2TimMessage message, TUIChatSeparateViewModel model) {
|
|
||||||
if (message.status == 6) {
|
if (message.status == 6) {
|
||||||
return (true, false);
|
return (true, false);
|
||||||
} else if (model.chatConfig.isGroupAdminRecallEnabled) {
|
} else if (model.chatConfig.isGroupAdminRecallEnabled) {
|
||||||
|
|
@ -422,11 +393,9 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
return (false, false);
|
return (false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _messageItemBuilder(
|
Widget _messageItemBuilder(V2TimMessage messageItem, TUIChatSeparateViewModel model) {
|
||||||
V2TimMessage messageItem, TUIChatSeparateViewModel model) {
|
|
||||||
final msgType = messageItem.elemType;
|
final msgType = messageItem.elemType;
|
||||||
final isShowJump = (model.jumpMsgID == messageItem.msgID) &&
|
final isShowJump = (model.jumpMsgID == messageItem.msgID) && (messageItem.msgID?.isNotEmpty ?? false);
|
||||||
(messageItem.msgID?.isNotEmpty ?? false);
|
|
||||||
final MessageItemBuilder? messageItemBuilder = widget.messageItemBuilder;
|
final MessageItemBuilder? messageItemBuilder = widget.messageItemBuilder;
|
||||||
final isFromSelf = messageItem.isSelf ?? true;
|
final isFromSelf = messageItem.isSelf ?? true;
|
||||||
void clearJump() {
|
void clearJump() {
|
||||||
|
|
@ -437,8 +406,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
|
|
||||||
switch (msgType) {
|
switch (msgType) {
|
||||||
case MessageElemType.V2TIM_ELEM_TYPE_CUSTOM:
|
case MessageElemType.V2TIM_ELEM_TYPE_CUSTOM:
|
||||||
final customWidget =
|
final customWidget = messageItemBuilder?.customMessageItemBuilder != null
|
||||||
messageItemBuilder?.customMessageItemBuilder != null
|
|
||||||
? messageItemBuilder!.customMessageItemBuilder!(
|
? messageItemBuilder!.customMessageItemBuilder!(
|
||||||
messageItem,
|
messageItem,
|
||||||
isShowJump,
|
isShowJump,
|
||||||
|
|
@ -482,8 +450,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
);
|
);
|
||||||
case MessageElemType.V2TIM_ELEM_TYPE_TEXT:
|
case MessageElemType.V2TIM_ELEM_TYPE_TEXT:
|
||||||
if (isReplyMessage(messageItem)) {
|
if (isReplyMessage(messageItem)) {
|
||||||
final customWidget =
|
final customWidget = messageItemBuilder?.textReplyMessageItemBuilder != null
|
||||||
messageItemBuilder?.textReplyMessageItemBuilder != null
|
|
||||||
? messageItemBuilder!.textReplyMessageItemBuilder!(
|
? messageItemBuilder!.textReplyMessageItemBuilder!(
|
||||||
messageItem,
|
messageItem,
|
||||||
isShowJump,
|
isShowJump,
|
||||||
|
|
@ -565,8 +532,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
isShowMessageReaction: widget.isUseMessageReaction,
|
isShowMessageReaction: widget.isUseMessageReaction,
|
||||||
);
|
);
|
||||||
case MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS:
|
case MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS:
|
||||||
final customWidget =
|
final customWidget = messageItemBuilder?.groupTipsMessageItemBuilder != null
|
||||||
messageItemBuilder?.groupTipsMessageItemBuilder != null
|
|
||||||
? messageItemBuilder!.groupTipsMessageItemBuilder!(
|
? messageItemBuilder!.groupTipsMessageItemBuilder!(
|
||||||
messageItem,
|
messageItem,
|
||||||
isShowJump,
|
isShowJump,
|
||||||
|
|
@ -608,8 +574,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
isShowMessageReaction: widget.isUseMessageReaction,
|
isShowMessageReaction: widget.isUseMessageReaction,
|
||||||
);
|
);
|
||||||
case MessageElemType.V2TIM_ELEM_TYPE_LOCATION:
|
case MessageElemType.V2TIM_ELEM_TYPE_LOCATION:
|
||||||
final customWidget =
|
final customWidget = messageItemBuilder?.locationMessageItemBuilder != null
|
||||||
messageItemBuilder?.locationMessageItemBuilder != null
|
|
||||||
? messageItemBuilder!.locationMessageItemBuilder!(
|
? messageItemBuilder!.locationMessageItemBuilder!(
|
||||||
messageItem,
|
messageItem,
|
||||||
isShowJump,
|
isShowJump,
|
||||||
|
|
@ -618,8 +583,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
: null;
|
: null;
|
||||||
return customWidget ?? Text(TIM_t("[位置]"));
|
return customWidget ?? Text(TIM_t("[位置]"));
|
||||||
case MessageElemType.V2TIM_ELEM_TYPE_MERGER:
|
case MessageElemType.V2TIM_ELEM_TYPE_MERGER:
|
||||||
final customWidget =
|
final customWidget = messageItemBuilder?.mergerMessageItemBuilder != null
|
||||||
messageItemBuilder?.mergerMessageItemBuilder != null
|
|
||||||
? messageItemBuilder!.mergerMessageItemBuilder!(
|
? messageItemBuilder!.mergerMessageItemBuilder!(
|
||||||
messageItem,
|
messageItem,
|
||||||
isShowJump,
|
isShowJump,
|
||||||
|
|
@ -644,11 +608,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
|
|
||||||
Widget _groupTipsMessageBuilder(TUIChatSeparateViewModel model) {
|
Widget _groupTipsMessageBuilder(TUIChatSeparateViewModel model) {
|
||||||
final messageItem = widget.message;
|
final messageItem = widget.message;
|
||||||
return Container(
|
return Container(padding: const EdgeInsets.only(bottom: 20), child: TIMUIKitGroupTipsElem(groupTipsElem: messageItem.groupTipsElem!, groupMemberList: model.groupMemberList ?? []));
|
||||||
padding: const EdgeInsets.only(bottom: 20),
|
|
||||||
child: TIMUIKitGroupTipsElem(
|
|
||||||
groupTipsElem: messageItem.groupTipsElem!,
|
|
||||||
groupMemberList: model.groupMemberList ?? []));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _selfRevokeEditMessageBuilder(theme, TUIChatSeparateViewModel model) {
|
Widget _selfRevokeEditMessageBuilder(theme, TUIChatSeparateViewModel model) {
|
||||||
|
|
@ -664,8 +624,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
text: TIM_t("重新编辑"),
|
text: TIM_t("重新编辑"),
|
||||||
recognizer: TapGestureRecognizer()
|
recognizer: TapGestureRecognizer()
|
||||||
..onTap = () {
|
..onTap = () {
|
||||||
widget.textFieldController
|
widget.textFieldController?.setTextField(widget.message.textElem?.text ?? "");
|
||||||
?.setTextField(widget.message.textElem?.text ?? "");
|
|
||||||
},
|
},
|
||||||
style: TextStyle(color: theme.primaryColor),
|
style: TextStyle(color: theme.primaryColor),
|
||||||
)
|
)
|
||||||
|
|
@ -682,15 +641,12 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _timeDividerBuilder(
|
Widget _timeDividerBuilder(theme, int timeStamp, TUIChatSeparateViewModel model) {
|
||||||
theme, int timeStamp, TUIChatSeparateViewModel model) {
|
|
||||||
return Container(
|
return Container(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
margin: const EdgeInsets.symmetric(vertical: 20),
|
margin: const EdgeInsets.symmetric(vertical: 20),
|
||||||
child: Text(
|
child: Text(
|
||||||
model.chatConfig.timeDividerConfig?.timestampParser != null
|
model.chatConfig.timeDividerConfig?.timestampParser != null ? (model.chatConfig.timeDividerConfig?.timestampParser!(timeStamp))! : TimeAgo().getTimeForMessage(1709740800),
|
||||||
? (model.chatConfig.timeDividerConfig?.timestampParser!(timeStamp))!
|
|
||||||
: TimeAgo().getTimeForMessage(timeStamp),
|
|
||||||
style: widget.themeData?.timelineTextStyle ??
|
style: widget.themeData?.timelineTextStyle ??
|
||||||
TextStyle(
|
TextStyle(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
|
|
@ -714,10 +670,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
width: 100,
|
width: 100,
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: LinearGradient(colors: [
|
gradient: LinearGradient(colors: [const Color(0x00C0E1FF), theme.primaryColor ?? CommonColor.lightPrimaryColor]),
|
||||||
const Color(0x00C0E1FF),
|
|
||||||
theme.primaryColor ?? CommonColor.lightPrimaryColor
|
|
||||||
]),
|
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -749,8 +702,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isRevocable(int timestamp) =>
|
bool isRevocable(int timestamp) => (DateTime.now().millisecondsSinceEpoch / 1000).ceil() - timestamp < 120;
|
||||||
(DateTime.now().millisecondsSinceEpoch / 1000).ceil() - timestamp < 120;
|
|
||||||
|
|
||||||
// TODO : 继续看这里
|
// TODO : 继续看这里
|
||||||
|
|
||||||
|
|
@ -771,38 +723,21 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
|
|
||||||
final screenHeight = MediaQuery.of(context).size.height;
|
final screenHeight = MediaQuery.of(context).size.height;
|
||||||
final screenWidth = MediaQuery.of(context).size.width;
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
final isDesktopScreen =
|
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
final isLongMessage = context.size!.height + 350 > screenHeight && !(isDesktopScreen);
|
||||||
final isLongMessage =
|
final tapDetails = (isDesktopScreen || isLongMessage) ? (details ?? _tapDetails) : details;
|
||||||
context.size!.height + 350 > screenHeight && !(isDesktopScreen);
|
|
||||||
final tapDetails =
|
|
||||||
(isDesktopScreen || isLongMessage) ? (details ?? _tapDetails) : details;
|
|
||||||
final isSelf = message.isSelf ?? true;
|
final isSelf = message.isSelf ?? true;
|
||||||
|
|
||||||
final targetWidth =
|
final targetWidth = min(MediaQuery.of(context).size.width * 0.84, 350).toDouble();
|
||||||
min(MediaQuery.of(context).size.width * 0.84, 350).toDouble();
|
final double dx = !isSelf ? min(tapDetails?.globalPosition.dx ?? targetWidth, screenWidth - targetWidth) : max(tapDetails?.globalPosition.dx ?? targetWidth, targetWidth).toDouble();
|
||||||
final double dx = !isSelf
|
final double dy = min(tapDetails?.globalPosition.dy ?? MediaQuery.of(context).size.height, MediaQuery.of(context).size.height - 320).toDouble();
|
||||||
? min(tapDetails?.globalPosition.dx ?? targetWidth,
|
|
||||||
screenWidth - targetWidth)
|
|
||||||
: max(tapDetails?.globalPosition.dx ?? targetWidth, targetWidth)
|
|
||||||
.toDouble();
|
|
||||||
final double dy = min(
|
|
||||||
tapDetails?.globalPosition.dy ?? MediaQuery.of(context).size.height,
|
|
||||||
MediaQuery.of(context).size.height - 320)
|
|
||||||
.toDouble();
|
|
||||||
final finalTapDetail = tapDetails != null
|
final finalTapDetail = tapDetails != null
|
||||||
? TapDownDetails(
|
? TapDownDetails(
|
||||||
globalPosition: Offset(dx, dy),
|
globalPosition: Offset(dx, dy),
|
||||||
)
|
)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
initTools(
|
initTools(context: c, model: model, isShowMoreSticker: isShowMoreSticker, details: finalTapDetail, theme: theme, isFromWideToolTip: isFromWideTooltip);
|
||||||
context: c,
|
|
||||||
model: model,
|
|
||||||
isShowMoreSticker: isShowMoreSticker,
|
|
||||||
details: finalTapDetail,
|
|
||||||
theme: theme,
|
|
||||||
isFromWideToolTip: isFromWideTooltip);
|
|
||||||
tooltip!.show(c, targetCenter: finalTapDetail?.globalPosition);
|
tooltip!.show(c, targetCenter: finalTapDetail?.globalPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -815,26 +750,15 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<V2TimValueCallback<V2TimMessageChangeInfo>> _modifySticker(
|
Future<V2TimValueCallback<V2TimMessageChangeInfo>> _modifySticker(int sticker) async {
|
||||||
int sticker) async {
|
|
||||||
return await Future.delayed(const Duration(milliseconds: 50), () async {
|
return await Future.delayed(const Duration(milliseconds: 50), () async {
|
||||||
return await MessageReactionUtils.clickOnSticker(widget.message, sticker);
|
return await MessageReactionUtils.clickOnSticker(widget.message, sticker);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
initTools(
|
initTools({BuildContext? context, bool isLongMessage = false, required TUIChatSeparateViewModel model, TUITheme? theme, bool? isShowMoreSticker, TapDownDetails? details, bool? isFromWideToolTip}) {
|
||||||
{BuildContext? context,
|
final isUseMessageReaction = widget.message.elemType == 2 ? false : model.chatConfig.isUseMessageReaction;
|
||||||
bool isLongMessage = false,
|
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||||
required TUIChatSeparateViewModel model,
|
|
||||||
TUITheme? theme,
|
|
||||||
bool? isShowMoreSticker,
|
|
||||||
TapDownDetails? details,
|
|
||||||
bool? isFromWideToolTip}) {
|
|
||||||
final isUseMessageReaction = widget.message.elemType == 2
|
|
||||||
? false
|
|
||||||
: model.chatConfig.isUseMessageReaction;
|
|
||||||
final isDesktopScreen =
|
|
||||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
|
||||||
final isSelf = widget.message.isSelf ?? true;
|
final isSelf = widget.message.isSelf ?? true;
|
||||||
double arrowTipDistance = 30;
|
double arrowTipDistance = 30;
|
||||||
double arrowBaseWidth = 10;
|
double arrowBaseWidth = 10;
|
||||||
|
|
@ -843,8 +767,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
TooltipDirection popupDirection = TooltipDirection.up;
|
TooltipDirection popupDirection = TooltipDirection.up;
|
||||||
double? left;
|
double? left;
|
||||||
double? right;
|
double? right;
|
||||||
SelectEmojiPanelPosition selectEmojiPanelPosition =
|
SelectEmojiPanelPosition selectEmojiPanelPosition = SelectEmojiPanelPosition.down;
|
||||||
SelectEmojiPanelPosition.down;
|
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
RenderBox? box = _key.currentContext?.findRenderObject() as RenderBox?;
|
RenderBox? box = _key.currentContext?.findRenderObject() as RenderBox?;
|
||||||
if (details != null && box != null) {
|
if (details != null && box != null) {
|
||||||
|
|
@ -867,9 +790,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
Offset offset = box.localToGlobal(Offset.zero);
|
Offset offset = box.localToGlobal(Offset.zero);
|
||||||
double boxWidth = box.size.width;
|
double boxWidth = box.size.width;
|
||||||
if (isSelf) {
|
if (isSelf) {
|
||||||
right = screenWidth -
|
right = screenWidth - offset.dx - ((isUseMessageReaction) ? boxWidth : (boxWidth / 1.3));
|
||||||
offset.dx -
|
|
||||||
((isUseMessageReaction) ? boxWidth : (boxWidth / 1.3));
|
|
||||||
} else {
|
} else {
|
||||||
left = offset.dx;
|
left = offset.dx;
|
||||||
}
|
}
|
||||||
|
|
@ -881,8 +802,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
popupDirection = TooltipDirection.down;
|
popupDirection = TooltipDirection.down;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
arrowTipDistance = (context.size!.height / 2).roundToDouble() +
|
arrowTipDistance = (context.size!.height / 2).roundToDouble() + (isLongMessage ? -120 : 10);
|
||||||
(isLongMessage ? -120 : 10);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -903,8 +823,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
showCloseButton: ShowCloseButton.none,
|
showCloseButton: ShowCloseButton.none,
|
||||||
touchThroughAreaShape: ClipAreaShape.rectangle,
|
touchThroughAreaShape: ClipAreaShape.rectangle,
|
||||||
content: TIMUIKitMessageTooltip(
|
content: TIMUIKitMessageTooltip(
|
||||||
iSUseDefaultHoverBar: model.chatConfig.isUseMessageHoverBarOnDesktop &&
|
iSUseDefaultHoverBar: model.chatConfig.isUseMessageHoverBarOnDesktop && widget.customMessageHoverBarOnDesktop == null,
|
||||||
widget.customMessageHoverBarOnDesktop == null,
|
|
||||||
model: model,
|
model: model,
|
||||||
groupMemberInfo: widget.groupMemberInfo,
|
groupMemberInfo: widget.groupMemberInfo,
|
||||||
isShowMoreSticker: isShowMoreSticker ?? false,
|
isShowMoreSticker: isShowMoreSticker ?? false,
|
||||||
|
|
@ -912,8 +831,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
isUseMessageReaction: isUseMessageReaction,
|
isUseMessageReaction: isUseMessageReaction,
|
||||||
message: widget.message,
|
message: widget.message,
|
||||||
allowAtUserWhenReply: widget.allowAtUserWhenReply,
|
allowAtUserWhenReply: widget.allowAtUserWhenReply,
|
||||||
onLongPressForOthersHeadPortrait:
|
onLongPressForOthersHeadPortrait: widget.onLongPressForOthersHeadPortrait,
|
||||||
widget.onLongPressForOthersHeadPortrait,
|
|
||||||
selectEmojiPanelPosition: selectEmojiPanelPosition,
|
selectEmojiPanelPosition: selectEmojiPanelPosition,
|
||||||
onCloseTooltip: () => tooltip?.close(),
|
onCloseTooltip: () => tooltip?.close(),
|
||||||
onSelectSticker: (int value) {
|
onSelectSticker: (int value) {
|
||||||
|
|
@ -924,8 +842,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _getMessageItemBuilder(V2TimMessage message, int? messageStatues,
|
Widget _getMessageItemBuilder(V2TimMessage message, int? messageStatues, TUIChatSeparateViewModel model) {
|
||||||
TUIChatSeparateViewModel model) {
|
|
||||||
final messageBuilder = _messageItemBuilder;
|
final messageBuilder = _messageItemBuilder;
|
||||||
|
|
||||||
return messageBuilder(widget.message, model);
|
return messageBuilder(widget.message, model);
|
||||||
|
|
@ -986,8 +903,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
return isvote;
|
return isvote;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MessageHoverControlItem> getMessageHoverControlBar(
|
List<MessageHoverControlItem> getMessageHoverControlBar(TUIChatSeparateViewModel model, TUITheme theme) {
|
||||||
TUIChatSeparateViewModel model, TUITheme theme) {
|
|
||||||
return [
|
return [
|
||||||
if (widget.isUseMessageReaction ?? false)
|
if (widget.isUseMessageReaction ?? false)
|
||||||
MessageHoverControlItem(
|
MessageHoverControlItem(
|
||||||
|
|
@ -998,8 +914,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
color: hexToColor("8f959e"),
|
color: hexToColor("8f959e"),
|
||||||
),
|
),
|
||||||
onClick: (details) {
|
onClick: (details) {
|
||||||
_onOpenToolTip(
|
_onOpenToolTip(context, widget.message, model, theme, details, true, true);
|
||||||
context, widget.message, model, theme, details, true, true);
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
if (widget.toolTipsConfig?.showReplyMessage ?? true)
|
if (widget.toolTipsConfig?.showReplyMessage ?? true)
|
||||||
|
|
@ -1013,21 +928,14 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
onClick: (_) {
|
onClick: (_) {
|
||||||
model.repliedMessage = widget.message;
|
model.repliedMessage = widget.message;
|
||||||
final isSelf = widget.message.isSelf ?? true;
|
final isSelf = widget.message.isSelf ?? true;
|
||||||
final isGroup =
|
final isGroup = TencentUtils.checkString(widget.message.groupID) != null;
|
||||||
TencentUtils.checkString(widget.message.groupID) != null;
|
final isAtWhenReply = !isSelf && isGroup && widget.allowAtUserWhenReply && widget.onLongPressForOthersHeadPortrait != null;
|
||||||
final isAtWhenReply = !isSelf &&
|
|
||||||
isGroup &&
|
|
||||||
widget.allowAtUserWhenReply &&
|
|
||||||
widget.onLongPressForOthersHeadPortrait != null;
|
|
||||||
|
|
||||||
/// If replying to a self message, do not add a at tag, only requestFocus.
|
/// If replying to a self message, do not add a at tag, only requestFocus.
|
||||||
widget.onLongPressForOthersHeadPortrait!(
|
widget.onLongPressForOthersHeadPortrait!(!isAtWhenReply ? null : widget.message.sender, !isAtWhenReply ? null : widget.message.nickName);
|
||||||
!isAtWhenReply ? null : widget.message.sender,
|
|
||||||
!isAtWhenReply ? null : widget.message.nickName);
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
if ((widget.toolTipsConfig?.showForwardMessage ?? true) &&
|
if ((widget.toolTipsConfig?.showForwardMessage ?? true) && !isVoteMessage(widget.message))
|
||||||
!isVoteMessage(widget.message))
|
|
||||||
MessageHoverControlItem(
|
MessageHoverControlItem(
|
||||||
name: TIM_t("转发"),
|
name: TIM_t("转发"),
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
|
|
@ -1067,8 +975,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
color: hexToColor("8f959e"),
|
color: hexToColor("8f959e"),
|
||||||
),
|
),
|
||||||
onClick: (details) {
|
onClick: (details) {
|
||||||
_onOpenToolTip(
|
_onOpenToolTip(context, widget.message, model, theme, details, true, false);
|
||||||
context, widget.message, model, theme, details, true, false);
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
...?model.chatConfig.additionalDesktopMessageHoverBarItem
|
...?model.chatConfig.additionalDesktopMessageHoverBarItem
|
||||||
|
|
@ -1078,47 +985,24 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
_onMsgSendFailIconTap(V2TimMessage message, TUIChatSeparateViewModel model) {
|
_onMsgSendFailIconTap(V2TimMessage message, TUIChatSeparateViewModel model) {
|
||||||
final convID = model.conversationID;
|
final convID = model.conversationID;
|
||||||
final convType = model.conversationType;
|
final convType = model.conversationType;
|
||||||
MessageUtils.handleMessageError(
|
MessageUtils.handleMessageError(model.reSendFailMessage(message: message, convType: convType ?? ConvType.c2c, convID: convID), context);
|
||||||
model.reSendFailMessage(
|
|
||||||
message: message,
|
|
||||||
convType: convType ?? ConvType.c2c,
|
|
||||||
convID: convID),
|
|
||||||
context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget renderHoverTipAndReadStatus(
|
Widget renderHoverTipAndReadStatus(TUIChatSeparateViewModel model, bool isSelf, V2TimMessage message, bool isPeerRead, TUITheme theme, bool isDownloadWaiting) {
|
||||||
TUIChatSeparateViewModel model,
|
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||||
bool isSelf,
|
final customHoverBar = widget.customMessageHoverBarOnDesktop != null ? widget.customMessageHoverBarOnDesktop!(message) : null;
|
||||||
V2TimMessage message,
|
|
||||||
bool isPeerRead,
|
|
||||||
TUITheme theme,
|
|
||||||
bool isDownloadWaiting) {
|
|
||||||
final isDesktopScreen =
|
|
||||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
|
||||||
final customHoverBar = widget.customMessageHoverBarOnDesktop != null
|
|
||||||
? widget.customMessageHoverBarOnDesktop!(message)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
final wideHoverTipList = (model.chatConfig.isUseMessageHoverBarOnDesktop &&
|
final wideHoverTipList = (model.chatConfig.isUseMessageHoverBarOnDesktop && customHoverBar == null) ? getMessageHoverControlBar(model, theme) : [];
|
||||||
customHoverBar == null)
|
|
||||||
? getMessageHoverControlBar(model, theme)
|
|
||||||
: [];
|
|
||||||
|
|
||||||
final lastItemName =
|
final lastItemName = wideHoverTipList.isNotEmpty ? wideHoverTipList.last.name : "";
|
||||||
wideHoverTipList.isNotEmpty ? wideHoverTipList.last.name : "";
|
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
if (isDesktopScreen &&
|
if (isDesktopScreen && isShowWideToolTip && customHoverBar == null && !((widget.message.elemType == 6 && isDownloadWaiting)))
|
||||||
isShowWideToolTip &&
|
|
||||||
customHoverBar == null &&
|
|
||||||
!((widget.message.elemType == 6 && isDownloadWaiting)))
|
|
||||||
Container(
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(4), border: Border.all(color: hexToColor("d9dde0"), width: 1)),
|
||||||
borderRadius: BorderRadius.circular(4),
|
|
||||||
border: Border.all(color: hexToColor("d9dde0"), width: 1)),
|
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 4),
|
margin: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: wideHoverTipList
|
children: wideHoverTipList
|
||||||
|
|
@ -1150,17 +1034,12 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
.toList(),
|
.toList(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (isDesktopScreen && isShowWideToolTip && customHoverBar != null)
|
if (isDesktopScreen && isShowWideToolTip && customHoverBar != null) customHoverBar,
|
||||||
customHoverBar,
|
if (!isDesktopScreen || (model.chatConfig.isUseMessageHoverBarOnDesktop && customHoverBar == null && !isShowWideToolTip))
|
||||||
if (!isDesktopScreen ||
|
|
||||||
(model.chatConfig.isUseMessageHoverBarOnDesktop &&
|
|
||||||
customHoverBar == null &&
|
|
||||||
!isShowWideToolTip))
|
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 24,
|
height: 24,
|
||||||
),
|
),
|
||||||
if (isSelf &&
|
if (isSelf && message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_FAIL)
|
||||||
message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_FAIL)
|
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.only(bottom: 3),
|
padding: const EdgeInsets.only(bottom: 3),
|
||||||
margin: const EdgeInsets.only(right: 6),
|
margin: const EdgeInsets.only(right: 6),
|
||||||
|
|
@ -1177,24 +1056,20 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
widget.showMessageReadRecipt &&
|
widget.showMessageReadRecipt &&
|
||||||
model.conversationType == ConvType.c2c &&
|
model.conversationType == ConvType.c2c &&
|
||||||
isSelf &&
|
isSelf &&
|
||||||
(message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC ||
|
(message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC || message.status == MessageStatus.V2TIM_MSG_STATUS_SENDING))
|
||||||
message.status == MessageStatus.V2TIM_MSG_STATUS_SENDING))
|
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.only(bottom: 3),
|
padding: const EdgeInsets.only(bottom: 3),
|
||||||
margin: const EdgeInsets.only(right: 6),
|
margin: const EdgeInsets.only(right: 6),
|
||||||
child: Text(
|
child: Text(
|
||||||
isPeerRead ? TIM_t("已读") : TIM_t("未读"),
|
isPeerRead ? TIM_t("已读") : TIM_t("未读"),
|
||||||
style: TextStyle(
|
style: TextStyle(color: theme.chatMessageItemUnreadStatusTextColor, fontSize: 12),
|
||||||
color: theme.chatMessageItemUnreadStatusTextColor,
|
|
||||||
fontSize: 12),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (model.chatConfig.isShowGroupReadingStatus &&
|
if (model.chatConfig.isShowGroupReadingStatus &&
|
||||||
model.chatConfig.isShowGroupMessageReadReceipt &&
|
model.chatConfig.isShowGroupMessageReadReceipt &&
|
||||||
model.conversationType == ConvType.group &&
|
model.conversationType == ConvType.group &&
|
||||||
isSelf &&
|
isSelf &&
|
||||||
(message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC ||
|
(message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC || message.status == MessageStatus.V2TIM_MSG_STATUS_SENDING))
|
||||||
message.status == MessageStatus.V2TIM_MSG_STATUS_SENDING))
|
|
||||||
TIMUIKitMessageReadReceipt(
|
TIMUIKitMessageReadReceipt(
|
||||||
messageItem: widget.message,
|
messageItem: widget.message,
|
||||||
onTapAvatar: widget.onTapForOthersPortrait,
|
onTapAvatar: widget.onTapForOthersPortrait,
|
||||||
|
|
@ -1205,16 +1080,13 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||||
final TUIChatSeparateViewModel model =
|
final TUIChatSeparateViewModel model = Provider.of<TUIChatSeparateViewModel>(context);
|
||||||
Provider.of<TUIChatSeparateViewModel>(context);
|
final isDownloadWaiting = context.select<TUIChatGlobalModel, bool>((value) => value.isWaiting(widget.message.msgID ?? ""));
|
||||||
final isDownloadWaiting = context.select<TUIChatGlobalModel, bool>(
|
|
||||||
(value) => value.isWaiting(widget.message.msgID ?? ""));
|
|
||||||
final TUITheme theme = value.theme;
|
final TUITheme theme = value.theme;
|
||||||
final message = widget.message;
|
final message = widget.message;
|
||||||
final msgType = message.elemType;
|
final msgType = message.elemType;
|
||||||
final isSelf = message.isSelf ?? true;
|
final isSelf = message.isSelf ?? true;
|
||||||
final isGroupTipsMsg =
|
final isGroupTipsMsg = msgType == MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS;
|
||||||
msgType == MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS;
|
|
||||||
|
|
||||||
final revokeStatus = isRevokeMessage(message, model);
|
final revokeStatus = isRevokeMessage(message, model);
|
||||||
final isRevokedMsg = revokeStatus.$1;
|
final isRevokedMsg = revokeStatus.$1;
|
||||||
|
|
@ -1224,14 +1096,10 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
final isLatestDivider = msgType == 101;
|
final isLatestDivider = msgType == 101;
|
||||||
final isPeerRead = message.isPeerRead ?? false;
|
final isPeerRead = message.isPeerRead ?? false;
|
||||||
final isGroupMessage = model.conversationType == ConvType.group;
|
final isGroupMessage = model.conversationType == ConvType.group;
|
||||||
final bool isRevokeEditable =
|
final bool isRevokeEditable = widget.message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT;
|
||||||
widget.message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT;
|
final isShowNickNameForSelf = isGroupMessage && model.chatConfig.isShowSelfNameInGroup;
|
||||||
final isShowNickNameForSelf =
|
final isShowNickNameForOthers = isGroupMessage && model.chatConfig.isShowOthersNameInGroup;
|
||||||
isGroupMessage && model.chatConfig.isShowSelfNameInGroup;
|
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||||
final isShowNickNameForOthers =
|
|
||||||
isGroupMessage && model.chatConfig.isShowOthersNameInGroup;
|
|
||||||
final isDesktopScreen =
|
|
||||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
|
||||||
if (isTimeDivider) {
|
if (isTimeDivider) {
|
||||||
return _timeDividerBuilder(theme, message.timestamp ?? 0, model);
|
return _timeDividerBuilder(theme, message.timestamp ?? 0, model);
|
||||||
}
|
}
|
||||||
|
|
@ -1246,8 +1114,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
|
|
||||||
if (isGroupTipsMsg) {
|
if (isGroupTipsMsg) {
|
||||||
if (widget.messageItemBuilder?.groupTipsMessageItemBuilder != null) {
|
if (widget.messageItemBuilder?.groupTipsMessageItemBuilder != null) {
|
||||||
final groupTipsMessage =
|
final groupTipsMessage = widget.messageItemBuilder!.groupTipsMessageItemBuilder!(
|
||||||
widget.messageItemBuilder!.groupTipsMessageItemBuilder!(
|
|
||||||
message,
|
message,
|
||||||
(model.jumpMsgID == message.msgID),
|
(model.jumpMsgID == message.msgID),
|
||||||
clearJump,
|
clearJump,
|
||||||
|
|
@ -1258,16 +1125,8 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isRevokedMsg) {
|
if (isRevokedMsg) {
|
||||||
final displayName = isAdminRevoke
|
final displayName = isAdminRevoke ? TIM_t("管理员") : (isSelf ? TIM_t("您") : TencentUtils.checkString(message.nickName) ?? TencentUtils.checkString(message.sender) ?? message.userID);
|
||||||
? TIM_t("管理员")
|
return isSelf && isRevokeEditable && isRevocable(message.timestamp!) ? _selfRevokeEditMessageBuilder(theme, model) : _revokedMessageBuilder(theme, displayName ?? "");
|
||||||
: (isSelf
|
|
||||||
? TIM_t("您")
|
|
||||||
: TencentUtils.checkString(message.nickName) ??
|
|
||||||
TencentUtils.checkString(message.sender) ??
|
|
||||||
message.userID);
|
|
||||||
return isSelf && isRevokeEditable && isRevocable(message.timestamp!)
|
|
||||||
? _selfRevokeEditMessageBuilder(theme, model)
|
|
||||||
: _revokedMessageBuilder(theme, displayName ?? "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用自定义行
|
// 使用自定义行
|
||||||
|
|
@ -1296,8 +1155,7 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
children: [
|
children: [
|
||||||
if (model.isMultiSelect)
|
if (model.isMultiSelect)
|
||||||
Container(
|
Container(
|
||||||
margin:
|
margin: EdgeInsets.only(right: 12, top: 10, left: isSelf ? 16 : 0),
|
||||||
EdgeInsets.only(right: 12, top: 10, left: isSelf ? 16 : 0),
|
|
||||||
child: CheckBoxButton(
|
child: CheckBoxButton(
|
||||||
isChecked: model.multiSelectedMessageList.contains(message),
|
isChecked: model.multiSelectedMessageList.contains(message),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
|
|
@ -1312,16 +1170,14 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
Expanded(
|
Expanded(
|
||||||
child: MouseRegion(
|
child: MouseRegion(
|
||||||
onEnter: (_) {
|
onEnter: (_) {
|
||||||
if (isDesktopScreen &&
|
if (isDesktopScreen && model.chatConfig.isUseMessageHoverBarOnDesktop) {
|
||||||
model.chatConfig.isUseMessageHoverBarOnDesktop) {
|
|
||||||
setState(() {
|
setState(() {
|
||||||
isShowWideToolTip = true;
|
isShowWideToolTip = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onExit: (_) {
|
onExit: (_) {
|
||||||
if (isDesktopScreen &&
|
if (isDesktopScreen && model.chatConfig.isUseMessageHoverBarOnDesktop) {
|
||||||
model.chatConfig.isUseMessageHoverBarOnDesktop) {
|
|
||||||
Tooltip.dismissAllToolTips();
|
Tooltip.dismissAllToolTips();
|
||||||
Future.delayed(const Duration(milliseconds: 100), () {
|
Future.delayed(const Duration(milliseconds: 100), () {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
@ -1331,12 +1187,10 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
behavior:
|
behavior: model.isMultiSelect ? HitTestBehavior.translucent : null,
|
||||||
model.isMultiSelect ? HitTestBehavior.translucent : null,
|
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (model.isMultiSelect) {
|
if (model.isMultiSelect) {
|
||||||
final checked =
|
final checked = model.multiSelectedMessageList.contains(message);
|
||||||
model.multiSelectedMessageList.contains(message);
|
|
||||||
if (checked) {
|
if (checked) {
|
||||||
model.removeFromMultiSelectedMessageList(message);
|
model.removeFromMultiSelectedMessageList(message);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1348,79 +1202,59 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: isSelf
|
mainAxisAlignment: isSelf ? MainAxisAlignment.end : MainAxisAlignment.start,
|
||||||
? MainAxisAlignment.end
|
|
||||||
: MainAxisAlignment.start,
|
|
||||||
children: [
|
children: [
|
||||||
if (!isSelf && widget.showAvatar)
|
if (!isSelf && widget.showAvatar)
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onLongPress: () {
|
onLongPress: () {
|
||||||
if (widget.onLongPressForOthersHeadPortrait !=
|
if (widget.onLongPressForOthersHeadPortrait != null) {}
|
||||||
null) {}
|
|
||||||
if (model.chatConfig.isAllowLongPressAvatarToAt) {
|
if (model.chatConfig.isAllowLongPressAvatarToAt) {
|
||||||
widget.onLongPressForOthersHeadPortrait!(
|
widget.onLongPressForOthersHeadPortrait!(message.sender, message.nickName);
|
||||||
message.sender, message.nickName);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onTapDown: isDesktopScreen
|
onTapDown: isDesktopScreen
|
||||||
? (details) {
|
? (details) {
|
||||||
if (widget.onTapForOthersPortrait != null &&
|
if (widget.onTapForOthersPortrait != null && widget.allowAvatarTap) {
|
||||||
widget.allowAvatarTap) {
|
widget.onTapForOthersPortrait!(message.sender ?? "", details);
|
||||||
widget.onTapForOthersPortrait!(
|
|
||||||
message.sender ?? "", details);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
onTap: isDesktopScreen
|
onTap: isDesktopScreen
|
||||||
? null
|
? null
|
||||||
: () {
|
: () {
|
||||||
if (widget.onTapForOthersPortrait != null &&
|
if (widget.onTapForOthersPortrait != null && widget.allowAvatarTap) {
|
||||||
widget.allowAvatarTap) {
|
widget.onTapForOthersPortrait!(message.sender ?? "", TapDownDetails());
|
||||||
widget.onTapForOthersPortrait!(
|
|
||||||
message.sender ?? "", TapDownDetails());
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSecondaryTap: isDesktopScreen
|
onSecondaryTap: isDesktopScreen
|
||||||
? null
|
? null
|
||||||
: () {
|
: () {
|
||||||
if (widget.onSecondaryTapForOthersPortrait !=
|
if (widget.onSecondaryTapForOthersPortrait != null && widget.allowAvatarTap) {
|
||||||
null &&
|
widget.onSecondaryTapForOthersPortrait!(message.sender ?? "", TapDownDetails());
|
||||||
widget.allowAvatarTap) {
|
|
||||||
widget.onSecondaryTapForOthersPortrait!(
|
|
||||||
message.sender ?? "", TapDownDetails());
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSecondaryTapDown: isDesktopScreen
|
onSecondaryTapDown: isDesktopScreen
|
||||||
? (details) {
|
? (details) {
|
||||||
if (widget.onSecondaryTapForOthersPortrait !=
|
if (widget.onSecondaryTapForOthersPortrait != null && widget.allowAvatarTap) {
|
||||||
null &&
|
widget.onSecondaryTapForOthersPortrait!(message.sender ?? "", details);
|
||||||
widget.allowAvatarTap) {
|
|
||||||
widget.onSecondaryTapForOthersPortrait!(
|
|
||||||
message.sender ?? "", details);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
child: widget.userAvatarBuilder != null
|
child: widget.userAvatarBuilder != null
|
||||||
? widget.userAvatarBuilder!(context, message)
|
? widget.userAvatarBuilder!(context, message)
|
||||||
: Container(
|
: Container(
|
||||||
margin: (isSelf && isShowNickNameForSelf) ||
|
margin: (isSelf && isShowNickNameForSelf) || (!isSelf && isShowNickNameForOthers) ? const EdgeInsets.only(top: 2) : null,
|
||||||
(!isSelf && isShowNickNameForOthers)
|
|
||||||
? const EdgeInsets.only(top: 2)
|
|
||||||
: null,
|
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 40,
|
width: 40,
|
||||||
height: 40,
|
height: 40,
|
||||||
child: Avatar(
|
child: Avatar(
|
||||||
faceUrl: message.faceUrl ?? "",
|
faceUrl: message.faceUrl ?? "",
|
||||||
showName:
|
showName: MessageUtils.getDisplayName(message),
|
||||||
MessageUtils.getDisplayName(message),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (isSelf &&
|
if (isSelf && widget.message.elemType == 6 && isDownloadWaiting)
|
||||||
widget.message.elemType == 6 &&
|
|
||||||
isDownloadWaiting)
|
|
||||||
Container(
|
Container(
|
||||||
margin: const EdgeInsets.only(top: 46, right: 10),
|
margin: const EdgeInsets.only(top: 46, right: 10),
|
||||||
child: LoadingAnimationWidget.threeArchedCircle(
|
child: LoadingAnimationWidget.threeArchedCircle(
|
||||||
|
|
@ -1429,102 +1263,55 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
margin: widget.showAvatar
|
margin: widget.showAvatar ? (isSelf ? const EdgeInsets.only(right: 13) : const EdgeInsets.only(left: 13)) : null,
|
||||||
? (isSelf
|
|
||||||
? const EdgeInsets.only(right: 13)
|
|
||||||
: const EdgeInsets.only(left: 13))
|
|
||||||
: null,
|
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: isSelf
|
crossAxisAlignment: isSelf ? CrossAxisAlignment.end : CrossAxisAlignment.start,
|
||||||
? CrossAxisAlignment.end
|
|
||||||
: CrossAxisAlignment.start,
|
|
||||||
children: [
|
children: [
|
||||||
if ((isSelf && isShowNickNameForSelf) ||
|
if ((isSelf && isShowNickNameForSelf) || (!isSelf && isShowNickNameForOthers))
|
||||||
(!isSelf && isShowNickNameForOthers))
|
|
||||||
widget.topRowBuilder != null
|
widget.topRowBuilder != null
|
||||||
? widget.topRowBuilder!(context, message)
|
? widget.topRowBuilder!(context, message)
|
||||||
: Container(
|
: Container(
|
||||||
margin: const EdgeInsets.only(bottom: 4),
|
margin: const EdgeInsets.only(bottom: 4),
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width / 1.7),
|
||||||
maxWidth: MediaQuery.of(context)
|
|
||||||
.size
|
|
||||||
.width /
|
|
||||||
1.7),
|
|
||||||
child: Text(
|
child: Text(
|
||||||
MessageUtils.getDisplayName(message),
|
MessageUtils.getDisplayName(message),
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: widget.themeData
|
style: widget.themeData?.nickNameTextStyle ?? TextStyle(fontSize: 12, color: theme.weakTextColor),
|
||||||
?.nickNameTextStyle ??
|
|
||||||
TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
color: theme.weakTextColor),
|
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
Row(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
if (isSelf)
|
if (isSelf) renderHoverTipAndReadStatus(model, isSelf, message, isPeerRead, theme, isDownloadWaiting),
|
||||||
renderHoverTipAndReadStatus(
|
|
||||||
model,
|
|
||||||
isSelf,
|
|
||||||
message,
|
|
||||||
isPeerRead,
|
|
||||||
theme,
|
|
||||||
isDownloadWaiting),
|
|
||||||
Container(
|
Container(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
maxWidth: constraints.maxWidth * 0.77,
|
maxWidth: constraints.maxWidth * 0.77,
|
||||||
),
|
),
|
||||||
child: Builder(builder: (context) {
|
child: Builder(builder: (context) {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment:
|
crossAxisAlignment: (message.isSelf ?? true) ? CrossAxisAlignment.end : CrossAxisAlignment.start,
|
||||||
(message.isSelf ?? true)
|
|
||||||
? CrossAxisAlignment.end
|
|
||||||
: CrossAxisAlignment.start,
|
|
||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
child: IgnorePointer(
|
child: IgnorePointer(ignoring: model.isMultiSelect, child: _getMessageItemBuilder(message, message.status, model)),
|
||||||
ignoring: model.isMultiSelect,
|
|
||||||
child: _getMessageItemBuilder(
|
|
||||||
message,
|
|
||||||
message.status,
|
|
||||||
model)),
|
|
||||||
onSecondaryTapDown: (details) {
|
onSecondaryTapDown: (details) {
|
||||||
if (widget.onLongPress != null) {
|
if (widget.onLongPress != null) {
|
||||||
widget.onLongPress!(
|
widget.onLongPress!(context, message);
|
||||||
context, message);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!PlatformUtils().isMobile) {
|
if (!PlatformUtils().isMobile) {
|
||||||
if (widget.allowLongPress) {
|
if (widget.allowLongPress) {
|
||||||
_onOpenToolTip(
|
_onOpenToolTip(context, message, model, theme, details, false, false);
|
||||||
context,
|
|
||||||
message,
|
|
||||||
model,
|
|
||||||
theme,
|
|
||||||
details,
|
|
||||||
false,
|
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLongPress: () {
|
onLongPress: () {
|
||||||
if (widget.onLongPress != null) {
|
if (widget.onLongPress != null) {
|
||||||
widget.onLongPress!(
|
widget.onLongPress!(context, message);
|
||||||
context, message);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (widget.allowLongPress &&
|
if (widget.allowLongPress && !isDesktopScreen) {
|
||||||
!isDesktopScreen) {
|
_onOpenToolTip(context, message, model, theme, null, false, false);
|
||||||
_onOpenToolTip(
|
|
||||||
context,
|
|
||||||
message,
|
|
||||||
model,
|
|
||||||
theme,
|
|
||||||
null,
|
|
||||||
false,
|
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onTapDown: (details) {
|
onTapDown: (details) {
|
||||||
|
|
@ -1533,10 +1320,8 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
),
|
),
|
||||||
TIMUIKitTextTranslationElem(
|
TIMUIKitTextTranslationElem(
|
||||||
message: message,
|
message: message,
|
||||||
isUseDefaultEmoji:
|
isUseDefaultEmoji: widget.isUseDefaultEmoji,
|
||||||
widget.isUseDefaultEmoji,
|
customEmojiStickerList: widget.customEmojiStickerList,
|
||||||
customEmojiStickerList:
|
|
||||||
widget.customEmojiStickerList,
|
|
||||||
isFromSelf: message.isSelf ?? true,
|
isFromSelf: message.isSelf ?? true,
|
||||||
isShowJump: false,
|
isShowJump: false,
|
||||||
clearJump: () {},
|
clearJump: () {},
|
||||||
|
|
@ -1545,35 +1330,16 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
if (!isSelf &&
|
if (!isSelf && message.elemType == MessageElemType.V2TIM_ELEM_TYPE_SOUND && message.localCustomInt != null && message.localCustomInt != HistoryMessageDartConstant.read)
|
||||||
message.elemType ==
|
Padding(padding: const EdgeInsets.only(left: 5, bottom: 12), child: Icon(Icons.circle, color: theme.cautionColor, size: 10)),
|
||||||
MessageElemType.V2TIM_ELEM_TYPE_SOUND &&
|
if (!isSelf) renderHoverTipAndReadStatus(model, isSelf, message, isPeerRead, theme, isDownloadWaiting),
|
||||||
message.localCustomInt != null &&
|
|
||||||
message.localCustomInt !=
|
|
||||||
HistoryMessageDartConstant.read)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
left: 5, bottom: 12),
|
|
||||||
child: Icon(Icons.circle,
|
|
||||||
color: theme.cautionColor, size: 10)),
|
|
||||||
if (!isSelf)
|
|
||||||
renderHoverTipAndReadStatus(
|
|
||||||
model,
|
|
||||||
isSelf,
|
|
||||||
message,
|
|
||||||
isPeerRead,
|
|
||||||
theme,
|
|
||||||
isDownloadWaiting),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (widget.bottomRowBuilder != null)
|
if (widget.bottomRowBuilder != null) widget.bottomRowBuilder!(context, message)
|
||||||
widget.bottomRowBuilder!(context, message)
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (!isSelf &&
|
if (!isSelf && widget.message.elemType == 6 && isDownloadWaiting)
|
||||||
widget.message.elemType == 6 &&
|
|
||||||
isDownloadWaiting)
|
|
||||||
Container(
|
Container(
|
||||||
margin: const EdgeInsets.only(top: 46, left: 10),
|
margin: const EdgeInsets.only(top: 46, left: 10),
|
||||||
child: LoadingAnimationWidget.threeArchedCircle(
|
child: LoadingAnimationWidget.threeArchedCircle(
|
||||||
|
|
@ -1589,16 +1355,11 @@ class _TIMUIKItHistoryMessageListItemState
|
||||||
height: 40,
|
height: 40,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTapDown: (details) {
|
onTapDown: (details) {
|
||||||
if (widget.onTapForOthersPortrait != null &&
|
if (widget.onTapForOthersPortrait != null && widget.allowAvatarTap) {
|
||||||
widget.allowAvatarTap) {
|
widget.onTapForOthersPortrait!(message.sender ?? "", details);
|
||||||
widget.onTapForOthersPortrait!(
|
|
||||||
message.sender ?? "", details);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Avatar(
|
child: Avatar(faceUrl: message.faceUrl ?? "", showName: MessageUtils.getDisplayName(message)),
|
||||||
faceUrl: message.faceUrl ?? "",
|
|
||||||
showName:
|
|
||||||
MessageUtils.getDisplayName(message)),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -2,38 +2,40 @@
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:crypto/crypto.dart';
|
|
||||||
import 'package:device_info_plus/device_info_plus.dart';
|
|
||||||
import 'package:http/http.dart' as http;
|
|
||||||
import 'package:open_file/open_file.dart';
|
|
||||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
|
|
||||||
import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart';
|
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart';
|
|
||||||
import 'package:universal_html/html.dart' as html;
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:crypto/crypto.dart';
|
||||||
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:image_gallery_saver/image_gallery_saver.dart';
|
||||||
import 'package:loading_animation_widget/loading_animation_widget.dart';
|
import 'package:loading_animation_widget/loading_animation_widget.dart';
|
||||||
|
import 'package:open_file/open_file.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:provider/provider.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_base.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.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/business_logic/view_models/tui_chat_global_model.dart';
|
||||||
|
import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.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/tencent_cloud_chat_uikit.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/constants/history_message_constant.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/message.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/utils/permission.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/utils/platform.dart';
|
||||||
|
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_wrapper.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_wrapper.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/image_screen.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/widgets/image_screen.dart';
|
||||||
|
import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart';
|
||||||
import 'package:transparent_image/transparent_image.dart';
|
import 'package:transparent_image/transparent_image.dart';
|
||||||
import 'package:image_gallery_saver/image_gallery_saver.dart';
|
import 'package:universal_html/html.dart' as html;
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart';
|
|
||||||
|
|
||||||
class TIMUIKitImageElem extends StatefulWidget {
|
class TIMUIKitImageElem extends StatefulWidget {
|
||||||
final V2TimMessage message;
|
final V2TimMessage message;
|
||||||
|
|
@ -43,15 +45,7 @@ class TIMUIKitImageElem extends StatefulWidget {
|
||||||
final bool? isShowMessageReaction;
|
final bool? isShowMessageReaction;
|
||||||
final TUIChatSeparateViewModel chatModel;
|
final TUIChatSeparateViewModel chatModel;
|
||||||
|
|
||||||
const TIMUIKitImageElem(
|
const TIMUIKitImageElem({required this.message, this.isShowJump = false, required this.chatModel, this.clearJump, this.isFrom, Key? key, this.isShowMessageReaction}) : super(key: key);
|
||||||
{required this.message,
|
|
||||||
this.isShowJump = false,
|
|
||||||
required this.chatModel,
|
|
||||||
this.clearJump,
|
|
||||||
this.isFrom,
|
|
||||||
Key? key,
|
|
||||||
this.isShowMessageReaction})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => _TIMUIKitImageElem();
|
State<StatefulWidget> createState() => _TIMUIKitImageElem();
|
||||||
|
|
@ -71,9 +65,7 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
||||||
|
|
||||||
String getOriginImgURL() {
|
String getOriginImgURL() {
|
||||||
// 实际拿的是原图
|
// 实际拿的是原图
|
||||||
V2TimImage? img = MessageUtils.getImageFromImgList(
|
V2TimImage? img = MessageUtils.getImageFromImgList(widget.message.imageElem!.imageList, HistoryMessageDartConstant.oriImgPrior);
|
||||||
widget.message.imageElem!.imageList,
|
|
||||||
HistoryMessageDartConstant.oriImgPrior);
|
|
||||||
return img == null ? widget.message.imageElem!.path! : img.url!;
|
return img == null ? widget.message.imageElem!.path! : img.url!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,8 +114,7 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
||||||
final http.Response r = await http.get(Uri.parse(imageUrl));
|
final http.Response r = await http.get(Uri.parse(imageUrl));
|
||||||
final data = r.bodyBytes;
|
final data = r.bodyBytes;
|
||||||
final base64data = base64Encode(data);
|
final base64data = base64Encode(data);
|
||||||
final a =
|
final a = html.AnchorElement(href: 'data:image/jpeg;base64,$base64data');
|
||||||
html.AnchorElement(href: 'data:image/jpeg;base64,$base64data');
|
|
||||||
a.download = md5.convert(utf8.encode(imageUrl)).toString();
|
a.download = md5.convert(utf8.encode(imageUrl)).toString();
|
||||||
a.click();
|
a.click();
|
||||||
a.remove();
|
a.remove();
|
||||||
|
|
@ -134,8 +125,7 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PlatformUtils().isIOS) {
|
if (PlatformUtils().isIOS) {
|
||||||
if (!await Permissions.checkPermission(
|
if (!await Permissions.checkPermission(context, Permission.photosAddOnly.value, theme!, false)) {
|
||||||
context, Permission.photosAddOnly.value, theme!, false)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -170,8 +160,7 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
||||||
|
|
||||||
if (model.getMessageProgress(widget.message.msgID) == 100) {
|
if (model.getMessageProgress(widget.message.msgID) == 100) {
|
||||||
String savePath;
|
String savePath;
|
||||||
if (widget.message.imageElem!.path != null &&
|
if (widget.message.imageElem!.path != null && widget.message.imageElem!.path != '') {
|
||||||
widget.message.imageElem!.path != '') {
|
|
||||||
savePath = widget.message.imageElem!.path!;
|
savePath = widget.message.imageElem!.path!;
|
||||||
} else {
|
} else {
|
||||||
savePath = model.getFileMessageLocation(widget.message.msgID);
|
savePath = model.getFileMessageLocation(widget.message.msgID);
|
||||||
|
|
@ -182,36 +171,21 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
||||||
|
|
||||||
if (PlatformUtils().isIOS) {
|
if (PlatformUtils().isIOS) {
|
||||||
if (result['isSuccess']) {
|
if (result['isSuccess']) {
|
||||||
onTIMCallback(TIMCallback(
|
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存成功"), infoCode: 6660406));
|
||||||
type: TIMCallbackType.INFO,
|
|
||||||
infoRecommendText: TIM_t("图片保存成功"),
|
|
||||||
infoCode: 6660406));
|
|
||||||
} else {
|
} else {
|
||||||
onTIMCallback(TIMCallback(
|
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存失败"), infoCode: 6660407));
|
||||||
type: TIMCallbackType.INFO,
|
|
||||||
infoRecommendText: TIM_t("图片保存失败"),
|
|
||||||
infoCode: 6660407));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
onTIMCallback(TIMCallback(
|
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存成功"), infoCode: 6660406));
|
||||||
type: TIMCallbackType.INFO,
|
|
||||||
infoRecommendText: TIM_t("图片保存成功"),
|
|
||||||
infoCode: 6660406));
|
|
||||||
} else {
|
} else {
|
||||||
onTIMCallback(TIMCallback(
|
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存失败"), infoCode: 6660407));
|
||||||
type: TIMCallbackType.INFO,
|
|
||||||
infoRecommendText: TIM_t("图片保存失败"),
|
|
||||||
infoCode: 6660407));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
onTIMCallback(TIMCallback(
|
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("the message is downloading"), infoCode: -1));
|
||||||
type: TIMCallbackType.INFO,
|
|
||||||
infoRecommendText: TIM_t("the message is downloading"),
|
|
||||||
infoCode: -1));
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -220,27 +194,15 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
||||||
|
|
||||||
if (PlatformUtils().isIOS) {
|
if (PlatformUtils().isIOS) {
|
||||||
if (result['isSuccess']) {
|
if (result['isSuccess']) {
|
||||||
onTIMCallback(TIMCallback(
|
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存成功"), infoCode: 6660406));
|
||||||
type: TIMCallbackType.INFO,
|
|
||||||
infoRecommendText: TIM_t("图片保存成功"),
|
|
||||||
infoCode: 6660406));
|
|
||||||
} else {
|
} else {
|
||||||
onTIMCallback(TIMCallback(
|
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存失败"), infoCode: 6660407));
|
||||||
type: TIMCallbackType.INFO,
|
|
||||||
infoRecommendText: TIM_t("图片保存失败"),
|
|
||||||
infoCode: 6660407));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
onTIMCallback(TIMCallback(
|
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存成功"), infoCode: 6660406));
|
||||||
type: TIMCallbackType.INFO,
|
|
||||||
infoRecommendText: TIM_t("图片保存成功"),
|
|
||||||
infoCode: 6660406));
|
|
||||||
} else {
|
} else {
|
||||||
onTIMCallback(TIMCallback(
|
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存失败"), infoCode: 6660407));
|
||||||
type: TIMCallbackType.INFO,
|
|
||||||
infoRecommendText: TIM_t("图片保存失败"),
|
|
||||||
infoCode: 6660407));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
@ -261,8 +223,7 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
||||||
if (!isWeb && filePath != null && File(filePath).existsSync()) {
|
if (!isWeb && filePath != null && File(filePath).existsSync()) {
|
||||||
imageUrl = filePath;
|
imageUrl = filePath;
|
||||||
isAssetBool = true;
|
isAssetBool = true;
|
||||||
} else if (localUrl != null &&
|
} else if (localUrl != null && (!isWeb && File(localUrl).existsSync())) {
|
||||||
(!isWeb && File(localUrl).existsSync())) {
|
|
||||||
imageUrl = localUrl;
|
imageUrl = localUrl;
|
||||||
isAssetBool = true;
|
isAssetBool = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -280,19 +241,13 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
onTIMCallback(TIMCallback(
|
onTIMCallback(TIMCallback(infoCode: 6660414, infoRecommendText: TIM_t("正在下载中"), type: TIMCallbackType.INFO));
|
||||||
infoCode: 6660414,
|
|
||||||
infoRecommendText: TIM_t("正在下载中"),
|
|
||||||
type: TIMCallbackType.INFO));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
V2TimImage? getImageFromList(V2TimImageTypesEnum imgType) {
|
V2TimImage? getImageFromList(V2TimImageTypesEnum imgType) {
|
||||||
V2TimImage? img = MessageUtils.getImageFromImgList(
|
V2TimImage? img = MessageUtils.getImageFromImgList(widget.message.imageElem!.imageList, HistoryMessageDartConstant.imgPriorMap[imgType] ?? HistoryMessageDartConstant.oriImgPrior);
|
||||||
widget.message.imageElem!.imageList,
|
|
||||||
HistoryMessageDartConstant.imgPriorMap[imgType] ??
|
|
||||||
HistoryMessageDartConstant.oriImgPrior);
|
|
||||||
|
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
@ -316,26 +271,18 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
||||||
));
|
));
|
||||||
|
|
||||||
bool checkIfDownloadSuccess() {
|
bool checkIfDownloadSuccess() {
|
||||||
final localUrl = TencentUtils.checkString(
|
final localUrl = TencentUtils.checkString(model.getFileMessageLocation(widget.message.msgID)) ?? widget.message.imageElem!.imageList![0]!.localUrl;
|
||||||
model.getFileMessageLocation(widget.message.msgID)) ??
|
return TencentUtils.checkString(localUrl) != null && File(localUrl!).existsSync();
|
||||||
widget.message.imageElem!.imageList![0]!.localUrl;
|
|
||||||
return TencentUtils.checkString(localUrl) != null &&
|
|
||||||
File(localUrl!).existsSync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onClickOpenImageInNewWindow() {
|
_onClickOpenImageInNewWindow() {
|
||||||
final localUrl = TencentUtils.checkString(
|
final localUrl = TencentUtils.checkString(model.getFileMessageLocation(widget.message.msgID)) ?? widget.message.imageElem!.imageList![0]!.localUrl;
|
||||||
model.getFileMessageLocation(widget.message.msgID)) ??
|
|
||||||
widget.message.imageElem!.imageList![0]!.localUrl;
|
|
||||||
Future.delayed(const Duration(milliseconds: 0), () async {
|
Future.delayed(const Duration(milliseconds: 0), () async {
|
||||||
final isDownloaded = checkIfDownloadSuccess();
|
final isDownloaded = checkIfDownloadSuccess();
|
||||||
if (isDownloaded) {
|
if (isDownloaded) {
|
||||||
launchDesktopFile(localUrl ?? "");
|
launchDesktopFile(localUrl ?? "");
|
||||||
} else {
|
} else {
|
||||||
onTIMCallback(TIMCallback(
|
onTIMCallback(TIMCallback(infoCode: 6660414, infoRecommendText: TIM_t("正在下载原始资源,请稍候..."), type: TIMCallbackType.INFO));
|
||||||
infoCode: 6660414,
|
|
||||||
infoRecommendText: TIM_t("正在下载原始资源,请稍候..."),
|
|
||||||
type: TIMCallbackType.INFO));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -344,27 +291,14 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
||||||
double? positionRadio,
|
double? positionRadio,
|
||||||
String? originImgUrl,
|
String? originImgUrl,
|
||||||
}) {
|
}) {
|
||||||
final localUrl = TencentUtils.checkString(
|
final localUrl = TencentUtils.checkString(model.getFileMessageLocation(widget.message.msgID)) ?? widget.message.imageElem!.imageList![0]!.localUrl;
|
||||||
model.getFileMessageLocation(widget.message.msgID)) ??
|
|
||||||
widget.message.imageElem!.imageList![0]!.localUrl;
|
|
||||||
if (checkIfDownloadSuccess()) {
|
if (checkIfDownloadSuccess()) {
|
||||||
TUIKitWidePopup.showMedia(
|
TUIKitWidePopup.showMedia(aspectRatio: positionRadio, context: context, mediaLocalPath: localUrl ?? "", onClickOrigin: () => _onClickOpenImageInNewWindow());
|
||||||
aspectRatio: positionRadio,
|
|
||||||
context: context,
|
|
||||||
mediaLocalPath: localUrl ?? "",
|
|
||||||
onClickOrigin: () => _onClickOpenImageInNewWindow());
|
|
||||||
} else {
|
} else {
|
||||||
if (TencentUtils.checkString(originImgUrl) != null) {
|
if (TencentUtils.checkString(originImgUrl) != null) {
|
||||||
TUIKitWidePopup.showMedia(
|
TUIKitWidePopup.showMedia(aspectRatio: positionRadio, context: context, mediaURL: originImgUrl, onClickOrigin: () => _onClickOpenImageInNewWindow());
|
||||||
aspectRatio: positionRadio,
|
|
||||||
context: context,
|
|
||||||
mediaURL: originImgUrl,
|
|
||||||
onClickOrigin: () => _onClickOpenImageInNewWindow());
|
|
||||||
} else {
|
} else {
|
||||||
onTIMCallback(TIMCallback(
|
onTIMCallback(TIMCallback(infoCode: 6660414, infoRecommendText: TIM_t("正在下载中"), type: TIMCallbackType.INFO));
|
||||||
infoCode: 6660414,
|
|
||||||
infoRecommendText: TIM_t("正在下载中"),
|
|
||||||
type: TIMCallbackType.INFO));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -431,10 +365,7 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (PlatformUtils().isDesktop) {
|
if (PlatformUtils().isDesktop) {
|
||||||
TUIKitWidePopup.showMedia(
|
TUIKitWidePopup.showMedia(mediaLocalPath: imgPath, context: context, onClickOrigin: () => launchDesktopFile(imgPath ?? ""));
|
||||||
mediaLocalPath: imgPath,
|
|
||||||
context: context,
|
|
||||||
onClickOrigin: () => launchDesktopFile(imgPath ?? ""));
|
|
||||||
} else {
|
} else {
|
||||||
Navigator.of(context).push(
|
Navigator.of(context).push(
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
|
|
@ -452,107 +383,56 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _renderAllImage(
|
Widget _renderAllImage({dynamic heroTag, required TUITheme theme, bool isNetworkImage = false, String? webPath, V2TimImage? originalImg, V2TimImage? smallImg, String? smallLocalPath, String? originLocalPath}) {
|
||||||
{dynamic heroTag,
|
|
||||||
required TUITheme theme,
|
|
||||||
bool isNetworkImage = false,
|
|
||||||
String? webPath,
|
|
||||||
V2TimImage? originalImg,
|
|
||||||
V2TimImage? smallImg,
|
|
||||||
String? smallLocalPath,
|
|
||||||
String? originLocalPath}) {
|
|
||||||
Widget getImageWidget() {
|
Widget getImageWidget() {
|
||||||
if (isNetworkImage) {
|
if (isNetworkImage) {
|
||||||
return Hero(
|
return Hero(
|
||||||
tag: heroTag,
|
tag: heroTag,
|
||||||
child: PlatformUtils().isWeb
|
child: PlatformUtils().isWeb
|
||||||
? Image.network(webPath ?? smallImg?.url ?? originalImg!.url!,
|
? Image.network(webPath ?? smallImg?.url ?? originalImg!.url!, fit: BoxFit.contain)
|
||||||
fit: BoxFit.contain)
|
|
||||||
: CachedNetworkImage(
|
: CachedNetworkImage(
|
||||||
alignment: Alignment.topCenter,
|
alignment: Alignment.topCenter,
|
||||||
imageUrl: webPath ?? smallImg?.url ?? originalImg!.url!,
|
imageUrl: webPath ?? smallImg?.url ?? originalImg!.url!,
|
||||||
errorWidget: (context, error, stackTrace) =>
|
errorWidget: (context, error, stackTrace) => errorPage(theme),
|
||||||
errorPage(theme),
|
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
cacheKey: smallImg?.uuid ?? originalImg!.uuid,
|
cacheKey: smallImg?.uuid ?? originalImg!.uuid,
|
||||||
placeholder: (context, url) =>
|
placeholder: (context, url) => Image(image: MemoryImage(kTransparentImage)),
|
||||||
Image(image: MemoryImage(kTransparentImage)),
|
|
||||||
fadeInDuration: const Duration(milliseconds: 0),
|
fadeInDuration: const Duration(milliseconds: 0),
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
final imgPath = (TencentUtils.checkString(smallLocalPath) != null
|
final imgPath = (TencentUtils.checkString(smallLocalPath) != null ? smallLocalPath : originLocalPath)!;
|
||||||
? smallLocalPath
|
return Hero(tag: heroTag, child: Image.file(File(imgPath), fit: BoxFit.contain));
|
||||||
: originLocalPath)!;
|
|
||||||
return Hero(
|
|
||||||
tag: heroTag,
|
|
||||||
child: Image.file(File(imgPath), fit: BoxFit.contain));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () => onClickImage(
|
onTap: () => onClickImage(
|
||||||
theme: theme,
|
theme: theme, heroTag: heroTag, isNetworkImage: isNetworkImage, imgUrl: webPath ?? smallImg?.url ?? originalImg?.url ?? "", imgPath: (TencentUtils.checkString(originLocalPath) != null ? originLocalPath : smallLocalPath) ?? ""),
|
||||||
heroTag: heroTag,
|
|
||||||
isNetworkImage: isNetworkImage,
|
|
||||||
imgUrl: webPath ?? smallImg?.url ?? originalImg?.url ?? "",
|
|
||||||
imgPath: (TencentUtils.checkString(originLocalPath) != null
|
|
||||||
? originLocalPath
|
|
||||||
: smallLocalPath) ??
|
|
||||||
""),
|
|
||||||
child: getImageWidget(),
|
child: getImageWidget(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initImages() async {
|
void initImages() async {
|
||||||
if (!PlatformUtils().isWeb &&
|
final zeroImageLocal = TencentUtils.checkString(widget.message.imageElem?.imageList?.firstWhereOrNull((element) => element?.type == 0)?.localUrl);
|
||||||
TencentUtils.checkString(widget.message.msgID) != null) {
|
final oneImageLocal = TencentUtils.checkString(widget.message.imageElem?.imageList?.firstWhereOrNull((element) => element?.type == 1)?.localUrl);
|
||||||
if (widget.message.imageElem?.imageList == null ||
|
final twoImageLocal = TencentUtils.checkString(widget.message.imageElem?.imageList?.firstWhereOrNull((element) => element?.type == 2)?.localUrl);
|
||||||
widget.message.imageElem!.imageList!.isEmpty) {
|
|
||||||
final response = await _messageService.getMessageOnlineUrl(
|
if (!PlatformUtils().isWeb && TencentUtils.checkString(widget.message.msgID) != null) {
|
||||||
msgID: widget.message.msgID!);
|
if ((widget.message.imageElem?.imageList) == null || widget.message.imageElem!.imageList!.isEmpty) {
|
||||||
|
final response = await _messageService.getMessageOnlineUrl(msgID: widget.message.msgID!);
|
||||||
final elem = response.data;
|
final elem = response.data;
|
||||||
if (elem != null && elem.imageElem != null) {
|
if (elem != null && elem.imageElem != null) {
|
||||||
widget.message.imageElem = elem.imageElem;
|
widget.message.imageElem = elem.imageElem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (widget.message.imageElem?.imageList == null ||
|
if (oneImageLocal == null || !File(oneImageLocal).existsSync()) {
|
||||||
widget.message.imageElem!.imageList!.isEmpty ||
|
_messageService.downloadMessage(msgID: widget.message.msgID!, messageType: 3, imageType: 1, isSnapshot: false);
|
||||||
TencentUtils.checkString(
|
|
||||||
widget.message.imageElem?.imageList?[0]?.localUrl) ==
|
|
||||||
null ||
|
|
||||||
!File(widget.message.imageElem!.imageList![0]!.localUrl!)
|
|
||||||
.existsSync()) {
|
|
||||||
_messageService.downloadMessage(
|
|
||||||
msgID: widget.message.msgID!,
|
|
||||||
messageType: 3,
|
|
||||||
imageType: 0,
|
|
||||||
isSnapshot: false);
|
|
||||||
}
|
}
|
||||||
if (widget.message.imageElem?.imageList == null ||
|
if (twoImageLocal == null || !File(twoImageLocal).existsSync()) {
|
||||||
widget.message.imageElem!.imageList!.length < 2 &&
|
_messageService.downloadMessage(msgID: widget.message.msgID!, messageType: 3, imageType: 2, isSnapshot: false);
|
||||||
TencentUtils.checkString(
|
|
||||||
widget.message.imageElem?.imageList?[1]?.localUrl) ==
|
|
||||||
null ||
|
|
||||||
!File(widget.message.imageElem!.imageList![1]!.localUrl!)
|
|
||||||
.existsSync()) {
|
|
||||||
_messageService.downloadMessage(
|
|
||||||
msgID: widget.message.msgID!,
|
|
||||||
messageType: 3,
|
|
||||||
imageType: 1,
|
|
||||||
isSnapshot: false);
|
|
||||||
}
|
}
|
||||||
if (widget.message.imageElem?.imageList != null ||
|
if (zeroImageLocal == null || !File(zeroImageLocal).existsSync()) {
|
||||||
widget.message.imageElem!.imageList!.length < 3 ||
|
_messageService.downloadMessage(msgID: widget.message.msgID!, messageType: 3, imageType: 0, isSnapshot: false);
|
||||||
TencentUtils.checkString(
|
|
||||||
widget.message.imageElem?.imageList?[2]?.localUrl) ==
|
|
||||||
null ||
|
|
||||||
!File(widget.message.imageElem!.imageList![2]!.localUrl!)
|
|
||||||
.existsSync()) {
|
|
||||||
_messageService.downloadMessage(
|
|
||||||
msgID: widget.message.msgID!,
|
|
||||||
messageType: 3,
|
|
||||||
imageType: 2,
|
|
||||||
isSnapshot: false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -566,33 +446,18 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
||||||
bool isNeedShowLocalPath() {
|
bool isNeedShowLocalPath() {
|
||||||
final current = (DateTime.now().millisecondsSinceEpoch / 1000).ceil();
|
final current = (DateTime.now().millisecondsSinceEpoch / 1000).ceil();
|
||||||
final timeStamp = widget.message.timestamp ?? current;
|
final timeStamp = widget.message.timestamp ?? current;
|
||||||
return (widget.message.isSelf ?? true) &&
|
return (widget.message.isSelf ?? true) && (isSent || current - timeStamp < 300);
|
||||||
(isSent || current - timeStamp < 300);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget? _renderImage(dynamic heroTag, TUITheme theme,
|
Widget? _renderImage(dynamic heroTag, TUITheme theme, {V2TimImage? originalImg, V2TimImage? smallImg}) {
|
||||||
{V2TimImage? originalImg, V2TimImage? smallImg}) {
|
|
||||||
if (PlatformUtils().isWeb && widget.message.imageElem!.path != null) {
|
if (PlatformUtils().isWeb && widget.message.imageElem!.path != null) {
|
||||||
// Displaying on Web only
|
// Displaying on Web only
|
||||||
return _renderAllImage(
|
return _renderAllImage(heroTag: heroTag, theme: theme, isNetworkImage: true, smallImg: smallImg, originalImg: originalImg, webPath: widget.message.imageElem!.path);
|
||||||
heroTag: heroTag,
|
|
||||||
theme: theme,
|
|
||||||
isNetworkImage: true,
|
|
||||||
smallImg: smallImg,
|
|
||||||
originalImg: originalImg,
|
|
||||||
webPath: widget.message.imageElem!.path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ((isNeedShowLocalPath() &&
|
if ((isNeedShowLocalPath() && widget.message.imageElem!.path != null && widget.message.imageElem!.path!.isNotEmpty && File(widget.message.imageElem!.path!).existsSync())) {
|
||||||
widget.message.imageElem!.path != null &&
|
return _renderAllImage(smallLocalPath: widget.message.imageElem!.path!, heroTag: heroTag, theme: theme, originLocalPath: widget.message.imageElem!.path!);
|
||||||
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!);
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// ignore: avoid_print
|
// ignore: avoid_print
|
||||||
|
|
@ -600,35 +465,17 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ((TencentUtils.checkString(smallImg?.localUrl) != null &&
|
if ((TencentUtils.checkString(smallImg?.localUrl) != null && File((smallImg?.localUrl!)!).existsSync()) || (TencentUtils.checkString(originalImg?.localUrl) != null && File((originalImg?.localUrl!)!).existsSync())) {
|
||||||
File((smallImg?.localUrl!)!).existsSync()) ||
|
return _renderAllImage(smallLocalPath: smallImg?.localUrl ?? "", heroTag: heroTag, theme: theme, originLocalPath: originalImg?.localUrl);
|
||||||
(TencentUtils.checkString(originalImg?.localUrl) != null &&
|
|
||||||
File((originalImg?.localUrl!)!).existsSync())) {
|
|
||||||
return _renderAllImage(
|
|
||||||
smallLocalPath: smallImg?.localUrl ?? "",
|
|
||||||
heroTag: heroTag,
|
|
||||||
theme: theme,
|
|
||||||
originLocalPath: originalImg?.localUrl);
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// ignore: avoid_print
|
// ignore: avoid_print
|
||||||
outputLogger.i(e);
|
outputLogger.i(e);
|
||||||
return _renderAllImage(
|
return _renderAllImage(heroTag: heroTag, theme: theme, isNetworkImage: true, smallImg: smallImg, originalImg: originalImg);
|
||||||
heroTag: heroTag,
|
|
||||||
theme: theme,
|
|
||||||
isNetworkImage: true,
|
|
||||||
smallImg: smallImg,
|
|
||||||
originalImg: originalImg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((smallImg?.url ?? originalImg?.url) != null &&
|
if ((smallImg?.url ?? originalImg?.url) != null && (smallImg?.url ?? originalImg?.url)!.isNotEmpty) {
|
||||||
(smallImg?.url ?? originalImg?.url)!.isNotEmpty) {
|
return _renderAllImage(heroTag: heroTag, theme: theme, isNetworkImage: true, smallImg: smallImg, originalImg: originalImg);
|
||||||
return _renderAllImage(
|
|
||||||
heroTag: heroTag,
|
|
||||||
theme: theme,
|
|
||||||
isNetworkImage: true,
|
|
||||||
smallImg: smallImg,
|
|
||||||
originalImg: originalImg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return errorDisplay(context, theme);
|
return errorDisplay(context, theme);
|
||||||
|
|
@ -640,10 +487,8 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
||||||
if (widget.message.status == MessageStatus.V2TIM_MSG_STATUS_SENDING) {
|
if (widget.message.status == MessageStatus.V2TIM_MSG_STATUS_SENDING) {
|
||||||
isSent = true;
|
isSent = true;
|
||||||
}
|
}
|
||||||
final isDesktopScreen =
|
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
final heroTag = "${widget.message.msgID ?? widget.message.id ?? widget.message.timestamp ?? DateTime.now().millisecondsSinceEpoch}${widget.isFrom}";
|
||||||
final heroTag =
|
|
||||||
"${widget.message.msgID ?? widget.message.id ?? widget.message.timestamp ?? DateTime.now().millisecondsSinceEpoch}${widget.isFrom}";
|
|
||||||
|
|
||||||
V2TimImage? originalImg = getImageFromList(V2TimImageTypesEnum.original);
|
V2TimImage? originalImg = getImageFromList(V2TimImageTypesEnum.original);
|
||||||
V2TimImage? smallImg = getImageFromList(V2TimImageTypesEnum.small);
|
V2TimImage? smallImg = getImageFromList(V2TimImageTypesEnum.small);
|
||||||
|
|
@ -654,16 +499,14 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
||||||
isFromSelf: widget.message.isSelf ?? true,
|
isFromSelf: widget.message.isSelf ?? true,
|
||||||
isShowMessageReaction: widget.isShowMessageReaction ?? true,
|
isShowMessageReaction: widget.isShowMessageReaction ?? true,
|
||||||
message: widget.message,
|
message: widget.message,
|
||||||
child: LayoutBuilder(
|
child: LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
|
||||||
builder: (BuildContext context, BoxConstraints constraints) {
|
|
||||||
return ConstrainedBox(
|
return ConstrainedBox(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
maxWidth: constraints.maxWidth * (isDesktopScreen ? 0.4 : 0.5),
|
maxWidth: constraints.maxWidth * (isDesktopScreen ? 0.4 : 0.5),
|
||||||
minWidth: 64,
|
minWidth: 64,
|
||||||
maxHeight: 256,
|
maxHeight: 256,
|
||||||
),
|
),
|
||||||
child: _renderImage(heroTag, theme,
|
child: _renderImage(heroTag, theme, originalImg: originalImg, smallImg: smallImg),
|
||||||
originalImg: originalImg, smallImg: smallImg),
|
|
||||||
);
|
);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
@ -672,9 +515,7 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
||||||
class ImageClipper extends CustomClipper<RRect> {
|
class ImageClipper extends CustomClipper<RRect> {
|
||||||
@override
|
@override
|
||||||
RRect getClip(Size size) {
|
RRect getClip(Size size) {
|
||||||
return RRect.fromRectAndRadius(
|
return RRect.fromRectAndRadius(Rect.fromLTWH(0, 0, size.width, min(size.height, 256)), const Radius.circular(5));
|
||||||
Rect.fromLTWH(0, 0, size.width, min(size.height, 256)),
|
|
||||||
const Radius.circular(5));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:provider/single_child_widget.dart';
|
import 'package:provider/single_child_widget.dart';
|
||||||
import 'package:scroll_to_index/scroll_to_index.dart';
|
import 'package:scroll_to_index/scroll_to_index.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/base_widgets/tim_ui_kit_state.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/chat_life_cycle.dart';
|
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/chat_life_cycle.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/business_logic/listener_model/tui_group_listener_model.dart';
|
import 'package:tencent_cloud_chat_uikit/business_logic/listener_model/tui_group_listener_model.dart';
|
||||||
|
|
@ -24,10 +25,10 @@ import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/at_member_panel.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/at_member_panel.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/tim_uikit_multi_select_panel.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/tim_uikit_multi_select_panel.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/tim_uikit_send_file.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/tim_uikit_send_file.dart';
|
||||||
|
|
||||||
import 'TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue.dart';
|
import 'TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue.dart';
|
||||||
import 'TIMUIKItMessageList/tim_uikit_chat_history_message_list_config.dart';
|
import 'TIMUIKItMessageList/tim_uikit_chat_history_message_list_config.dart';
|
||||||
import 'TIMUIKItMessageList/tim_uikit_history_message_list_container.dart';
|
import 'TIMUIKItMessageList/tim_uikit_history_message_list_container.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
|
||||||
|
|
||||||
class TIMUIKitChat extends StatefulWidget {
|
class TIMUIKitChat extends StatefulWidget {
|
||||||
int startTime = 0;
|
int startTime = 0;
|
||||||
|
|
@ -53,8 +54,7 @@ class TIMUIKitChat extends StatefulWidget {
|
||||||
final ConvType? conversationType;
|
final ConvType? conversationType;
|
||||||
|
|
||||||
/// use for customize avatar
|
/// use for customize avatar
|
||||||
final Widget Function(BuildContext context, V2TimMessage message)?
|
final Widget Function(BuildContext context, V2TimMessage message)? userAvatarBuilder;
|
||||||
userAvatarBuilder;
|
|
||||||
|
|
||||||
/// Use for show conversation name.
|
/// Use for show conversation name.
|
||||||
/// This field is not necessary to be provided, when `conversation` is provided, unless you want to cover this field manually.
|
/// This field is not necessary to be provided, when `conversation` is provided, unless you want to cover this field manually.
|
||||||
|
|
@ -64,11 +64,9 @@ class TIMUIKitChat extends StatefulWidget {
|
||||||
final void Function(String userID, TapDownDetails tapDetails)? onTapAvatar;
|
final void Function(String userID, TapDownDetails tapDetails)? onTapAvatar;
|
||||||
|
|
||||||
/// Avatar and name in message reaction secondary tap callback.
|
/// Avatar and name in message reaction secondary tap callback.
|
||||||
final void Function(String userID, TapDownDetails tapDetails)?
|
final void Function(String userID, TapDownDetails tapDetails)? onSecondaryTapAvatar;
|
||||||
onSecondaryTapAvatar;
|
|
||||||
|
|
||||||
@Deprecated(
|
@Deprecated("Nickname will not shows in one-to-one chat, if you tend to control it in group chat, please use `isShowSelfNameInGroup` and `isShowOthersNameInGroup` from `config: TIMUIKitChatConfig` instead")
|
||||||
"Nickname will not shows in one-to-one chat, if you tend to control it in group chat, please use `isShowSelfNameInGroup` and `isShowOthersNameInGroup` from `config: TIMUIKitChatConfig` instead")
|
|
||||||
|
|
||||||
/// Should show the nick name.
|
/// Should show the nick name.
|
||||||
final bool showNickName;
|
final bool showNickName;
|
||||||
|
|
@ -80,12 +78,10 @@ class TIMUIKitChat extends StatefulWidget {
|
||||||
final bool showTotalUnReadCount;
|
final bool showTotalUnReadCount;
|
||||||
|
|
||||||
/// Deprecated("Please use [extraTipsActionItemBuilder] instead")
|
/// Deprecated("Please use [extraTipsActionItemBuilder] instead")
|
||||||
final Widget? Function(V2TimMessage message, Function() closeTooltip,
|
final Widget? Function(V2TimMessage message, Function() closeTooltip, [Key? key, BuildContext? context])? exteraTipsActionItemBuilder;
|
||||||
[Key? key, BuildContext? context])? exteraTipsActionItemBuilder;
|
|
||||||
|
|
||||||
/// The builder for extra tips action.
|
/// The builder for extra tips action.
|
||||||
final Widget? Function(V2TimMessage message, Function() closeTooltip,
|
final Widget? Function(V2TimMessage message, Function() closeTooltip, [Key? key, BuildContext? context])? extraTipsActionItemBuilder;
|
||||||
[Key? key, BuildContext? context])? extraTipsActionItemBuilder;
|
|
||||||
|
|
||||||
/// The text of draft shows in TextField.
|
/// The text of draft shows in TextField.
|
||||||
/// [Recommend]: You can specify this field with the draftText from V2TimConversation.
|
/// [Recommend]: You can specify this field with the draftText from V2TimConversation.
|
||||||
|
|
@ -176,13 +172,10 @@ class TIMUIKitChat extends StatefulWidget {
|
||||||
this.conversationShowName,
|
this.conversationShowName,
|
||||||
this.abstractMessageBuilder,
|
this.abstractMessageBuilder,
|
||||||
this.onTapAvatar,
|
this.onTapAvatar,
|
||||||
@Deprecated(
|
@Deprecated("Nickname will not show in one-to-one chat, if you tend to control it in group chat, please use `isShowSelfNameInGroup` and `isShowOthersNameInGroup` from `config: TIMUIKitChatConfig` instead") this.showNickName = false,
|
||||||
"Nickname will not show in one-to-one chat, if you tend to control it in group chat, please use `isShowSelfNameInGroup` and `isShowOthersNameInGroup` from `config: TIMUIKitChatConfig` instead")
|
|
||||||
this.showNickName = false,
|
|
||||||
this.showTotalUnReadCount = false,
|
this.showTotalUnReadCount = false,
|
||||||
this.messageItemBuilder,
|
this.messageItemBuilder,
|
||||||
@Deprecated("Please use [extraTipsActionItemBuilder] instead")
|
@Deprecated("Please use [extraTipsActionItemBuilder] instead") this.exteraTipsActionItemBuilder,
|
||||||
this.exteraTipsActionItemBuilder,
|
|
||||||
this.extraTipsActionItemBuilder,
|
this.extraTipsActionItemBuilder,
|
||||||
this.draftText,
|
this.draftText,
|
||||||
this.textFieldHintText,
|
this.textFieldHintText,
|
||||||
|
|
@ -216,30 +209,24 @@ class TIMUIKitChat extends StatefulWidget {
|
||||||
|
|
||||||
class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
||||||
TUIChatSeparateViewModel model = TUIChatSeparateViewModel();
|
TUIChatSeparateViewModel model = TUIChatSeparateViewModel();
|
||||||
final TUISelfInfoViewModel selfInfoViewModel =
|
final TUISelfInfoViewModel selfInfoViewModel = serviceLocator<TUISelfInfoViewModel>();
|
||||||
serviceLocator<TUISelfInfoViewModel>();
|
|
||||||
final TUIThemeViewModel themeViewModel = serviceLocator<TUIThemeViewModel>();
|
final TUIThemeViewModel themeViewModel = serviceLocator<TUIThemeViewModel>();
|
||||||
final TUIConversationViewModel conversationViewModel =
|
final TUIConversationViewModel conversationViewModel = serviceLocator<TUIConversationViewModel>();
|
||||||
serviceLocator<TUIConversationViewModel>();
|
TIMUIKitInputTextFieldController textFieldController = TIMUIKitInputTextFieldController();
|
||||||
TIMUIKitInputTextFieldController textFieldController =
|
|
||||||
TIMUIKitInputTextFieldController();
|
|
||||||
bool isInit = false;
|
bool isInit = false;
|
||||||
final TUIChatGlobalModel chatGlobalModel =
|
final TUIChatGlobalModel chatGlobalModel = serviceLocator<TUIChatGlobalModel>();
|
||||||
serviceLocator<TUIChatGlobalModel>();
|
|
||||||
bool _dragging = false;
|
bool _dragging = false;
|
||||||
|
|
||||||
final GlobalKey alignKey = GlobalKey();
|
final GlobalKey alignKey = GlobalKey();
|
||||||
final GlobalKey listContainerKey = GlobalKey();
|
final GlobalKey listContainerKey = GlobalKey();
|
||||||
|
|
||||||
late AutoScrollController autoController = AutoScrollController(
|
late AutoScrollController autoController = AutoScrollController(
|
||||||
viewportBoundaryGetter: () =>
|
viewportBoundaryGetter: () => Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom),
|
||||||
Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom),
|
|
||||||
axis: Axis.vertical,
|
axis: Axis.vertical,
|
||||||
);
|
);
|
||||||
|
|
||||||
late AutoScrollController atMemberPanelScroll = AutoScrollController(
|
late AutoScrollController atMemberPanelScroll = AutoScrollController(
|
||||||
viewportBoundaryGetter: () =>
|
viewportBoundaryGetter: () => Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom),
|
||||||
Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom),
|
|
||||||
axis: Axis.vertical,
|
axis: Axis.vertical,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -304,11 +291,7 @@ class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
||||||
updateDraft() async {
|
updateDraft() async {
|
||||||
final isTopic = widget.conversation.conversationID.contains("@TOPIC#");
|
final isTopic = widget.conversation.conversationID.contains("@TOPIC#");
|
||||||
if (isTopic) {
|
if (isTopic) {
|
||||||
final topicInfoList = await TencentImSDKPlugin.v2TIMManager
|
final topicInfoList = await TencentImSDKPlugin.v2TIMManager.getGroupManager().getTopicInfoList(groupID: widget.groupID!, topicIDList: [widget.conversation.conversationID]);
|
||||||
.getGroupManager()
|
|
||||||
.getTopicInfoList(
|
|
||||||
groupID: widget.groupID!,
|
|
||||||
topicIDList: [widget.conversation.conversationID]);
|
|
||||||
final topicInfo = topicInfoList.data?.first.topicInfo;
|
final topicInfo = topicInfoList.data?.first.topicInfo;
|
||||||
final draftText = topicInfo?.draftText;
|
final draftText = topicInfo?.draftText;
|
||||||
if (TencentUtils.checkString(draftText) != null) {
|
if (TencentUtils.checkString(draftText) != null) {
|
||||||
|
|
@ -333,8 +316,7 @@ class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
TIM_t_para("{{option1}} 条入群请求", "$option1 条入群请求")(
|
TIM_t_para("{{option1}} 条入群请求", "$option1 条入群请求")(option1: option1),
|
||||||
option1: option1),
|
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
),
|
),
|
||||||
|
|
@ -353,17 +335,11 @@ class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
||||||
}
|
}
|
||||||
|
|
||||||
String _getTitle() {
|
String _getTitle() {
|
||||||
return TencentUtils.checkString(widget.conversationShowName) ??
|
return TencentUtils.checkString(widget.conversationShowName) ?? widget.conversation.showName ?? "Chat";
|
||||||
widget.conversation.showName ??
|
|
||||||
"Chat";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String _getConvID() {
|
String _getConvID() {
|
||||||
return TencentUtils.checkString(widget.conversationID) ??
|
return TencentUtils.checkString(widget.conversationID) ?? (widget.conversation.type == 1 ? widget.conversation.userID : widget.conversation.groupID) ?? "";
|
||||||
(widget.conversation.type == 1
|
|
||||||
? widget.conversation.userID
|
|
||||||
: widget.conversation.groupID) ??
|
|
||||||
"";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConvType _getConvType() {
|
ConvType _getConvType() {
|
||||||
|
|
@ -373,8 +349,7 @@ class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
||||||
@override
|
@override
|
||||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||||
final TUITheme theme = value.theme;
|
final TUITheme theme = value.theme;
|
||||||
final closePanel =
|
final closePanel = OptimizeUtils.throttle((_) => textFieldController.hideAllPanel(), 60);
|
||||||
OptimizeUtils.throttle((_) => textFieldController.hideAllPanel(), 60);
|
|
||||||
final isBuild = isInit;
|
final isBuild = isInit;
|
||||||
isInit = true;
|
isInit = true;
|
||||||
|
|
||||||
|
|
@ -393,28 +368,22 @@ class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
||||||
Provider(create: (_) => widget.config),
|
Provider(create: (_) => widget.config),
|
||||||
],
|
],
|
||||||
builder: (context, model, w) {
|
builder: (context, model, w) {
|
||||||
final TUIChatGlobalModel chatGlobalModel =
|
final TUIChatGlobalModel chatGlobalModel = Provider.of<TUIChatGlobalModel>(context, listen: true);
|
||||||
Provider.of<TUIChatGlobalModel>(context, listen: true);
|
|
||||||
|
|
||||||
widget.controller?.model = model;
|
widget.controller?.model = model;
|
||||||
widget.controller?.textFieldController = textFieldController;
|
widget.controller?.textFieldController = textFieldController;
|
||||||
widget.controller?.scrollController = autoController;
|
widget.controller?.scrollController = autoController;
|
||||||
List<V2TimGroupApplication> filteredApplicationList = [];
|
List<V2TimGroupApplication> filteredApplicationList = [];
|
||||||
if (widget.conversationType == ConvType.group &&
|
if (widget.conversationType == ConvType.group && widget.onDealWithGroupApplication != null) {
|
||||||
widget.onDealWithGroupApplication != null) {
|
filteredApplicationList = chatGlobalModel.groupApplicationList.where((item) {
|
||||||
filteredApplicationList =
|
return (item.groupID == widget.conversationID) && item.handleStatus == 0;
|
||||||
chatGlobalModel.groupApplicationList.where((item) {
|
|
||||||
return (item.groupID == widget.conversationID) &&
|
|
||||||
item.handleStatus == 0;
|
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
final selfUserID = selfInfoViewModel.loginInfo?.userID;
|
final selfUserID = selfInfoViewModel.loginInfo?.userID;
|
||||||
final TUIGroupListenerModel groupListenerModel =
|
final TUIGroupListenerModel groupListenerModel = Provider.of<TUIGroupListenerModel>(context, listen: true);
|
||||||
Provider.of<TUIGroupListenerModel>(context, listen: true);
|
|
||||||
final NeedUpdate? needUpdate = groupListenerModel.needUpdate;
|
final NeedUpdate? needUpdate = groupListenerModel.needUpdate;
|
||||||
if (needUpdate != null &&
|
if (needUpdate != null && needUpdate.groupID == widget.conversationID) {
|
||||||
needUpdate.groupID == widget.conversationID) {
|
|
||||||
groupListenerModel.needUpdate = null;
|
groupListenerModel.needUpdate = null;
|
||||||
switch (needUpdate.updateType) {
|
switch (needUpdate.updateType) {
|
||||||
case UpdateType.groupInfo:
|
case UpdateType.groupInfo:
|
||||||
|
|
@ -432,24 +401,13 @@ class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
||||||
}
|
}
|
||||||
|
|
||||||
List<CustomEmojiFaceData> customImageSmallPngEmojiPackages = [];
|
List<CustomEmojiFaceData> customImageSmallPngEmojiPackages = [];
|
||||||
if (widget.config?.stickerPanelConfig?.customStickerPackages !=
|
if (widget.config?.stickerPanelConfig?.customStickerPackages != null && widget.config!.stickerPanelConfig!.customStickerPackages.isNotEmpty) {
|
||||||
null &&
|
customImageSmallPngEmojiPackages = widget.config!.stickerPanelConfig!.customStickerPackages.where((element) => element.isEmoji == true).map((e) {
|
||||||
widget.config!.stickerPanelConfig!.customStickerPackages
|
return CustomEmojiFaceData(name: e.name, isEmoji: true, icon: e.menuItem.url ?? "", list: e.stickerList.map((e) => e.url ?? "").toList());
|
||||||
.isNotEmpty) {
|
|
||||||
customImageSmallPngEmojiPackages = widget
|
|
||||||
.config!.stickerPanelConfig!.customStickerPackages
|
|
||||||
.where((element) => element.isEmoji == true)
|
|
||||||
.map((e) {
|
|
||||||
return CustomEmojiFaceData(
|
|
||||||
name: e.name,
|
|
||||||
isEmoji: true,
|
|
||||||
icon: e.menuItem.url ?? "",
|
|
||||||
list: e.stickerList.map((e) => e.url ?? "").toList());
|
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
if (customImageSmallPngEmojiPackages.isEmpty) {
|
if (customImageSmallPngEmojiPackages.isEmpty) {
|
||||||
customImageSmallPngEmojiPackages
|
customImageSmallPngEmojiPackages.addAll(widget.customEmojiStickerList);
|
||||||
.addAll(widget.customEmojiStickerList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
|
|
@ -464,21 +422,14 @@ class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
||||||
config: widget.appBarConfig,
|
config: widget.appBarConfig,
|
||||||
conversationShowName: _getTitle(),
|
conversationShowName: _getTitle(),
|
||||||
conversationID: _getConvID(),
|
conversationID: _getConvID(),
|
||||||
showC2cMessageEditStatus:
|
showC2cMessageEditStatus: widget.config?.showC2cMessageEditStatus ?? true,
|
||||||
widget.config?.showC2cMessageEditStatus ?? true,
|
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
body: DropTarget(
|
body: DropTarget(
|
||||||
onDragDone: (detail) {
|
onDragDone: (detail) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_dragging = false;
|
_dragging = false;
|
||||||
sendFileWithConfirmation(
|
sendFileWithConfirmation(files: detail.files, conversation: widget.conversation, conversationType: _getConvType(), model: model, theme: theme, context: context);
|
||||||
files: detail.files,
|
|
||||||
conversation: widget.conversation,
|
|
||||||
conversationType: _getConvType(),
|
|
||||||
model: model,
|
|
||||||
theme: theme,
|
|
||||||
context: context);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onDragEntered: (detail) {
|
onDragEntered: (detail) {
|
||||||
|
|
@ -497,9 +448,7 @@ class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
if (widget.customAppBar != null) widget.customAppBar!,
|
if (widget.customAppBar != null) widget.customAppBar!,
|
||||||
if (filteredApplicationList.isNotEmpty)
|
if (filteredApplicationList.isNotEmpty) _renderJoinGroupApplication(filteredApplicationList.length, theme),
|
||||||
_renderJoinGroupApplication(
|
|
||||||
filteredApplicationList.length, theme),
|
|
||||||
if (widget.topFixWidget != null) widget.topFixWidget!,
|
if (widget.topFixWidget != null) widget.topFixWidget!,
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
|
|
@ -510,45 +459,31 @@ class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
||||||
child: Listener(
|
child: Listener(
|
||||||
onPointerMove: closePanel,
|
onPointerMove: closePanel,
|
||||||
child: TIMUIKitHistoryMessageListContainer(
|
child: TIMUIKitHistoryMessageListContainer(
|
||||||
customMessageHoverBarOnDesktop:
|
customMessageHoverBarOnDesktop: widget.customMessageHoverBarOnDesktop,
|
||||||
widget.customMessageHoverBarOnDesktop,
|
|
||||||
conversation: widget.conversation,
|
conversation: widget.conversation,
|
||||||
groupMemberInfo: model.groupMemberList
|
groupMemberInfo: model.groupMemberList?.firstWhere((element) => element?.userID == selfUserID, orElse: () => null),
|
||||||
?.firstWhere(
|
|
||||||
(element) =>
|
|
||||||
element?.userID == selfUserID,
|
|
||||||
orElse: () => null),
|
|
||||||
textFieldController: textFieldController,
|
textFieldController: textFieldController,
|
||||||
customEmojiStickerList:
|
customEmojiStickerList: widget.customEmojiStickerList,
|
||||||
widget.customEmojiStickerList,
|
isUseDefaultEmoji: widget.config!.isUseDefaultEmoji,
|
||||||
isUseDefaultEmoji:
|
|
||||||
widget.config!.isUseDefaultEmoji,
|
|
||||||
key: listContainerKey,
|
key: listContainerKey,
|
||||||
isAllowScroll: true,
|
isAllowScroll: true,
|
||||||
userAvatarBuilder: widget.userAvatarBuilder,
|
userAvatarBuilder: widget.userAvatarBuilder,
|
||||||
toolTipsConfig: widget.toolTipsConfig,
|
toolTipsConfig: widget.toolTipsConfig,
|
||||||
groupAtInfoList: widget.groupAtInfoList,
|
groupAtInfoList: widget.groupAtInfoList,
|
||||||
tongueItemBuilder: widget.tongueItemBuilder,
|
tongueItemBuilder: widget.tongueItemBuilder,
|
||||||
onLongPressForOthersHeadPortrait:
|
onLongPressForOthersHeadPortrait: (String? userId, String? nickName) {
|
||||||
(String? userId, String? nickName) {
|
textFieldController.longPressToAt(nickName, userId);
|
||||||
textFieldController.longPressToAt(
|
|
||||||
nickName, userId);
|
|
||||||
},
|
},
|
||||||
mainHistoryListConfig:
|
mainHistoryListConfig: widget.mainHistoryListConfig,
|
||||||
widget.mainHistoryListConfig,
|
|
||||||
initFindingMsg: widget.initFindingMsg,
|
initFindingMsg: widget.initFindingMsg,
|
||||||
extraTipsActionItemBuilder:
|
extraTipsActionItemBuilder: widget.extraTipsActionItemBuilder ?? widget.exteraTipsActionItemBuilder,
|
||||||
widget.extraTipsActionItemBuilder ??
|
|
||||||
widget.exteraTipsActionItemBuilder,
|
|
||||||
conversationType: _getConvType(),
|
conversationType: _getConvType(),
|
||||||
scrollController: autoController,
|
scrollController: autoController,
|
||||||
onSecondaryTapAvatar:
|
onSecondaryTapAvatar: widget.onSecondaryTapAvatar,
|
||||||
widget.onSecondaryTapAvatar,
|
|
||||||
onTapAvatar: widget.onTapAvatar,
|
onTapAvatar: widget.onTapAvatar,
|
||||||
// ignore: deprecated_member_use_from_same_package
|
// ignore: deprecated_member_use_from_same_package
|
||||||
showNickName: widget.showNickName,
|
showNickName: widget.showNickName,
|
||||||
messageItemBuilder:
|
messageItemBuilder: widget.messageItemBuilder,
|
||||||
widget.messageItemBuilder,
|
|
||||||
conversationID: _getConvID(),
|
conversationID: _getConvID(),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
|
|
@ -565,47 +500,26 @@ class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
||||||
: TIMUIKitInputTextField(
|
: TIMUIKitInputTextField(
|
||||||
chatConfig: widget.config,
|
chatConfig: widget.config,
|
||||||
groupID: widget.groupID,
|
groupID: widget.groupID,
|
||||||
atMemberPanelScroll:
|
atMemberPanelScroll: atMemberPanelScroll,
|
||||||
atMemberPanelScroll,
|
groupType: widget.conversation.groupType,
|
||||||
groupType:
|
currentConversation: widget.conversation,
|
||||||
widget.conversation.groupType,
|
|
||||||
currentConversation:
|
|
||||||
widget.conversation,
|
|
||||||
model: model,
|
model: model,
|
||||||
controller: textFieldController,
|
controller: textFieldController,
|
||||||
customEmojiStickerList:
|
customEmojiStickerList: customImageSmallPngEmojiPackages,
|
||||||
customImageSmallPngEmojiPackages,
|
isUseDefaultEmoji: widget.config!.isUseDefaultEmoji,
|
||||||
isUseDefaultEmoji:
|
customStickerPanel: widget.customStickerPanel,
|
||||||
widget.config!.isUseDefaultEmoji,
|
morePanelConfig: widget.morePanelConfig,
|
||||||
customStickerPanel:
|
|
||||||
widget.customStickerPanel,
|
|
||||||
morePanelConfig:
|
|
||||||
widget.morePanelConfig,
|
|
||||||
scrollController: autoController,
|
scrollController: autoController,
|
||||||
conversationID: _getConvID(),
|
conversationID: _getConvID(),
|
||||||
conversationType: _getConvType(),
|
conversationType: _getConvType(),
|
||||||
initText: TencentUtils.checkString(
|
initText: TencentUtils.checkString(widget.draftText) ??
|
||||||
widget.draftText) ??
|
|
||||||
(PlatformUtils().isWeb
|
(PlatformUtils().isWeb
|
||||||
? TencentUtils.checkString(
|
? TencentUtils.checkString(conversationViewModel.getWebDraft(conversationID: widget.conversation.conversationID))
|
||||||
conversationViewModel
|
: TencentUtils.checkString(widget.conversation.draftText)),
|
||||||
.getWebDraft(
|
|
||||||
conversationID: widget
|
|
||||||
.conversation
|
|
||||||
.conversationID))
|
|
||||||
: TencentUtils.checkString(
|
|
||||||
widget.conversation
|
|
||||||
.draftText)),
|
|
||||||
hintText: widget.textFieldHintText,
|
hintText: widget.textFieldHintText,
|
||||||
showMorePanel: widget.config
|
showMorePanel: widget.config?.isAllowShowMorePanel ?? true,
|
||||||
?.isAllowShowMorePanel ??
|
showSendAudio: widget.config?.isAllowSoundMessage ?? true,
|
||||||
true,
|
showSendEmoji: widget.config?.isAllowEmojiPanel ?? true,
|
||||||
showSendAudio: widget.config
|
|
||||||
?.isAllowSoundMessage ??
|
|
||||||
true,
|
|
||||||
showSendEmoji: widget
|
|
||||||
.config?.isAllowEmojiPanel ??
|
|
||||||
true,
|
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
selector: (c, model) {
|
selector: (c, model) {
|
||||||
|
|
@ -620,8 +534,7 @@ class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
||||||
),
|
),
|
||||||
AtMemberPanel(
|
AtMemberPanel(
|
||||||
atMemberPanelScroll: atMemberPanelScroll,
|
atMemberPanelScroll: atMemberPanelScroll,
|
||||||
onSelectMember: (member) =>
|
onSelectMember: (member) => textFieldController.handleAtMember(member),
|
||||||
textFieldController.handleAtMember(member),
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -634,14 +547,12 @@ class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
||||||
class TIMUIKitChatProviderScope extends StatelessWidget {
|
class TIMUIKitChatProviderScope extends StatelessWidget {
|
||||||
final TUIChatGlobalModel globalModel = serviceLocator<TUIChatGlobalModel>();
|
final TUIChatGlobalModel globalModel = serviceLocator<TUIChatGlobalModel>();
|
||||||
TUIChatSeparateViewModel? model;
|
TUIChatSeparateViewModel? model;
|
||||||
final TUIGroupListenerModel groupListenerModel =
|
final TUIGroupListenerModel groupListenerModel = serviceLocator<TUIGroupListenerModel>();
|
||||||
serviceLocator<TUIGroupListenerModel>();
|
|
||||||
final TUIThemeViewModel themeViewModel = serviceLocator<TUIThemeViewModel>();
|
final TUIThemeViewModel themeViewModel = serviceLocator<TUIThemeViewModel>();
|
||||||
final Widget? child;
|
final Widget? child;
|
||||||
|
|
||||||
/// You could get the model from here, and transfer it to other widget from TUIKit.
|
/// You could get the model from here, and transfer it to other widget from TUIKit.
|
||||||
final Widget Function(BuildContext, TUIChatSeparateViewModel, Widget?)
|
final Widget Function(BuildContext, TUIChatSeparateViewModel, Widget?) builder;
|
||||||
builder;
|
|
||||||
final List<SingleChildWidget>? providers;
|
final List<SingleChildWidget>? providers;
|
||||||
|
|
||||||
/// `TIMUIKitChatController` needs to be provided if you use it outside.
|
/// `TIMUIKitChatController` needs to be provided if you use it outside.
|
||||||
|
|
@ -712,16 +623,13 @@ class TIMUIKitChatProviderScope extends StatelessWidget {
|
||||||
preGroupMemberList: groupMemberList,
|
preGroupMemberList: groupMemberList,
|
||||||
groupID: groupID,
|
groupID: groupID,
|
||||||
);
|
);
|
||||||
model?.showC2cMessageEditStatus = (conversationType == ConvType.c2c
|
model?.showC2cMessageEditStatus = (conversationType == ConvType.c2c ? config?.showC2cMessageEditStatus ?? true : false);
|
||||||
? config?.showC2cMessageEditStatus ?? true
|
|
||||||
: false);
|
|
||||||
loadData();
|
loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
loadData() {
|
loadData() {
|
||||||
// if (model!.haveMoreData) {
|
// if (model!.haveMoreData) {
|
||||||
model!.loadChatRecord(
|
model!.loadChatRecord(count: kIsWeb ? 15 : HistoryMessageDartConstant.getCount);
|
||||||
count: kIsWeb ? 15 : HistoryMessageDartConstant.getCount);
|
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -245,7 +245,7 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
||||||
},
|
},
|
||||||
backgroundColor: theme.conversationItemSliderClearBgColor ?? CommonColor.primaryColor,
|
backgroundColor: theme.conversationItemSliderClearBgColor ?? CommonColor.primaryColor,
|
||||||
foregroundColor: theme.conversationItemSliderTextColor,
|
foregroundColor: theme.conversationItemSliderTextColor,
|
||||||
label: TIM_t("清除聊天"),
|
label: TIM_t("清除"),
|
||||||
spacing: 0,
|
spacing: 0,
|
||||||
autoClose: true,
|
autoClose: true,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,10 @@ import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.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/base_widgets/tim_ui_kit_state.dart';
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart';
|
||||||
|
|
||||||
import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart';
|
import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart';
|
||||||
|
|
||||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
|
||||||
import 'package:tencent_im_base/tencent_im_base.dart';
|
import 'package:tencent_im_base/tencent_im_base.dart';
|
||||||
|
|
||||||
class TIMUIKitLastMsg extends StatefulWidget {
|
class TIMUIKitLastMsg extends StatefulWidget {
|
||||||
|
|
@ -18,13 +16,7 @@ class TIMUIKitLastMsg extends StatefulWidget {
|
||||||
final BuildContext context;
|
final BuildContext context;
|
||||||
final double fontSize;
|
final double fontSize;
|
||||||
|
|
||||||
const TIMUIKitLastMsg(
|
const TIMUIKitLastMsg({Key? key, this.lastMsg, required this.groupAtInfoList, required this.context, this.fontSize = 14.0}) : super(key: key);
|
||||||
{Key? key,
|
|
||||||
this.lastMsg,
|
|
||||||
required this.groupAtInfoList,
|
|
||||||
required this.context,
|
|
||||||
this.fontSize = 14.0})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<TIMUIKitLastMsg> createState() => _TIMUIKitLastMsgState();
|
State<TIMUIKitLastMsg> createState() => _TIMUIKitLastMsgState();
|
||||||
|
|
@ -42,8 +34,7 @@ class _TIMUIKitLastMsgState extends TIMUIKitState<TIMUIKitLastMsg> {
|
||||||
@override
|
@override
|
||||||
void didUpdateWidget(covariant TIMUIKitLastMsg oldWidget) {
|
void didUpdateWidget(covariant TIMUIKitLastMsg oldWidget) {
|
||||||
super.didUpdateWidget(oldWidget);
|
super.didUpdateWidget(oldWidget);
|
||||||
if ((oldWidget.lastMsg?.msgID != widget.lastMsg?.msgID) ||
|
if ((oldWidget.lastMsg?.msgID != widget.lastMsg?.msgID) || (oldWidget.lastMsg?.id != widget.lastMsg?.id) || (oldWidget.lastMsg?.status != widget.lastMsg?.status)) {
|
||||||
(oldWidget.lastMsg?.id != widget.lastMsg?.id)) {
|
|
||||||
_getMsgElem();
|
_getMsgElem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -72,15 +63,10 @@ class _TIMUIKitLastMsgState extends TIMUIKitState<TIMUIKitLastMsg> {
|
||||||
final isAdminRevoke = revokeStatus.$2;
|
final isAdminRevoke = revokeStatus.$2;
|
||||||
if (isRevokedMessage) {
|
if (isRevokedMessage) {
|
||||||
final isSelf = widget.lastMsg!.isSelf ?? true;
|
final isSelf = widget.lastMsg!.isSelf ?? true;
|
||||||
final option1 = isAdminRevoke
|
final option1 = isAdminRevoke ? TIM_t("管理员") : (isSelf ? TIM_t("您") : widget.lastMsg!.nickName ?? widget.lastMsg?.sender);
|
||||||
? TIM_t("管理员")
|
|
||||||
: (isSelf
|
|
||||||
? TIM_t("您")
|
|
||||||
: widget.lastMsg!.nickName ?? widget.lastMsg?.sender);
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
groupTipsAbstractText = TIM_t_para(
|
groupTipsAbstractText = TIM_t_para("{{option1}}撤回了一条消息", "$option1撤回了一条消息")(option1: option1);
|
||||||
"{{option1}}撤回了一条消息", "$option1撤回了一条消息")(option1: option1);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -93,8 +79,7 @@ class _TIMUIKitLastMsgState extends TIMUIKitState<TIMUIKitLastMsg> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> _getLastMsgShowText(
|
Future<String?> _getLastMsgShowText(V2TimMessage? message, BuildContext context) async {
|
||||||
V2TimMessage? message, BuildContext context) async {
|
|
||||||
final msgType = message!.elemType;
|
final msgType = message!.elemType;
|
||||||
switch (msgType) {
|
switch (msgType) {
|
||||||
case MessageElemType.V2TIM_ELEM_TYPE_CUSTOM:
|
case MessageElemType.V2TIM_ELEM_TYPE_CUSTOM:
|
||||||
|
|
@ -107,11 +92,9 @@ class _TIMUIKitLastMsgState extends TIMUIKitState<TIMUIKitLastMsg> {
|
||||||
return TIM_t("[表情]");
|
return TIM_t("[表情]");
|
||||||
case MessageElemType.V2TIM_ELEM_TYPE_FILE:
|
case MessageElemType.V2TIM_ELEM_TYPE_FILE:
|
||||||
final option1 = widget.lastMsg!.fileElem!.fileName;
|
final option1 = widget.lastMsg!.fileElem!.fileName;
|
||||||
return TIM_t_para("[文件] {{option1}}", "[文件] $option1")(
|
return TIM_t_para("[文件] {{option1}}", "[文件] $option1")(option1: option1);
|
||||||
option1: option1);
|
|
||||||
case MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS:
|
case MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS:
|
||||||
return await MessageUtils.groupTipsMessageAbstract(
|
return await MessageUtils.groupTipsMessageAbstract(widget.lastMsg!.groupTipsElem!, []);
|
||||||
widget.lastMsg!.groupTipsElem!, []);
|
|
||||||
case MessageElemType.V2TIM_ELEM_TYPE_IMAGE:
|
case MessageElemType.V2TIM_ELEM_TYPE_IMAGE:
|
||||||
return TIM_t("[图片]");
|
return TIM_t("[图片]");
|
||||||
case MessageElemType.V2TIM_ELEM_TYPE_VIDEO:
|
case MessageElemType.V2TIM_ELEM_TYPE_VIDEO:
|
||||||
|
|
@ -159,18 +142,15 @@ class _TIMUIKitLastMsgState extends TIMUIKitState<TIMUIKitLastMsg> {
|
||||||
margin: const EdgeInsets.only(right: 2),
|
margin: const EdgeInsets.only(right: 2),
|
||||||
child: icon,
|
child: icon,
|
||||||
),
|
),
|
||||||
if (widget.groupAtInfoList.isNotEmpty)
|
if (widget.groupAtInfoList.isNotEmpty) Text(_getAtMessage(), style: TextStyle(color: theme.cautionColor, fontSize: widget.fontSize)),
|
||||||
Text(_getAtMessage(),
|
if (TencentUtils.checkString(groupTipsAbstractText) != null)
|
||||||
style: TextStyle(
|
Expanded(
|
||||||
color: theme.cautionColor, fontSize: widget.fontSize)),
|
|
||||||
if(TencentUtils.checkString(groupTipsAbstractText) != null)Expanded(
|
|
||||||
child: Text(
|
child: Text(
|
||||||
groupTipsAbstractText,
|
groupTipsAbstractText,
|
||||||
softWrap: true,
|
softWrap: true,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: TextStyle(
|
style: TextStyle(height: 1, color: theme.weakTextColor, fontSize: widget.fontSize),
|
||||||
height: 1, color: theme.weakTextColor, fontSize: widget.fontSize),
|
|
||||||
)),
|
)),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
56
pubspec.lock
56
pubspec.lock
|
|
@ -851,6 +851,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "1.0.4"
|
||||||
|
mime_type:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: mime_type
|
||||||
|
sha256: "2ad6e67d3d2de9ac0f8ef5352d998fd103cb21351ae8c02fb0c78b079b37d275"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
nested:
|
nested:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -935,50 +943,50 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: path_provider
|
name: path_provider
|
||||||
sha256: "3087813781ab814e4157b172f1a11c46be20179fcc9bea043e0fba36bc0acaa2"
|
sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.15"
|
version: "2.1.2"
|
||||||
path_provider_android:
|
path_provider_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86"
|
sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.27"
|
version: "2.2.2"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_foundation
|
name: path_provider_foundation
|
||||||
sha256: "1995d88ec2948dac43edf8fe58eb434d35d22a2940ecee1a9fefcd62beee6eb3"
|
sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.3"
|
version: "2.3.2"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_linux
|
name: path_provider_linux
|
||||||
sha256: ffbb8cc9ed2c9ec0e4b7a541e56fd79b138e8f47d2fb86815f15358a349b3b57
|
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.11"
|
version: "2.2.1"
|
||||||
path_provider_platform_interface:
|
path_provider_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_platform_interface
|
name: path_provider_platform_interface
|
||||||
sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec"
|
sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.6"
|
version: "2.1.1"
|
||||||
path_provider_windows:
|
path_provider_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_windows
|
name: path_provider_windows
|
||||||
sha256: "1cb68ba4cd3a795033de62ba1b7b4564dace301f952de6bfb3cd91b202b6ee96"
|
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.7"
|
version: "2.2.1"
|
||||||
permission_handler:
|
permission_handler:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -1292,42 +1300,34 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: tencent_chat_i18n_tool
|
name: tencent_chat_i18n_tool
|
||||||
sha256: "0ee982e814bedd0aea4751b972901c6cfcfb224cfeb8e13ae02e43c0b8a58bbc"
|
sha256: d1e68f06a0cf8372eebd9a6b0f01f57e68b569cf909756ee6bdbbe625688debd
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.0"
|
version: "2.3.0"
|
||||||
tencent_cloud_chat_sdk:
|
tencent_cloud_chat_sdk:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: tencent_cloud_chat_sdk
|
name: tencent_cloud_chat_sdk
|
||||||
sha256: "7dbb354209eca61f2c816c8ba7c1b1282dd5fb7e090135186bde56c89d976110"
|
sha256: a78f1f20dc9ebe40aee1bbb47da097780028434d77e97774fbe733debb21e18e
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.2"
|
version: "7.7.5296"
|
||||||
tencent_cloud_uikit_core:
|
tencent_cloud_uikit_core:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: tencent_cloud_uikit_core
|
name: tencent_cloud_uikit_core
|
||||||
sha256: "5624654c52a230111cbcfcaa648b9c6e3ee877018f16bc5eec076b639655a191"
|
sha256: "7ddb2c034e5f832261ba268957e282b7c2e738acb1d21aa40c62dad4eaa433ea"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.1"
|
version: "1.5.2"
|
||||||
tencent_im_base:
|
tencent_im_base:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: tencent_im_base
|
name: tencent_im_base
|
||||||
sha256: "52a99ef1c9dbd219530cf6f96a9891ab316f789b9b2c11634e0002d0a0f0f63c"
|
sha256: "035d97d24bebb87654700d4afc8227de8721a259ef5d0195f3207cb0eb0cdc7a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.3.775296"
|
||||||
tencent_im_sdk_plugin_platform_interface:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: tencent_im_sdk_plugin_platform_interface
|
|
||||||
sha256: "3b39f19fcc2306c7cbdabe79e532bbb7feade695630f5373308a52703ece482c"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.0"
|
|
||||||
tencent_keyboard_visibility:
|
tencent_keyboard_visibility:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
name: tencent_cloud_chat_uikit
|
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.
|
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.0
|
version: 2.5.1
|
||||||
homepage: https://trtc.io/products/chat?utm_source=gfs&utm_medium=link&utm_campaign=%E6%B8%A0%E9%81%93&_channel_track_key=k6WgfCKn
|
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
|
repository: https://github.com/TencentCloud/chat-uikit-flutter
|
||||||
documentation: https://comm.qq.com/im/doc/flutter/en/TUIKit/readme.html
|
documentation: https://comm.qq.com/im/doc/flutter/en/TUIKit/readme.html
|
||||||
|
|
@ -62,7 +62,7 @@ dependencies:
|
||||||
open_file: ^3.3.2
|
open_file: ^3.3.2
|
||||||
tencent_keyboard_visibility: ^1.0.1
|
tencent_keyboard_visibility: ^1.0.1
|
||||||
tim_ui_kit_sticker_plugin: ^3.1.0
|
tim_ui_kit_sticker_plugin: ^3.1.0
|
||||||
tencent_im_base: ^3.1.0
|
tencent_im_base: ^3.3.775296
|
||||||
fc_native_video_thumbnail: any
|
fc_native_video_thumbnail: any
|
||||||
path: ^1.8.1
|
path: ^1.8.1
|
||||||
tencent_cloud_uikit_core: ^1.2.1
|
tencent_cloud_uikit_core: ^1.2.1
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue