From 7a2d31ea715e7272514e88965cb986a506f9a2aa Mon Sep 17 00:00:00 2001 From: vinsonswang Date: Tue, 17 Dec 2024 11:07:49 +0800 Subject: [PATCH] tencent_cloud_chat_uikit source code update to version 4.0.0. --- CHANGELOG.md | 10 + ..._uikit_chat_history_message_list_item.dart | 31 +- ..._uikit_history_message_list_container.dart | 17 +- .../tim_uikit_chat_image_elem.dart | 4 +- .../tim_uikit_chat_reply_elem.dart | 21 +- .../tim_uikit_chat_text_elem.dart | 13 - .../tim_uikit_chat_text_translate_elem.dart | 13 - .../DefaultSpecialTextSpanBuilder.dart | 4 - .../special_text/emoji_text.dart | 34 +- .../tim_uikit_text_field.dart | 316 +++++++++++------ .../tim_uikit_text_field_layout/narrow.dart | 177 ++++++---- .../tim_uikit_text_field_layout/wide.dart | 320 +++++++++++------- lib/ui/views/TIMUIKitChat/tim_uikit_chat.dart | 213 ++++++++---- .../TIMUIKitChat/tim_uikit_chat_config.dart | 25 +- .../tim_uikit_conversation_last_msg.dart | 90 +++-- .../link_preview/compiler/md_text.dart | 7 +- .../link_preview/link_preview_entry.dart | 3 - .../link_preview/widgets/link_text.dart | 8 - pubspec.yaml | 2 +- 19 files changed, 788 insertions(+), 520 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e00177..96d9153 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# 4.0.0 +## Breaking changes +* Upgraded the plugin tim_ui_kit_sticker_plugin to 4.0.0, no longer supports QQ emoji and unicode emoji. +* Delete the useQQStickerPackage and unicodeEmojiList parameters in StickerPanelConfig. +* Delete the isUseDefaultEmoji parameter in TIMUIKitChatConfig. +* Delete the isUseDefaultEmoji parameter in each widget. + +## Bug Fixes +* Solve the problem that showReplyMessage and showForwardMessage in ToolTipsConfig do not take effect after being set to false. + # 3.1.0+2 * Replace the flutter_slidable library with flutter_slidable_plus_plus to solve the compatibility issue of flutter 3.27.0 version. diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart index 38c3d6e..1fc7eb6 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart @@ -271,9 +271,6 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget { // open MessageReaction final bool? isUseMessageReaction; - /// Whether to use the default emoji - final bool isUseDefaultEmoji; - final List customEmojiStickerList; final V2TimGroupMemberFullInfo? groupMemberInfo; @@ -309,7 +306,6 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget { this.topRowBuilder, this.isUseMessageReaction, this.bottomRowBuilder, - this.isUseDefaultEmoji = false, this.customEmojiStickerList = const [], this.textFieldController, this.onSecondaryTapForOthersPortrait, @@ -502,7 +498,6 @@ class _TIMUIKItHistoryMessageListItemState fontStyle: widget.themeData?.messageTextStyle, backgroundColor: widget.themeData?.messageBackgroundColor, textPadding: widget.textPadding, - isUseDefaultEmoji: widget.isUseDefaultEmoji, customEmojiStickerList: widget.customEmojiStickerList, chatModel: model, isShowMessageReaction: widget.isUseMessageReaction, @@ -527,7 +522,6 @@ class _TIMUIKItHistoryMessageListItemState backgroundColor: widget.themeData?.messageBackgroundColor, textPadding: widget.textPadding, isShowMessageReaction: widget.isUseMessageReaction, - isUseDefaultEmoji: widget.isUseDefaultEmoji, customEmojiStickerList: widget.customEmojiStickerList, ); case MessageElemType.V2TIM_ELEM_TYPE_FACE: @@ -888,17 +882,23 @@ class _TIMUIKItHistoryMessageListItemState } } - if (widget.message.status != MessageStatus.V2TIM_MSG_STATUS_SEND_FAIL) { - widget.toolTipsConfig?.showReplyMessage = true; - } else { - widget.toolTipsConfig?.showReplyMessage = false; + // 如果配置了显示回复消息,则需要根据消息状态来决定是否可以回复;如果配置了不显示回复消息,则不需要判断消息状态。 + if ((widget.toolTipsConfig?.showReplyMessage ?? true)) { + if (widget.message.status != MessageStatus.V2TIM_MSG_STATUS_SEND_FAIL) { + widget.toolTipsConfig?.showReplyMessage = true; + } else { + widget.toolTipsConfig?.showReplyMessage = false; + } } - if (widget.message.status != MessageStatus.V2TIM_MSG_STATUS_SEND_FAIL && - !(widget.message.hasRiskContent ?? false)) { - widget.toolTipsConfig?.showForwardMessage = true; - } else { - widget.toolTipsConfig?.showForwardMessage = false; + // 如果配置了显示转发消息,则需要根据消息状态来决定是否可以转发;如果配置了不显示转发消息,则不需要判断消息状态。 + if ((widget.toolTipsConfig?.showForwardMessage ?? true)) { + if (widget.message.status != MessageStatus.V2TIM_MSG_STATUS_SEND_FAIL && + !(widget.message.hasRiskContent ?? false)) { + widget.toolTipsConfig?.showForwardMessage = true; + } else { + widget.toolTipsConfig?.showForwardMessage = false; + } } tooltip = SuperTooltip( @@ -1561,7 +1561,6 @@ class _TIMUIKItHistoryMessageListItemState ), TIMUIKitTextTranslationElem( message: message, - isUseDefaultEmoji: widget.isUseDefaultEmoji, customEmojiStickerList: widget.customEmojiStickerList, isFromSelf: message.isSelf ?? true, diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_history_message_list_container.dart b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_history_message_list_container.dart index 599971d..74b45ad 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_history_message_list_container.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_history_message_list_container.dart @@ -68,9 +68,6 @@ class TIMUIKitHistoryMessageListContainer extends StatefulWidget { /// tool tips panel configuration, long press message will show tool tips panel final ToolTipsConfig? toolTipsConfig; - /// Whether to use the default emoji - final bool isUseDefaultEmoji; - final List customEmojiStickerList; final bool isAllowScroll; @@ -105,7 +102,6 @@ class TIMUIKitHistoryMessageListContainer extends StatefulWidget { this.initFindingMsg, this.mainHistoryListConfig, this.toolTipsConfig, - this.isUseDefaultEmoji = false, this.customEmojiStickerList = const [], this.textFieldController, required this.conversation, @@ -131,10 +127,11 @@ class _TIMUIKitHistoryMessageListContainerState if ((direction == LoadDirection.previous) || (direction == LoadDirection.latest && model.haveMoreLatestData)) { return await model.loadChatRecord( - direction: direction, - count: count ?? (kIsWeb ? 15 : HistoryMessageDartConstant.getCount), - lastMsgID: lastMsgID, - lastMsgSeq: lastSeq ?? -1,); + direction: direction, + count: count ?? (kIsWeb ? 15 : HistoryMessageDartConstant.getCount), + lastMsgID: lastMsgID, + lastMsgSeq: lastSeq ?? -1, + ); } else { return false; } @@ -182,7 +179,6 @@ class _TIMUIKitHistoryMessageListContainerState textFieldController: widget.textFieldController, userAvatarBuilder: widget.userAvatarBuilder, customEmojiStickerList: widget.customEmojiStickerList, - isUseDefaultEmoji: widget.isUseDefaultEmoji, topRowBuilder: _getTopRowBuilder(model), onScrollToIndex: _historyMessageListController.scrollToIndex, onScrollToIndexBegin: @@ -206,7 +202,8 @@ class _TIMUIKitHistoryMessageListContainerState tongueItemBuilder: widget.tongueItemBuilder, initFindingMsg: widget.initFindingMsg, messageList: messageList, - onLoadMore: (String? a, LoadDirection direction, [int? b, int? lastSeq]) async { + onLoadMore: (String? a, LoadDirection direction, + [int? b, int? lastSeq]) async { return await requestForData(a, direction, model, b, lastSeq); }, ); diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_image_elem.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_image_elem.dart index 5f6a54f..88cfe67 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_image_elem.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_image_elem.dart @@ -180,7 +180,7 @@ class _TIMUIKitImageElem extends TIMUIKitState { } File f = File(savePath); if (f.existsSync()) { - var result = await ImageGallerySaver.saveFile(savePath); + var result = await ImageGallerySaverPlus.saveFile(savePath); if (PlatformUtils().isIOS) { if (result['isSuccess']) { @@ -218,7 +218,7 @@ class _TIMUIKitImageElem extends TIMUIKitState { return; } - var result = await ImageGallerySaver.saveFile(imageUrl); + var result = await ImageGallerySaverPlus.saveFile(imageUrl); if (PlatformUtils().isIOS) { if (result['isSuccess']) { diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_reply_elem.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_reply_elem.dart index 69c5f36..b13b584 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_reply_elem.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_reply_elem.dart @@ -37,7 +37,6 @@ class TIMUIKitReplyElem extends StatefulWidget { final EdgeInsetsGeometry? textPadding; final TUIChatSeparateViewModel chatModel; final bool? isShowMessageReaction; - final bool isUseDefaultEmoji; final List customEmojiStickerList; const TIMUIKitReplyElem({ @@ -51,7 +50,6 @@ class TIMUIKitReplyElem extends StatefulWidget { this.isShowMessageReaction, this.backgroundColor, this.textPadding, - this.isUseDefaultEmoji = false, this.customEmojiStickerList = const [], required this.chatModel, }) : super(key: key); @@ -94,7 +92,7 @@ class _TIMUIKitReplyElemState extends TIMUIKitState { } final messageID = cloudCustomData.messageID; - if(PlatformUtils().isWeb){ + if (PlatformUtils().isWeb) { return; } V2TimMessage? message = await widget.chatModel.findMessage(messageID); @@ -289,12 +287,12 @@ class _TIMUIKitReplyElemState extends TIMUIKitState { } void _jumpToRawMsg() { - if (rawMessage?.status != MessageStatus.V2TIM_MSG_STATUS_LOCAL_REVOKED && rawMessage?.timestamp != null) { + if (rawMessage?.status != MessageStatus.V2TIM_MSG_STATUS_LOCAL_REVOKED && + rawMessage?.timestamp != null) { widget.scrollToIndex(rawMessage); } else { onTIMCallback(TIMCallback( - type: TIMCallbackType.INFO, - infoRecommendText: TIM_t("无法定位到原消息"))); + type: TIMCallbackType.INFO, infoRecommendText: TIM_t("无法定位到原消息"))); } } @@ -370,10 +368,6 @@ class _TIMUIKitReplyElemState extends TIMUIKitState { widget.message.textElem?.text ?? "", widget.chatModel.chatConfig.isSupportMarkdownForTextMessage, onLinkTap: widget.chatModel.chatConfig.onTapLink, - isUseQQPackage: (widget.chatModel.chatConfig.stickerPanelConfig - ?.useTencentCloudChatStickerPackage ?? - true) || - widget.isUseDefaultEmoji, isUseTencentCloudChatPackage: widget.chatModel.chatConfig .stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true, @@ -440,13 +434,6 @@ class _TIMUIKitReplyElemState extends TIMUIKitState { fontSize: isDesktopScreen ? 14 : 16, height: widget.chatModel.chatConfig.textHeight), specialTextSpanBuilder: DefaultSpecialTextSpanBuilder( - isUseQQPackage: (widget - .chatModel - .chatConfig - .stickerPanelConfig - ?.useTencentCloudChatStickerPackage ?? - true) || - widget.isUseDefaultEmoji, isUseTencentCloudChatPackage: widget .chatModel .chatConfig diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_elem.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_elem.dart index ad2a18d..984e84f 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_elem.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_elem.dart @@ -24,7 +24,6 @@ class TIMUIKitTextElem extends StatefulWidget { final EdgeInsetsGeometry? textPadding; final TUIChatSeparateViewModel chatModel; final bool? isShowMessageReaction; - final bool isUseDefaultEmoji; final List customEmojiStickerList; const TIMUIKitTextElem( @@ -39,7 +38,6 @@ class TIMUIKitTextElem extends StatefulWidget { this.backgroundColor, this.textPadding, required this.chatModel, - this.isUseDefaultEmoji = false, this.customEmojiStickerList = const []}) : super(key: key); @@ -167,10 +165,6 @@ class _TIMUIKitTextElemState extends TIMUIKitState { widget.message.textElem?.text ?? "", widget.chatModel.chatConfig.isSupportMarkdownForTextMessage, onLinkTap: widget.chatModel.chatConfig.onTapLink, - isUseQQPackage: (widget.chatModel.chatConfig.stickerPanelConfig - ?.useTencentCloudChatStickerPackage ?? - true) || - widget.isUseDefaultEmoji, isUseTencentCloudChatPackage: widget.chatModel.chatConfig .stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true, @@ -238,13 +232,6 @@ class _TIMUIKitTextElemState extends TIMUIKitState { fontSize: isDesktopScreen ? 14 : 16, height: widget.chatModel.chatConfig.textHeight), specialTextSpanBuilder: DefaultSpecialTextSpanBuilder( - isUseQQPackage: (widget - .chatModel - .chatConfig - .stickerPanelConfig - ?.useTencentCloudChatStickerPackage ?? - true) || - widget.isUseDefaultEmoji, isUseTencentCloudChatPackage: widget .chatModel .chatConfig diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_translate_elem.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_translate_elem.dart index d63189f..76388f4 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_translate_elem.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_translate_elem.dart @@ -22,7 +22,6 @@ class TIMUIKitTextTranslationElem extends StatefulWidget { final EdgeInsetsGeometry? textPadding; final TUIChatSeparateViewModel chatModel; final bool? isShowMessageReaction; - final bool isUseDefaultEmoji; final List customEmojiStickerList; const TIMUIKitTextTranslationElem( @@ -37,7 +36,6 @@ class TIMUIKitTextTranslationElem extends StatefulWidget { this.backgroundColor, this.textPadding, required this.chatModel, - this.isUseDefaultEmoji = false, this.customEmojiStickerList = const []}) : super(key: key); @@ -124,10 +122,6 @@ class _TIMUIKitTextTranslationElemState final textWithLink = LinkPreviewEntry.getHyperlinksText(translateText ?? "", widget.chatModel.chatConfig.isSupportMarkdownForTextMessage, onLinkTap: widget.chatModel.chatConfig.onTapLink, - isUseQQPackage: (widget.chatModel.chatConfig.stickerPanelConfig - ?.useTencentCloudChatStickerPackage ?? - true) || - widget.isUseDefaultEmoji, isUseTencentCloudChatPackage: widget.chatModel.chatConfig .stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true, @@ -166,13 +160,6 @@ class _TIMUIKitTextTranslationElemState fontSize: isDesktopScreen ? 14 : 16, height: widget.chatModel.chatConfig.textHeight), specialTextSpanBuilder: DefaultSpecialTextSpanBuilder( - isUseQQPackage: (widget - .chatModel - .chatConfig - .stickerPanelConfig - ?.useTencentCloudChatStickerPackage ?? - true) || - widget.isUseDefaultEmoji, isUseTencentCloudChatPackage: widget .chatModel .chatConfig diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart index 859064a..d7d724e 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart @@ -9,7 +9,6 @@ import 'emoji_text.dart'; class DefaultSpecialTextSpanBuilder extends SpecialTextSpanBuilder { DefaultSpecialTextSpanBuilder({ - this.isUseQQPackage = false, this.isUseTencentCloudChatPackage = false, this.customEmojiStickerList = const [], this.showAtBackground = false, @@ -19,8 +18,6 @@ class DefaultSpecialTextSpanBuilder extends SpecialTextSpanBuilder { /// whether show background for @somebody final bool showAtBackground; - final bool isUseQQPackage; - final bool isUseTencentCloudChatPackage; final bool checkHttpLink; @@ -41,7 +38,6 @@ class DefaultSpecialTextSpanBuilder extends SpecialTextSpanBuilder { return EmojiText(textStyle, isUseTencentCloudChatPackage: isUseTencentCloudChatPackage, start: index! - (EmojiText.flag.length - 1), - isUseQQPackage: isUseQQPackage, customEmojiStickerList: customEmojiStickerList); } else if (isStart(flag, HttpText.flag) && checkHttpLink) { return HttpText(textStyle, onTap, diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/emoji_text.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/emoji_text.dart index a92a025..552de93 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/emoji_text.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/emoji_text.dart @@ -8,12 +8,10 @@ class EmojiText extends SpecialText { EmojiText(TextStyle? textStyle, {this.start, this.isUseTencentCloudChatPackage = false, - this.isUseQQPackage = false, this.customEmojiStickerList = const []}) : super(EmojiText.flag, ']', textStyle); static const String flag = '['; final int? start; - final bool isUseQQPackage; final bool isUseTencentCloudChatPackage; final List customEmojiStickerList; @@ -22,7 +20,6 @@ class EmojiText extends SpecialText { final String key = toString(); final EmojiUtil emojiUtil = EmojiUtil( isUseTencentCloudChatPackage: isUseTencentCloudChatPackage, - isUseQQPackage: isUseQQPackage, customEmojiStickerList: customEmojiStickerList); if (emojiUtil.emojiMap.containsKey(key)) { @@ -33,18 +30,7 @@ class EmojiText extends SpecialText { size = ts.fontSize! * 1.44; } - if (isUseQQPackage == true && - (emojiUtil.emojiKeyCategoryMap["4349"]?.contains(key) ?? false)) { - return ImageSpan( - AssetImage(emojiUtil.emojiMap[key]!, - package: "tim_ui_kit_sticker_plugin"), - actualText: key, - imageWidth: size, - imageHeight: size, - start: start!, - // fit: BoxFit.cover, - margin: const EdgeInsets.all(0)); - } else if (isUseTencentCloudChatPackage == true && + if (isUseTencentCloudChatPackage == true && (emojiUtil.emojiKeyCategoryMap["tcc1"]?.contains(key) ?? false)) { return ImageSpan( AssetImage(emojiUtil.emojiMap[key]!, @@ -73,8 +59,7 @@ class EmojiText extends SpecialText { class EmojiUtil { // Private constructor initializing the emoji data EmojiUtil._internal( - {required this.isUseQQPackage, - required this.isUseTencentCloudChatPackage, + {required this.isUseTencentCloudChatPackage, required this.customEmojiStickerList}) { _emojiMap.addAll(loadDefaultEmojis()); @@ -83,7 +68,6 @@ class EmojiUtil { _emojiKeyCategoryMap["custom"] = customEmojis.$2; } - final bool isUseQQPackage; final bool isUseTencentCloudChatPackage; final List customEmojiStickerList; @@ -93,20 +77,12 @@ class EmojiUtil { for (final emojiGroup in TUIKitStickerConstData.emojiList) { final groupName = emojiGroup.name; final keyList = []; - if ((isUseQQPackage && groupName == "4349") || - (isUseTencentCloudChatPackage && groupName == "tcc1")) { + if (isUseTencentCloudChatPackage && groupName == "tcc1") { for (final emoji in emojiGroup.list) { String emojiName = emoji.split('.png')[0]; defaultEmojiMap['[$emojiName]'] = '$_emojiFilePath/$groupName/$emojiName.png'; keyList.add('[$emojiName]'); - - if (groupName == "4349") { - final zhKey = TUIKitStickerConstData.emojiMapList[emojiName]; - defaultEmojiMap['[$zhKey]'] = - '$_emojiFilePath/$groupName/$emojiName.png'; - keyList.add('[$zhKey]'); - } } _emojiKeyCategoryMap[groupName] = keyList; } @@ -149,11 +125,9 @@ class EmojiUtil { // Factory constructor to return the singleton instance of EmojiUtil with custom parameters factory EmojiUtil( - {bool isUseQQPackage = false, - bool isUseTencentCloudChatPackage = false, + {bool isUseTencentCloudChatPackage = false, List customEmojiStickerList = const []}) { return _instance ??= EmojiUtil._internal( - isUseQQPackage: isUseQQPackage, customEmojiStickerList: customEmojiStickerList, isUseTencentCloudChatPackage: isUseTencentCloudChatPackage); } diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field.dart index ffe4036..f323a0a 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field.dart @@ -142,7 +142,8 @@ class _InputTextFieldState extends TIMUIKitState { double inputWidth = 900; Map mentionedMembersMap = {}; late TextEditingController textEditingController; - final TUIConversationViewModel conversationModel = serviceLocator(); + final TUIConversationViewModel conversationModel = + serviceLocator(); final TUISelfInfoViewModel selfModel = serviceLocator(); MuteStatus muteStatus = MuteStatus.none; bool _isComposingText = false; @@ -154,41 +155,29 @@ class _InputTextFieldState extends TIMUIKitState { // Keep using original scheme. return; } - final stickerConfig = widget.model.chatConfig.stickerPanelConfig ?? StickerPanelConfig(); + final stickerConfig = + widget.model.chatConfig.stickerPanelConfig ?? StickerPanelConfig(); if (stickerConfig.useTencentCloudChatStickerPackage) { - final tccEmojiSet = TUIKitStickerConstData.emojiList.firstWhere((element) => element.name == "tcc1"); + final tccEmojiSet = TUIKitStickerConstData.emojiList + .firstWhere((element) => element.name == "tcc1"); stickerPackageList.add(CustomStickerPackage( name: tccEmojiSet.name, baseUrl: "assets/custom_face_resource/${tccEmojiSet.name}", isEmoji: tccEmojiSet.isEmoji, isDefaultEmoji: true, - stickerList: tccEmojiSet.list.asMap().keys.map((idx) => CustomSticker(index: idx, name: tccEmojiSet.list[idx])).toList(), + stickerList: tccEmojiSet.list + .asMap() + .keys + .map((idx) => + CustomSticker(index: idx, name: tccEmojiSet.list[idx])) + .toList(), menuItem: CustomSticker( index: 0, name: tccEmojiSet.icon, ))); } - if (stickerConfig.useQQStickerPackage) { - final qqEmojiSet = TUIKitStickerConstData.emojiList.firstWhere((element) => element.name == "4349"); - stickerPackageList.add(CustomStickerPackage( - name: qqEmojiSet.name, - baseUrl: "assets/custom_face_resource/${qqEmojiSet.name}", - isEmoji: qqEmojiSet.isEmoji, - isDefaultEmoji: true, - stickerList: qqEmojiSet.list.asMap().keys.map((idx) => CustomSticker(index: idx, name: qqEmojiSet.list[idx])).toList(), - menuItem: CustomSticker( - index: 0, - name: qqEmojiSet.icon, - ))); - } - if (stickerConfig.unicodeEmojiList.isNotEmpty) { - final defEmojiList = TUIKitStickerConstData.defaultUnicodeEmojiList.map((emojiItem) { - return CustomSticker(index: 0, name: emojiItem.toString(), unicode: emojiItem); - }).toList(); - stickerPackageList.add(CustomStickerPackage(name: "defaultEmoji", stickerList: defEmojiList, menuItem: defEmojiList[0])); - } - stickerPackageList.addAll(stickerConfig.customStickerPackages); + stickerPackageList.addAll(stickerConfig.customStickerPackages); return stickerPackageList; } @@ -215,7 +204,8 @@ class _InputTextFieldState extends TIMUIKitState { if (cursorPosition > 0) { final EmojiUtil emojiUtil = EmojiUtil(); int removeLength = 1; - int openBracketIndex = originalText.lastIndexOf('[', cursorPosition - 1); + int openBracketIndex = + originalText.lastIndexOf('[', cursorPosition - 1); if (openBracketIndex != -1 && originalText[cursorPosition - 1] == ']') { // Small png emoji @@ -224,18 +214,23 @@ class _InputTextFieldState extends TIMUIKitState { if (emojiUtil.emojiMap.containsKey(key)) { removeLength = cursorPosition - openBracketIndex; } - } else if (cursorPosition > 1 && isEmoji(originalText.substring(cursorPosition - 2, cursorPosition))) { + } else if (cursorPosition > 1 && + isEmoji( + originalText.substring(cursorPosition - 2, cursorPosition))) { removeLength = 2; } - text = originalText.substring(0, cursorPosition - removeLength) + originalText.substring(cursorPosition); + text = originalText.substring(0, cursorPosition - removeLength) + + originalText.substring(cursorPosition); currentCursor = (currentCursor ?? removeLength) - removeLength; } textEditingController.text = text; if (TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop) { - textEditingController.selection = TextSelection.fromPosition(TextPosition(offset: currentCursor ?? textEditingController.text.length)); + textEditingController.selection = TextSelection.fromPosition( + TextPosition( + offset: currentCursor ?? textEditingController.text.length)); focusNode.requestFocus(); } } @@ -255,7 +250,9 @@ class _InputTextFieldState extends TIMUIKitState { void _addStickerToText(String sticker) { final currentText = textEditingController.text; - if (currentCursor != null && currentCursor! > -1 && currentCursor! < currentText.length + 1) { + if (currentCursor != null && + currentCursor! > -1 && + currentCursor! < currentText.length + 1) { final firstString = currentText.substring(0, currentCursor); final secondString = currentText.substring(currentCursor!); currentCursor = currentCursor! + sticker.length; @@ -266,7 +263,8 @@ class _InputTextFieldState extends TIMUIKitState { } if (TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop) { - textEditingController.selection = TextSelection.fromPosition(TextPosition(offset: currentCursor ?? textEditingController.text.length)); + textEditingController.selection = TextSelection.fromPosition(TextPosition( + offset: currentCursor ?? textEditingController.text.length)); focusNode.requestFocus(); } } @@ -275,13 +273,23 @@ class _InputTextFieldState extends TIMUIKitState { return text.replaceAll(RegExp(r'\ufeff'), ""); } - Future handleSetDraftText({String? id, ConvType? convType, String? groupID}) async { + Future handleSetDraftText( + {String? id, ConvType? convType, String? groupID}) async { String text = textEditingController.text; String convID = id ?? widget.conversationID; final isTopic = convID.contains("@TOPIC#"); - String conversationID = isTopic ? convID : ((convType ?? widget.conversationType) == ConvType.c2c ? "${TUIConversationViewModel.conversationC2CPrefix}$convID" : "${TUIConversationViewModel.conversationGroupPrefix}$convID"); + String conversationID = isTopic + ? convID + : ((convType ?? widget.conversationType) == ConvType.c2c + ? "${TUIConversationViewModel.conversationC2CPrefix}$convID" + : "${TUIConversationViewModel.conversationGroupPrefix}$convID"); String draftText = _filterU200b(text); - return await conversationModel.setConversationDraft(groupID: groupID ?? widget.groupID, isTopic: isTopic, isAllowWeb: widget.model.chatConfig.isUseDraftOnWeb, conversationID: conversationID, draftText: draftText); + return await conversationModel.setConversationDraft( + groupID: groupID ?? widget.groupID, + isTopic: isTopic, + isAllowWeb: widget.model.chatConfig.isUseDraftOnWeb, + conversationID: conversationID, + draftText: draftText); } // 和onSubmitted一样,只是保持焦点的不同 @@ -329,9 +337,21 @@ class _InputTextFieldState extends TIMUIKitState { } if (widget.model.repliedMessage != null) { - MessageUtils.handleMessageError(widget.model.sendFaceMessage(index: index, data: data, convID: widget.conversationID, convType: convType), context); + MessageUtils.handleMessageError( + widget.model.sendFaceMessage( + index: index, + data: data, + convID: widget.conversationID, + convType: convType), + context); } else { - MessageUtils.handleMessageError(widget.model.sendFaceMessage(index: index, data: data, convID: widget.conversationID, convType: convType), context); + MessageUtils.handleMessageError( + widget.model.sendFaceMessage( + index: index, + data: data, + convID: widget.conversationID, + convType: convType), + context); } } @@ -351,11 +371,24 @@ class _InputTextFieldState extends TIMUIKitState { final convType = widget.conversationType; if (text.isNotEmpty && text != zeroWidthSpace) { if (widget.model.repliedMessage != null) { - MessageUtils.handleMessageError(widget.model.sendReplyMessage(text: text, convID: widget.conversationID, convType: convType, atUserIDList: getUserIdFromMemberInfoMap()), context); + MessageUtils.handleMessageError( + widget.model.sendReplyMessage( + text: text, + convID: widget.conversationID, + convType: convType, + atUserIDList: getUserIdFromMemberInfoMap()), + context); } else if (mentionedMembersMap.isNotEmpty) { - widget.model.sendTextAtMessage(text: text, convType: widget.conversationType, convID: widget.conversationID, atUserList: getUserIdFromMemberInfoMap()); + widget.model.sendTextAtMessage( + text: text, + convType: widget.conversationType, + convID: widget.conversationID, + atUserList: getUserIdFromMemberInfoMap()); } else { - MessageUtils.handleMessageError(widget.model.sendTextMessage(text: text, convID: widget.conversationID, convType: convType), context); + MessageUtils.handleMessageError( + widget.model.sendTextMessage( + text: text, convID: widget.conversationID, convType: convType), + context); } textEditingController.clear(); currentCursor = null; @@ -368,7 +401,8 @@ class _InputTextFieldState extends TIMUIKitState { } void goDownBottom() { - if (globalModel.getMessageListPosition(widget.conversationID) == HistoryMessagePosition.notShowLatest) { + if (globalModel.getMessageListPosition(widget.conversationID) == + HistoryMessagePosition.notShowLatest) { return; } Future.delayed(const Duration(milliseconds: 50), () { @@ -397,14 +431,18 @@ class _InputTextFieldState extends TIMUIKitState { } String _getShowName(V2TimGroupMemberFullInfo? item) { - return TencentUtils.checkStringWithoutSpace(item?.nameCard) ?? TencentUtils.checkStringWithoutSpace(item?.nickName) ?? TencentUtils.checkStringWithoutSpace(item?.userID) ?? ""; + return TencentUtils.checkStringWithoutSpace(item?.nameCard) ?? + TencentUtils.checkStringWithoutSpace(item?.nickName) ?? + TencentUtils.checkStringWithoutSpace(item?.userID) ?? + ""; } mentionMemberInMessage(String? userID, String? nickName) { if (TencentUtils.checkString(userID) == null) { focusNode.requestFocus(); } else { - final memberInfo = widget.model.groupMemberList?.firstWhereOrNull((element) => element?.userID == userID) ?? + final memberInfo = widget.model.groupMemberList + ?.firstWhereOrNull((element) => element?.userID == userID) ?? V2TimGroupMemberFullInfo( userID: userID ?? "", nickName: nickName, @@ -415,7 +453,8 @@ class _InputTextFieldState extends TIMUIKitState { //please do not delete space focusNode.requestFocus(); textEditingController.text = text; - textEditingController.selection = TextSelection.fromPosition(TextPosition(offset: text.length)); + textEditingController.selection = + TextSelection.fromPosition(TextPosition(offset: text.length)); lastText = text; _isComposingText = false; narrowTextFieldKey.currentState?.showKeyboard = true; @@ -443,10 +482,16 @@ class _InputTextFieldState extends TIMUIKitState { maxLines: null, ); textPainter.layout(maxWidth: inputWidth); - final TextPosition lastLineOffset = textPainter.getPositionForOffset(Offset(textPainter.width, textPainter.height)); - final Offset caretPosition = textPainter.getOffsetForCaret(lastLineOffset, Rect.zero); + final TextPosition lastLineOffset = textPainter + .getPositionForOffset(Offset(textPainter.width, textPainter.height)); + final Offset caretPosition = + textPainter.getOffsetForCaret(lastLineOffset, Rect.zero); final dx = min(inputWidth - 180, caretPosition.dx + 16); - final dy = max(24, 21 * widget.model.chatConfig.desktopMessageInputFieldLines - caretPosition.dy).toDouble(); + final dy = max( + 24, + 21 * widget.model.chatConfig.desktopMessageInputFieldLines - + caretPosition.dy) + .toDouble(); return Offset(dx, dy); } @@ -483,13 +528,19 @@ class _InputTextFieldState extends TIMUIKitState { mentionedMembersMap = map; } - (int, String, bool)? findChangedCharacter(String originalString, String newString) { + (int, String, bool)? findChangedCharacter( + String originalString, String newString) { if (newString.length < originalString.length) { final originalStringLength = originalString.length; final newStringLength = newString.length; for (int i = 0; i < newString.length; ++i) { - if (originalString[originalStringLength - i - 1] != newString[newStringLength - i - 1]) { - return (newStringLength - i, originalString[originalStringLength - i - 1], false); + if (originalString[originalStringLength - i - 1] != + newString[newStringLength - i - 1]) { + return ( + newStringLength - i, + originalString[originalStringLength - i - 1], + false + ); } } return (newString.length, originalString[newString.length], false); @@ -508,8 +559,11 @@ class _InputTextFieldState extends TIMUIKitState { _handleAtText(String text, TUIChatSeparateViewModel model) async { final text = textEditingController.text; final String originalText = lastText; - String? groupID = widget.conversationType == ConvType.group ? widget.conversationID : null; - final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + String? groupID = widget.conversationType == ConvType.group + ? widget.conversationID + : null; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; if (groupID == null) { lastText = text; @@ -529,9 +583,11 @@ class _InputTextFieldState extends TIMUIKitState { String atTag = originalText.substring(atIndex, spaceIndex); String deletedChar = originalText[diffIndex]; if (shouldRemoveAtTag(atTag, deletedChar)) { - final newText = originalText.substring(0, atIndex) + originalText.substring(spaceIndex + 1); + final newText = originalText.substring(0, atIndex) + + originalText.substring(spaceIndex + 1); textEditingController.text = newText; - textEditingController.selection = TextSelection.collapsed(offset: atIndex); + textEditingController.selection = + TextSelection.collapsed(offset: atIndex); lastText = newText; updateMentionedMap(); return; @@ -541,13 +597,14 @@ class _InputTextFieldState extends TIMUIKitState { } final int selfRole = widget.model.selfMemberInfo?.role ?? 0; - final bool canAtAll = widget.model.chatConfig.isMemberCanAtAll ? true : (selfRole == GroupMemberRoleType - .V2TIM_GROUP_MEMBER_ROLE_ADMIN || selfRole - == - GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER); + final bool canAtAll = widget.model.chatConfig.isMemberCanAtAll + ? true + : (selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN || + selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER); if (isDesktopScreen) { - (int, String, bool)? changedCharacterRecord = findChangedCharacter(originalText, text); + (int, String, bool)? changedCharacterRecord = + findChangedCharacter(originalText, text); int? changedTextPosition = changedCharacterRecord?.$1; String? changedCharacter = changedCharacterRecord?.$2; bool isAdded = changedCharacterRecord?.$3 ?? false; @@ -556,10 +613,13 @@ class _InputTextFieldState extends TIMUIKitState { int? atPlace; if (changedTextPosition != null) { - subText = isAdded == true ? text.substring(0, changedTextPosition + 1) : text.substring(0, changedTextPosition); + subText = isAdded == true + ? text.substring(0, changedTextPosition + 1) + : text.substring(0, changedTextPosition); atPlace = subText.lastIndexOf('@'); if (atPlace != -1) { - keyword = text.substring(atPlace + 1, changedTextPosition + (isAdded ? 1 : 0)); + keyword = text.substring( + atPlace + 1, changedTextPosition + (isAdded ? 1 : 0)); } } else { atPlace = -1; @@ -572,21 +632,28 @@ class _InputTextFieldState extends TIMUIKitState { model.atPositionY = atPosition.dy; isAddingAtSearchWords = true; } - List showAtMemberList = (model.groupMemberList ?? []) + List showAtMemberList = (model + .groupMemberList ?? + []) .where((element) { - final showName = (TencentUtils.checkStringWithoutSpace(element?.friendRemark) ?? + final showName = (TencentUtils.checkStringWithoutSpace( + element?.friendRemark) ?? TencentUtils.checkStringWithoutSpace(element?.nameCard) ?? TencentUtils.checkStringWithoutSpace(element?.nickName) ?? TencentUtils.checkStringWithoutSpace(element?.userID) ?? "") .toLowerCase(); keyword ??= ""; - return element != null && showName.contains(keyword!.toLowerCase()) && TencentUtils.checkString(showName) != null && element.userID != widget.model.selfMemberInfo?.userID; + return element != null && + showName.contains(keyword!.toLowerCase()) && + TencentUtils.checkString(showName) != null && + element.userID != widget.model.selfMemberInfo?.userID; }) .whereType() .toList(); - showAtMemberList.sort((V2TimGroupMemberFullInfo userA, V2TimGroupMemberFullInfo userB) { + showAtMemberList.sort( + (V2TimGroupMemberFullInfo userA, V2TimGroupMemberFullInfo userB) { final isUserAIsGroupAdmin = userA.role == 300; final isUserAIsGroupOwner = userA.role == 400; @@ -609,7 +676,11 @@ class _InputTextFieldState extends TIMUIKitState { keyword ??= ""; if (canAtAll && showAtMemberList.isNotEmpty && keyword!.isEmpty) { - showAtMemberList = [V2TimGroupMemberFullInfo(userID: "__kImSDK_MesssageAtALL__", nickName: TIM_t("所有人")), ...showAtMemberList]; + showAtMemberList = [ + V2TimGroupMemberFullInfo( + userID: "__kImSDK_MesssageAtALL__", nickName: TIM_t("所有人")), + ...showAtMemberList + ]; } model.activeAtIndex = 0; @@ -621,11 +692,19 @@ class _InputTextFieldState extends TIMUIKitState { model.showAtMemberList = []; isAddingAtSearchWords = false; } - } else if (textLength > 0 && text[textLength - 1] == "@" && lastText.length < textLength) { - List selectedAtMemberList = await Navigator.push( + } else if (textLength > 0 && + text[textLength - 1] == "@" && + lastText.length < textLength) { + List selectedAtMemberList = + await Navigator.push( context, MaterialPageRoute( - builder: (context) => AtText(groupMemberList: model.groupMemberList, groupInfo: model.groupInfo, groupID: groupID, canAtAll: canAtAll, groupType: widget.groupType), + builder: (context) => AtText( + groupMemberList: model.groupMemberList, + groupInfo: model.groupInfo, + groupID: groupID, + canAtAll: canAtAll, + groupType: widget.groupType), ), ); @@ -635,7 +714,8 @@ class _InputTextFieldState extends TIMUIKitState { if (memberInfo != null) { mentionedMembersMap["@$showName"] = memberInfo; String addAtCharacter = i == 0 ? "" : "@"; - textEditingController.text = "${textEditingController.text}$addAtCharacter$showName "; + textEditingController.text = + "${textEditingController.text}$addAtCharacter$showName "; lastText = "${textEditingController.text}$addAtCharacter$showName "; } } @@ -646,17 +726,22 @@ class _InputTextFieldState extends TIMUIKitState { void replaceAtTag(String selectedMember) { int cursorPosition = textEditingController.selection.baseOffset; - int atIndex = textEditingController.text.lastIndexOf('@', cursorPosition - 1); + int atIndex = + textEditingController.text.lastIndexOf('@', cursorPosition - 1); if (atIndex >= 0) { String beforeAt = textEditingController.text.substring(0, atIndex); String afterAt = textEditingController.text.substring(cursorPosition); - textEditingController.text = beforeAt + '@' + selectedMember + ' ' + afterAt; - textEditingController.selection = TextSelection.collapsed(offset: atIndex + selectedMember.length + 2); + textEditingController.text = + beforeAt + '@' + selectedMember + ' ' + afterAt; + textEditingController.selection = + TextSelection.collapsed(offset: atIndex + selectedMember.length + 2); lastText = beforeAt + '@' + selectedMember + ' ' + afterAt; } } - void handleAtMember({V2TimGroupMemberFullInfo? memberInfo, bool? isAddToCursorPosition = false}) { + void handleAtMember( + {V2TimGroupMemberFullInfo? memberInfo, + bool? isAddToCursorPosition = false}) { if (memberInfo != null) { final String showName = _getShowName(memberInfo); mentionedMembersMap["@$showName"] = memberInfo; @@ -670,17 +755,24 @@ class _InputTextFieldState extends TIMUIKitState { KeyEventResult handleDesktopKeyEvent(FocusNode node, RawKeyEvent event) { final activeIndex = widget.model.activeAtIndex; final showMemberList = widget.model.showAtMemberList; - final isPressEnter = (event.physicalKey == PhysicalKeyboardKey.enter) || (event.physicalKey == PhysicalKeyboardKey.numpadEnter); + final isPressEnter = (event.physicalKey == PhysicalKeyboardKey.enter) || + (event.physicalKey == PhysicalKeyboardKey.numpadEnter); if (event.runtimeType == RawKeyDownEvent) { if (event.physicalKey == PhysicalKeyboardKey.backspace) { if (textEditingController.text.isEmpty && lastText.isEmpty) { widget.model.repliedMessage = null; return KeyEventResult.handled; } - } else if ((event.isShiftPressed || event.isAltPressed || event.isControlPressed || event.isMetaPressed) && isPressEnter) { + } else if ((event.isShiftPressed || + event.isAltPressed || + event.isControlPressed || + event.isMetaPressed) && + isPressEnter) { final offset = textEditingController.selection.baseOffset; - textEditingController.text = '${lastText.substring(0, offset)}\n${lastText.substring(offset)}'; - textEditingController.selection = TextSelection.fromPosition(TextPosition(offset: offset + 1)); + textEditingController.text = + '${lastText.substring(0, offset)}\n${lastText.substring(offset)}'; + textEditingController.selection = + TextSelection.fromPosition(TextPosition(offset: offset + 1)); lastText = textEditingController.text; return KeyEventResult.handled; @@ -690,26 +782,34 @@ class _InputTextFieldState extends TIMUIKitState { onSubmitted(); } else { isAddingAtSearchWords = false; - final V2TimGroupMemberFullInfo? memberInfo = showMemberList[activeIndex]; + final V2TimGroupMemberFullInfo? memberInfo = + showMemberList[activeIndex]; if (memberInfo != null) { - handleAtMember(memberInfo: memberInfo, isAddToCursorPosition: true); + handleAtMember( + memberInfo: memberInfo, isAddToCursorPosition: true); } } return KeyEventResult.handled; } } - if (event.isKeyPressed(LogicalKeyboardKey.arrowUp) && isAddingAtSearchWords && showMemberList.isNotEmpty) { + if (event.isKeyPressed(LogicalKeyboardKey.arrowUp) && + isAddingAtSearchWords && + showMemberList.isNotEmpty) { final newIndex = max(activeIndex - 1, 0); widget.model.activeAtIndex = newIndex; - widget.atMemberPanelScroll?.scrollToIndex(newIndex, preferPosition: AutoScrollPosition.middle); + widget.atMemberPanelScroll?.scrollToIndex(newIndex, + preferPosition: AutoScrollPosition.middle); return KeyEventResult.handled; } - if (event.isKeyPressed(LogicalKeyboardKey.arrowDown) && isAddingAtSearchWords && showMemberList.isNotEmpty) { + if (event.isKeyPressed(LogicalKeyboardKey.arrowDown) && + isAddingAtSearchWords && + showMemberList.isNotEmpty) { final newIndex = min(activeIndex + 1, showMemberList.length - 1); widget.model.activeAtIndex = newIndex; - widget.atMemberPanelScroll?.scrollToIndex(newIndex, preferPosition: AutoScrollPosition.middle); + widget.atMemberPanelScroll?.scrollToIndex(newIndex, + preferPosition: AutoScrollPosition.middle); return KeyEventResult.handled; } } @@ -727,7 +827,8 @@ class _InputTextFieldState extends TIMUIKitState { } else { focusNode = FocusNode(); } - textEditingController = widget.controller?.textEditingController ?? TextEditingController(); + textEditingController = + widget.controller?.textEditingController ?? TextEditingController(); if (widget.initText != null) { textEditingController.text = widget.initText!; } @@ -735,7 +836,10 @@ class _InputTextFieldState extends TIMUIKitState { widget.controller?.addListener(controllerHandler); } final AppLocale appLocale = I18nUtils.findDeviceLocale(null); - languageType = (appLocale == AppLocale.zhHans || appLocale == AppLocale.zhHant) ? 'zh' : 'en'; + languageType = + (appLocale == AppLocale.zhHans || appLocale == AppLocale.zhHant) + ? 'zh' + : 'en'; textEditingController.addListener(() { _isComposingText = textEditingController.value.composing.start != -1; }); @@ -745,11 +849,13 @@ class _InputTextFieldState extends TIMUIKitState { controllerHandler() { final actionType = widget.controller?.actionType; if (actionType == ActionType.longPressToAt) { - mentionMemberInMessage(widget.controller?.atUserID, widget.controller?.atUserName); + mentionMemberInMessage( + widget.controller?.atUserID, widget.controller?.atUserName); } else if (actionType == ActionType.setTextField) { final newText = widget.controller?.inputText ?? ""; textEditingController.text = newText; - textEditingController.selection = TextSelection.fromPosition(TextPosition(offset: textEditingController.text.length)); + textEditingController.selection = TextSelection.fromPosition( + TextPosition(offset: textEditingController.text.length)); lastText = textEditingController.text; focusNode.requestFocus(); return; @@ -767,14 +873,18 @@ class _InputTextFieldState extends TIMUIKitState { super.didUpdateWidget(oldWidget); if (widget.conversationID != oldWidget.conversationID) { mentionedMembersMap.clear(); - handleSetDraftText(id: oldWidget.conversationID, convType: oldWidget.conversationType, groupID: oldWidget.groupID); + handleSetDraftText( + id: oldWidget.conversationID, + convType: oldWidget.conversationType, + groupID: oldWidget.groupID); if (oldWidget.initText != widget.initText) { textEditingController.text = widget.initText ?? ""; } else { textEditingController.clear(); } } - if (widget.initText != oldWidget.initText && TencentUtils.checkString(widget.initText) != null) { + if (widget.initText != oldWidget.initText && + TencentUtils.checkString(widget.initText) != null) { textEditingController.text = widget.initText!; focusNode.requestFocus(); } @@ -792,8 +902,12 @@ class _InputTextFieldState extends TIMUIKitState { Future getMemberMuteStatus(String userID) async { // Get the mute state of the members recursively - if (widget.model.groupMemberList?.any((item) => (item?.userID == userID)) ?? false) { - final int muteUntil = widget.model.groupMemberList?.firstWhere((item) => (item?.userID == userID))?.muteUntil ?? 0; + if (widget.model.groupMemberList?.any((item) => (item?.userID == userID)) ?? + false) { + final int muteUntil = widget.model.groupMemberList + ?.firstWhere((item) => (item?.userID == userID)) + ?.muteUntil ?? + 0; return muteUntil * 1000 > DateTime.now().millisecondsSinceEpoch; } else { return false; @@ -806,22 +920,30 @@ class _InputTextFieldState extends TIMUIKitState { } final int selfRole = widget.model.selfMemberInfo?.role ?? 0; - final bool willNotBeenMuted = (selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN || selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER); + final bool willNotBeenMuted = + (selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN || + selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER); if (widget.conversationType == ConvType.group && !willNotBeenMuted) { - if ((model.groupInfo?.isAllMuted ?? false) && muteStatus != MuteStatus.all) { + if ((model.groupInfo?.isAllMuted ?? false) && + muteStatus != MuteStatus.all) { Future.delayed(const Duration(seconds: 0), () { setState(() { muteStatus = MuteStatus.all; }); }); - } else if (selfModel.loginInfo?.userID != null && await getMemberMuteStatus(selfModel.loginInfo!.userID!) && muteStatus != MuteStatus.me) { + } else if (selfModel.loginInfo?.userID != null && + await getMemberMuteStatus(selfModel.loginInfo!.userID!) && + muteStatus != MuteStatus.me) { Future.delayed(const Duration(seconds: 0), () { setState(() { muteStatus = MuteStatus.me; }); }); - } else if (!(model.groupInfo?.isAllMuted ?? false) && !(selfModel.loginInfo?.userID != null && await getMemberMuteStatus(selfModel.loginInfo!.userID!)) && muteStatus != MuteStatus.none) { + } else if (!(model.groupInfo?.isAllMuted ?? false) && + !(selfModel.loginInfo?.userID != null && + await getMemberMuteStatus(selfModel.loginInfo!.userID!)) && + muteStatus != MuteStatus.none) { Future.delayed(const Duration(seconds: 0), () { setState(() { muteStatus = MuteStatus.none; @@ -850,7 +972,8 @@ class _InputTextFieldState extends TIMUIKitState { @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final theme = value.theme; - final TUIChatSeparateViewModel model = Provider.of(context); + final TUIChatSeparateViewModel model = + Provider.of(context); _getMuteType(model); @@ -870,7 +993,8 @@ class _InputTextFieldState extends TIMUIKitState { } final forbiddenText = getForbiddenText(); - return LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) { + return LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { inputWidth = constraints.maxWidth; return TUIKitScreenUtils.getDeviceWidget( context: context, diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/narrow.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/narrow.dart index 8c9c31c..b12c200 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/narrow.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/narrow.dart @@ -132,10 +132,12 @@ class TIMUIKitTextFieldLayoutNarrow extends StatefulWidget { : super(key: key); @override - State createState() => _TIMUIKitTextFieldLayoutNarrowState(); + State createState() => + _TIMUIKitTextFieldLayoutNarrowState(); } -class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState { +class _TIMUIKitTextFieldLayoutNarrowState + extends TIMUIKitState { final TUISettingModel settingModel = serviceLocator(); bool showMore = false; @@ -209,14 +211,13 @@ class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState= 46 && showKeyboard == false) { + } else if (widget.textEditingController.text.length >= 46 && + showKeyboard == false) { return 25 + (bottomPadding ?? 0.0); } else { return bottomPadding ?? 0; @@ -323,14 +325,20 @@ class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState createState() => _TIMUIKitTextFieldLayoutWideState(); + State createState() => + _TIMUIKitTextFieldLayoutWideState(); } -class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState { +class _TIMUIKitTextFieldLayoutWideState + extends TIMUIKitState { final TUISettingModel settingModel = serviceLocator(); OverlayEntry? entry; final ImagePicker _picker = ImagePicker(); @@ -265,11 +269,13 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState generateBarIcons(List items, TUITheme theme) { + List generateBarIcons( + List items, TUITheme theme) { final defaultItems = defaultControlBarItems.map((e) => e.item); return items.map((e) { final GlobalKey key = GlobalKey(); @@ -498,12 +511,15 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState= 104857600) { - onTIMCallback( - TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("发送失败,视频不能大于100MB"), infoCode: 6660405)); + onTIMCallback(TIMCallback( + type: TIMCallbackType.INFO, + infoRecommendText: TIM_t("发送失败,视频不能大于100MB"), + infoCode: 6660405)); return; } @@ -612,7 +646,9 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState itemsList = [ if (config.showStickerPanel) DesktopControlBarItem( @@ -835,9 +900,13 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState generateControlBar(TUIChatSeparateViewModel model, TUITheme theme) { + List generateControlBar( + TUIChatSeparateViewModel model, TUITheme theme) { final List itemsList = [ ...defaultControlBarItems, ...(widget.chatConfig.additionalDesktopControlBarItems ?? []) @@ -860,22 +930,29 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState _handleKeyEvent(RawKeyEvent event) async { if (PlatformUtils().isDesktop && - ((event.isKeyPressed(LogicalKeyboardKey.controlLeft) && event.logicalKey == LogicalKeyboardKey.keyV) || - (event.isMetaPressed && event.logicalKey == LogicalKeyboardKey.keyV))) { + ((event.isKeyPressed(LogicalKeyboardKey.controlLeft) && + event.logicalKey == LogicalKeyboardKey.keyV) || + (event.isMetaPressed && + event.logicalKey == LogicalKeyboardKey.keyV))) { final bytes = await Pasteboard.image; if (bytes != null) { String directory; if (PlatformUtils().isWindows) { - final String documentsDirectoryPath = "${Platform.environment['USERPROFILE']}"; + final String documentsDirectoryPath = + "${Platform.environment['USERPROFILE']}"; PackageInfo packageInfo = await PackageInfo.fromPlatform(); String pkgName = packageInfo.packageName; - directory = p.join(documentsDirectoryPath, "Documents", ".TencentCloudChat", pkgName, "screenshots"); + directory = p.join(documentsDirectoryPath, "Documents", + ".TencentCloudChat", pkgName, "screenshots"); } else { final dic = await getApplicationSupportDirectory(); directory = dic.path; @@ -883,7 +960,8 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState { TUIChatSeparateViewModel model = TUIChatSeparateViewModel(); - final TUISelfInfoViewModel selfInfoViewModel = serviceLocator(); + final TUISelfInfoViewModel selfInfoViewModel = + serviceLocator(); final TUIThemeViewModel themeViewModel = serviceLocator(); - final TUIConversationViewModel conversationViewModel = serviceLocator(); - TIMUIKitInputTextFieldController textFieldController = TIMUIKitInputTextFieldController(); + final TUIConversationViewModel conversationViewModel = + serviceLocator(); + TIMUIKitInputTextFieldController textFieldController = + TIMUIKitInputTextFieldController(); bool isInit = false; - final TUIChatGlobalModel chatGlobalModel = serviceLocator(); + final TUIChatGlobalModel chatGlobalModel = + serviceLocator(); bool _dragging = false; final GlobalKey alignKey = GlobalKey(); final GlobalKey listContainerKey = GlobalKey(); late AutoScrollController autoController = AutoScrollController( - viewportBoundaryGetter: () => Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom), + viewportBoundaryGetter: () => + Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom), axis: Axis.vertical, ); late AutoScrollController atMemberPanelScroll = AutoScrollController( - viewportBoundaryGetter: () => Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom), + viewportBoundaryGetter: () => + Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom), axis: Axis.vertical, ); @@ -293,7 +307,11 @@ class _TUIChatState extends TIMUIKitState { updateDraft() async { final isTopic = widget.conversation.conversationID.contains("@TOPIC#"); if (isTopic) { - final topicInfoList = await TencentImSDKPlugin.v2TIMManager.getGroupManager().getTopicInfoList(groupID: widget.groupID!, topicIDList: [widget.conversation.conversationID]); + final topicInfoList = await TencentImSDKPlugin.v2TIMManager + .getGroupManager() + .getTopicInfoList( + groupID: widget.groupID!, + topicIDList: [widget.conversation.conversationID]); final topicInfo = topicInfoList.data?.first.topicInfo; final draftText = topicInfo?.draftText; if (TencentUtils.checkString(draftText) != null) { @@ -318,7 +336,8 @@ class _TUIChatState extends TIMUIKitState { crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - TIM_t_para("{{option1}} 条入群请求", "$option1 条入群请求")(option1: option1), + TIM_t_para("{{option1}} 条入群请求", "$option1 条入群请求")( + option1: option1), style: const TextStyle( fontSize: 12, ), @@ -337,11 +356,17 @@ class _TUIChatState extends TIMUIKitState { } String _getTitle() { - return TencentUtils.checkString(widget.conversationShowName) ?? widget.conversation.showName ?? "Chat"; + return TencentUtils.checkString(widget.conversationShowName) ?? + widget.conversation.showName ?? + "Chat"; } String _getConvID() { - return TencentUtils.checkString(widget.conversationID) ?? (widget.conversation.type == 1 ? widget.conversation.userID : widget.conversation.groupID) ?? ""; + return TencentUtils.checkString(widget.conversationID) ?? + (widget.conversation.type == 1 + ? widget.conversation.userID + : widget.conversation.groupID) ?? + ""; } ConvType _getConvType() { @@ -352,9 +377,9 @@ class _TUIChatState extends TIMUIKitState { if (_getConvType() != ConvType.group) { return; } - final w = await TUICore.instance.raiseExtension(TUIExtensionID.joinInGroup, {GROUP_ID: widget.conversationID!}); - if(w != _joinInGroupCallWidget){ - + final w = await TUICore.instance.raiseExtension( + TUIExtensionID.joinInGroup, {GROUP_ID: widget.conversationID!}); + if (w != _joinInGroupCallWidget) { setState(() { _joinInGroupCallWidget = w; }); @@ -383,22 +408,28 @@ class _TUIChatState extends TIMUIKitState { Provider(create: (_) => widget.config), ], builder: (context, model, w) { - final TUIChatGlobalModel chatGlobalModel = Provider.of(context, listen: true); + final TUIChatGlobalModel chatGlobalModel = + Provider.of(context, listen: true); widget.controller?.model = model; widget.controller?.textFieldController = textFieldController; widget.controller?.scrollController = autoController; List filteredApplicationList = []; - if (widget.conversationType == ConvType.group && widget.onDealWithGroupApplication != null) { - filteredApplicationList = chatGlobalModel.groupApplicationList.where((item) { - return (item.groupID == widget.conversationID) && item.handleStatus == 0; + if (widget.conversationType == ConvType.group && + widget.onDealWithGroupApplication != null) { + filteredApplicationList = + chatGlobalModel.groupApplicationList.where((item) { + return (item.groupID == widget.conversationID) && + item.handleStatus == 0; }).toList(); } final selfUserID = selfInfoViewModel.loginInfo?.userID; - final TUIGroupListenerModel groupListenerModel = Provider.of(context, listen: true); + final TUIGroupListenerModel groupListenerModel = + Provider.of(context, listen: true); final NeedUpdate? needUpdate = groupListenerModel.needUpdate; - if (needUpdate != null && needUpdate.groupID == widget.conversationID) { + if (needUpdate != null && + needUpdate.groupID == widget.conversationID) { groupListenerModel.needUpdate = null; switch (needUpdate.updateType) { case UpdateType.groupInfo: @@ -416,13 +447,24 @@ class _TUIChatState extends TIMUIKitState { } List customImageSmallPngEmojiPackages = []; - if (widget.config?.stickerPanelConfig?.customStickerPackages != null && widget.config!.stickerPanelConfig!.customStickerPackages.isNotEmpty) { - customImageSmallPngEmojiPackages = widget.config!.stickerPanelConfig!.customStickerPackages.where((element) => element.isEmoji == true).map((e) { - return CustomEmojiFaceData(name: e.name, isEmoji: true, icon: e.menuItem.url ?? "", list: e.stickerList.map((e) => e.url ?? "").toList()); + if (widget.config?.stickerPanelConfig?.customStickerPackages != + null && + widget.config!.stickerPanelConfig!.customStickerPackages + .isNotEmpty) { + customImageSmallPngEmojiPackages = widget + .config!.stickerPanelConfig!.customStickerPackages + .where((element) => element.isEmoji == true) + .map((e) { + return CustomEmojiFaceData( + name: e.name, + isEmoji: true, + icon: e.menuItem.url ?? "", + list: e.stickerList.map((e) => e.url ?? "").toList()); }).toList(); } if (customImageSmallPngEmojiPackages.isEmpty) { - customImageSmallPngEmojiPackages.addAll(widget.customEmojiStickerList); + customImageSmallPngEmojiPackages + .addAll(widget.customEmojiStickerList); } return GestureDetector( @@ -437,14 +479,21 @@ class _TUIChatState extends TIMUIKitState { config: widget.appBarConfig, conversationShowName: _getTitle(), conversationID: _getConvID(), - showC2cMessageEditStatus: widget.config?.showC2cMessageEditStatus ?? true, + showC2cMessageEditStatus: + widget.config?.showC2cMessageEditStatus ?? true, ) : null, body: DropTarget( onDragDone: (detail) { setState(() { _dragging = false; - sendFileWithConfirmation(files: detail.files, conversation: widget.conversation, conversationType: _getConvType(), model: model, theme: theme, context: context); + sendFileWithConfirmation( + files: detail.files, + conversation: widget.conversation, + conversationType: _getConvType(), + model: model, + theme: theme, + context: context); }); }, onDragEntered: (detail) { @@ -463,9 +512,12 @@ class _TUIChatState extends TIMUIKitState { crossAxisAlignment: CrossAxisAlignment.start, children: [ if (widget.customAppBar != null) widget.customAppBar!, - if (filteredApplicationList.isNotEmpty) _renderJoinGroupApplication(filteredApplicationList.length, theme), + if (filteredApplicationList.isNotEmpty) + _renderJoinGroupApplication( + filteredApplicationList.length, theme), if (widget.topFixWidget != null) widget.topFixWidget!, - if (_joinInGroupCallWidget != null) Center(child: _joinInGroupCallWidget!), + if (_joinInGroupCallWidget != null) + Center(child: _joinInGroupCallWidget!), Expanded( child: Container( color: theme.chatBgColor, @@ -474,31 +526,43 @@ class _TUIChatState extends TIMUIKitState { alignment: Alignment.topCenter, child: Listener( child: TIMUIKitHistoryMessageListContainer( - customMessageHoverBarOnDesktop: widget.customMessageHoverBarOnDesktop, + customMessageHoverBarOnDesktop: + widget.customMessageHoverBarOnDesktop, conversation: widget.conversation, - groupMemberInfo: model.groupMemberList?.firstWhere((element) => element?.userID == selfUserID, orElse: () => null), + groupMemberInfo: model.groupMemberList + ?.firstWhere( + (element) => + element?.userID == selfUserID, + orElse: () => null), textFieldController: textFieldController, - customEmojiStickerList: widget.customEmojiStickerList, - isUseDefaultEmoji: widget.config!.isUseDefaultEmoji, + customEmojiStickerList: + widget.customEmojiStickerList, key: listContainerKey, isAllowScroll: true, userAvatarBuilder: widget.userAvatarBuilder, toolTipsConfig: widget.toolTipsConfig, groupAtInfoList: widget.groupAtInfoList, tongueItemBuilder: widget.tongueItemBuilder, - onLongPressForOthersHeadPortrait: (String? userId, String? nickName) { - textFieldController.longPressToAt(nickName, userId); + onLongPressForOthersHeadPortrait: + (String? userId, String? nickName) { + textFieldController.longPressToAt( + nickName, userId); }, - mainHistoryListConfig: widget.mainHistoryListConfig, + mainHistoryListConfig: + widget.mainHistoryListConfig, initFindingMsg: widget.initFindingMsg, - extraTipsActionItemBuilder: widget.extraTipsActionItemBuilder ?? widget.exteraTipsActionItemBuilder, + extraTipsActionItemBuilder: + widget.extraTipsActionItemBuilder ?? + widget.exteraTipsActionItemBuilder, conversationType: _getConvType(), scrollController: autoController, - onSecondaryTapAvatar: widget.onSecondaryTapAvatar, + onSecondaryTapAvatar: + widget.onSecondaryTapAvatar, onTapAvatar: widget.onTapAvatar, // ignore: deprecated_member_use_from_same_package showNickName: widget.showNickName, - messageItemBuilder: widget.messageItemBuilder, + messageItemBuilder: + widget.messageItemBuilder, conversationID: _getConvID(), ), )), @@ -515,26 +579,45 @@ class _TUIChatState extends TIMUIKitState { : TIMUIKitInputTextField( chatConfig: widget.config, groupID: widget.groupID, - atMemberPanelScroll: atMemberPanelScroll, - groupType: widget.conversation.groupType, - currentConversation: widget.conversation, + atMemberPanelScroll: + atMemberPanelScroll, + groupType: + widget.conversation.groupType, + currentConversation: + widget.conversation, model: model, controller: textFieldController, - customEmojiStickerList: customImageSmallPngEmojiPackages, - isUseDefaultEmoji: widget.config!.isUseDefaultEmoji, - customStickerPanel: widget.customStickerPanel, - morePanelConfig: widget.morePanelConfig, + customEmojiStickerList: + customImageSmallPngEmojiPackages, + customStickerPanel: + widget.customStickerPanel, + morePanelConfig: + widget.morePanelConfig, scrollController: autoController, conversationID: _getConvID(), conversationType: _getConvType(), - initText: TencentUtils.checkString(widget.draftText) ?? + initText: TencentUtils.checkString( + widget.draftText) ?? (PlatformUtils().isWeb - ? TencentUtils.checkString(conversationViewModel.getWebDraft(conversationID: widget.conversation.conversationID)) - : TencentUtils.checkString(widget.conversation.draftText)), + ? TencentUtils.checkString( + conversationViewModel + .getWebDraft( + conversationID: widget + .conversation + .conversationID)) + : TencentUtils.checkString( + widget.conversation + .draftText)), hintText: widget.textFieldHintText, - showMorePanel: widget.config?.isAllowShowMorePanel ?? true, - showSendAudio: widget.config?.isAllowSoundMessage ?? true, - showSendEmoji: widget.config?.isAllowEmojiPanel ?? true, + showMorePanel: widget.config + ?.isAllowShowMorePanel ?? + true, + showSendAudio: widget.config + ?.isAllowSoundMessage ?? + true, + showSendEmoji: widget + .config?.isAllowEmojiPanel ?? + true, )); }, selector: (c, model) { @@ -549,7 +632,8 @@ class _TUIChatState extends TIMUIKitState { ), AtMemberPanel( atMemberPanelScroll: atMemberPanelScroll, - onSelectMember: (member) => textFieldController.handleAtMember(member), + onSelectMember: (member) => + textFieldController.handleAtMember(member), ) ], ), @@ -562,12 +646,14 @@ class _TUIChatState extends TIMUIKitState { class TIMUIKitChatProviderScope extends StatelessWidget { final TUIChatGlobalModel globalModel = serviceLocator(); TUIChatSeparateViewModel? model; - final TUIGroupListenerModel groupListenerModel = serviceLocator(); + final TUIGroupListenerModel groupListenerModel = + serviceLocator(); final TUIThemeViewModel themeViewModel = serviceLocator(); final Widget? child; /// You could get the model from here, and transfer it to other widget from TUIKit. - final Widget Function(BuildContext, TUIChatSeparateViewModel, Widget?) builder; + final Widget Function(BuildContext, TUIChatSeparateViewModel, Widget?) + builder; final List? providers; /// `TIMUIKitChatController` needs to be provided if you use it outside. @@ -638,13 +724,16 @@ class TIMUIKitChatProviderScope extends StatelessWidget { preGroupMemberList: groupMemberList, groupID: groupID, ); - model?.showC2cMessageEditStatus = (conversationType == ConvType.c2c ? config?.showC2cMessageEditStatus ?? true : false); + model?.showC2cMessageEditStatus = (conversationType == ConvType.c2c + ? config?.showC2cMessageEditStatus ?? true + : false); loadData(); } loadData() { // if (model!.haveMoreData) { - model!.loadChatRecord(count: kIsWeb ? 15 : HistoryMessageDartConstant.getCount); + model!.loadChatRecord( + count: kIsWeb ? 15 : HistoryMessageDartConstant.getCount); // } } diff --git a/lib/ui/views/TIMUIKitChat/tim_uikit_chat_config.dart b/lib/ui/views/TIMUIKitChat/tim_uikit_chat_config.dart index d02f777..5e3378c 100644 --- a/lib/ui/views/TIMUIKitChat/tim_uikit_chat_config.dart +++ b/lib/ui/views/TIMUIKitChat/tim_uikit_chat_config.dart @@ -24,29 +24,18 @@ class TimeDividerConfig { /// StickerPanelConfig is a configuration class for the sticker panel component. /// It allows customization of specific features such as display options for the -/// message area, sticker packages, unicode emoji lists, and custom sticker packages. +/// message area, sticker packages, and custom sticker packages. class StickerPanelConfig { - /// Determines whether to use the QQ Sticker Package. - /// Default value: true - final bool useQQStickerPackage; - /// Determines whether to use the Tencent Cloud Chat Sticker Package. /// Default value: true final bool useTencentCloudChatStickerPackage; - /// A list of unicode emoji, represented as integers. - /// Default value: a list of common Unicode Emojis. - /// To exclude Unicode Emoji from the display, pass an empty list. - final List unicodeEmojiList; - /// A list of CustomStickerPackage instances, where each instance represents a sticker package. /// Default value: an empty list. final List customStickerPackages; StickerPanelConfig({ - this.useQQStickerPackage = true, this.useTencentCloudChatStickerPackage = true, - this.unicodeEmojiList = TUIKitStickerConstData.defaultUnicodeEmojiList, this.customStickerPackages = const [], }); } @@ -185,9 +174,6 @@ class TIMUIKitChatConfig { /// The default action is opening the link with the default browser of system. final void Function(String url)? onTapLink; - /// Whether to use the default emoji - final bool isUseDefaultEmoji; - /// Whether shows avatar on history message list. /// [Default]: true. final bool isShowAvatar; @@ -273,7 +259,7 @@ class TIMUIKitChatConfig { this.isUseMessageReaction = true, this.isShowAvatar = true, this.isShowSelfNameInGroup = false, - this.isAtWhenReplyDynamic, + this.isAtWhenReplyDynamic, this.offlinePushInfo, @Deprecated("Please use [isShowReadingStatus] instead") this.isShowGroupMessageReadReceipt = true, @@ -285,10 +271,8 @@ class TIMUIKitChatConfig { this.notificationTitle = "", this.notificationIOSSound = "", this.isAllowSoundMessage = true, - @Deprecated("not support") - this.groupReadReceiptPermisionList, - @Deprecated("not support") - this.groupReadReceiptPermissionList, + @Deprecated("not support") this.groupReadReceiptPermisionList, + @Deprecated("not support") this.groupReadReceiptPermissionList, this.isAllowEmojiPanel = true, this.isAllowShowMorePanel = true, this.isShowReadingStatus = true, @@ -304,6 +288,5 @@ class TIMUIKitChatConfig { this.showC2cMessageEditStatus = true, this.additionalDesktopControlBarItems, this.isAllowLongPressAvatarToAt = true, - this.isUseDefaultEmoji = false, this.isMemberCanAtAll = false}); } diff --git a/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_last_msg.dart b/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_last_msg.dart index f73adc4..734d75c 100644 --- a/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_last_msg.dart +++ b/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_last_msg.dart @@ -7,6 +7,7 @@ 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/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; @@ -82,18 +83,29 @@ class _TIMUIKitLastMsgState extends TIMUIKitState { final isAdminRevoke = revokeStatus.$2; if (isRevokedMessage) { final isSelf = widget.lastMsg!.isSelf ?? true; - final option1 = - isAdminRevoke ? TIM_t("管理员") : (isSelf ? TIM_t("您") : widget.lastMsg!.nickName ?? widget.lastMsg?.sender); + final option1 = isAdminRevoke + ? TIM_t("管理员") + : (isSelf + ? TIM_t("您") + : widget.lastMsg!.nickName ?? widget.lastMsg?.sender); if (mounted) { setState(() { - groupTipsAbstractText = TIM_t_para("{{option1}}撤回了一条消息", "$option1撤回了一条消息")(option1: option1); + groupTipsAbstractText = TIM_t_para( + "{{option1}}撤回了一条消息", "$option1撤回了一条消息")(option1: option1); }); } } else { - String msgShowText = await _getLastMsgShowText(widget.lastMsg, widget.context) ?? ""; + String originalText = + await _getLastMsgShowText(widget.lastMsg, widget.context) ?? ""; + String replaceText = TUIKitStickerConstData.emojiZhNameMap.keys + .fold(originalText, (previousValue, key) { + return previousValue.replaceAll( + key, TIM_t(TUIKitStickerConstData.emojiZhNameMap[key]!)); + }); + if (mounted) { setState(() { - groupTipsAbstractText = msgShowText; + groupTipsAbstractText = replaceText; }); } } @@ -102,14 +114,16 @@ class _TIMUIKitLastMsgState extends TIMUIKitState { String _getDisturbUnreadCountInfo() { if (widget.isDisturb && widget.unreadCount > 0) { final option1 = widget.unreadCount.toString(); - String unreadCountText = TIM_t_para("[{{option1}} 条]", "[$option1 条]")(option1: option1); + String unreadCountText = + TIM_t_para("[{{option1}} 条]", "[$option1 条]")(option1: option1); return unreadCountText; } return ""; } - Future _getLastMsgShowText(V2TimMessage? message, BuildContext context) async { + Future _getLastMsgShowText( + V2TimMessage? message, BuildContext context) async { final msgType = message!.elemType; switch (msgType) { case MessageElemType.V2TIM_ELEM_TYPE_CUSTOM: @@ -122,9 +136,11 @@ class _TIMUIKitLastMsgState extends TIMUIKitState { return TIM_t("[表情]"); case MessageElemType.V2TIM_ELEM_TYPE_FILE: final option1 = widget.lastMsg!.fileElem!.fileName; - return TIM_t_para("[文件] {{option1}}", "[文件] $option1")(option1: option1); + return TIM_t_para("[文件] {{option1}}", "[文件] $option1")( + option1: option1); case MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS: - return await MessageUtils.groupTipsMessageAbstract(widget.lastMsg!.groupTipsElem!, []); + return await MessageUtils.groupTipsMessageAbstract( + widget.lastMsg!.groupTipsElem!, []); case MessageElemType.V2TIM_ELEM_TYPE_IMAGE: return TIM_t("[图片]"); case MessageElemType.V2TIM_ELEM_TYPE_VIDEO: @@ -186,7 +202,8 @@ class _TIMUIKitLastMsgState extends TIMUIKitState { @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { - final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; final TUITheme theme = value.theme; final icon = _getIconByMsgStatus(context); String disturbUnreadCountInfo = _getDisturbUnreadCountInfo(); @@ -197,39 +214,44 @@ class _TIMUIKitLastMsgState extends TIMUIKitState { child: icon, ), if (widget.groupAtInfoList.isNotEmpty) - Text(_getAtMessage(), style: TextStyle(color: theme.cautionColor, fontSize: widget.fontSize)), + Text(_getAtMessage(), + style: TextStyle( + color: theme.cautionColor, fontSize: widget.fontSize)), if (widget.draftText != null && widget.draftText != "") - Text(_getDraftShowText(), style: TextStyle(color: theme.conversationItemDraftTextColor, fontSize: widget.fontSize)), + Text(_getDraftShowText(), + style: TextStyle( + color: theme.conversationItemDraftTextColor, + fontSize: widget.fontSize)), if (disturbUnreadCountInfo != "") - Text(disturbUnreadCountInfo, style: TextStyle(color: theme.weakTextColor, fontSize: widget.fontSize)), + Text(disturbUnreadCountInfo, + style: TextStyle( + color: theme.weakTextColor, fontSize: widget.fontSize)), if (widget.draftText != null && widget.draftText != "") - Expanded( - child: ExtendedText( - groupTipsAbstractText, - softWrap: true, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle(height: 1, color: theme.weakTextColor, fontSize: widget.fontSize), - specialTextSpanBuilder: DefaultSpecialTextSpanBuilder( - isUseQQPackage: true, - isUseTencentCloudChatPackage: true, - showAtBackground: true, - ) - ), - ), - if (widget.draftText == null || widget.draftText == "" && TencentUtils.checkString(groupTipsAbstractText) != null) Expanded( child: ExtendedText( groupTipsAbstractText, softWrap: true, maxLines: 1, overflow: TextOverflow.ellipsis, - style: TextStyle(height: 1, color: theme.weakTextColor, fontSize: widget.fontSize), - specialTextSpanBuilder: DefaultSpecialTextSpanBuilder( - isUseQQPackage: true, - isUseTencentCloudChatPackage: true, - showAtBackground: true, - ) + style: TextStyle( + height: 1, + color: theme.weakTextColor, + fontSize: widget.fontSize), + ), + ), + if (widget.draftText == null || + widget.draftText == "" && + TencentUtils.checkString(groupTipsAbstractText) != null) + Expanded( + child: ExtendedText( + groupTipsAbstractText, + softWrap: true, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + height: 1, + color: theme.weakTextColor, + fontSize: widget.fontSize), ), ) ]); diff --git a/lib/ui/widgets/link_preview/compiler/md_text.dart b/lib/ui/widgets/link_preview/compiler/md_text.dart index daf869f..f62da8b 100644 --- a/lib/ui/widgets/link_preview/compiler/md_text.dart +++ b/lib/ui/widgets/link_preview/compiler/md_text.dart @@ -3,15 +3,14 @@ import 'package:tim_ui_kit_sticker_plugin/utils/tim_custom_face_data.dart'; RegExp emojiExp = RegExp(r'\[([\u4e00-\u9fa5A-Za-z0-9]+)\]'); -String mdTextCompiler(String originalText, { - bool isUseQQPackage = false, +String mdTextCompiler( + String originalText, { bool isUseTencentCloudChatPackage = false, List customEmojiStickerList = const [], }) { String text = originalText; final EmojiUtil emojiUtil = EmojiUtil( isUseTencentCloudChatPackage: isUseTencentCloudChatPackage, - isUseQQPackage: isUseQQPackage, customEmojiStickerList: customEmojiStickerList); text = text.replaceAllMapped(emojiExp, (match) { @@ -26,4 +25,4 @@ String mdTextCompiler(String originalText, { }); return text; -} \ No newline at end of file +} diff --git a/lib/ui/widgets/link_preview/link_preview_entry.dart b/lib/ui/widgets/link_preview/link_preview_entry.dart index fc257d7..b01dd8d 100644 --- a/lib/ui/widgets/link_preview/link_preview_entry.dart +++ b/lib/ui/widgets/link_preview/link_preview_entry.dart @@ -12,13 +12,11 @@ class LinkPreviewEntry { static LinkPreviewText? getHyperlinksText(String messageText, bool isMarkdown, {Function(String)? onLinkTap, bool isEnableTextSelection = false, - bool isUseQQPackage = false, bool isUseTencentCloudChatPackage = false, List customEmojiStickerList = const []}) { return ({TextStyle? style}) { return isMarkdown ? LinkTextMarkdown( - isUseQQPackage: isUseQQPackage, isUseTencentCloudChatPackage: isUseTencentCloudChatPackage, customEmojiStickerList: customEmojiStickerList, isEnableTextSelection: isEnableTextSelection, @@ -31,7 +29,6 @@ class LinkPreviewEntry { messageText: messageText, style: style, onLinkTap: onLinkTap, - isUseQQPackage: isUseQQPackage, isUseTencentCloudChatPackage: isUseTencentCloudChatPackage, customEmojiStickerList: customEmojiStickerList); }; diff --git a/lib/ui/widgets/link_preview/widgets/link_text.dart b/lib/ui/widgets/link_preview/widgets/link_text.dart index a0bd62c..72f1c27 100644 --- a/lib/ui/widgets/link_preview/widgets/link_text.dart +++ b/lib/ui/widgets/link_preview/widgets/link_text.dart @@ -28,8 +28,6 @@ class LinkTextMarkdown extends TIMStatelessWidget { final bool? isEnableTextSelection; - final bool isUseQQPackage; - final bool isUseTencentCloudChatPackage; final List customEmojiStickerList; @@ -37,7 +35,6 @@ class LinkTextMarkdown extends TIMStatelessWidget { const LinkTextMarkdown( {Key? key, required this.messageText, - this.isUseQQPackage = false, this.isUseTencentCloudChatPackage = false, this.customEmojiStickerList = const [], this.isEnableTextSelection, @@ -49,7 +46,6 @@ class LinkTextMarkdown extends TIMStatelessWidget { Widget timBuild(BuildContext context) { return MarkdownBody( data: mdTextCompiler(messageText, - isUseQQPackage: isUseQQPackage, isUseTencentCloudChatPackage: isUseTencentCloudChatPackage, customEmojiStickerList: customEmojiStickerList), selectable: isEnableTextSelection ?? false, @@ -85,8 +81,6 @@ class LinkText extends TIMStatelessWidget { /// text style for default words final TextStyle? style; - final bool isUseQQPackage; - final bool isUseTencentCloudChatPackage; final List customEmojiStickerList; @@ -99,7 +93,6 @@ class LinkText extends TIMStatelessWidget { this.onLinkTap, this.isEnableTextSelection, this.style, - this.isUseQQPackage = false, this.isUseTencentCloudChatPackage = false, this.customEmojiStickerList = const []}) : super(key: key); @@ -172,7 +165,6 @@ class LinkText extends TIMStatelessWidget { }, style: style ?? const TextStyle(fontSize: 16.0), specialTextSpanBuilder: DefaultSpecialTextSpanBuilder( - isUseQQPackage: isUseQQPackage, isUseTencentCloudChatPackage: isUseTencentCloudChatPackage, customEmojiStickerList: customEmojiStickerList, showAtBackground: true, diff --git a/pubspec.yaml b/pubspec.yaml index 71fd4c8..65648a8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: tencent_cloud_chat_uikit description: A powerful chat UI component library and business logic for Tencent Cloud Chat, creating seamless in-app chat modules for delightful user experiences. -version: 3.1.0+2 +version: 4.0.0 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