feat: Upgrade to 2.5.1+4
This commit is contained in:
parent
da84ca9bc6
commit
68dc760e32
|
|
@ -3,6 +3,7 @@
|
|||
## Improvements
|
||||
|
||||
* Improved memory usage, enhancing performance.
|
||||
* Improved the logger storage.
|
||||
|
||||
# 2.5.0
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import shared_preferences_foundation
|
|||
import sqflite
|
||||
import tencent_cloud_chat_sdk
|
||||
import url_launcher_macos
|
||||
import wakelock_plus
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
|
||||
|
|
@ -37,4 +38,5 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||
TencentCloudChatSdkPlugin.register(with: registry.registrar(forPlugin: "TencentCloudChatSdkPlugin"))
|
||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,14 +161,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.1"
|
||||
chewie_for_us:
|
||||
chewie:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: chewie_for_us
|
||||
sha256: "0307723e811508d361fffa6f8bbd9040b1bfea5536544e4d655e10c27de002ec"
|
||||
name: chewie
|
||||
sha256: "8bc4ac4cf3f316e50a25958c0f5eb9bb12cf7e8308bb1d74a43b230da2cfc144"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.0"
|
||||
version: "1.7.5"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -241,6 +241,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.10"
|
||||
dbus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dbus
|
||||
sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.10"
|
||||
desktop_drop:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1233,33 +1241,33 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: tencent_cloud_chat_sdk
|
||||
sha256: a78f1f20dc9ebe40aee1bbb47da097780028434d77e97774fbe733debb21e18e
|
||||
sha256: "358e79b51aba5457418d3bb87e0bbd0f088a1eaf4c4463d09bdda93d1d655aa3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.7.5296"
|
||||
version: "7.9.5672"
|
||||
tencent_cloud_chat_uikit:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: ".."
|
||||
relative: true
|
||||
source: path
|
||||
version: "2.5.1"
|
||||
version: "2.5.1+2"
|
||||
tencent_cloud_uikit_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: tencent_cloud_uikit_core
|
||||
sha256: "7ddb2c034e5f832261ba268957e282b7c2e738acb1d21aa40c62dad4eaa433ea"
|
||||
sha256: "61a5400b3fe75c00252272469f332e7ec07f6d1932ee636a3f2b919cf9805cb8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.2"
|
||||
version: "1.6.0"
|
||||
tencent_im_base:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: tencent_im_base
|
||||
sha256: "035d97d24bebb87654700d4afc8227de8721a259ef5d0195f3207cb0eb0cdc7a"
|
||||
sha256: daee1faac70fdf5fa4a53576db4fb7268ba5d897cc036353d3114a31abb76fb1
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.3.775296"
|
||||
version: "3.3.775297"
|
||||
tencent_im_sdk_plugin_desktop:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -1516,22 +1524,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "13.0.0"
|
||||
wakelock_for_us:
|
||||
wakelock_plus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: wakelock_for_us
|
||||
sha256: a5bdd445e51a617f7c24be8165230391447301f622aacd050038cee7b41989b4
|
||||
name: wakelock_plus
|
||||
sha256: f268ca2116db22e57577fb99d52515a24bdc1d570f12ac18bb762361d43b043d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.3+1"
|
||||
wakelock_platform_interface:
|
||||
version: "1.1.4"
|
||||
wakelock_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: wakelock_platform_interface
|
||||
sha256: "1f4aeb81fb592b863da83d2d0f7b8196067451e4df91046c26b54a403f9de621"
|
||||
name: wakelock_plus_platform_interface
|
||||
sha256: "40fabed5da06caff0796dc638e1f07ee395fb18801fbff3255a2372db2d80385"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.0"
|
||||
version: "1.1.0"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@ abstract class DefaultLifeCycle {
|
|||
return message;
|
||||
}
|
||||
|
||||
static Future<V2TimMessage> defaultTwoMessagesSolution(V2TimMessage message, [V2TimMessage? repliedMessage]) async {
|
||||
return message;
|
||||
}
|
||||
|
||||
static Future<List<V2TimMessage>> defaultMessageListSolution(List<V2TimMessage> list) async {
|
||||
return list;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class ChatLifeCycle {
|
|||
|
||||
/// Before a new message will be sent.
|
||||
/// Returns null can block the message from sending.
|
||||
MessageFunction messageWillSend;
|
||||
Future<V2TimMessage?> Function(V2TimMessage message, [V2TimMessage? repliedMessage]) messageWillSend;
|
||||
|
||||
/// After a new message been sent.
|
||||
MessageFunctionNullCallback messageDidSend;
|
||||
|
|
@ -43,7 +43,7 @@ class ChatLifeCycle {
|
|||
this.shouldDeleteMessage = DefaultLifeCycle.defaultAsyncBooleanSolution,
|
||||
this.messageDidSend = DefaultLifeCycle.defaultNullCallbackSolution,
|
||||
this.didGetHistoricalMessageList = DefaultLifeCycle.defaultMessageListSolution,
|
||||
this.messageWillSend = DefaultLifeCycle.defaultMessageSolution,
|
||||
this.messageWillSend = DefaultLifeCycle.defaultTwoMessagesSolution,
|
||||
this.modifiedMessageWillMount = DefaultLifeCycle.defaultMessageSolution,
|
||||
this.newMessageWillMount = DefaultLifeCycle.defaultMessageSolution,
|
||||
this.messageShouldMount = DefaultLifeCycle.defaultBooleanSolution,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -17,7 +17,6 @@ import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
|
|||
import 'package:tencent_cloud_chat_uikit/ui/constants/history_message_constant.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
|
||||
|
||||
enum ConvType { none, c2c, group }
|
||||
|
||||
|
|
@ -504,6 +503,11 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass {
|
|||
}
|
||||
|
||||
_onReceiveNewMsg(V2TimMessage msgComing) async {
|
||||
final convID = TencentUtils.checkString(msgComing.userID) ?? msgComing.groupID;
|
||||
if(convID != currentSelectedConv){
|
||||
return;
|
||||
}
|
||||
|
||||
final V2TimMessage? newMsg = _lifeCycle?.newMessageWillMount != null ? await _lifeCycle?.newMessageWillMount(msgComing) : msgComing;
|
||||
if (newMsg == null) {
|
||||
return;
|
||||
|
|
@ -511,13 +515,12 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass {
|
|||
// check the message is editing status msg. and flutter is only support the latest version
|
||||
bool isEditMessage = _editStatusCheck(msgComing);
|
||||
|
||||
// if the message is edit status message dont up to screen
|
||||
// if the message is edit status message don't up to screen
|
||||
if (isEditMessage) {
|
||||
return;
|
||||
}
|
||||
|
||||
_checkFromUserisActive(msgComing);
|
||||
final convID = TencentUtils.checkString(newMsg.userID) ?? newMsg.groupID;
|
||||
final convType = TencentUtils.checkString(newMsg.groupID) != null ? ConvType.group : ConvType.c2c;
|
||||
if (convID != null && convID == currentSelectedConv) {
|
||||
final position = getMessageListPosition(convID);
|
||||
|
|
@ -557,7 +560,8 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass {
|
|||
}
|
||||
}
|
||||
} else if (convID != null) {
|
||||
final currentMsg = _messageListMap[convID] ?? [];
|
||||
final tempCurrentMsgList = _messageListMap[convID] ?? [];
|
||||
final currentMsg = tempCurrentMsgList..sublist(max(0, (tempCurrentMsgList.length - 20)));
|
||||
_messageListMap[convID] = [newMsg, ...currentMsg];
|
||||
notifyListeners();
|
||||
}
|
||||
|
|
@ -641,6 +645,7 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass {
|
|||
|
||||
Future<void> onMessageDownloadProgressCallback(V2TimMessageDownloadProgress messageProgress) async {
|
||||
final currentProgress = getMessageProgress(messageProgress.msgID);
|
||||
print("onMessageDownloadProgressCallback, ${messageProgress.type} - ${messageProgress.isFinish} - ${messageProgress.currentSize} - $currentProgress - ");
|
||||
|
||||
if (messageProgress.isError || messageProgress.errorCode != 0) {
|
||||
V2TimMessage? message = await _findAndRetrieveMessage(messageProgress.msgID);
|
||||
|
|
@ -666,7 +671,7 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass {
|
|||
if (message != null) {
|
||||
bool isImageType = message.elemType == MessageElemType.V2TIM_ELEM_TYPE_IMAGE;
|
||||
bool isVideoType = message.elemType == MessageElemType.V2TIM_ELEM_TYPE_VIDEO;
|
||||
final originalImageType = PlatformUtils().isIOS ? 1 : 0;
|
||||
const originalImageType = 0;
|
||||
if (!isImageType && !isVideoType) {
|
||||
_updateMessageLocationAndDownloadFile(messageProgress);
|
||||
} else if ((isImageType && messageProgress.type == originalImageType) || (isVideoType && !messageProgress.isSnapshot)) {
|
||||
|
|
|
|||
|
|
@ -119,9 +119,9 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
notifyListeners();
|
||||
}, onSyncServerFinish: () {
|
||||
// Remove the process to load such a many of conversations after launching
|
||||
// if (!PlatformUtils().isWeb) {
|
||||
// loadInitConversation();
|
||||
// }
|
||||
if (!PlatformUtils().isWeb) {
|
||||
loadInitConversation();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,9 +95,6 @@ class CoreServicesImpl implements CoreServices {
|
|||
if (platform != null) {
|
||||
TUIKitScreenUtils.deviceType = platform;
|
||||
}
|
||||
if (TencentUtils.checkString(uikitLogPath) != null) {
|
||||
logOutputGenerator(uikitLogPath!);
|
||||
}
|
||||
addIdentifier();
|
||||
if (extraLanguage != null) {
|
||||
Future.delayed(const Duration(milliseconds: 1), () {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ class MessageServiceImpl extends MessageService {
|
|||
|
||||
@override
|
||||
Future<MessageListResponse> getHistoryMessageListV2({
|
||||
HistoryMsgGetTypeEnum getType = HistoryMsgGetTypeEnum.V2TIM_GET_LOCAL_OLDER_MSG,
|
||||
HistoryMsgGetTypeEnum getType =
|
||||
HistoryMsgGetTypeEnum.V2TIM_GET_LOCAL_OLDER_MSG,
|
||||
String? userID,
|
||||
String? groupID,
|
||||
int lastMsgSeq = -1,
|
||||
|
|
@ -25,8 +26,16 @@ class MessageServiceImpl extends MessageService {
|
|||
List<int>? messageTypeList,
|
||||
}) async {
|
||||
bool haveMoreData = true;
|
||||
final res =
|
||||
await TencentImSDKPlugin.v2TIMManager.getMessageManager().getHistoryMessageList(count: count, getType: getType, userID: userID, groupID: groupID, lastMsgID: lastMsgID, lastMsgSeq: lastMsgSeq, messageTypeList: messageTypeList);
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.getHistoryMessageList(
|
||||
count: count,
|
||||
getType: getType,
|
||||
userID: userID,
|
||||
groupID: groupID,
|
||||
lastMsgID: lastMsgID,
|
||||
lastMsgSeq: lastMsgSeq,
|
||||
messageTypeList: messageTypeList);
|
||||
final List<V2TimMessage> responseMessageList = res.data ?? [];
|
||||
final conversationID = userID ?? groupID;
|
||||
final cachedMessageList = messageListMap[conversationID];
|
||||
|
|
@ -36,29 +45,41 @@ class MessageServiceImpl extends MessageService {
|
|||
combinedMessageList = [...cachedMessageList, ...responseMessageList];
|
||||
// 首次加载
|
||||
} else {
|
||||
final bool existSendingMessage = sendingMessage[conversationID] != null && sendingMessage[conversationID]!.isNotEmpty;
|
||||
final bool existSendingMessage = sendingMessage[conversationID] != null &&
|
||||
sendingMessage[conversationID]!.isNotEmpty;
|
||||
// 存在未发送完成的消息
|
||||
if (existSendingMessage) {
|
||||
combinedMessageList = [...sendingMessage[conversationID]!, ...responseMessageList];
|
||||
combinedMessageList = [
|
||||
...sendingMessage[conversationID]!,
|
||||
...responseMessageList
|
||||
];
|
||||
} else {
|
||||
sendingMessage.remove(conversationID);
|
||||
combinedMessageList = responseMessageList;
|
||||
}
|
||||
}
|
||||
if (res.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: res.desc,
|
||||
errorCode: res.code));
|
||||
}
|
||||
if (responseMessageList.isEmpty || (!PlatformUtils().isWeb && responseMessageList.length < count) || (PlatformUtils().isWeb && responseMessageList.length < min(count, 20))) {
|
||||
if (responseMessageList.isEmpty ||
|
||||
(!PlatformUtils().isWeb && responseMessageList.length < count) ||
|
||||
(PlatformUtils().isWeb &&
|
||||
responseMessageList.length < min(count, 20))) {
|
||||
haveMoreData = false;
|
||||
} else {
|
||||
haveMoreData = true;
|
||||
}
|
||||
return MessageListResponse(haveMoreData: haveMoreData, data: combinedMessageList);
|
||||
return MessageListResponse(
|
||||
haveMoreData: haveMoreData, data: combinedMessageList);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<V2TimMessage>> getHistoryMessageList({
|
||||
HistoryMsgGetTypeEnum getType = HistoryMsgGetTypeEnum.V2TIM_GET_LOCAL_OLDER_MSG,
|
||||
HistoryMsgGetTypeEnum getType =
|
||||
HistoryMsgGetTypeEnum.V2TIM_GET_LOCAL_OLDER_MSG,
|
||||
String? userID,
|
||||
String? groupID,
|
||||
int lastMsgSeq = -1,
|
||||
|
|
@ -66,30 +87,53 @@ class MessageServiceImpl extends MessageService {
|
|||
String? lastMsgID,
|
||||
List<int>? messageTypeList,
|
||||
}) async {
|
||||
final res =
|
||||
await TencentImSDKPlugin.v2TIMManager.getMessageManager().getHistoryMessageList(count: count, getType: getType, userID: userID, groupID: groupID, lastMsgID: lastMsgID, lastMsgSeq: lastMsgSeq, messageTypeList: messageTypeList);
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.getHistoryMessageList(
|
||||
count: count,
|
||||
getType: getType,
|
||||
userID: userID,
|
||||
groupID: groupID,
|
||||
lastMsgID: lastMsgID,
|
||||
lastMsgSeq: lastMsgSeq,
|
||||
messageTypeList: messageTypeList);
|
||||
final reponseMessageList = res.data ?? [];
|
||||
if (res.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: res.desc,
|
||||
errorCode: res.code));
|
||||
}
|
||||
return reponseMessageList;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimMessageListResult?> getHistoryMessageListWithComplete({
|
||||
HistoryMsgGetTypeEnum getType = HistoryMsgGetTypeEnum.V2TIM_GET_LOCAL_OLDER_MSG,
|
||||
HistoryMsgGetTypeEnum getType =
|
||||
HistoryMsgGetTypeEnum.V2TIM_GET_LOCAL_OLDER_MSG,
|
||||
String? userID,
|
||||
String? groupID,
|
||||
int lastMsgSeq = -1,
|
||||
int lastMsgSeq = 0,
|
||||
required int count,
|
||||
String? lastMsgID,
|
||||
List<int>? messageTypeList,
|
||||
}) async {
|
||||
final res =
|
||||
await TencentImSDKPlugin.v2TIMManager.getMessageManager().getHistoryMessageListV2(count: count, getType: getType, userID: userID, groupID: groupID, lastMsgID: lastMsgID, lastMsgSeq: lastMsgSeq, messageTypeList: messageTypeList);
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.getHistoryMessageListV2(
|
||||
count: count,
|
||||
getType: getType,
|
||||
userID: userID,
|
||||
groupID: groupID,
|
||||
lastMsgID: lastMsgID,
|
||||
lastMsgSeq: lastMsgSeq,
|
||||
messageTypeList: messageTypeList);
|
||||
final responseMessageList = res.data;
|
||||
if (res.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: res.desc,
|
||||
errorCode: res.code));
|
||||
}
|
||||
return responseMessageList;
|
||||
}
|
||||
|
|
@ -98,31 +142,45 @@ class MessageServiceImpl extends MessageService {
|
|||
Future addSimpleMsgListener({
|
||||
required V2TimSimpleMsgListener listener,
|
||||
}) async {
|
||||
return TencentImSDKPlugin.v2TIMManager.addSimpleMsgListener(listener: listener);
|
||||
return TencentImSDKPlugin.v2TIMManager
|
||||
.addSimpleMsgListener(listener: listener);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> removeSimpleMsgListener({V2TimSimpleMsgListener? listener}) {
|
||||
return TencentImSDKPlugin.v2TIMManager.removeSimpleMsgListener(listener: listener);
|
||||
return TencentImSDKPlugin.v2TIMManager
|
||||
.removeSimpleMsgListener(listener: listener);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> addAdvancedMsgListener({
|
||||
required V2TimAdvancedMsgListener listener,
|
||||
}) {
|
||||
return TencentImSDKPlugin.v2TIMManager.getMessageManager().addAdvancedMsgListener(listener: listener);
|
||||
return TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.addAdvancedMsgListener(listener: listener);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimValueCallback<V2TimGroupMessageReadMemberList>> getGroupMessageReadMemberList({
|
||||
Future<V2TimValueCallback<V2TimGroupMessageReadMemberList>>
|
||||
getGroupMessageReadMemberList({
|
||||
required String messageID,
|
||||
required GetGroupMessageReadMemberListFilter filter,
|
||||
int nextSeq = 0,
|
||||
int count = 100,
|
||||
}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().getGroupMessageReadMemberList(messageID: messageID, filter: filter, nextSeq: nextSeq, count: count);
|
||||
final result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.getGroupMessageReadMemberList(
|
||||
messageID: messageID,
|
||||
filter: filter,
|
||||
nextSeq: nextSeq,
|
||||
count: count);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -131,9 +189,14 @@ class MessageServiceImpl extends MessageService {
|
|||
Future<V2TimValueCallback<List<V2TimMessageReceipt>>> getMessageReadReceipts({
|
||||
required List<String> messageIDList,
|
||||
}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().getMessageReadReceipts(messageIDList: messageIDList);
|
||||
final result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.getMessageReadReceipts(messageIDList: messageIDList);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -142,43 +205,61 @@ class MessageServiceImpl extends MessageService {
|
|||
Future<V2TimCallback> sendMessageReadReceipts({
|
||||
required List<String> messageIDList,
|
||||
}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessageReadReceipts(messageIDList: messageIDList);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
return _retryMarkMessageAsRead(action: (){
|
||||
return TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.sendMessageReadReceipts(messageIDList: messageIDList);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimMsgCreateInfoResult?> createTextMessage({required String text}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createTextMessage(text: text);
|
||||
Future<V2TimMsgCreateInfoResult?> createTextMessage(
|
||||
{required String text}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.createTextMessage(text: text);
|
||||
if (res.code == 0) {
|
||||
final messageResult = res.data;
|
||||
return messageResult;
|
||||
}
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: res.desc,
|
||||
errorCode: res.code));
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimMsgCreateInfoResult?> createCustomMessage({required String data}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createCustomMessage(data: data);
|
||||
Future<V2TimMsgCreateInfoResult?> createCustomMessage(
|
||||
{required String data}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.createCustomMessage(data: data);
|
||||
if (res.code == 0) {
|
||||
final messageResult = res.data;
|
||||
return messageResult;
|
||||
}
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: res.desc,
|
||||
errorCode: res.code));
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimMsgCreateInfoResult?> createFaceMessage({required int index, required String data}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createFaceMessage(index: index, data: data);
|
||||
Future<V2TimMsgCreateInfoResult?> createFaceMessage(
|
||||
{required int index, required String data}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.createFaceMessage(index: index, data: data);
|
||||
if (res.code == 0) {
|
||||
final messageResult = res.data;
|
||||
return messageResult;
|
||||
}
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: res.desc,
|
||||
errorCode: res.code));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -186,31 +267,51 @@ class MessageServiceImpl extends MessageService {
|
|||
Future<V2TimValueCallback<V2TimMessage>> reSendMessage(
|
||||
{required String msgID, // 自己创建的ID
|
||||
bool? onlineUserOnly}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().reSendMessage(msgID: msgID, onlineUserOnly: onlineUserOnly ?? false);
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.reSendMessage(msgID: msgID, onlineUserOnly: onlineUserOnly ?? false);
|
||||
if (res.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: res.desc,
|
||||
errorCode: res.code));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimMsgCreateInfoResult?> createTextAtMessage({required String text, required List<String> atUserList}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createTextAtMessage(text: text, atUserList: atUserList);
|
||||
Future<V2TimMsgCreateInfoResult?> createTextAtMessage(
|
||||
{required String text, required List<String> atUserList}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.createTextAtMessage(text: text, atUserList: atUserList);
|
||||
if (res.code == 0) {
|
||||
final messageResult = res.data;
|
||||
return messageResult;
|
||||
}
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: res.desc,
|
||||
errorCode: res.code));
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimMsgCreateInfoResult?> createImageMessage({String? imageName, String? imagePath, dynamic inputElement}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createImageMessage(imageName: imageName, imagePath: imagePath ?? "", inputElement: inputElement);
|
||||
Future<V2TimMsgCreateInfoResult?> createImageMessage(
|
||||
{String? imageName, String? imagePath, dynamic inputElement}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.createImageMessage(
|
||||
imageName: imageName,
|
||||
imagePath: imagePath ?? "",
|
||||
inputElement: inputElement);
|
||||
if (res.code == 0) {
|
||||
return res.data;
|
||||
}
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: res.desc,
|
||||
errorCode: res.code));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -219,11 +320,16 @@ class MessageServiceImpl extends MessageService {
|
|||
required String soundPath,
|
||||
required int duration,
|
||||
}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createSoundMessage(soundPath: soundPath, duration: duration);
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.createSoundMessage(soundPath: soundPath, duration: duration);
|
||||
if (res.code == 0) {
|
||||
return res.data;
|
||||
}
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: res.desc,
|
||||
errorCode: res.code));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -240,19 +346,23 @@ class MessageServiceImpl extends MessageService {
|
|||
String? cloudCustomData,
|
||||
String? localCustomData,
|
||||
}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessage(
|
||||
id: id,
|
||||
receiver: receiver,
|
||||
groupID: groupID,
|
||||
priority: priority,
|
||||
onlineUserOnly: onlineUserOnly,
|
||||
offlinePushInfo: offlinePushInfo,
|
||||
needReadReceipt: needReadReceipt,
|
||||
localCustomData: localCustomData,
|
||||
cloudCustomData: cloudCustomData,
|
||||
);
|
||||
final result =
|
||||
await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessage(
|
||||
id: id,
|
||||
receiver: receiver,
|
||||
groupID: groupID,
|
||||
priority: priority,
|
||||
onlineUserOnly: onlineUserOnly,
|
||||
offlinePushInfo: offlinePushInfo,
|
||||
needReadReceipt: needReadReceipt,
|
||||
localCustomData: localCustomData,
|
||||
cloudCustomData: cloudCustomData,
|
||||
);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -264,22 +374,36 @@ class MessageServiceImpl extends MessageService {
|
|||
}) async {
|
||||
V2TimCallback result;
|
||||
if (kIsWeb) {
|
||||
result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().deleteMessages(msgIDs: [], webMessageInstanceList: [webMessageInstance]);
|
||||
result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.deleteMessages(
|
||||
msgIDs: [], webMessageInstanceList: [webMessageInstance]);
|
||||
} else {
|
||||
result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().deleteMessageFromLocalStorage(msgID: msgID);
|
||||
result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.deleteMessageFromLocalStorage(msgID: msgID);
|
||||
}
|
||||
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimCallback> revokeMessage({required String msgID, Object? webMessageInstance}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().revokeMessage(msgID: msgID, webMessageInstatnce: webMessageInstance);
|
||||
Future<V2TimCallback> revokeMessage(
|
||||
{required String msgID, Object? webMessageInstance}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.revokeMessage(msgID: msgID, webMessageInstatnce: webMessageInstance);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -288,9 +412,14 @@ class MessageServiceImpl extends MessageService {
|
|||
Future<V2TimCallback> clearC2CHistoryMessage({
|
||||
required String userID,
|
||||
}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().clearC2CHistoryMessage(userID: userID);
|
||||
final result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.clearC2CHistoryMessage(userID: userID);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -299,38 +428,77 @@ class MessageServiceImpl extends MessageService {
|
|||
Future<V2TimCallback> clearGroupHistoryMessage({
|
||||
required String groupID,
|
||||
}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().clearGroupHistoryMessage(groupID: groupID);
|
||||
final result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.clearGroupHistoryMessage(groupID: groupID);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<V2TimCallback> _retryMarkMessageAsRead({
|
||||
required Future<V2TimCallback> Function() action,
|
||||
int retries = 3,
|
||||
}) async {
|
||||
V2TimCallback result;
|
||||
int attempts = 0;
|
||||
do {
|
||||
result = await action();
|
||||
if (result.code == 0) {
|
||||
return result;
|
||||
}
|
||||
attempts++;
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
} while (attempts < retries);
|
||||
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimCallback> markC2CMessageAsRead({
|
||||
required String userID,
|
||||
}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().markC2CMessageAsRead(userID: userID);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}) {
|
||||
return _retryMarkMessageAsRead(action: () {
|
||||
return TencentImSDKPlugin.v2TIMManager
|
||||
.getConversationManager()
|
||||
.cleanConversationUnreadMessageCount(
|
||||
conversationID: "c2c_$userID",
|
||||
cleanTimestamp: 0,
|
||||
cleanSequence: 0,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimCallback> markGroupMessageAsRead({
|
||||
required String groupID,
|
||||
}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().markGroupMessageAsRead(groupID: groupID);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}) {
|
||||
return _retryMarkMessageAsRead(action: () {
|
||||
return TencentImSDKPlugin.v2TIMManager
|
||||
.getConversationManager()
|
||||
.cleanConversationUnreadMessageCount(
|
||||
conversationID: "group_$groupID",
|
||||
cleanTimestamp: 0,
|
||||
cleanSequence: 0,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> removeAdvancedMsgListener({V2TimAdvancedMsgListener? listener}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().removeAdvancedMsgListener(listener: listener);
|
||||
Future<void> removeAdvancedMsgListener(
|
||||
{V2TimAdvancedMsgListener? listener}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.removeAdvancedMsgListener(listener: listener);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -338,11 +506,16 @@ class MessageServiceImpl extends MessageService {
|
|||
Future<List<V2TimMessage>?> downloadMergerMessage({
|
||||
required String msgID,
|
||||
}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().downloadMergerMessage(msgID: msgID);
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.downloadMergerMessage(msgID: msgID);
|
||||
if (res.code == 0) {
|
||||
return res.data;
|
||||
}
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: res.desc,
|
||||
errorCode: res.code));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -350,11 +523,16 @@ class MessageServiceImpl extends MessageService {
|
|||
Future<V2TimMsgCreateInfoResult?> createForwardMessage({
|
||||
required String msgID,
|
||||
}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createForwardMessage(msgID: msgID);
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.createForwardMessage(msgID: msgID);
|
||||
if (res.code == 0) {
|
||||
return res.data;
|
||||
}
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: res.desc,
|
||||
errorCode: res.code));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -365,30 +543,62 @@ class MessageServiceImpl extends MessageService {
|
|||
required List<String> abstractList,
|
||||
required String compatibleText,
|
||||
}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createMergerMessage(msgIDList: msgIDList, title: title, abstractList: abstractList, compatibleText: compatibleText);
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.createMergerMessage(
|
||||
msgIDList: msgIDList,
|
||||
title: title,
|
||||
abstractList: abstractList,
|
||||
compatibleText: compatibleText);
|
||||
if (res.code == 0) {
|
||||
return res.data;
|
||||
}
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: res.desc,
|
||||
errorCode: res.code));
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimCallback> deleteMessages({required List<String> msgIDs, List<dynamic>? webMessageInstanceList}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().deleteMessages(msgIDs: msgIDs, webMessageInstanceList: webMessageInstanceList);
|
||||
Future<V2TimCallback> deleteMessages(
|
||||
{required List<String> msgIDs,
|
||||
List<dynamic>? webMessageInstanceList}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.deleteMessages(
|
||||
msgIDs: msgIDs, webMessageInstanceList: webMessageInstanceList);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimMsgCreateInfoResult?> createVideoMessage({String? videoPath, String? type, int? duration, String? snapshotPath, dynamic inputElement}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createVideoMessage(videoFilePath: videoPath ?? "", type: type ?? "", duration: duration ?? 1, snapshotPath: snapshotPath ?? "", inputElement: inputElement);
|
||||
Future<V2TimMsgCreateInfoResult?> createVideoMessage(
|
||||
{String? videoPath,
|
||||
String? type,
|
||||
int? duration,
|
||||
String? snapshotPath,
|
||||
dynamic inputElement}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.createVideoMessage(
|
||||
videoFilePath: videoPath ?? "",
|
||||
type: type ?? "",
|
||||
duration: duration ?? 1,
|
||||
snapshotPath: snapshotPath ?? "",
|
||||
inputElement: inputElement);
|
||||
if (res.code == 0) {
|
||||
return res.data;
|
||||
}
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: res.desc,
|
||||
errorCode: res.code));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -401,38 +611,75 @@ class MessageServiceImpl extends MessageService {
|
|||
bool needReadReceipt = false,
|
||||
required V2TimMessage replyMessage, // 被回复的消息
|
||||
}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendReplyMessage(id: id, receiver: receiver, offlinePushInfo: offlinePushInfo, groupID: groupID, needReadReceipt: needReadReceipt, replyMessage: replyMessage);
|
||||
final result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.sendReplyMessage(
|
||||
id: id,
|
||||
receiver: receiver,
|
||||
offlinePushInfo: offlinePushInfo,
|
||||
groupID: groupID,
|
||||
needReadReceipt: needReadReceipt,
|
||||
replyMessage: replyMessage);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimMsgCreateInfoResult?> createFileMessage({String? filePath, required String fileName, dynamic inputElement}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createFileMessage(filePath: filePath ?? "", fileName: fileName, inputElement: inputElement);
|
||||
Future<V2TimMsgCreateInfoResult?> createFileMessage(
|
||||
{String? filePath,
|
||||
required String fileName,
|
||||
dynamic inputElement}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.createFileMessage(
|
||||
filePath: filePath ?? "",
|
||||
fileName: fileName,
|
||||
inputElement: inputElement);
|
||||
if (res.code == 0) {
|
||||
return res.data;
|
||||
}
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: res.desc,
|
||||
errorCode: res.code));
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimMsgCreateInfoResult?> createLocationMessage({required String desc, required double longitude, required double latitude}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createLocationMessage(desc: desc, longitude: longitude, latitude: latitude);
|
||||
Future<V2TimMsgCreateInfoResult?> createLocationMessage(
|
||||
{required String desc,
|
||||
required double longitude,
|
||||
required double latitude}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.createLocationMessage(
|
||||
desc: desc, longitude: longitude, latitude: latitude);
|
||||
if (res.code == 0) {
|
||||
return res.data;
|
||||
}
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: res.desc,
|
||||
errorCode: res.code));
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimValueCallback<V2TimMessageSearchResult>> searchLocalMessages({required V2TimMessageSearchParam searchParam}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().searchLocalMessages(searchParam: searchParam);
|
||||
Future<V2TimValueCallback<V2TimMessageSearchResult>> searchLocalMessages(
|
||||
{required V2TimMessageSearchParam searchParam}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.searchLocalMessages(searchParam: searchParam);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -441,19 +688,30 @@ class MessageServiceImpl extends MessageService {
|
|||
Future<List<V2TimMessage>?> findMessages({
|
||||
required List<String> messageIDList,
|
||||
}) async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().findMessages(messageIDList: messageIDList);
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.findMessages(messageIDList: messageIDList);
|
||||
if (res.code == 0) {
|
||||
return res.data;
|
||||
}
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: res.desc,
|
||||
errorCode: res.code));
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimCallback> setLocalCustomInt({required String msgID, required int localCustomInt}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().setLocalCustomInt(msgID: msgID, localCustomInt: localCustomInt);
|
||||
Future<V2TimCallback> setLocalCustomInt(
|
||||
{required String msgID, required int localCustomInt}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.setLocalCustomInt(msgID: msgID, localCustomInt: localCustomInt);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -463,9 +721,14 @@ class MessageServiceImpl extends MessageService {
|
|||
required List<String> userIDList,
|
||||
required ReceiveMsgOptEnum opt,
|
||||
}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().setC2CReceiveMessageOpt(userIDList: userIDList, opt: opt);
|
||||
final result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.setC2CReceiveMessageOpt(userIDList: userIDList, opt: opt);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -475,55 +738,96 @@ class MessageServiceImpl extends MessageService {
|
|||
required String groupID,
|
||||
required ReceiveMsgOptEnum opt,
|
||||
}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().setGroupReceiveMessageOpt(groupID: groupID, opt: opt);
|
||||
final result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.setGroupReceiveMessageOpt(groupID: groupID, opt: opt);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimValueCallback<V2TimMessageChangeInfo>> modifyMessage({required V2TimMessage message}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().modifyMessage(message: message);
|
||||
Future<V2TimValueCallback<V2TimMessageChangeInfo>> modifyMessage(
|
||||
{required V2TimMessage message}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.modifyMessage(message: message);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimCallback> setLocalCustomData({required String msgID, required String localCustomData}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().setLocalCustomData(msgID: msgID, localCustomData: localCustomData);
|
||||
Future<V2TimCallback> setLocalCustomData(
|
||||
{required String msgID, required String localCustomData}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.setLocalCustomData(msgID: msgID, localCustomData: localCustomData);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimValueCallback<V2TimMessageOnlineUrl>> getMessageOnlineUrl({required String msgID}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().getMessageOnlineUrl(msgID: msgID);
|
||||
Future<V2TimValueCallback<V2TimMessageOnlineUrl>> getMessageOnlineUrl(
|
||||
{required String msgID}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.getMessageOnlineUrl(msgID: msgID);
|
||||
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<V2TimCallback> downloadMessage({required String msgID, required int messageType, required int imageType, required bool isSnapshot}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().downloadMessage(msgID: msgID, messageType: messageType, imageType: imageType, isSnapshot: isSnapshot);
|
||||
Future<V2TimCallback> downloadMessage(
|
||||
{required String msgID,
|
||||
required int messageType,
|
||||
required int imageType,
|
||||
required bool isSnapshot}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.downloadMessage(
|
||||
msgID: msgID,
|
||||
messageType: messageType,
|
||||
imageType: imageType,
|
||||
isSnapshot: isSnapshot);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> translateText(String text, String target) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager.getMessageManager().translateText(texts: [text], targetLanguage: target);
|
||||
final result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.translateText(texts: [text], targetLanguage: target);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(type: TIMCallbackType.API_ERROR, errorMsg: result.desc, errorCode: result.code));
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
errorMsg: result.desc,
|
||||
errorCode: result.code));
|
||||
}
|
||||
return result.data?[text] ?? "";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,107 +1,15 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:logger/logger.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
|
||||
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
|
||||
|
||||
final outputLogger = Logger(
|
||||
output: _outputLogger ?? logOutputGenerator(null),
|
||||
);
|
||||
final outputLogger = TencentCloudChatLog();
|
||||
|
||||
TUIKitOutput? _outputLogger;
|
||||
|
||||
TUIKitOutput logOutputGenerator(String? path) {
|
||||
_outputLogger = TUIKitOutput(path);
|
||||
return _outputLogger!;
|
||||
}
|
||||
|
||||
class TUIKitOutput extends LogOutput {
|
||||
Future<void> createDirectoryIfNotExists(String path) async {
|
||||
final directory = Directory(p.dirname(path));
|
||||
|
||||
if (await directory.exists() == false) {
|
||||
await directory.create(recursive: true);
|
||||
class TencentCloudChatLog{
|
||||
void i(String text){
|
||||
if(!PlatformUtils().isWeb){
|
||||
TencentImSDKPlugin.v2TIMManager
|
||||
.uikitTrace(trace: text);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> deleteFilesOlderThanDays(String directoryPath, int days) async {
|
||||
final directory = Directory(directoryPath);
|
||||
final threshold = DateTime.now().subtract(Duration(days: days));
|
||||
|
||||
await for (var fileEntity in directory.list(followLinks: false)) {
|
||||
if (fileEntity is File) {
|
||||
final lastModified = await fileEntity.lastModified();
|
||||
if (lastModified.isBefore(threshold)) {
|
||||
await fileEntity.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> getPlatformLogPath({String? path}) async {
|
||||
if (TencentUtils.checkString(path) != null) {
|
||||
print("The path to local log: $path");
|
||||
return path!;
|
||||
}
|
||||
|
||||
final String documentsDirectoryPath =
|
||||
"${Platform.environment['USERPROFILE']}";
|
||||
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
||||
String pkgName = packageInfo.packageName;
|
||||
var timeName =
|
||||
"${DateTime.now().year}-${DateTime.now().month}-${DateTime.now().day}";
|
||||
final logPath = p.join(documentsDirectoryPath, "Documents", ".TencentCloudChat",
|
||||
pkgName, "uikit_log", 'Flutter-TUIKit-$timeName.log');
|
||||
print("The path to local log: $logPath");
|
||||
|
||||
return logPath;
|
||||
}
|
||||
|
||||
File? logFile;
|
||||
|
||||
TUIKitOutput(String? path) {
|
||||
if (!PlatformUtils().isWeb) {
|
||||
getPlatformLogPath(path: path).then((logFilePath) async {
|
||||
await createDirectoryIfNotExists(logFilePath);
|
||||
deleteFilesOlderThanDays(p.dirname(logFilePath), 7);
|
||||
logFile = File(logFilePath);
|
||||
if (logFile != null) {
|
||||
if (!logFile!.existsSync()) {
|
||||
logFile!.createSync(recursive: true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void output(OutputEvent event) {
|
||||
var msg = "\n";
|
||||
for (var line in event.lines) {
|
||||
msg += "$line \n";
|
||||
}
|
||||
if (!PlatformUtils().isWeb) {
|
||||
if (logFile != null) {
|
||||
final sink = logFile!.openWrite(
|
||||
mode: FileMode.append,
|
||||
encoding: const SystemEncoding(),
|
||||
);
|
||||
sink.write(utf8.decode(utf8.encode(msg)));
|
||||
sink.close();
|
||||
} else {
|
||||
Future.delayed(const Duration(seconds: 1)).then((value) {
|
||||
if (logFile != null) {
|
||||
final sink = logFile!.openWrite(
|
||||
mode: FileMode.append,
|
||||
encoding: const SystemEncoding(),
|
||||
);
|
||||
sink.write(msg);
|
||||
sink.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -32,11 +32,13 @@ class SoundPlayer {
|
|||
_soundInterruptListener!();
|
||||
}
|
||||
await _audioPlayer.setUrl(url);
|
||||
|
||||
await _audioPlayer.play();
|
||||
}
|
||||
|
||||
static stop() {
|
||||
_audioPlayer.stop();
|
||||
|
||||
}
|
||||
|
||||
static dispose() {
|
||||
|
|
|
|||
|
|
@ -1,19 +1,18 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:scroll_to_index/scroll_to_index.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart';
|
||||
import 'package:tencent_im_base/tencent_im_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue.dart';
|
||||
import 'package:tencent_im_base/tencent_im_base.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
class TIMUIKitHistoryMessageListTongueContainer extends StatefulWidget {
|
||||
final Widget Function(void Function(), MessageListTongueType, int)?
|
||||
tongueItemBuilder;
|
||||
final Widget Function(void Function(), MessageListTongueType, int)? tongueItemBuilder;
|
||||
final List<V2TimGroupAtInfo?>? groupAtInfoList;
|
||||
final Function(String targetSeq) scrollToIndexBySeq;
|
||||
final AutoScrollController scrollController;
|
||||
|
|
@ -31,12 +30,10 @@ class TIMUIKitHistoryMessageListTongueContainer extends StatefulWidget {
|
|||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() =>
|
||||
_TIMUIKitHistoryMessageListTongueContainerState();
|
||||
State<StatefulWidget> createState() => _TIMUIKitHistoryMessageListTongueContainerState();
|
||||
}
|
||||
|
||||
class _TIMUIKitHistoryMessageListTongueContainerState
|
||||
extends TIMUIKitState<TIMUIKitHistoryMessageListTongueContainer> {
|
||||
class _TIMUIKitHistoryMessageListTongueContainerState extends TIMUIKitState<TIMUIKitHistoryMessageListTongueContainer> {
|
||||
bool isFinishJumpToAt = false;
|
||||
List<V2TimGroupAtInfo?>? groupAtInfoList = [];
|
||||
final TUIChatGlobalModel globalModel = serviceLocator<TUIChatGlobalModel>();
|
||||
|
|
@ -50,10 +47,8 @@ class _TIMUIKitHistoryMessageListTongueContainerState
|
|||
}
|
||||
|
||||
void changePositionState(HistoryMessagePosition newPosition) {
|
||||
if (globalModel.getMessageListPosition(widget.model.conversationID) !=
|
||||
newPosition) {
|
||||
globalModel.setMessageListPosition(
|
||||
widget.model.conversationID, newPosition);
|
||||
if (globalModel.getMessageListPosition(widget.model.conversationID) != newPosition) {
|
||||
globalModel.setMessageListPosition(widget.model.conversationID, newPosition);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -64,19 +59,11 @@ class _TIMUIKitHistoryMessageListTongueContainerState
|
|||
if (offset <= 0.0 && conversationUnreadCount != 0) {
|
||||
widget.model.showLatestUnread();
|
||||
}
|
||||
if (widget.scrollController.offset <=
|
||||
widget.scrollController.position.minScrollExtent &&
|
||||
!widget.scrollController.position.outOfRange &&
|
||||
!widget.model.haveMoreLatestData) {
|
||||
if (widget.scrollController.offset <= widget.scrollController.position.minScrollExtent && !widget.scrollController.position.outOfRange && !widget.model.haveMoreLatestData) {
|
||||
changePositionState(HistoryMessagePosition.bottom);
|
||||
} else if (widget.scrollController.offset <= screenHeight * 1.6 &&
|
||||
widget.scrollController.offset > 0 &&
|
||||
!widget.scrollController.position.outOfRange &&
|
||||
!widget.model.haveMoreLatestData) {
|
||||
} else if (widget.scrollController.offset <= screenHeight * 1.6 && widget.scrollController.offset > 0 && !widget.scrollController.position.outOfRange && !widget.model.haveMoreLatestData) {
|
||||
changePositionState(HistoryMessagePosition.inTwoScreen);
|
||||
} else if (widget.scrollController.offset > screenHeight * 1.6 &&
|
||||
!widget.scrollController.position.outOfRange &&
|
||||
!widget.model.haveMoreLatestData) {
|
||||
} else if (widget.scrollController.offset > screenHeight * 1.6 && !widget.scrollController.position.outOfRange && !widget.model.haveMoreLatestData) {
|
||||
changePositionState(HistoryMessagePosition.awayTwoScreen);
|
||||
}
|
||||
}
|
||||
|
|
@ -85,15 +72,11 @@ class _TIMUIKitHistoryMessageListTongueContainerState
|
|||
widget.scrollController.addListener(scrollHandler);
|
||||
}
|
||||
|
||||
MessageListTongueType _getTongueValueType(
|
||||
List<V2TimGroupAtInfo?>? groupAtInfoList) {
|
||||
if (globalModel.getMessageListPosition(widget.model.conversationID) ==
|
||||
HistoryMessagePosition.notShowLatest) {
|
||||
MessageListTongueType _getTongueValueType(List<V2TimGroupAtInfo?>? groupAtInfoList) {
|
||||
if (globalModel.getMessageListPosition(widget.model.conversationID) == HistoryMessagePosition.notShowLatest) {
|
||||
return MessageListTongueType.none;
|
||||
}
|
||||
if (groupAtInfoList != null &&
|
||||
groupAtInfoList.isNotEmpty &&
|
||||
!isFinishJumpToAt) {
|
||||
if (groupAtInfoList != null && groupAtInfoList.isNotEmpty && !isFinishJumpToAt) {
|
||||
if (groupAtInfoList[0]!.atType == 1) {
|
||||
return MessageListTongueType.atMe;
|
||||
} else {
|
||||
|
|
@ -109,8 +92,7 @@ class _TIMUIKitHistoryMessageListTongueContainerState
|
|||
return MessageListTongueType.showUnread;
|
||||
}
|
||||
|
||||
if (globalModel.getMessageListPosition(widget.model.conversationID) ==
|
||||
HistoryMessagePosition.awayTwoScreen) {
|
||||
if (globalModel.getMessageListPosition(widget.model.conversationID) == HistoryMessagePosition.awayTwoScreen) {
|
||||
return MessageListTongueType.toLatest;
|
||||
}
|
||||
|
||||
|
|
@ -128,14 +110,8 @@ class _TIMUIKitHistoryMessageListTongueContainerState
|
|||
return Selector<TUIChatGlobalModel, Tuple2<HistoryMessagePosition, int>>(
|
||||
builder: (context, value, child) {
|
||||
return Positioned(
|
||||
bottom: _getTongueValueType(groupAtInfoList) !=
|
||||
MessageListTongueType.showPrevious
|
||||
? 16
|
||||
: null,
|
||||
top: _getTongueValueType(groupAtInfoList) ==
|
||||
MessageListTongueType.showPrevious
|
||||
? 16
|
||||
: null,
|
||||
bottom: _getTongueValueType(groupAtInfoList) != MessageListTongueType.showPrevious ? 16 : null,
|
||||
top: _getTongueValueType(groupAtInfoList) == MessageListTongueType.showPrevious ? 16 : null,
|
||||
right: 16,
|
||||
child: TIMUIKitHistoryMessageListTongue(
|
||||
previousCount: widget.conversation.unreadCount ?? 0,
|
||||
|
|
@ -153,29 +129,24 @@ class _TIMUIKitHistoryMessageListTongueContainerState
|
|||
} else {
|
||||
widget.scrollToIndexBySeq(groupAtInfoList!.removeAt(0)!.seq);
|
||||
}
|
||||
} else if ((widget.conversation.unreadCount ?? 0) > 20 &&
|
||||
!isClickShowPrevious) {
|
||||
} else if ((widget.conversation.unreadCount ?? 0) > 20 && !isClickShowPrevious) {
|
||||
try {
|
||||
isClickShowPrevious = true;
|
||||
final String? lastSeqString =
|
||||
widget.conversation.lastMessage?.seq;
|
||||
final int? lastSeq =
|
||||
TencentUtils.checkString(lastSeqString) != null
|
||||
? int.parse(lastSeqString!)
|
||||
: null;
|
||||
final String? lastSeqString = widget.conversation.lastMessage?.seq;
|
||||
final int? lastSeq = TencentUtils.checkString(lastSeqString) != null ? int.parse(lastSeqString!) : null;
|
||||
final int? previousCount = widget.conversation.unreadCount;
|
||||
if (lastSeq != null && previousCount != null) {
|
||||
final targetSeq = lastSeq - previousCount;
|
||||
await widget.model
|
||||
.loadListForSpecificMessage(seq: targetSeq);
|
||||
// widget.scrollToIndexBySeq((targetSeq + 1).toString());
|
||||
await widget.model.loadListForSpecificMessage(seq: targetSeq);
|
||||
// Future.delayed(const Duration(milliseconds: 100), () {
|
||||
// widget.scrollToIndexBySeq((targetSeq).toString());
|
||||
// });
|
||||
}
|
||||
} catch (e) {
|
||||
// TODO: 这里后续加个弹窗提示客户,找消息失败了
|
||||
}
|
||||
// widget.model.loadListForSpecificMessage(seq: count);
|
||||
} else if (value.item1 == HistoryMessagePosition.awayTwoScreen ||
|
||||
globalModel.unreadCountForConversation > 0) {
|
||||
} else if (value.item1 == HistoryMessagePosition.awayTwoScreen || globalModel.unreadCountForConversation > 0) {
|
||||
widget.model.showLatestUnread();
|
||||
widget.scrollController.animateTo(
|
||||
widget.scrollController.position.minScrollExtent,
|
||||
|
|
@ -191,8 +162,7 @@ class _TIMUIKitHistoryMessageListTongueContainerState
|
|||
);
|
||||
},
|
||||
selector: (c, model) {
|
||||
final mesageListPosition =
|
||||
model.getMessageListPosition(widget.model.conversationID);
|
||||
final mesageListPosition = model.getMessageListPosition(widget.model.conversationID);
|
||||
final unreadCountForConversation = model.unreadCountForConversation;
|
||||
return Tuple2(mesageListPosition, unreadCountForConversation);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -646,7 +646,7 @@ class _TIMUIKItHistoryMessageListItemState extends TIMUIKitState<TIMUIKitHistory
|
|||
alignment: Alignment.center,
|
||||
margin: const EdgeInsets.symmetric(vertical: 20),
|
||||
child: Text(
|
||||
model.chatConfig.timeDividerConfig?.timestampParser != null ? (model.chatConfig.timeDividerConfig?.timestampParser!(timeStamp))! : TimeAgo().getTimeForMessage(1709740800),
|
||||
model.chatConfig.timeDividerConfig?.timestampParser != null ? (model.chatConfig.timeDividerConfig?.timestampParser!(timeStamp))! : TimeAgo().getTimeForMessage(timeStamp),
|
||||
style: widget.themeData?.timelineTextStyle ??
|
||||
TextStyle(
|
||||
fontSize: 12,
|
||||
|
|
|
|||
|
|
@ -213,6 +213,9 @@ class TIMUIKitMessageTooltipState
|
|||
widget.message.elemType == MessageElemType.V2TIM_ELEM_TYPE_IMAGE &&
|
||||
fileBeenDownloaded);
|
||||
|
||||
final dynamicQuote =
|
||||
model.chatConfig.isAtWhenReplyDynamic?.call(widget.message);
|
||||
|
||||
final List<MessageToolTipItem> defaultTipsList = [
|
||||
if (fileBeenDownloaded)
|
||||
MessageToolTipItem(
|
||||
|
|
@ -240,7 +243,8 @@ class TIMUIKitMessageTooltipState
|
|||
onClick: () => _onTap("forwardMessage", model)),
|
||||
if (shouldShowReplyAction)
|
||||
MessageToolTipItem(
|
||||
label: TIM_t(model.chatConfig.isAtWhenReply ? "回复" : "引用"),
|
||||
label: TIM_t(
|
||||
(dynamicQuote ?? model.chatConfig.isAtWhenReply) ? "回复" : "引用"),
|
||||
id: "replyMessage",
|
||||
iconImageAsset: "images/reply_message.png",
|
||||
onClick: () => _onTap("replyMessage", model)),
|
||||
|
|
@ -502,7 +506,7 @@ class TIMUIKitMessageTooltipState
|
|||
} else if (widget.message.elemType ==
|
||||
MessageElemType.V2TIM_ELEM_TYPE_IMAGE) {
|
||||
final savePath = (TencentUtils.checkString(
|
||||
widget.message.imageElem!.imageList?[0]?.localUrl) ??
|
||||
widget.message.imageElem!.imageList?[0]?.localUrl) ??
|
||||
TencentUtils.checkString(widget.message.imageElem?.path) ??
|
||||
"");
|
||||
copyImageToClipboard(savePath);
|
||||
|
|
@ -510,12 +514,14 @@ class TIMUIKitMessageTooltipState
|
|||
break;
|
||||
case "replyMessage":
|
||||
model.repliedMessage = widget.message;
|
||||
final dynamicQuote =
|
||||
model.chatConfig.isAtWhenReplyDynamic?.call(widget.message);
|
||||
final isSelf = widget.message.isSelf ?? true;
|
||||
final isGroup =
|
||||
TencentUtils.checkString(widget.message.groupID) != null;
|
||||
final isAtWhenReply = !isSelf &&
|
||||
isGroup &&
|
||||
widget.allowAtUserWhenReply &&
|
||||
(dynamicQuote ?? widget.allowAtUserWhenReply) &&
|
||||
widget.onLongPressForOthersHeadPortrait != null;
|
||||
|
||||
/// If replying to a self message, do not add a at tag, only requestFocus.
|
||||
|
|
|
|||
|
|
@ -32,7 +32,16 @@ class TIMUIKitFileElem extends StatefulWidget {
|
|||
final bool? isShowMessageReaction;
|
||||
final TUIChatSeparateViewModel chatModel;
|
||||
|
||||
const TIMUIKitFileElem({Key? key, required this.chatModel, required this.messageID, required this.fileElem, required this.isSelf, required this.isShowJump, this.clearJump, required this.message, this.isShowMessageReaction})
|
||||
const TIMUIKitFileElem(
|
||||
{Key? key,
|
||||
required this.chatModel,
|
||||
required this.messageID,
|
||||
required this.fileElem,
|
||||
required this.isSelf,
|
||||
required this.isShowJump,
|
||||
this.clearJump,
|
||||
required this.message,
|
||||
this.isShowMessageReaction})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
|
|
@ -44,14 +53,19 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
bool isWebDownloading = false;
|
||||
final TUIChatGlobalModel model = serviceLocator<TUIChatGlobalModel>();
|
||||
int downloadProgress = 0;
|
||||
late V2TimAdvancedMsgListener advancedMsgListener;
|
||||
V2TimAdvancedMsgListener? advancedMsgListener;
|
||||
final GlobalKey containerKey = GlobalKey();
|
||||
double? containerHeight;
|
||||
bool? _downloadFailed = false;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
TencentImSDKPlugin.v2TIMManager.getMessageManager().removeAdvancedMsgListener(listener: advancedMsgListener);
|
||||
if (advancedMsgListener != null) {
|
||||
TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.removeAdvancedMsgListener(listener: advancedMsgListener);
|
||||
advancedMsgListener = null;
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
@ -63,8 +77,15 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
hasFile();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> addAdvancedMsgListenerForDownload() async {
|
||||
if(advancedMsgListener != null){
|
||||
return false;
|
||||
}
|
||||
advancedMsgListener = V2TimAdvancedMsgListener(
|
||||
onMessageDownloadProgressCallback: (V2TimMessageDownloadProgress messageProgress) async {
|
||||
onMessageDownloadProgressCallback:
|
||||
(V2TimMessageDownloadProgress messageProgress) async {
|
||||
if (messageProgress.msgID == widget.message.msgID) {
|
||||
if (messageProgress.isError || messageProgress.errorCode != 0) {
|
||||
setState(() {
|
||||
|
|
@ -79,12 +100,17 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
downloadProgress = 100;
|
||||
});
|
||||
|
||||
TencentImSDKPlugin.v2TIMManager.getMessageManager().removeAdvancedMsgListener(
|
||||
listener: advancedMsgListener,
|
||||
);
|
||||
if (advancedMsgListener != null) {
|
||||
TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.removeAdvancedMsgListener(listener: advancedMsgListener);
|
||||
advancedMsgListener = null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final currentProgress = (messageProgress.currentSize / messageProgress.totalSize * 100).floor();
|
||||
final currentProgress =
|
||||
(messageProgress.currentSize / messageProgress.totalSize * 100)
|
||||
.floor();
|
||||
if (mounted && currentProgress > downloadProgress) {
|
||||
setState(() {
|
||||
downloadProgress = currentProgress;
|
||||
|
|
@ -94,11 +120,17 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
}
|
||||
},
|
||||
);
|
||||
TencentImSDKPlugin.v2TIMManager.getMessageManager().addAdvancedMsgListener(listener: advancedMsgListener);
|
||||
await TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.addAdvancedMsgListener(listener: advancedMsgListener!);
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<String> getSavePath() async {
|
||||
String savePathWithAppPath = '/storage/emulated/0/Android/data/com.tencent.flutter.tuikit/cache/' + (widget.message.msgID ?? "") + widget.fileElem!.fileName!;
|
||||
String savePathWithAppPath =
|
||||
'/storage/emulated/0/Android/data/com.tencent.flutter.tuikit/cache/' +
|
||||
(widget.message.msgID ?? "") +
|
||||
widget.fileElem!.fileName!;
|
||||
return savePathWithAppPath;
|
||||
}
|
||||
|
||||
|
|
@ -106,7 +138,11 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
if (PlatformUtils().isWeb) {
|
||||
return true;
|
||||
}
|
||||
String savePath = TencentUtils.checkString(model.getFileMessageLocation(widget.messageID)) ?? TencentUtils.checkString(widget.message.fileElem!.localUrl) ?? widget.message.fileElem?.path ?? '';
|
||||
String savePath = TencentUtils.checkString(
|
||||
model.getFileMessageLocation(widget.messageID)) ??
|
||||
TencentUtils.checkString(widget.message.fileElem!.localUrl) ??
|
||||
widget.message.fileElem?.path ??
|
||||
'';
|
||||
File f = File(savePath);
|
||||
if (f.existsSync() && widget.messageID != null) {
|
||||
filePath = savePath;
|
||||
|
|
@ -118,6 +154,12 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
if (model.getMessageProgress(widget.messageID) != 100) {
|
||||
model.setMessageProgress(widget.messageID!, 100);
|
||||
}
|
||||
if (advancedMsgListener != null) {
|
||||
TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.removeAdvancedMsgListener(listener: advancedMsgListener);
|
||||
advancedMsgListener = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -159,7 +201,8 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
downloadFile(TUITheme theme) async {
|
||||
if (PlatformUtils().isMobile) {
|
||||
if (PlatformUtils().isIOS) {
|
||||
if (!await Permissions.checkPermission(context, Permission.photosAddOnly.value, theme, false)) {
|
||||
if (!await Permissions.checkPermission(
|
||||
context, Permission.photosAddOnly.value, theme, false)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -191,13 +234,18 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
}
|
||||
|
||||
tryOpenFile(context, theme) async {
|
||||
if (!PlatformUtils().isWeb && (await hasZeroSize(filePath) || widget.message.status == 3)) {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: "不支持 0KB 文件的传输", infoCode: 6660417));
|
||||
if (!PlatformUtils().isWeb &&
|
||||
(await hasZeroSize(filePath) || widget.message.status == 3)) {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: "不支持 0KB 文件的传输",
|
||||
infoCode: 6660417));
|
||||
return;
|
||||
}
|
||||
if (PlatformUtils().isMobile) {
|
||||
if (PlatformUtils().isIOS) {
|
||||
if (!await Permissions.checkPermission(context, Permission.photosAddOnly.value, theme!, false)) {
|
||||
if (!await Permissions.checkPermission(
|
||||
context, Permission.photosAddOnly.value, theme!, false)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -241,7 +289,8 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
);
|
||||
|
||||
final html.AnchorElement downloadAnchor = html.document.createElement('a') as html.AnchorElement;
|
||||
final html.AnchorElement downloadAnchor =
|
||||
html.document.createElement('a') as html.AnchorElement;
|
||||
|
||||
final html.Blob blob = html.Blob([response.bodyBytes]);
|
||||
|
||||
|
|
@ -253,7 +302,8 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
html.AnchorElement(
|
||||
href: widget.fileElem?.path ?? "",
|
||||
)
|
||||
..setAttribute("download", widget.message.fileElem?.fileName ?? fileName)
|
||||
..setAttribute(
|
||||
"download", widget.message.fileElem?.fileName ?? fileName)
|
||||
..setAttribute("target", '_blank')
|
||||
..style.display = "none"
|
||||
..click();
|
||||
|
|
@ -272,14 +322,24 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
final fileName = widget.fileElem!.fileName ?? "";
|
||||
final fileSize = widget.fileElem!.fileSize;
|
||||
final borderRadius = widget.isSelf
|
||||
? const BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(2), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10))
|
||||
: const BorderRadius.only(topLeft: Radius.circular(2), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10));
|
||||
? const BorderRadius.only(
|
||||
topLeft: Radius.circular(10),
|
||||
topRight: Radius.circular(2),
|
||||
bottomLeft: Radius.circular(10),
|
||||
bottomRight: Radius.circular(10))
|
||||
: const BorderRadius.only(
|
||||
topLeft: Radius.circular(2),
|
||||
topRight: Radius.circular(10),
|
||||
bottomLeft: Radius.circular(10),
|
||||
bottomRight: Radius.circular(10));
|
||||
String? fileFormat;
|
||||
if (widget.fileElem?.fileName != null && widget.fileElem!.fileName!.isNotEmpty) {
|
||||
if (widget.fileElem?.fileName != null &&
|
||||
widget.fileElem!.fileName!.isNotEmpty) {
|
||||
final String fileName = widget.fileElem!.fileName!;
|
||||
fileFormat = fileName.split(".")[max(fileName.split(".").length - 1, 0)];
|
||||
}
|
||||
final RenderBox? containerRenderBox = containerKey.currentContext?.findRenderObject() as RenderBox?;
|
||||
final RenderBox? containerRenderBox =
|
||||
containerKey.currentContext?.findRenderObject() as RenderBox?;
|
||||
if (containerRenderBox != null) {
|
||||
containerHeight = containerRenderBox.size.height;
|
||||
}
|
||||
|
|
@ -312,6 +372,8 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
await addAdvancedMsgListenerForDownload();
|
||||
if (await hasFile()) {
|
||||
if (received == 100) {
|
||||
tryOpenFile(context, theme);
|
||||
|
|
@ -328,14 +390,20 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
}
|
||||
if (checkIsWaiting()) {
|
||||
onTIMCallback(
|
||||
TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("已加入待下载队列,其他文件下载中"), infoCode: 6660413),
|
||||
TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("已加入待下载队列,其他文件下载中"),
|
||||
infoCode: 6660413),
|
||||
);
|
||||
return;
|
||||
} else {
|
||||
await addUrlToWaitingPath(theme);
|
||||
}
|
||||
} catch (e) {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: "文件处理异常", infoCode: 6660416));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: "文件处理异常",
|
||||
infoCode: 6660416));
|
||||
}
|
||||
},
|
||||
child: ConstrainedBox(
|
||||
|
|
@ -344,7 +412,8 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
width: 237,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: theme.weakDividerColor ?? CommonColor.weakDividerColor,
|
||||
color: theme.weakDividerColor ??
|
||||
CommonColor.weakDividerColor,
|
||||
),
|
||||
borderRadius: borderRadius),
|
||||
child: Stack(children: [
|
||||
|
|
@ -353,44 +422,55 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
child: LinearProgressIndicator(
|
||||
minHeight: ((containerHeight) ?? 72) - 6,
|
||||
value: (received == 100 ? 0 : received) / 100,
|
||||
backgroundColor: received == 100 ? theme.weakBackgroundColor : Colors.white,
|
||||
valueColor: AlwaysStoppedAnimation(theme.lightPrimaryMaterialColor.shade50),
|
||||
backgroundColor: received == 100
|
||||
? theme.weakBackgroundColor
|
||||
: Colors.white,
|
||||
valueColor: AlwaysStoppedAnimation(
|
||||
theme.lightPrimaryMaterialColor.shade50),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
|
||||
child: Row(mainAxisAlignment: widget.isSelf ? MainAxisAlignment.end : MainAxisAlignment.start, children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8, horizontal: 12),
|
||||
child: Row(
|
||||
mainAxisAlignment: widget.isSelf
|
||||
? MainAxisAlignment.end
|
||||
: MainAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
constraints: const BoxConstraints(maxWidth: 160),
|
||||
child: LayoutBuilder(
|
||||
builder: (buildContext, boxConstraints) {
|
||||
return CustomText(
|
||||
fileName,
|
||||
width: boxConstraints.maxWidth,
|
||||
maxLines: 1,
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
constraints:
|
||||
const BoxConstraints(maxWidth: 160),
|
||||
child: LayoutBuilder(
|
||||
builder: (buildContext, boxConstraints) {
|
||||
return CustomText(
|
||||
fileName,
|
||||
width: boxConstraints.maxWidth,
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
color: theme.darkTextColor,
|
||||
fontSize: 16,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
if (fileSize != null)
|
||||
Text(
|
||||
showFileSize(fileSize),
|
||||
style: TextStyle(
|
||||
color: theme.darkTextColor,
|
||||
fontSize: 16,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
fontSize: 14,
|
||||
color: theme.weakTextColor),
|
||||
)
|
||||
],
|
||||
)),
|
||||
TIMUIKitFileIcon(
|
||||
fileFormat: fileFormat,
|
||||
),
|
||||
if (fileSize != null)
|
||||
Text(
|
||||
showFileSize(fileSize),
|
||||
style: TextStyle(fontSize: 14, color: theme.weakTextColor),
|
||||
)
|
||||
],
|
||||
)),
|
||||
TIMUIKitFileIcon(
|
||||
fileFormat: fileFormat,
|
||||
),
|
||||
])),
|
||||
])),
|
||||
]),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -45,7 +45,15 @@ class TIMUIKitImageElem extends StatefulWidget {
|
|||
final bool? isShowMessageReaction;
|
||||
final TUIChatSeparateViewModel chatModel;
|
||||
|
||||
const TIMUIKitImageElem({required this.message, this.isShowJump = false, required this.chatModel, this.clearJump, this.isFrom, Key? key, this.isShowMessageReaction}) : super(key: key);
|
||||
const TIMUIKitImageElem(
|
||||
{required this.message,
|
||||
this.isShowJump = false,
|
||||
required this.chatModel,
|
||||
this.clearJump,
|
||||
this.isFrom,
|
||||
Key? key,
|
||||
this.isShowMessageReaction})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _TIMUIKitImageElem();
|
||||
|
|
@ -65,7 +73,9 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
|
||||
String getOriginImgURL() {
|
||||
// 实际拿的是原图
|
||||
V2TimImage? img = MessageUtils.getImageFromImgList(widget.message.imageElem!.imageList, HistoryMessageDartConstant.oriImgPrior);
|
||||
V2TimImage? img = MessageUtils.getImageFromImgList(
|
||||
widget.message.imageElem!.imageList,
|
||||
HistoryMessageDartConstant.oriImgPrior);
|
||||
return img == null ? widget.message.imageElem!.path! : img.url!;
|
||||
}
|
||||
|
||||
|
|
@ -114,7 +124,8 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
final http.Response r = await http.get(Uri.parse(imageUrl));
|
||||
final data = r.bodyBytes;
|
||||
final base64data = base64Encode(data);
|
||||
final a = html.AnchorElement(href: 'data:image/jpeg;base64,$base64data');
|
||||
final a =
|
||||
html.AnchorElement(href: 'data:image/jpeg;base64,$base64data');
|
||||
a.download = md5.convert(utf8.encode(imageUrl)).toString();
|
||||
a.click();
|
||||
a.remove();
|
||||
|
|
@ -125,7 +136,8 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
}
|
||||
|
||||
if (PlatformUtils().isIOS) {
|
||||
if (!await Permissions.checkPermission(context, Permission.photosAddOnly.value, theme!, false)) {
|
||||
if (!await Permissions.checkPermission(
|
||||
context, Permission.photosAddOnly.value, theme!, false)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -160,7 +172,8 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
|
||||
if (model.getMessageProgress(widget.message.msgID) == 100) {
|
||||
String savePath;
|
||||
if (widget.message.imageElem!.path != null && widget.message.imageElem!.path != '') {
|
||||
if (widget.message.imageElem!.path != null &&
|
||||
widget.message.imageElem!.path != '') {
|
||||
savePath = widget.message.imageElem!.path!;
|
||||
} else {
|
||||
savePath = model.getFileMessageLocation(widget.message.msgID);
|
||||
|
|
@ -171,21 +184,36 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
|
||||
if (PlatformUtils().isIOS) {
|
||||
if (result['isSuccess']) {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存成功"), infoCode: 6660406));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("图片保存成功"),
|
||||
infoCode: 6660406));
|
||||
} else {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存失败"), infoCode: 6660407));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("图片保存失败"),
|
||||
infoCode: 6660407));
|
||||
}
|
||||
} else {
|
||||
if (result != null) {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存成功"), infoCode: 6660406));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("图片保存成功"),
|
||||
infoCode: 6660406));
|
||||
} else {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存失败"), infoCode: 6660407));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("图片保存失败"),
|
||||
infoCode: 6660407));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("the message is downloading"), infoCode: -1));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("the message is downloading"),
|
||||
infoCode: -1));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -194,15 +222,27 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
|
||||
if (PlatformUtils().isIOS) {
|
||||
if (result['isSuccess']) {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存成功"), infoCode: 6660406));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("图片保存成功"),
|
||||
infoCode: 6660406));
|
||||
} else {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存失败"), infoCode: 6660407));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("图片保存失败"),
|
||||
infoCode: 6660407));
|
||||
}
|
||||
} else {
|
||||
if (result != null) {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存成功"), infoCode: 6660406));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("图片保存成功"),
|
||||
infoCode: 6660406));
|
||||
} else {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("图片保存失败"), infoCode: 6660407));
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("图片保存失败"),
|
||||
infoCode: 6660407));
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
@ -223,7 +263,8 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
if (!isWeb && filePath != null && File(filePath).existsSync()) {
|
||||
imageUrl = filePath;
|
||||
isAssetBool = true;
|
||||
} else if (localUrl != null && (!isWeb && File(localUrl).existsSync())) {
|
||||
} else if (localUrl != null &&
|
||||
(!isWeb && File(localUrl).existsSync())) {
|
||||
imageUrl = localUrl;
|
||||
isAssetBool = true;
|
||||
} else {
|
||||
|
|
@ -241,13 +282,19 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
);
|
||||
}
|
||||
} catch (e) {
|
||||
onTIMCallback(TIMCallback(infoCode: 6660414, infoRecommendText: TIM_t("正在下载中"), type: TIMCallbackType.INFO));
|
||||
onTIMCallback(TIMCallback(
|
||||
infoCode: 6660414,
|
||||
infoRecommendText: TIM_t("正在下载中"),
|
||||
type: TIMCallbackType.INFO));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
V2TimImage? getImageFromList(V2TimImageTypesEnum imgType) {
|
||||
V2TimImage? img = MessageUtils.getImageFromImgList(widget.message.imageElem!.imageList, HistoryMessageDartConstant.imgPriorMap[imgType] ?? HistoryMessageDartConstant.oriImgPrior);
|
||||
V2TimImage? img = MessageUtils.getImageFromImgList(
|
||||
widget.message.imageElem!.imageList,
|
||||
HistoryMessageDartConstant.imgPriorMap[imgType] ??
|
||||
HistoryMessageDartConstant.oriImgPrior);
|
||||
|
||||
return img;
|
||||
}
|
||||
|
|
@ -271,18 +318,26 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
));
|
||||
|
||||
bool checkIfDownloadSuccess() {
|
||||
final localUrl = TencentUtils.checkString(model.getFileMessageLocation(widget.message.msgID)) ?? widget.message.imageElem!.imageList![0]!.localUrl;
|
||||
return TencentUtils.checkString(localUrl) != null && File(localUrl!).existsSync();
|
||||
final localUrl = TencentUtils.checkString(
|
||||
model.getFileMessageLocation(widget.message.msgID)) ??
|
||||
widget.message.imageElem!.imageList![0]!.localUrl;
|
||||
return TencentUtils.checkString(localUrl) != null &&
|
||||
File(localUrl!).existsSync();
|
||||
}
|
||||
|
||||
_onClickOpenImageInNewWindow() {
|
||||
final localUrl = TencentUtils.checkString(model.getFileMessageLocation(widget.message.msgID)) ?? widget.message.imageElem!.imageList![0]!.localUrl;
|
||||
final localUrl = TencentUtils.checkString(
|
||||
model.getFileMessageLocation(widget.message.msgID)) ??
|
||||
widget.message.imageElem!.imageList![0]!.localUrl;
|
||||
Future.delayed(const Duration(milliseconds: 0), () async {
|
||||
final isDownloaded = checkIfDownloadSuccess();
|
||||
if (isDownloaded) {
|
||||
launchDesktopFile(localUrl ?? "");
|
||||
} else {
|
||||
onTIMCallback(TIMCallback(infoCode: 6660414, infoRecommendText: TIM_t("正在下载原始资源,请稍候..."), type: TIMCallbackType.INFO));
|
||||
onTIMCallback(TIMCallback(
|
||||
infoCode: 6660414,
|
||||
infoRecommendText: TIM_t("正在下载原始资源,请稍候..."),
|
||||
type: TIMCallbackType.INFO));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -291,14 +346,27 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
double? positionRadio,
|
||||
String? originImgUrl,
|
||||
}) {
|
||||
final localUrl = TencentUtils.checkString(model.getFileMessageLocation(widget.message.msgID)) ?? widget.message.imageElem!.imageList![0]!.localUrl;
|
||||
final localUrl = TencentUtils.checkString(
|
||||
model.getFileMessageLocation(widget.message.msgID)) ??
|
||||
widget.message.imageElem!.imageList![0]!.localUrl;
|
||||
if (checkIfDownloadSuccess()) {
|
||||
TUIKitWidePopup.showMedia(aspectRatio: positionRadio, context: context, mediaLocalPath: localUrl ?? "", onClickOrigin: () => _onClickOpenImageInNewWindow());
|
||||
TUIKitWidePopup.showMedia(
|
||||
aspectRatio: positionRadio,
|
||||
context: context,
|
||||
mediaLocalPath: localUrl ?? "",
|
||||
onClickOrigin: () => _onClickOpenImageInNewWindow());
|
||||
} else {
|
||||
if (TencentUtils.checkString(originImgUrl) != null) {
|
||||
TUIKitWidePopup.showMedia(aspectRatio: positionRadio, context: context, mediaURL: originImgUrl, onClickOrigin: () => _onClickOpenImageInNewWindow());
|
||||
TUIKitWidePopup.showMedia(
|
||||
aspectRatio: positionRadio,
|
||||
context: context,
|
||||
mediaURL: originImgUrl,
|
||||
onClickOrigin: () => _onClickOpenImageInNewWindow());
|
||||
} else {
|
||||
onTIMCallback(TIMCallback(infoCode: 6660414, infoRecommendText: TIM_t("正在下载中"), type: TIMCallbackType.INFO));
|
||||
onTIMCallback(TIMCallback(
|
||||
infoCode: 6660414,
|
||||
infoRecommendText: TIM_t("正在下载中"),
|
||||
type: TIMCallbackType.INFO));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -365,7 +433,10 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
}
|
||||
} else {
|
||||
if (PlatformUtils().isDesktop) {
|
||||
TUIKitWidePopup.showMedia(mediaLocalPath: imgPath, context: context, onClickOrigin: () => launchDesktopFile(imgPath ?? ""));
|
||||
TUIKitWidePopup.showMedia(
|
||||
mediaLocalPath: imgPath,
|
||||
context: context,
|
||||
onClickOrigin: () => launchDesktopFile(imgPath ?? ""));
|
||||
} else {
|
||||
Navigator.of(context).push(
|
||||
PageRouteBuilder(
|
||||
|
|
@ -383,56 +454,134 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
}
|
||||
}
|
||||
|
||||
Widget _renderAllImage({dynamic heroTag, required TUITheme theme, bool isNetworkImage = false, String? webPath, V2TimImage? originalImg, V2TimImage? smallImg, String? smallLocalPath, String? originLocalPath}) {
|
||||
Widget _renderAllImage(
|
||||
{dynamic heroTag,
|
||||
double? positionRadio,
|
||||
required TUITheme theme,
|
||||
bool isNetworkImage = false,
|
||||
String? webPath,
|
||||
V2TimImage? originalImg,
|
||||
V2TimImage? smallImg,
|
||||
String? smallLocalPath,
|
||||
String? originLocalPath}) {
|
||||
Widget getImageWidget() {
|
||||
if (isNetworkImage) {
|
||||
return Hero(
|
||||
tag: heroTag,
|
||||
child: PlatformUtils().isWeb
|
||||
? Image.network(webPath ?? smallImg?.url ?? originalImg!.url!, fit: BoxFit.contain)
|
||||
? Image.network(webPath ?? smallImg?.url ?? originalImg!.url!,
|
||||
fit: BoxFit.contain)
|
||||
: CachedNetworkImage(
|
||||
alignment: Alignment.topCenter,
|
||||
imageUrl: webPath ?? smallImg?.url ?? originalImg!.url!,
|
||||
errorWidget: (context, error, stackTrace) => errorPage(theme),
|
||||
errorWidget: (context, error, stackTrace) =>
|
||||
errorPage(theme),
|
||||
fit: BoxFit.contain,
|
||||
cacheKey: smallImg?.uuid ?? originalImg!.uuid,
|
||||
placeholder: (context, url) => Image(image: MemoryImage(kTransparentImage)),
|
||||
placeholder: (context, url) =>
|
||||
Image(image: MemoryImage(kTransparentImage)),
|
||||
fadeInDuration: const Duration(milliseconds: 0),
|
||||
));
|
||||
} else {
|
||||
final imgPath = (TencentUtils.checkString(smallLocalPath) != null ? smallLocalPath : originLocalPath)!;
|
||||
return Hero(tag: heroTag, child: Image.file(File(imgPath), fit: BoxFit.contain));
|
||||
final imgPath = (TencentUtils.checkString(smallLocalPath) != null
|
||||
? smallLocalPath
|
||||
: originLocalPath)!;
|
||||
return Hero(
|
||||
tag: heroTag,
|
||||
child: Image.file(File(imgPath), fit: BoxFit.contain));
|
||||
}
|
||||
}
|
||||
|
||||
double? currentPositionRadio;
|
||||
// File imgF = File((TencentUtils.checkString(originLocalPath) != null
|
||||
// ? originLocalPath
|
||||
// : smallLocalPath) ??
|
||||
// "");
|
||||
// bool isExist = imgF.existsSync();
|
||||
//
|
||||
// if (!isExist) {
|
||||
// return errorDisplay(context, theme);
|
||||
// }
|
||||
// Image image = Image.file(imgF);
|
||||
//
|
||||
// image.image
|
||||
// .resolve(const ImageConfiguration())
|
||||
// .addListener(ImageStreamListener((image, synchronousCall) {
|
||||
// if (image.image.width != 0 && image.image.height != 0) {
|
||||
// currentPositionRadio = image.image.width / image.image.height;
|
||||
// }
|
||||
// }));
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () => onClickImage(
|
||||
theme: theme, heroTag: heroTag, isNetworkImage: isNetworkImage, imgUrl: webPath ?? smallImg?.url ?? originalImg?.url ?? "", imgPath: (TencentUtils.checkString(originLocalPath) != null ? originLocalPath : smallLocalPath) ?? ""),
|
||||
child: getImageWidget(),
|
||||
theme: theme,
|
||||
heroTag: heroTag,
|
||||
isNetworkImage: isNetworkImage,
|
||||
imgUrl: webPath ?? smallImg?.url ?? originalImg?.url ?? "",
|
||||
imgPath: (TencentUtils.checkString(originLocalPath) != null
|
||||
? originLocalPath
|
||||
: smallLocalPath) ??
|
||||
""),
|
||||
child: Stack(
|
||||
children: [
|
||||
if (currentPositionRadio != null || positionRadio != null)
|
||||
AspectRatio(
|
||||
aspectRatio: (currentPositionRadio ?? positionRadio)!,
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(color: Colors.transparent),
|
||||
),
|
||||
),
|
||||
getImageWidget(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void initImages() async {
|
||||
final zeroImageLocal = TencentUtils.checkString(widget.message.imageElem?.imageList?.firstWhereOrNull((element) => element?.type == 0)?.localUrl);
|
||||
final oneImageLocal = TencentUtils.checkString(widget.message.imageElem?.imageList?.firstWhereOrNull((element) => element?.type == 1)?.localUrl);
|
||||
final twoImageLocal = TencentUtils.checkString(widget.message.imageElem?.imageList?.firstWhereOrNull((element) => element?.type == 2)?.localUrl);
|
||||
final zeroImageLocal = TencentUtils.checkString(widget
|
||||
.message.imageElem?.imageList
|
||||
?.firstWhereOrNull((element) => element?.type == 0)
|
||||
?.localUrl);
|
||||
final oneImageLocal = TencentUtils.checkString(widget
|
||||
.message.imageElem?.imageList
|
||||
?.firstWhereOrNull((element) => element?.type == 1)
|
||||
?.localUrl);
|
||||
final twoImageLocal = TencentUtils.checkString(widget
|
||||
.message.imageElem?.imageList
|
||||
?.firstWhereOrNull((element) => element?.type == 2)
|
||||
?.localUrl);
|
||||
|
||||
if (!PlatformUtils().isWeb && TencentUtils.checkString(widget.message.msgID) != null) {
|
||||
if ((widget.message.imageElem?.imageList) == null || widget.message.imageElem!.imageList!.isEmpty) {
|
||||
final response = await _messageService.getMessageOnlineUrl(msgID: widget.message.msgID!);
|
||||
if (!PlatformUtils().isWeb &&
|
||||
TencentUtils.checkString(widget.message.msgID) != null) {
|
||||
if ((widget.message.imageElem?.imageList) == null ||
|
||||
widget.message.imageElem!.imageList!.isEmpty) {
|
||||
final response = await _messageService.getMessageOnlineUrl(
|
||||
msgID: widget.message.msgID!);
|
||||
final elem = response.data;
|
||||
if (elem != null && elem.imageElem != null) {
|
||||
widget.message.imageElem = elem.imageElem;
|
||||
}
|
||||
}
|
||||
if (oneImageLocal == null || !File(oneImageLocal).existsSync()) {
|
||||
_messageService.downloadMessage(msgID: widget.message.msgID!, messageType: 3, imageType: 1, isSnapshot: false);
|
||||
_messageService.downloadMessage(
|
||||
msgID: widget.message.msgID!,
|
||||
messageType: 3,
|
||||
imageType: 1,
|
||||
isSnapshot: false);
|
||||
}
|
||||
if (twoImageLocal == null || !File(twoImageLocal).existsSync()) {
|
||||
_messageService.downloadMessage(msgID: widget.message.msgID!, messageType: 3, imageType: 2, isSnapshot: false);
|
||||
_messageService.downloadMessage(
|
||||
msgID: widget.message.msgID!,
|
||||
messageType: 3,
|
||||
imageType: 2,
|
||||
isSnapshot: false);
|
||||
}
|
||||
if (zeroImageLocal == null || !File(zeroImageLocal).existsSync()) {
|
||||
_messageService.downloadMessage(msgID: widget.message.msgID!, messageType: 3, imageType: 0, isSnapshot: false);
|
||||
_messageService.downloadMessage(
|
||||
msgID: widget.message.msgID!,
|
||||
messageType: 3,
|
||||
imageType: 0,
|
||||
isSnapshot: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -446,36 +595,83 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
bool isNeedShowLocalPath() {
|
||||
final current = (DateTime.now().millisecondsSinceEpoch / 1000).ceil();
|
||||
final timeStamp = widget.message.timestamp ?? current;
|
||||
return (widget.message.isSelf ?? true) && (isSent || current - timeStamp < 300);
|
||||
return (widget.message.isSelf ?? true) &&
|
||||
(isSent || current - timeStamp < 300);
|
||||
}
|
||||
|
||||
Widget? _renderImage(dynamic heroTag, TUITheme theme, {V2TimImage? originalImg, V2TimImage? smallImg}) {
|
||||
Widget? _renderImage(dynamic heroTag, TUITheme theme,
|
||||
{V2TimImage? originalImg, V2TimImage? smallImg}) {
|
||||
|
||||
double positionRadio = 1.0;
|
||||
if (smallImg?.width != null &&
|
||||
smallImg?.height != null &&
|
||||
smallImg?.width != 0 &&
|
||||
smallImg?.height != 0) {
|
||||
positionRadio = (smallImg!.width! / smallImg.height!);
|
||||
}
|
||||
|
||||
if (PlatformUtils().isWeb && widget.message.imageElem!.path != null) {
|
||||
// Displaying on Web only
|
||||
return _renderAllImage(heroTag: heroTag, theme: theme, isNetworkImage: true, smallImg: smallImg, originalImg: originalImg, webPath: widget.message.imageElem!.path);
|
||||
return _renderAllImage(
|
||||
heroTag: heroTag,
|
||||
theme: theme,
|
||||
isNetworkImage: true,
|
||||
smallImg: smallImg,
|
||||
originalImg: originalImg,
|
||||
positionRadio: positionRadio,
|
||||
webPath: widget.message.imageElem!.path);
|
||||
}
|
||||
|
||||
try {
|
||||
if ((isNeedShowLocalPath() && widget.message.imageElem!.path != null && widget.message.imageElem!.path!.isNotEmpty && File(widget.message.imageElem!.path!).existsSync())) {
|
||||
return _renderAllImage(smallLocalPath: widget.message.imageElem!.path!, heroTag: heroTag, theme: theme, originLocalPath: widget.message.imageElem!.path!);
|
||||
if ((isNeedShowLocalPath() &&
|
||||
widget.message.imageElem!.path != null &&
|
||||
widget.message.imageElem!.path!.isNotEmpty &&
|
||||
File(widget.message.imageElem!.path!).existsSync())) {
|
||||
return _renderAllImage(
|
||||
smallLocalPath: widget.message.imageElem!.path!,
|
||||
heroTag: heroTag,
|
||||
theme: theme,
|
||||
positionRadio: positionRadio,
|
||||
originLocalPath: widget.message.imageElem!.path!);
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore: avoid_print
|
||||
outputLogger.i(e);
|
||||
outputLogger.i(e.toString());
|
||||
}
|
||||
|
||||
try {
|
||||
if ((TencentUtils.checkString(smallImg?.localUrl) != null && File((smallImg?.localUrl!)!).existsSync()) || (TencentUtils.checkString(originalImg?.localUrl) != null && File((originalImg?.localUrl!)!).existsSync())) {
|
||||
return _renderAllImage(smallLocalPath: smallImg?.localUrl ?? "", heroTag: heroTag, theme: theme, originLocalPath: originalImg?.localUrl);
|
||||
if ((TencentUtils.checkString(smallImg?.localUrl) != null &&
|
||||
File((smallImg?.localUrl!)!).existsSync()) ||
|
||||
(TencentUtils.checkString(originalImg?.localUrl) != null &&
|
||||
File((originalImg?.localUrl!)!).existsSync())) {
|
||||
return _renderAllImage(
|
||||
smallLocalPath: smallImg?.localUrl ?? "",
|
||||
heroTag: heroTag,
|
||||
theme: theme,
|
||||
positionRadio: positionRadio,
|
||||
originLocalPath: originalImg?.localUrl);
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore: avoid_print
|
||||
outputLogger.i(e);
|
||||
return _renderAllImage(heroTag: heroTag, theme: theme, isNetworkImage: true, smallImg: smallImg, originalImg: originalImg);
|
||||
outputLogger.i(e.toString());
|
||||
return _renderAllImage(
|
||||
heroTag: heroTag,
|
||||
theme: theme,
|
||||
isNetworkImage: true,
|
||||
smallImg: smallImg,
|
||||
positionRadio: positionRadio,
|
||||
originalImg: originalImg);
|
||||
}
|
||||
|
||||
if ((smallImg?.url ?? originalImg?.url) != null && (smallImg?.url ?? originalImg?.url)!.isNotEmpty) {
|
||||
return _renderAllImage(heroTag: heroTag, theme: theme, isNetworkImage: true, smallImg: smallImg, originalImg: originalImg);
|
||||
if ((smallImg?.url ?? originalImg?.url) != null &&
|
||||
(smallImg?.url ?? originalImg?.url)!.isNotEmpty) {
|
||||
return _renderAllImage(
|
||||
heroTag: heroTag,
|
||||
theme: theme,
|
||||
isNetworkImage: true,
|
||||
positionRadio: positionRadio,
|
||||
smallImg: smallImg,
|
||||
originalImg: originalImg);
|
||||
}
|
||||
|
||||
return errorDisplay(context, theme);
|
||||
|
|
@ -487,8 +683,10 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
if (widget.message.status == MessageStatus.V2TIM_MSG_STATUS_SENDING) {
|
||||
isSent = true;
|
||||
}
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final heroTag = "${widget.message.msgID ?? widget.message.id ?? widget.message.timestamp ?? DateTime.now().millisecondsSinceEpoch}${widget.isFrom}";
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final heroTag =
|
||||
"${widget.message.msgID ?? widget.message.id ?? widget.message.timestamp ?? DateTime.now().millisecondsSinceEpoch}${widget.isFrom}";
|
||||
|
||||
V2TimImage? originalImg = getImageFromList(V2TimImageTypesEnum.original);
|
||||
V2TimImage? smallImg = getImageFromList(V2TimImageTypesEnum.small);
|
||||
|
|
@ -499,14 +697,16 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
isFromSelf: widget.message.isSelf ?? true,
|
||||
isShowMessageReaction: widget.isShowMessageReaction ?? true,
|
||||
message: widget.message,
|
||||
child: LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
|
||||
child: LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
return ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: constraints.maxWidth * (isDesktopScreen ? 0.4 : 0.5),
|
||||
minWidth: 64,
|
||||
maxHeight: 256,
|
||||
),
|
||||
child: _renderImage(heroTag, theme, originalImg: originalImg, smallImg: smallImg),
|
||||
child: _renderImage(heroTag, theme,
|
||||
originalImg: originalImg, smallImg: smallImg),
|
||||
);
|
||||
}));
|
||||
}
|
||||
|
|
@ -515,7 +715,9 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
class ImageClipper extends CustomClipper<RRect> {
|
||||
@override
|
||||
RRect getClip(Size size) {
|
||||
return RRect.fromRectAndRadius(Rect.fromLTWH(0, 0, size.width, min(size.height, 256)), const Radius.circular(5));
|
||||
return RRect.fromRectAndRadius(
|
||||
Rect.fromLTWH(0, 0, size.width, min(size.height, 256)),
|
||||
const Radius.circular(5));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import 'dart:convert';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_model_tools.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart';
|
||||
import 'package:extended_text/extended_text.dart';
|
||||
|
|
@ -93,6 +94,9 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
|
|||
}
|
||||
|
||||
final messageID = cloudCustomData.messageID;
|
||||
if(PlatformUtils().isWeb){
|
||||
return;
|
||||
}
|
||||
V2TimMessage? message = await widget.chatModel.findMessage(messageID);
|
||||
if (message == null) {
|
||||
try {
|
||||
|
|
@ -168,7 +172,7 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
|
|||
}
|
||||
if (message == null) {
|
||||
if (repliedMessage?.messageAbstract != null) {
|
||||
_renderMessageSummary(theme);
|
||||
return _renderMessageSummary(theme);
|
||||
}
|
||||
return const SizedBox(width: 0, height: 12);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ class _SendSoundMessageState extends TIMUIKitState<SendSoundMessage> {
|
|||
isRecording = true;
|
||||
});
|
||||
} else {
|
||||
outputLogger.i(status);
|
||||
outputLogger.i(status.toString());
|
||||
}
|
||||
});
|
||||
final amplitudesResponseSubscription =
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
}
|
||||
} catch (e) {
|
||||
// ignore: avoid_print
|
||||
outputLogger.i(e);
|
||||
outputLogger.i(e.toString());
|
||||
}
|
||||
generateDefaultControlBarItems();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -230,6 +230,8 @@ class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
|||
axis: Axis.vertical,
|
||||
);
|
||||
|
||||
Widget? joinInGroupCallWidget;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
|
@ -346,12 +348,21 @@ class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
|||
return widget.conversation.type == 1 ? ConvType.c2c : ConvType.group;
|
||||
}
|
||||
|
||||
_updateJoinInGroupCallWidget() async {
|
||||
if (_getConvType() != ConvType.group) {
|
||||
return;
|
||||
}
|
||||
joinInGroupCallWidget = await TUICore.instance.raiseExtension(TUIExtensionID.joinInGroup, {GROUP_ID: widget.conversationID!});
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
final closePanel = OptimizeUtils.throttle((_) => textFieldController.hideAllPanel(), 60);
|
||||
final isBuild = isInit;
|
||||
isInit = true;
|
||||
_updateJoinInGroupCallWidget();
|
||||
|
||||
return TIMUIKitChatProviderScope(
|
||||
model: model,
|
||||
|
|
@ -450,6 +461,7 @@ class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
|||
if (widget.customAppBar != null) widget.customAppBar!,
|
||||
if (filteredApplicationList.isNotEmpty) _renderJoinGroupApplication(filteredApplicationList.length, theme),
|
||||
if (widget.topFixWidget != null) widget.topFixWidget!,
|
||||
if (joinInGroupCallWidget != null) Center(child: joinInGroupCallWidget!),
|
||||
Expanded(
|
||||
child: Container(
|
||||
color: theme.chatBgColor,
|
||||
|
|
|
|||
|
|
@ -96,6 +96,10 @@ class TIMUIKitChatConfig {
|
|||
/// [Default]: true.
|
||||
final bool isAtWhenReply;
|
||||
|
||||
/// Control if allowed to at when reply automatically.
|
||||
/// [Default]: true.
|
||||
final bool Function(V2TimMessage message)? isAtWhenReplyDynamic;
|
||||
|
||||
/// The main switch of the group read receipt.
|
||||
final bool isShowGroupMessageReadReceipt;
|
||||
|
||||
|
|
@ -258,6 +262,7 @@ class TIMUIKitChatConfig {
|
|||
this.isUseMessageReaction = true,
|
||||
this.isShowAvatar = true,
|
||||
this.isShowSelfNameInGroup = false,
|
||||
this.isAtWhenReplyDynamic,
|
||||
this.offlinePushInfo,
|
||||
@Deprecated("Please use [isShowGroupReadingStatus] instead")
|
||||
this.isShowGroupMessageReadReceipt = true,
|
||||
|
|
|
|||
|
|
@ -1,21 +1,15 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
|
||||
|
||||
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/group/group_services.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
|
||||
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart';
|
||||
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_im_base/tencent_im_base.dart';
|
||||
|
||||
typedef GroupApplicationItemBuilder = Widget Function(
|
||||
BuildContext context, V2TimGroupApplication applicationInfo, int index);
|
||||
typedef GroupApplicationItemBuilder = Widget Function(BuildContext context, V2TimGroupApplication applicationInfo, int index);
|
||||
|
||||
enum ApplicationStatus {
|
||||
none,
|
||||
|
|
@ -30,16 +24,13 @@ class TIMUIKitGroupApplicationList extends StatefulWidget {
|
|||
/// group ID
|
||||
final String groupID;
|
||||
|
||||
const TIMUIKitGroupApplicationList(
|
||||
{Key? key, this.itemBuilder, required this.groupID})
|
||||
: super(key: key);
|
||||
const TIMUIKitGroupApplicationList({Key? key, this.itemBuilder, required this.groupID}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => TIMUIKitGroupApplicationListState();
|
||||
}
|
||||
|
||||
class TIMUIKitGroupApplicationListState
|
||||
extends TIMUIKitState<TIMUIKitGroupApplicationList> {
|
||||
class TIMUIKitGroupApplicationListState extends TIMUIKitState<TIMUIKitGroupApplicationList> {
|
||||
final TUIChatGlobalModel model = serviceLocator<TUIChatGlobalModel>();
|
||||
final GroupServices _groupServices = serviceLocator<GroupServices>();
|
||||
List<V2TimGroupApplication> groupApplicationList = [];
|
||||
|
|
@ -48,26 +39,20 @@ class TIMUIKitGroupApplicationListState
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
groupApplicationList = model.groupApplicationList
|
||||
.where((item) => (item.groupID == widget.groupID))
|
||||
.toList();
|
||||
applicationStatusList =
|
||||
groupApplicationList.map((item) => ApplicationStatus.none).toList();
|
||||
groupApplicationList = model.groupApplicationList.where((item) => (item.groupID == widget.groupID)).toList();
|
||||
applicationStatusList = groupApplicationList.map((item) => ApplicationStatus.none).toList();
|
||||
}
|
||||
|
||||
GroupApplicationItemBuilder _getItemBuilder() {
|
||||
return widget.itemBuilder ?? _defaultItemBuilder;
|
||||
}
|
||||
|
||||
Widget _defaultItemBuilder(
|
||||
BuildContext context, V2TimGroupApplication applicationInfo, int index) {
|
||||
Widget _defaultItemBuilder(BuildContext context, V2TimGroupApplication applicationInfo, int index) {
|
||||
final theme = Provider.of<TUIThemeViewModel>(context).theme;
|
||||
final ApplicationStatus currentStatus = applicationStatusList[index];
|
||||
|
||||
String _getUserName() {
|
||||
if (applicationInfo.fromUserNickName != null &&
|
||||
applicationInfo.fromUserNickName!.isNotEmpty &&
|
||||
applicationInfo.fromUserNickName != applicationInfo.fromUser) {
|
||||
if (applicationInfo.fromUserNickName != null && applicationInfo.fromUserNickName!.isNotEmpty && applicationInfo.fromUserNickName != applicationInfo.fromUser) {
|
||||
return "${applicationInfo.fromUserNickName} (${applicationInfo.fromUser})";
|
||||
} else {
|
||||
return "${applicationInfo.fromUser}";
|
||||
|
|
@ -76,17 +61,14 @@ class TIMUIKitGroupApplicationListState
|
|||
|
||||
String _getRequestMessage() {
|
||||
String option2 = applicationInfo.requestMsg ?? "";
|
||||
return TIM_t_para("验证消息: {{option2}}", "验证消息: $option2")(
|
||||
option2: option2);
|
||||
return TIM_t_para("验证消息: {{option2}}", "验证消息: $option2")(option2: option2);
|
||||
}
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: theme.weakDividerColor ?? const Color(0xFFDBDBDB))),
|
||||
border: Border(bottom: BorderSide(color: theme.weakDividerColor ?? const Color(0xFFDBDBDB))),
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
|
|
@ -96,11 +78,7 @@ class TIMUIKitGroupApplicationListState
|
|||
child: SizedBox(
|
||||
height: 40,
|
||||
width: 40,
|
||||
child: Avatar(
|
||||
faceUrl: applicationInfo.fromUserFaceUrl ?? "",
|
||||
showName: applicationInfo.fromUserNickName ??
|
||||
applicationInfo.fromUser ??
|
||||
""),
|
||||
child: Avatar(faceUrl: applicationInfo.fromUserFaceUrl ?? "", showName: applicationInfo.fromUserNickName ?? applicationInfo.fromUser ?? ""),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
|
|
@ -109,10 +87,7 @@ class TIMUIKitGroupApplicationListState
|
|||
children: [
|
||||
Text(
|
||||
_getUserName(),
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: theme.darkTextColor),
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: theme.darkTextColor),
|
||||
),
|
||||
Text(
|
||||
_getRequestMessage(),
|
||||
|
|
@ -120,21 +95,13 @@ class TIMUIKitGroupApplicationListState
|
|||
),
|
||||
],
|
||||
)),
|
||||
if (currentStatus == ApplicationStatus.none &&
|
||||
applicationInfo.handleStatus == 0)
|
||||
if (currentStatus == ApplicationStatus.none && applicationInfo.handleStatus == 0)
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 8, right: 8),
|
||||
child: InkWell(
|
||||
child: Container(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
color: theme.primaryColor,
|
||||
border: Border.all(
|
||||
width: 1,
|
||||
color: theme.weakTextColor ??
|
||||
CommonColor.weakTextColor)),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(4), color: theme.primaryColor, border: Border.all(width: 1, color: theme.weakTextColor ?? CommonColor.weakTextColor)),
|
||||
child: Text(
|
||||
TIM_t("同意"), // agree
|
||||
style: const TextStyle(
|
||||
|
|
@ -160,19 +127,11 @@ class TIMUIKitGroupApplicationListState
|
|||
}
|
||||
}),
|
||||
),
|
||||
if (currentStatus == ApplicationStatus.none &&
|
||||
applicationInfo.handleStatus == 0)
|
||||
if (currentStatus == ApplicationStatus.none && applicationInfo.handleStatus == 0)
|
||||
InkWell(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
color: Colors.white,
|
||||
border: Border.all(
|
||||
width: 1,
|
||||
color:
|
||||
theme.weakTextColor ?? CommonColor.weakTextColor)),
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(4), color: Colors.white, border: Border.all(width: 1, color: theme.weakTextColor ?? CommonColor.weakTextColor)),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
child: Text(
|
||||
TIM_t("拒绝"), // reject
|
||||
style: TextStyle(
|
||||
|
|
@ -182,12 +141,7 @@ class TIMUIKitGroupApplicationListState
|
|||
),
|
||||
onTap: () async {
|
||||
final res = await _groupServices.refuseGroupApplication(
|
||||
addTime: applicationInfo.addTime!,
|
||||
groupID: applicationInfo.groupID,
|
||||
fromUser: applicationInfo.fromUser!,
|
||||
toUser: applicationInfo.toUser!,
|
||||
type:
|
||||
GroupApplicationTypeEnum.values[applicationInfo.type]);
|
||||
addTime: applicationInfo.addTime!, groupID: applicationInfo.groupID, fromUser: applicationInfo.fromUser!, toUser: applicationInfo.toUser!, type: GroupApplicationTypeEnum.values[applicationInfo.type]);
|
||||
if (res.code == 0) {
|
||||
setState(() {
|
||||
applicationStatusList[index] = ApplicationStatus.reject;
|
||||
|
|
@ -198,8 +152,7 @@ class TIMUIKitGroupApplicationListState
|
|||
}
|
||||
},
|
||||
),
|
||||
if (currentStatus == ApplicationStatus.accept ||
|
||||
applicationInfo.handleStatus == 1)
|
||||
if (currentStatus == ApplicationStatus.accept || applicationInfo.handleResult == 1)
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 8),
|
||||
child: Text(
|
||||
|
|
@ -207,8 +160,7 @@ class TIMUIKitGroupApplicationListState
|
|||
style: TextStyle(fontSize: 15, color: theme.weakTextColor),
|
||||
),
|
||||
),
|
||||
if (currentStatus == ApplicationStatus.reject ||
|
||||
applicationInfo.handleStatus == 2)
|
||||
if (currentStatus == ApplicationStatus.reject || applicationInfo.handleResult == 2)
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 8),
|
||||
child: Text(
|
||||
|
|
@ -228,8 +180,7 @@ class TIMUIKitGroupApplicationListState
|
|||
return MultiProvider(
|
||||
providers: [ChangeNotifierProvider.value(value: model)],
|
||||
builder: (context, w) {
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
return Container(
|
||||
decoration: isDesktopScreen ? null : BoxDecoration(color: theme.weakBackgroundColor),
|
||||
child: ListView.builder(
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:chewie_for_us/chewie_for_us.dart';
|
||||
import 'package:chewie_for_us/src/animated_play_pause.dart';
|
||||
import 'package:chewie_for_us/src/helpers/utils.dart';
|
||||
import 'package:chewie_for_us/src/material/material_progress_bar.dart';
|
||||
import 'package:chewie/chewie.dart';
|
||||
import 'package:chewie/src/animated_play_pause.dart';
|
||||
import 'package:chewie/src/helpers/utils.dart';
|
||||
import 'package:chewie/src/material/material_progress_bar.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:loading_animation_widget/loading_animation_widget.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
|
|
@ -380,8 +380,7 @@ class _VideoCustomControlsState extends TIMUIKitState<VideoCustomControls> with
|
|||
|
||||
_startHideTimer();
|
||||
},
|
||||
colors: chewieController.materialProgressColors ??
|
||||
ChewieProgressColors(playedColor: Colors.white, handleColor: Colors.white, bufferedColor: Colors.white38, backgroundColor: Colors.white24),
|
||||
colors: chewieController.materialProgressColors ?? ChewieProgressColors(playedColor: Colors.white, handleColor: Colors.white, bufferedColor: Colors.white38, backgroundColor: Colors.white24),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,30 +1,27 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:chewie/chewie.dart';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:image_gallery_saver/image_gallery_saver.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
|
||||
import 'package:extended_image/extended_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:image_gallery_saver/image_gallery_saver.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
|
||||
import 'package:universal_html/html.dart' as html;
|
||||
import 'package:chewie_for_us/chewie_for_us.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/permission.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/video_custom_control.dart';
|
||||
import 'package:universal_html/html.dart' as html;
|
||||
import 'package:video_player/video_player.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
|
||||
class VideoScreen extends StatefulWidget {
|
||||
const VideoScreen({required this.message,
|
||||
required this.heroTag,
|
||||
required this.videoElement,
|
||||
Key? key})
|
||||
: super(key: key);
|
||||
const VideoScreen({required this.message, required this.heroTag, required this.videoElement, Key? key}) : super(key: key);
|
||||
|
||||
final V2TimMessage message;
|
||||
final dynamic heroTag;
|
||||
|
|
@ -37,8 +34,7 @@ class VideoScreen extends StatefulWidget {
|
|||
class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
||||
late VideoPlayerController videoPlayerController;
|
||||
late ChewieController chewieController;
|
||||
GlobalKey<ExtendedImageSlidePageState> slidePagekey =
|
||||
GlobalKey<ExtendedImageSlidePageState>();
|
||||
GlobalKey<ExtendedImageSlidePageState> slidePagekey = GlobalKey<ExtendedImageSlidePageState>();
|
||||
final TUIChatGlobalModel model = serviceLocator<TUIChatGlobalModel>();
|
||||
bool isInit = false;
|
||||
|
||||
|
|
@ -56,22 +52,19 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
}
|
||||
|
||||
//保存网络视频到本地
|
||||
Future<void> _saveNetworkVideo(context,
|
||||
String videoUrl, {
|
||||
bool isAsset = true,
|
||||
}) async {
|
||||
Future<void> _saveNetworkVideo(
|
||||
context,
|
||||
String videoUrl, {
|
||||
bool isAsset = true,
|
||||
}) async {
|
||||
if (PlatformUtils().isWeb) {
|
||||
RegExp exp = RegExp(r"((\.){1}[^?]{2,4})");
|
||||
String? suffix = exp
|
||||
.allMatches(videoUrl)
|
||||
.last
|
||||
.group(0);
|
||||
String? suffix = exp.allMatches(videoUrl).last.group(0);
|
||||
var xhr = html.HttpRequest();
|
||||
xhr.open('get', videoUrl);
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.onLoad.listen((event) {
|
||||
final a = html.AnchorElement(
|
||||
href: html.Url.createObjectUrl(html.Blob([xhr.response])));
|
||||
final a = html.AnchorElement(href: html.Url.createObjectUrl(html.Blob([xhr.response])));
|
||||
a.download = '${md5.convert(utf8.encode(videoUrl)).toString()}$suffix';
|
||||
a.click();
|
||||
a.remove();
|
||||
|
|
@ -92,7 +85,8 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
|
||||
if ((androidInfo.version.sdkInt) >= 33) {
|
||||
final videos = await Permissions.checkPermission(
|
||||
context, Permission.videos.value,
|
||||
context,
|
||||
Permission.videos.value,
|
||||
);
|
||||
|
||||
if (!videos) {
|
||||
|
|
@ -100,7 +94,8 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
}
|
||||
} else {
|
||||
final storage = await Permissions.checkPermission(
|
||||
context, Permission.storage.value,
|
||||
context,
|
||||
Permission.storage.value,
|
||||
);
|
||||
if (!storage) {
|
||||
return;
|
||||
|
|
@ -115,8 +110,7 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
}
|
||||
if (model.getMessageProgress(widget.message.msgID) == 100) {
|
||||
String savePath;
|
||||
if (widget.message.videoElem!.localVideoUrl != null &&
|
||||
widget.message.videoElem!.localVideoUrl != '') {
|
||||
if (widget.message.videoElem!.localVideoUrl != null && widget.message.videoElem!.localVideoUrl != '') {
|
||||
savePath = widget.message.videoElem!.localVideoUrl!;
|
||||
} else {
|
||||
savePath = model.getFileMessageLocation(widget.message.msgID);
|
||||
|
|
@ -126,62 +120,35 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
var result = await ImageGallerySaver.saveFile(savePath);
|
||||
if (PlatformUtils().isIOS) {
|
||||
if (result['isSuccess']) {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("视频保存成功"),
|
||||
infoCode: 6660402));
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频保存成功"), infoCode: 6660402));
|
||||
} else {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("视频保存失败"),
|
||||
infoCode: 6660403));
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频保存失败"), infoCode: 6660403));
|
||||
}
|
||||
} else {
|
||||
if (result != null) {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("视频保存成功"),
|
||||
infoCode: 6660402));
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频保存成功"), infoCode: 6660402));
|
||||
} else {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("视频保存失败"),
|
||||
infoCode: 6660403));
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频保存失败"), infoCode: 6660403));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("the message is downloading"),
|
||||
infoCode: -1));
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("the message is downloading"), infoCode: -1));
|
||||
}
|
||||
return;
|
||||
}
|
||||
var result = await ImageGallerySaver.saveFile(savePath);
|
||||
if (PlatformUtils().isIOS) {
|
||||
if (result['isSuccess']) {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("视频保存成功"),
|
||||
infoCode: 6660402));
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频保存成功"), infoCode: 6660402));
|
||||
} else {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("视频保存失败"),
|
||||
infoCode: 6660403));
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频保存失败"), infoCode: 6660403));
|
||||
}
|
||||
} else {
|
||||
if (result != null) {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("视频保存成功"),
|
||||
infoCode: 6660402));
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频保存成功"), infoCode: 6660402));
|
||||
} else {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("视频保存失败"),
|
||||
infoCode: 6660403));
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频保存失败"), infoCode: 6660403));
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
@ -195,8 +162,7 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
isAsset: true,
|
||||
);
|
||||
}
|
||||
if (widget.videoElement.videoPath != '' &&
|
||||
widget.videoElement.videoPath != null) {
|
||||
if (widget.videoElement.videoPath != '' && widget.videoElement.videoPath != null) {
|
||||
File f = File(widget.videoElement.videoPath!);
|
||||
if (f.existsSync()) {
|
||||
return await _saveNetworkVideo(
|
||||
|
|
@ -206,8 +172,7 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
);
|
||||
}
|
||||
}
|
||||
if (widget.videoElement.localVideoUrl != '' &&
|
||||
widget.videoElement.localVideoUrl != null) {
|
||||
if (widget.videoElement.localVideoUrl != '' && widget.videoElement.localVideoUrl != null) {
|
||||
File f = File(widget.videoElement.localVideoUrl!);
|
||||
if (f.existsSync()) {
|
||||
return await _saveNetworkVideo(
|
||||
|
|
@ -246,8 +211,7 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
|
||||
setVideoPlayerController() async {
|
||||
if (!PlatformUtils().isWeb) {
|
||||
if (TencentUtils.checkString(widget.message.msgID) != null &&
|
||||
widget.videoElement.localVideoUrl == null) {
|
||||
if (TencentUtils.checkString(widget.message.msgID) != null && widget.videoElement.localVideoUrl == null) {
|
||||
String savePath = model.getFileMessageLocation(widget.message.msgID);
|
||||
File f = File(savePath);
|
||||
if (f.existsSync()) {
|
||||
|
|
@ -257,28 +221,26 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
}
|
||||
|
||||
VideoPlayerController player = PlatformUtils().isWeb
|
||||
? ((TencentUtils.checkString(widget.videoElement.videoPath) != null) ||
|
||||
widget.message.status == MessageStatus.V2TIM_MSG_STATUS_SENDING
|
||||
? VideoPlayerController.networkUrl(
|
||||
Uri.parse(widget.videoElement.videoPath!),
|
||||
)
|
||||
: (TencentUtils.checkString(widget.videoElement.localVideoUrl) == null)
|
||||
? VideoPlayerController.networkUrl(
|
||||
Uri.parse(widget.videoElement.videoUrl!),
|
||||
)
|
||||
: VideoPlayerController.networkUrl(
|
||||
Uri.parse(widget.videoElement.localVideoUrl!),
|
||||
))
|
||||
: (TencentUtils.checkString(widget.videoElement.videoPath) != null ||
|
||||
widget.message.status == MessageStatus.V2TIM_MSG_STATUS_SENDING)
|
||||
? VideoPlayerController.file(File(widget.videoElement.videoPath!))
|
||||
: (TencentUtils.checkString(widget.videoElement.localVideoUrl) == null)
|
||||
? VideoPlayerController.networkUrl(
|
||||
Uri.parse(widget.videoElement.videoUrl!),
|
||||
)
|
||||
: VideoPlayerController.file(File(
|
||||
widget.videoElement.localVideoUrl!,
|
||||
));
|
||||
? ((TencentUtils.checkString(widget.videoElement.videoPath) != null) || widget.message.status == MessageStatus.V2TIM_MSG_STATUS_SENDING
|
||||
? VideoPlayerController.networkUrl(
|
||||
Uri.parse(widget.videoElement.videoPath!),
|
||||
)
|
||||
: (TencentUtils.checkString(widget.videoElement.localVideoUrl) == null)
|
||||
? VideoPlayerController.networkUrl(
|
||||
Uri.parse(widget.videoElement.videoUrl!),
|
||||
)
|
||||
: VideoPlayerController.networkUrl(
|
||||
Uri.parse(widget.videoElement.localVideoUrl!),
|
||||
))
|
||||
: (TencentUtils.checkString(widget.videoElement.videoPath) != null || widget.message.status == MessageStatus.V2TIM_MSG_STATUS_SENDING)
|
||||
? VideoPlayerController.file(File(widget.videoElement.videoPath!))
|
||||
: (TencentUtils.checkString(widget.videoElement.localVideoUrl) == null)
|
||||
? VideoPlayerController.networkUrl(
|
||||
Uri.parse(widget.videoElement.videoUrl!),
|
||||
)
|
||||
: VideoPlayerController.file(File(
|
||||
widget.videoElement.localVideoUrl!,
|
||||
));
|
||||
await player.initialize();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
double w = getVideoWidth();
|
||||
|
|
@ -303,8 +265,7 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
|
||||
@override
|
||||
didUpdateWidget(oldWidget) {
|
||||
if (oldWidget.videoElement.videoUrl != widget.videoElement.videoUrl ||
|
||||
oldWidget.videoElement.videoPath != widget.videoElement.videoPath) {
|
||||
if (oldWidget.videoElement.videoUrl != widget.videoElement.videoUrl || oldWidget.videoElement.videoPath != widget.videoElement.videoPath) {
|
||||
setVideoPlayerController();
|
||||
}
|
||||
super.didUpdateWidget(oldWidget);
|
||||
|
|
@ -330,10 +291,7 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
child: Container(
|
||||
color: Colors.transparent,
|
||||
constraints: BoxConstraints.expand(
|
||||
height: MediaQuery
|
||||
.of(context)
|
||||
.size
|
||||
.height,
|
||||
height: MediaQuery.of(context).size.height,
|
||||
),
|
||||
child: ExtendedImageSlidePage(
|
||||
key: slidePagekey,
|
||||
|
|
@ -342,13 +300,12 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
return Colors.black;
|
||||
}
|
||||
double opacity = 0.0;
|
||||
opacity = offset.distance /
|
||||
(Offset(size.width, size.height).distance / 2.0);
|
||||
return Colors.black
|
||||
.withOpacity(min(1.0, max(1.0 - opacity, 0.0)));
|
||||
opacity = offset.distance / (Offset(size.width, size.height).distance / 2.0);
|
||||
return Colors.black.withOpacity(min(1.0, max(1.0 - opacity, 0.0)));
|
||||
},
|
||||
slideType: SlideType.onlyImage,
|
||||
slideEndHandler: (Offset offset, {
|
||||
slideEndHandler: (
|
||||
Offset offset, {
|
||||
ExtendedImageSlidePageState? state,
|
||||
ScaleEndDetails? details,
|
||||
}) {
|
||||
|
|
@ -364,24 +321,15 @@ class _VideoScreenState extends TIMUIKitState<VideoScreen> {
|
|||
color: Colors.black,
|
||||
child: isInit
|
||||
? Chewie(
|
||||
controller: chewieController,
|
||||
)
|
||||
: const Center(
|
||||
child:
|
||||
CircularProgressIndicator(color: Colors.white))),
|
||||
controller: chewieController,
|
||||
)
|
||||
: const Center(child: CircularProgressIndicator(color: Colors.white))),
|
||||
heroBuilderForSlidingPage: (Widget result) {
|
||||
return Hero(
|
||||
tag: widget.heroTag,
|
||||
child: result,
|
||||
flightShuttleBuilder: (BuildContext flightContext,
|
||||
Animation<double> animation,
|
||||
HeroFlightDirection flightDirection,
|
||||
BuildContext fromHeroContext,
|
||||
BuildContext toHeroContext) {
|
||||
final Hero hero =
|
||||
(flightDirection == HeroFlightDirection.pop
|
||||
? fromHeroContext.widget
|
||||
: toHeroContext.widget) as Hero;
|
||||
flightShuttleBuilder: (BuildContext flightContext, Animation<double> animation, HeroFlightDirection flightDirection, BuildContext fromHeroContext, BuildContext toHeroContext) {
|
||||
final Hero hero = (flightDirection == HeroFlightDirection.pop ? fromHeroContext.widget : toHeroContext.widget) as Hero;
|
||||
|
||||
return hero.child;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,15 +2,15 @@
|
|||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:chewie_for_us/chewie_for_us.dart';
|
||||
import 'package:chewie/chewie.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/drag_widget.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:video_player/video_player.dart';
|
||||
|
||||
class TUIKitWidePopup {
|
||||
|
|
@ -70,26 +70,10 @@ class TUIKitWidePopup {
|
|||
}
|
||||
isShow = true;
|
||||
|
||||
final TUISelfInfoViewModel selfInfoViewModel =
|
||||
serviceLocator<TUISelfInfoViewModel>();
|
||||
final TUISelfInfoViewModel selfInfoViewModel = serviceLocator<TUISelfInfoViewModel>();
|
||||
|
||||
if (selfInfoViewModel.globalConfig?.showDesktopModalFunc != null) {
|
||||
final res = await selfInfoViewModel.globalConfig!.showDesktopModalFunc!(
|
||||
operationKey,
|
||||
context,
|
||||
child,
|
||||
theme,
|
||||
width,
|
||||
height,
|
||||
offset,
|
||||
initText,
|
||||
borderRadius,
|
||||
isDarkBackground,
|
||||
title,
|
||||
onSubmit,
|
||||
submitWidget,
|
||||
onConfirm,
|
||||
onCancel);
|
||||
final res = await selfInfoViewModel.globalConfig!.showDesktopModalFunc!(operationKey, context, child, theme, width, height, offset, initText, borderRadius, isDarkBackground, title, onSubmit, submitWidget, onConfirm, onCancel);
|
||||
|
||||
if (res == true) {
|
||||
return;
|
||||
|
|
@ -102,8 +86,7 @@ class TUIKitWidePopup {
|
|||
width: width,
|
||||
height: height,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
borderRadius ?? const BorderRadius.all(Radius.circular(16)),
|
||||
borderRadius: borderRadius ?? const BorderRadius.all(Radius.circular(16)),
|
||||
color: theme?.wideBackgroundColor ?? const Color(0xFFffffff),
|
||||
border: isDarkBackground
|
||||
? Border.all(
|
||||
|
|
@ -129,9 +112,7 @@ class TUIKitWidePopup {
|
|||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: hexToColor("f5f6f7"),
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(16),
|
||||
topRight: Radius.circular(16)),
|
||||
borderRadius: const BorderRadius.only(topLeft: Radius.circular(16), topRight: Radius.circular(16)),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
|
|
@ -139,9 +120,7 @@ class TUIKitWidePopup {
|
|||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
color: theme?.darkTextColor ?? const Color(0xFF444444)),
|
||||
style: TextStyle(fontSize: 18, color: theme?.darkTextColor ?? const Color(0xFF444444)),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
|
|
@ -156,9 +135,7 @@ class TUIKitWidePopup {
|
|||
entry = null;
|
||||
}
|
||||
},
|
||||
child: onSubmit != null
|
||||
? (submitWidget ?? const Icon(Icons.check))
|
||||
: const Icon(Icons.close),
|
||||
child: onSubmit != null ? (submitWidget ?? const Icon(Icons.check)) : const Icon(Icons.close),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
|
@ -212,8 +189,7 @@ class TUIKitWidePopup {
|
|||
},
|
||||
child: Text(
|
||||
TIM_t("取消"),
|
||||
style: TextStyle(
|
||||
color: theme?.weakTextColor ?? Colors.black),
|
||||
style: TextStyle(color: theme?.weakTextColor ?? Colors.black),
|
||||
)),
|
||||
),
|
||||
if (onConfirm != null)
|
||||
|
|
@ -293,8 +269,7 @@ class TUIKitWidePopup {
|
|||
required VoidCallback onClickOrigin,
|
||||
double? aspectRatio,
|
||||
}) async {
|
||||
assert((mediaLocalPath != null) || (mediaURL != null),
|
||||
"At least one of mediaLocalPath or mediaURL must be provided.");
|
||||
assert((mediaLocalPath != null) || (mediaURL != null), "At least one of mediaLocalPath or mediaURL must be provided.");
|
||||
|
||||
String _removeQueryString(String urlString) {
|
||||
Uri uri = Uri.parse(urlString);
|
||||
|
|
@ -310,10 +285,8 @@ class TUIKitWidePopup {
|
|||
final String mediaPath = mediaLocalPath ?? mediaURL ?? "";
|
||||
final isLocalResource = mediaLocalPath != null;
|
||||
|
||||
String fileExtension = p
|
||||
.extension(isLocalResource ? mediaPath : _removeQueryString(mediaPath));
|
||||
bool isVideo =
|
||||
['.mp4', '.avi', '.mov', '.flv', '.wmv'].contains(fileExtension);
|
||||
String fileExtension = p.extension(isLocalResource ? mediaPath : _removeQueryString(mediaPath));
|
||||
bool isVideo = ['.mp4', '.avi', '.mov', '.flv', '.wmv'].contains(fileExtension);
|
||||
|
||||
VideoPlayerController? videoController;
|
||||
ChewieController? chewieController;
|
||||
|
|
@ -324,8 +297,7 @@ class TUIKitWidePopup {
|
|||
if (isLocalResource) {
|
||||
videoController = VideoPlayerController.file(File(mediaPath));
|
||||
} else {
|
||||
videoController =
|
||||
VideoPlayerController.networkUrl(Uri.parse(mediaPath));
|
||||
videoController = VideoPlayerController.networkUrl(Uri.parse(mediaPath));
|
||||
}
|
||||
|
||||
await videoController.initialize();
|
||||
|
|
@ -342,9 +314,7 @@ class TUIKitWidePopup {
|
|||
|
||||
mediaWidget = Chewie(controller: chewieController);
|
||||
} else {
|
||||
mediaWidget = isLocalResource
|
||||
? Image.file(File(mediaPath), fit: BoxFit.contain)
|
||||
: Image.network(mediaPath, fit: BoxFit.contain);
|
||||
mediaWidget = isLocalResource ? Image.file(File(mediaPath), fit: BoxFit.contain) : Image.network(mediaPath, fit: BoxFit.contain);
|
||||
}
|
||||
|
||||
showDialog(
|
||||
|
|
@ -373,11 +343,7 @@ class TUIKitWidePopup {
|
|||
maxWidth: MediaQuery.of(context).size.width * 0.85,
|
||||
maxHeight: MediaQuery.of(context).size.height * 0.82,
|
||||
),
|
||||
child: aspectRatioFinal != null
|
||||
? AspectRatio(
|
||||
aspectRatio: aspectRatioFinal,
|
||||
child: mediaWidget)
|
||||
: mediaWidget,
|
||||
child: aspectRatioFinal != null ? AspectRatio(aspectRatio: aspectRatioFinal, child: mediaWidget) : mediaWidget,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
InkWell(
|
||||
|
|
|
|||
44
pubspec.lock
44
pubspec.lock
|
|
@ -217,14 +217,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.3"
|
||||
chewie_for_us:
|
||||
chewie:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: chewie_for_us
|
||||
sha256: "0307723e811508d361fffa6f8bbd9040b1bfea5536544e4d655e10c27de002ec"
|
||||
name: chewie
|
||||
sha256: "8bc4ac4cf3f316e50a25958c0f5eb9bb12cf7e8308bb1d74a43b230da2cfc144"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.0"
|
||||
version: "1.7.5"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -313,6 +313,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
dbus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dbus
|
||||
sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.10"
|
||||
desktop_drop:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -1308,26 +1316,26 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: tencent_cloud_chat_sdk
|
||||
sha256: a78f1f20dc9ebe40aee1bbb47da097780028434d77e97774fbe733debb21e18e
|
||||
sha256: "358e79b51aba5457418d3bb87e0bbd0f088a1eaf4c4463d09bdda93d1d655aa3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.7.5296"
|
||||
version: "7.9.5672"
|
||||
tencent_cloud_uikit_core:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: tencent_cloud_uikit_core
|
||||
sha256: "7ddb2c034e5f832261ba268957e282b7c2e738acb1d21aa40c62dad4eaa433ea"
|
||||
sha256: "61a5400b3fe75c00252272469f332e7ec07f6d1932ee636a3f2b919cf9805cb8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.2"
|
||||
version: "1.6.0"
|
||||
tencent_im_base:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: tencent_im_base
|
||||
sha256: "035d97d24bebb87654700d4afc8227de8721a259ef5d0195f3207cb0eb0cdc7a"
|
||||
sha256: daee1faac70fdf5fa4a53576db4fb7268ba5d897cc036353d3114a31abb76fb1
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.3.775296"
|
||||
version: "3.3.775297"
|
||||
tencent_keyboard_visibility:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -1560,22 +1568,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.16"
|
||||
wakelock_for_us:
|
||||
wakelock_plus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: wakelock_for_us
|
||||
sha256: a5bdd445e51a617f7c24be8165230391447301f622aacd050038cee7b41989b4
|
||||
name: wakelock_plus
|
||||
sha256: f268ca2116db22e57577fb99d52515a24bdc1d570f12ac18bb762361d43b043d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.3+1"
|
||||
wakelock_platform_interface:
|
||||
version: "1.1.4"
|
||||
wakelock_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: wakelock_platform_interface
|
||||
sha256: "1f4aeb81fb592b863da83d2d0f7b8196067451e4df91046c26b54a403f9de621"
|
||||
name: wakelock_plus_platform_interface
|
||||
sha256: "40fabed5da06caff0796dc638e1f07ee395fb18801fbff3255a2372db2d80385"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.0"
|
||||
version: "1.1.0"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
|||
13
pubspec.yaml
13
pubspec.yaml
|
|
@ -1,6 +1,6 @@
|
|||
name: tencent_cloud_chat_uikit
|
||||
description: A powerful chat UI component library and business logic for Tencent Cloud Chat, creating seamless in-app chat modules for delightful user experiences.
|
||||
version: 2.5.1
|
||||
version: 2.5.1+4
|
||||
homepage: https://trtc.io/products/chat?utm_source=gfs&utm_medium=link&utm_campaign=%E6%B8%A0%E9%81%93&_channel_track_key=k6WgfCKn
|
||||
repository: https://github.com/TencentCloud/chat-uikit-flutter
|
||||
documentation: https://comm.qq.com/im/doc/flutter/en/TUIKit/readme.html
|
||||
|
|
@ -29,7 +29,7 @@ dependencies:
|
|||
file_picker: ^5.3.0
|
||||
tencent_super_tooltip: ^0.0.1
|
||||
video_player: ^2.7.0
|
||||
chewie_for_us: ^1.5.0
|
||||
chewie: ^1.7.5
|
||||
flutter_slidable: ^3.0.1
|
||||
flutter_plugin_record_plus: ^0.0.16
|
||||
azlistview_all_platforms: ^2.1.2
|
||||
|
|
@ -62,10 +62,10 @@ dependencies:
|
|||
open_file: ^3.3.2
|
||||
tencent_keyboard_visibility: ^1.0.1
|
||||
tim_ui_kit_sticker_plugin: ^3.1.0
|
||||
tencent_im_base: ^3.3.775296
|
||||
tencent_im_base: ^3.3.775297
|
||||
fc_native_video_thumbnail: any
|
||||
path: ^1.8.1
|
||||
tencent_cloud_uikit_core: ^1.2.1
|
||||
tencent_cloud_uikit_core: ^1.6.0
|
||||
pasteboard: ^0.2.0
|
||||
desktop_drop: ^0.4.4
|
||||
device_info_plus: any
|
||||
|
|
@ -82,6 +82,11 @@ dev_dependencies:
|
|||
build_runner: any
|
||||
lints: ^1.0.1
|
||||
|
||||
dependency_overrides:
|
||||
|
||||
# tencent_chat_i18n_tool:
|
||||
# path: D:\Project\tencent-chat-i18n-tool
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue