From eb2dd69ac95750b2293e47682c037f8998f9e6e2 Mon Sep 17 00:00:00 2001 From: vinsonswang Date: Tue, 17 Dec 2024 19:57:23 +0800 Subject: [PATCH] tencent_cloud_chat_uikit source code update to version 4.0.1 --- CHANGELOG.md | 6 +- .../tim_uikit_chat_reply_elem.dart | 15 + .../tim_uikit_chat_text_elem.dart | 15 + .../tim_uikit_chat_text_translate_elem.dart | 15 + .../DefaultSpecialTextSpanBuilder.dart | 9 + .../special_text/emoji_text.dart | 76 ++++- .../tim_uikit_text_field_layout/narrow.dart | 186 +++++----- .../tim_uikit_text_field_layout/wide.dart | 318 +++++++----------- .../TIMUIKitChat/tim_uikit_chat_config.dart | 18 +- .../tim_uikit_conversation_last_msg.dart | 56 +-- .../link_preview/compiler/md_text.dart | 9 +- .../link_preview/link_preview_entry.dart | 8 + .../link_preview/widgets/link_text.dart | 15 + pubspec.yaml | 4 +- 14 files changed, 392 insertions(+), 358 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96d9153..9e0e67c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ +# 4.0.1 +* Upgraded the plugin tim_ui_kit_sticker_plugin to 4.0.1. +* Use the 'useTencentCloudChatStickerPackageOldKeys' parameter in StickerPanelConfig to control whether the emoticon is compatible with version 3.x. + # 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. +* Upgraded the plugin tim_ui_kit_sticker_plugin to 4.0.0. * Delete the useQQStickerPackage and unicodeEmojiList parameters in StickerPanelConfig. * Delete the isUseDefaultEmoji parameter in TIMUIKitChatConfig. * Delete the isUseDefaultEmoji parameter in each widget. 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 b13b584..e599c69 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 @@ -368,9 +368,15 @@ class _TIMUIKitReplyElemState extends TIMUIKitState { widget.message.textElem?.text ?? "", widget.chatModel.chatConfig.isSupportMarkdownForTextMessage, onLinkTap: widget.chatModel.chatConfig.onTapLink, + isUseQQPackage: widget + .chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? + true, isUseTencentCloudChatPackage: widget.chatModel.chatConfig .stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true, + isUseTencentCloudChatPackageOldKeys: widget.chatModel.chatConfig + .stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ?? + false, customEmojiStickerList: widget.customEmojiStickerList, isEnableTextSelection: widget.chatModel.chatConfig.isEnableTextSelection ?? false); @@ -434,12 +440,21 @@ class _TIMUIKitReplyElemState extends TIMUIKitState { fontSize: isDesktopScreen ? 14 : 16, height: widget.chatModel.chatConfig.textHeight), specialTextSpanBuilder: DefaultSpecialTextSpanBuilder( + isUseQQPackage: widget.chatModel.chatConfig + .stickerPanelConfig?.useQQStickerPackage ?? + true, isUseTencentCloudChatPackage: widget .chatModel .chatConfig .stickerPanelConfig ?.useTencentCloudChatStickerPackage ?? true, + isUseTencentCloudChatPackageOldKeys: widget + .chatModel + .chatConfig + .stickerPanelConfig + ?.useTencentCloudChatStickerPackageOldKeys ?? + false, customEmojiStickerList: widget.customEmojiStickerList, showAtBackground: true, )), 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 984e84f..0e94a45 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 @@ -165,9 +165,15 @@ class _TIMUIKitTextElemState extends TIMUIKitState { widget.message.textElem?.text ?? "", widget.chatModel.chatConfig.isSupportMarkdownForTextMessage, onLinkTap: widget.chatModel.chatConfig.onTapLink, + isUseQQPackage: widget + .chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? + true, isUseTencentCloudChatPackage: widget.chatModel.chatConfig .stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true, + isUseTencentCloudChatPackageOldKeys: widget.chatModel.chatConfig + .stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ?? + false, customEmojiStickerList: widget.customEmojiStickerList, isEnableTextSelection: widget.chatModel.chatConfig.isEnableTextSelection ?? false); @@ -232,12 +238,21 @@ class _TIMUIKitTextElemState extends TIMUIKitState { fontSize: isDesktopScreen ? 14 : 16, height: widget.chatModel.chatConfig.textHeight), specialTextSpanBuilder: DefaultSpecialTextSpanBuilder( + isUseQQPackage: widget.chatModel.chatConfig + .stickerPanelConfig?.useQQStickerPackage ?? + true, isUseTencentCloudChatPackage: widget .chatModel .chatConfig .stickerPanelConfig ?.useTencentCloudChatStickerPackage ?? true, + isUseTencentCloudChatPackageOldKeys: widget + .chatModel + .chatConfig + .stickerPanelConfig + ?.useTencentCloudChatStickerPackageOldKeys ?? + false, customEmojiStickerList: widget.customEmojiStickerList, showAtBackground: true, checkHttpLink: true, 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 76388f4..a789b78 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 @@ -122,9 +122,15 @@ class _TIMUIKitTextTranslationElemState final textWithLink = LinkPreviewEntry.getHyperlinksText(translateText ?? "", widget.chatModel.chatConfig.isSupportMarkdownForTextMessage, onLinkTap: widget.chatModel.chatConfig.onTapLink, + isUseQQPackage: widget + .chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? + true, isUseTencentCloudChatPackage: widget.chatModel.chatConfig .stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true, + isUseTencentCloudChatPackageOldKeys: widget.chatModel.chatConfig + .stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ?? + false, customEmojiStickerList: widget.customEmojiStickerList, isEnableTextSelection: widget.chatModel.chatConfig.isEnableTextSelection ?? false); @@ -160,12 +166,21 @@ class _TIMUIKitTextTranslationElemState fontSize: isDesktopScreen ? 14 : 16, height: widget.chatModel.chatConfig.textHeight), specialTextSpanBuilder: DefaultSpecialTextSpanBuilder( + isUseQQPackage: widget.chatModel.chatConfig + .stickerPanelConfig?.useQQStickerPackage ?? + true, isUseTencentCloudChatPackage: widget .chatModel .chatConfig .stickerPanelConfig ?.useTencentCloudChatStickerPackage ?? true, + isUseTencentCloudChatPackageOldKeys: widget + .chatModel + .chatConfig + .stickerPanelConfig + ?.useTencentCloudChatStickerPackageOldKeys ?? + false, customEmojiStickerList: widget.customEmojiStickerList, showAtBackground: true, )), diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart index d7d724e..1e59e67 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart @@ -9,7 +9,9 @@ import 'emoji_text.dart'; class DefaultSpecialTextSpanBuilder extends SpecialTextSpanBuilder { DefaultSpecialTextSpanBuilder({ + this.isUseQQPackage = false, this.isUseTencentCloudChatPackage = false, + this.isUseTencentCloudChatPackageOldKeys = false, this.customEmojiStickerList = const [], this.showAtBackground = false, this.checkHttpLink = true, @@ -18,8 +20,12 @@ class DefaultSpecialTextSpanBuilder extends SpecialTextSpanBuilder { /// whether show background for @somebody final bool showAtBackground; + final bool isUseQQPackage; + final bool isUseTencentCloudChatPackage; + final bool isUseTencentCloudChatPackageOldKeys; + final bool checkHttpLink; final List customEmojiStickerList; @@ -37,6 +43,9 @@ class DefaultSpecialTextSpanBuilder extends SpecialTextSpanBuilder { if (isStart(flag, EmojiText.flag)) { return EmojiText(textStyle, isUseTencentCloudChatPackage: isUseTencentCloudChatPackage, + isUseTencentCloudChatPackageOldKeys: + isUseTencentCloudChatPackageOldKeys, + isUseQQPackage: isUseQQPackage, start: index! - (EmojiText.flag.length - 1), customEmojiStickerList: customEmojiStickerList); } else if (isStart(flag, HttpText.flag) && checkHttpLink) { 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 552de93..454f65a 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/emoji_text.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/emoji_text.dart @@ -7,19 +7,25 @@ import 'package:tim_ui_kit_sticker_plugin/utils/tim_custom_face_data.dart'; class EmojiText extends SpecialText { EmojiText(TextStyle? textStyle, {this.start, + this.isUseQQPackage = false, this.isUseTencentCloudChatPackage = false, + this.isUseTencentCloudChatPackageOldKeys = false, this.customEmojiStickerList = const []}) : super(EmojiText.flag, ']', textStyle); static const String flag = '['; final int? start; + final bool isUseQQPackage; final bool isUseTencentCloudChatPackage; + final bool isUseTencentCloudChatPackageOldKeys; final List customEmojiStickerList; @override InlineSpan finishText() { final String key = toString(); final EmojiUtil emojiUtil = EmojiUtil( + isUseQQPackage: isUseQQPackage, isUseTencentCloudChatPackage: isUseTencentCloudChatPackage, + isUseTencentCloudChatPackageOldKeys: isUseTencentCloudChatPackageOldKeys, customEmojiStickerList: customEmojiStickerList); if (emojiUtil.emojiMap.containsKey(key)) { @@ -30,11 +36,17 @@ class EmojiText extends SpecialText { size = ts.fontSize! * 1.44; } - if (isUseTencentCloudChatPackage == true && + 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 && (emojiUtil.emojiKeyCategoryMap["tcc1"]?.contains(key) ?? false)) { - return ImageSpan( - AssetImage(emojiUtil.emojiMap[key]!, - package: "tim_ui_kit_sticker_plugin"), + return ImageSpan(AssetImage(emojiUtil.emojiMap[key]!, package: "tim_ui_kit_sticker_plugin"), actualText: key, imageWidth: size, imageHeight: size, @@ -59,7 +71,9 @@ class EmojiText extends SpecialText { class EmojiUtil { // Private constructor initializing the emoji data EmojiUtil._internal( - {required this.isUseTencentCloudChatPackage, + {required this.isUseQQPackage, + required this.isUseTencentCloudChatPackage, + required this.isUseTencentCloudChatPackageOldKeys, required this.customEmojiStickerList}) { _emojiMap.addAll(loadDefaultEmojis()); @@ -68,7 +82,9 @@ class EmojiUtil { _emojiKeyCategoryMap["custom"] = customEmojis.$2; } + final bool isUseQQPackage; final bool isUseTencentCloudChatPackage; + final bool isUseTencentCloudChatPackageOldKeys; final List customEmojiStickerList; // Load the default emojis into a Map @@ -77,12 +93,30 @@ class EmojiUtil { for (final emojiGroup in TUIKitStickerConstData.emojiList) { final groupName = emojiGroup.name; final keyList = []; + if (isUseQQPackage && groupName == "4349") { + for (final emoji in emojiGroup.list) { + String emojiName = emoji.split('.png')[0]; + defaultEmojiMap['[$emojiName]'] = '$_emojiFilePath/$groupName/$emojiName.png'; + keyList.add('[$emojiName]'); + + final zhKey = TUIKitStickerConstData.emoji4349ZhMapList[emojiName]; + defaultEmojiMap['[$zhKey]'] = '$_emojiFilePath/$groupName/$emojiName.png'; + keyList.add('[$zhKey]'); + } + _emojiKeyCategoryMap[groupName] = keyList; + } + 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]'); + String compatibleEmojiName = emojiName; + if (isUseTencentCloudChatPackageOldKeys) { + // 兼容旧版本的 key 值 + compatibleEmojiName = getCompatibleEmojiName(emojiName); + } + + defaultEmojiMap['[$compatibleEmojiName]'] = '$_emojiFilePath/$groupName/$emojiName.png'; + keyList.add('[$compatibleEmojiName]'); } _emojiKeyCategoryMap[groupName] = keyList; } @@ -97,8 +131,7 @@ class EmojiUtil { for (final customEmojiGroup in customEmojiStickerList) { for (final customEmoji in customEmojiGroup.list) { String customEmojiName = customEmoji.split('.png')[0]; - customEmojiMap['[$customEmojiName]'] = - '$_emojiFilePath/${customEmojiGroup.name}/$customEmojiName.png'; + customEmojiMap['[$customEmojiName]'] = '$_emojiFilePath/${customEmojiGroup.name}/$customEmojiName.png'; keyList.add('[$customEmojiName]'); } } @@ -125,10 +158,29 @@ class EmojiUtil { // Factory constructor to return the singleton instance of EmojiUtil with custom parameters factory EmojiUtil( - {bool isUseTencentCloudChatPackage = false, + {bool isUseQQPackage = false, + bool isUseTencentCloudChatPackage = false, + bool isUseTencentCloudChatPackageOldKeys = false, List customEmojiStickerList = const []}) { return _instance ??= EmojiUtil._internal( + isUseQQPackage: isUseQQPackage, customEmojiStickerList: customEmojiStickerList, - isUseTencentCloudChatPackage: isUseTencentCloudChatPackage); + isUseTencentCloudChatPackage: isUseTencentCloudChatPackage, + isUseTencentCloudChatPackageOldKeys: isUseTencentCloudChatPackageOldKeys); + } + + static String getCompatibleEmojiName(String emojiName) { + String compatibleEmojiName = emojiName; + try { + compatibleEmojiName = emojiName.split('_')[1]; + // 对特殊字符串 Ok 进行处理 + if (compatibleEmojiName == 'Ok') { + compatibleEmojiName = 'OK'; + } + } catch (e) { + print(e); + } + + return compatibleEmojiName; } } 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 b12c200..a20c97d 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 @@ -17,6 +17,7 @@ import 'package:tencent_cloud_chat_uikit/ui/utils/optimize_utils.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/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/emoji_text.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_send_sound_message.dart'; import 'package:tencent_keyboard_visibility/tencent_keyboard_visibility.dart'; @@ -37,6 +38,8 @@ class TIMUIKitTextFieldLayoutNarrow extends StatefulWidget { /// Whether to use the default emoji final bool isUseDefaultEmoji; + final bool isUseTencentCloudChatPackageOldKeys; + final TUIChatSeparateViewModel model; /// background color @@ -103,6 +106,7 @@ class TIMUIKitTextFieldLayoutNarrow extends StatefulWidget { required this.backSpaceText, required this.addStickerToText, required this.isUseDefaultEmoji, + this.isUseTencentCloudChatPackageOldKeys = false, required this.languageType, required this.textEditingController, this.morePanelConfig, @@ -132,12 +136,10 @@ 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; @@ -211,13 +213,16 @@ class _TIMUIKitTextFieldLayoutNarrowState }, addCustomEmojiText: ((String singleEmojiName) { String? emojiName = singleEmojiName.split('.png')[0]; - final newText = TIM_t('[$emojiName]'); + String compatibleEmojiName = emojiName; + if (widget.isUseTencentCloudChatPackageOldKeys) { + compatibleEmojiName = EmojiUtil.getCompatibleEmojiName(emojiName); + } + + String newText = '[$compatibleEmojiName]'; widget.addStickerToText(newText); setSendButton(); }), - defaultCustomEmojiStickerList: widget.isUseDefaultEmoji - ? TUIKitStickerConstData.emojiList - : []) + defaultCustomEmojiStickerList: widget.isUseDefaultEmoji ? TUIKitStickerConstData.emojiList : []) : StickerPanel( isWideScreen: false, sendTextMsg: () { @@ -237,7 +242,12 @@ class _TIMUIKitTextFieldLayoutNarrowState }, addCustomEmojiText: ((String singleEmojiName) { String? emojiName = singleEmojiName.split('.png')[0]; - final newText = TIM_t('[$emojiName]'); + String compatibleEmojiName = emojiName; + if (widget.isUseTencentCloudChatPackageOldKeys) { + compatibleEmojiName = EmojiUtil.getCompatibleEmojiName(emojiName); + } + + String newText = '[$compatibleEmojiName]'; widget.addStickerToText(newText); setSendButton(); }), @@ -246,10 +256,7 @@ class _TIMUIKitTextFieldLayoutNarrowState } if (showMore) { - return MorePanel( - morePanelConfig: widget.morePanelConfig, - conversationID: widget.conversationID, - conversationType: widget.conversationType); + return MorePanel(morePanelConfig: widget.morePanelConfig, conversationID: widget.conversationID, conversationType: widget.conversationType); } return const SizedBox(height: 0); @@ -271,8 +278,7 @@ class _TIMUIKitTextFieldLayoutNarrowState return height; } else if (showMore || showEmojiPanel) { return 248.0 + (bottomPadding ?? 0.0); - } else if (widget.textEditingController.text.length >= 46 && - showKeyboard == false) { + } else if (widget.textEditingController.text.length >= 46 && showKeyboard == false) { return 25 + (bottomPadding ?? 0.0); } else { return bottomPadding ?? 0; @@ -325,20 +331,14 @@ class _TIMUIKitTextFieldLayoutNarrowState } String getAbstractMessage(V2TimMessage message) { - final String? customAbstractMessage = - widget.model.abstractMessageBuilder != null - ? widget.model.abstractMessageBuilder!(message) - : null; - return customAbstractMessage ?? - MessageUtils.getAbstractMessageAsync( - message, widget.model.groupMemberList ?? []); + final String? customAbstractMessage = widget.model.abstractMessageBuilder != null ? widget.model.abstractMessageBuilder!(message) : null; + return customAbstractMessage ?? MessageUtils.getAbstractMessageAsync(message, widget.model.groupMemberList ?? []); } _buildRepliedMessage(V2TimMessage? repliedMessage) { final haveRepliedMessage = repliedMessage != null; if (haveRepliedMessage) { - final String text = - "${MessageUtils.getDisplayName(repliedMessage)}:${getAbstractMessage(repliedMessage)}"; + final String text = "${MessageUtils.getDisplayName(repliedMessage)}:${getAbstractMessage(repliedMessage)}"; return Container( color: widget.backgroundColor ?? hexToColor("f5f5f6"), alignment: Alignment.centerLeft, @@ -419,8 +419,7 @@ class _TIMUIKitTextFieldLayoutNarrowState child: Column( children: [ Container( - padding: - const EdgeInsets.symmetric(vertical: 8, horizontal: 16), + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), constraints: const BoxConstraints(minHeight: 50), child: Row( children: [ @@ -444,28 +443,24 @@ class _TIMUIKitTextFieldLayoutNarrowState } }, child: SvgPicture.asset( - showSendSoundText - ? 'images/keyboard.svg' - : 'images/voice.svg', + showSendSoundText ? 'images/keyboard.svg' : 'images/voice.svg', package: 'tencent_cloud_chat_uikit', color: const Color.fromRGBO(68, 68, 68, 1), height: 28, width: 28, ), ), - const SizedBox( - width: 10, - ), - Expanded( - child: showSendSoundText - ? SendSoundMessage( - onDownBottom: widget.goDownBottom, - conversationID: widget.conversationID, - conversationType: widget.conversationType) - : Stack(children: [ - Center( - child: KeyboardVisibility( - child: ExtendedTextField( + const SizedBox( + width: 10, + ), + Expanded( + child: showSendSoundText + ? SendSoundMessage(onDownBottom: widget.goDownBottom, conversationID: widget.conversationID, conversationType: widget.conversationType) + : Stack( + children: [ + Center( + child: KeyboardVisibility( + child: ExtendedTextField( maxLines: 4, minLines: 1, focusNode: widget.focusNode, @@ -479,24 +474,19 @@ class _TIMUIKitTextFieldLayoutNarrowState }); }, keyboardType: TextInputType.multiline, - textInputAction: - PlatformUtils().isAndroid - ? TextInputAction.newline - : TextInputAction.send, + textInputAction: PlatformUtils().isAndroid ? TextInputAction.newline : TextInputAction.send, onEditingComplete: () { widget.onSubmitted(); if (showKeyboard) { widget.focusNode.requestFocus(); } setState(() { - if (widget.textEditingController - .text.isEmpty) { + if (widget.textEditingController.text.isEmpty) { showMoreButton = true; } }); }, - textAlignVertical: - TextAlignVertical.top, + textAlignVertical: TextAlignVertical.top, decoration: InputDecoration( border: InputBorder.none, hintStyle: const TextStyle( @@ -507,52 +497,42 @@ class _TIMUIKitTextFieldLayoutNarrowState filled: true, isDense: true, hintText: widget.hintText ?? ''), - controller: - widget.textEditingController, - specialTextSpanBuilder: PlatformUtils() - .isWeb + controller: widget.textEditingController, + specialTextSpanBuilder: PlatformUtils().isWeb ? null : DefaultSpecialTextSpanBuilder( - isUseTencentCloudChatPackage: - widget - .model - .chatConfig - .stickerPanelConfig - ?.useTencentCloudChatStickerPackage ?? - true, - customEmojiStickerList: widget - .customEmojiStickerList, + isUseQQPackage: widget.model.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? true, + isUseTencentCloudChatPackage: widget.model.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true, + isUseTencentCloudChatPackageOldKeys: widget.model.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ?? false, + customEmojiStickerList: widget.customEmojiStickerList, showAtBackground: true, checkHttpLink: false, )), - onChanged: (bool visibility) { - if (showKeyboard != visibility) { - setState(() { - showKeyboard = visibility; - }); - } + onChanged: (bool visibility) { + if (showKeyboard != visibility) { + setState(() { + showKeyboard = visibility; + }); + } }), + ), + RawKeyboardListener( + autofocus: true, + focusNode: FocusNode(), + onKey: (key) { + if (key is RawKeyDownEvent && key.logicalKey == LogicalKeyboardKey.backspace) { + if (widget.onDeleteText != null) { + widget.onDeleteText!(widget.textEditingController.text); + } + } + }, child: Container(), + ), + ] ), - RawKeyboardListener( - autofocus: true, - focusNode: FocusNode(), - onKey: (key) { - if (key is RawKeyDownEvent && - key.logicalKey == - LogicalKeyboardKey.backspace) { - if (widget.onDeleteText != null) { - widget.onDeleteText!( - widget.textEditingController.text); - } - } - }, - child: Container(), - ), - ]), - ), - const SizedBox( - width: 10, - ), + ), + const SizedBox( + width: 10, + ), if (widget.showSendEmoji) InkWell( onTap: () { @@ -560,25 +540,18 @@ class _TIMUIKitTextFieldLayoutNarrowState widget.goDownBottom(); }, child: PlatformUtils().isWeb - ? Icon( - showEmojiPanel - ? Icons.keyboard_alt_outlined - : Icons.mood_outlined, - color: hexToColor("5c6168"), - size: 32) + ? Icon(showEmojiPanel ? Icons.keyboard_alt_outlined : Icons.mood_outlined, color: hexToColor("5c6168"), size: 32) : SvgPicture.asset( - showEmojiPanel - ? 'images/keyboard.svg' - : 'images/face.svg', + showEmojiPanel ? 'images/keyboard.svg' : 'images/face.svg', package: 'tencent_cloud_chat_uikit', color: const Color.fromRGBO(68, 68, 68, 1), height: 28, width: 28, ), ), - const SizedBox( - width: 10, - ), + const SizedBox( + width: 10, + ), if (widget.showMorePanel && showMoreButton) InkWell( onTap: () { @@ -587,8 +560,7 @@ class _TIMUIKitTextFieldLayoutNarrowState widget.goDownBottom(); }, child: PlatformUtils().isWeb - ? Icon(Icons.add_circle_outline_outlined, - color: hexToColor("5c6168"), size: 32) + ? Icon(Icons.add_circle_outline_outlined, color: hexToColor("5c6168"), size: 32) : SvgPicture.asset( 'images/add.svg', package: 'tencent_cloud_chat_uikit', @@ -597,8 +569,7 @@ class _TIMUIKitTextFieldLayoutNarrowState width: 28, ), ), - if ((isAndroidDevice() || isWebDevice()) && - !showMoreButton) + if ((isAndroidDevice() || isWebDevice()) && !showMoreButton) SizedBox( height: 32.0, child: ElevatedButton( @@ -620,10 +591,7 @@ class _TIMUIKitTextFieldLayoutNarrowState ), ), AnimatedContainer( - duration: Duration( - milliseconds: (showKeyboard && PlatformUtils().isAndroid) - ? 200 - : 340), + duration: Duration(milliseconds: (showKeyboard && PlatformUtils().isAndroid) ? 200 : 340), curve: Curves.fastOutSlowIn, height: max(_getBottomHeight(), 0.0), child: ListView( diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/wide.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/wide.dart index 785197f..f6bb8f6 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/wide.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/wide.dart @@ -30,6 +30,7 @@ import 'package:tencent_cloud_chat_uikit/ui/utils/optimize_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_shot.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/emoji_text.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/drag_widget.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart'; import 'package:universal_html/html.dart' as html; @@ -56,9 +57,7 @@ class DesktopControlBarItem { required this.onClick, this.showName, this.size}) - : assert(icon != null || - TencentUtils.checkString(imgPath) != null || - TencentUtils.checkString(svgPath) != null); + : assert(icon != null || TencentUtils.checkString(imgPath) != null || TencentUtils.checkString(svgPath) != null); } class DesktopControlBarConfig { @@ -93,6 +92,8 @@ class TIMUIKitTextFieldLayoutWide extends StatefulWidget { /// Whether to use the default emoji final bool isUseDefaultEmoji; + final bool isCompatibleWithTencentCloudChatPackageOldKeys; + final TUIChatSeparateViewModel model; /// background color @@ -160,6 +161,7 @@ class TIMUIKitTextFieldLayoutWide extends StatefulWidget { required this.backSpaceText, required this.addStickerToText, required this.isUseDefaultEmoji, + this.isCompatibleWithTencentCloudChatPackageOldKeys = false, required this.languageType, required this.textEditingController, this.morePanelConfig, @@ -190,12 +192,10 @@ class TIMUIKitTextFieldLayoutWide extends StatefulWidget { : super(key: key); @override - State createState() => - _TIMUIKitTextFieldLayoutWideState(); + State createState() => _TIMUIKitTextFieldLayoutWideState(); } -class _TIMUIKitTextFieldLayoutWideState - extends TIMUIKitState { +class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState { final TUISettingModel settingModel = serviceLocator(); OverlayEntry? entry; final ImagePicker _picker = ImagePicker(); @@ -269,13 +269,11 @@ class _TIMUIKitTextFieldLayoutWideState } String getAbstractMessage(V2TimMessage message) { - final String? customAbstractMessage = - widget.model.abstractMessageBuilder != null - ? widget.model.abstractMessageBuilder!(widget.model.repliedMessage!) - : null; + final String? customAbstractMessage = widget.model.abstractMessageBuilder != null + ? widget.model.abstractMessageBuilder!(widget.model.repliedMessage!) + : null; return customAbstractMessage ?? - MessageUtils.getAbstractMessageAsync( - widget.model.repliedMessage!, widget.model.groupMemberList ?? []); + MessageUtils.getAbstractMessageAsync(widget.model.repliedMessage!, widget.model.groupMemberList ?? []); } _buildRepliedMessage(V2TimMessage? repliedMessage) { @@ -298,10 +296,7 @@ class _TIMUIKitTextFieldLayoutWideState softWrap: true, maxLines: 1, overflow: TextOverflow.ellipsis, - style: TextStyle( - color: hexToColor("8f959e"), - fontSize: 14, - fontWeight: FontWeight.bold), + style: TextStyle(color: hexToColor("8f959e"), fontSize: 14, fontWeight: FontWeight.bold), ), Expanded( child: Text( @@ -346,8 +341,7 @@ class _TIMUIKitTextFieldLayoutWideState }, initOffset: offset != null ? Offset(offset.dx, max(offset.dy, 16)) - : Offset(MediaQuery.of(context).size.height * 0.5 + 20, - MediaQuery.of(context).size.height * 0.5 - 100), + : Offset(MediaQuery.of(context).size.height * 0.5 + 20, MediaQuery.of(context).size.height * 0.5 - 100), child: Container( decoration: BoxDecoration( borderRadius: const BorderRadius.all(Radius.circular(8)), @@ -385,14 +379,17 @@ class _TIMUIKitTextFieldLayoutWideState }, addCustomEmojiText: ((String singleEmojiName) { String? emojiName = singleEmojiName.split('.png')[0]; - final newText = TIM_t('[$emojiName]'); + String compatibleEmojiName = emojiName; + if (widget.isCompatibleWithTencentCloudChatPackageOldKeys) { + compatibleEmojiName = EmojiUtil.getCompatibleEmojiName(emojiName); + } + + String newText = '[$compatibleEmojiName]'; widget.addStickerToText(newText); entry?.remove(); entry = null; }), - defaultCustomEmojiStickerList: widget.isUseDefaultEmoji - ? TUIKitStickerConstData.emojiList - : []) + defaultCustomEmojiStickerList: widget.isUseDefaultEmoji ? TUIKitStickerConstData.emojiList : []) : Material( color: Colors.transparent, child: StickerPanel( @@ -415,9 +412,13 @@ class _TIMUIKitTextFieldLayoutWideState entry = null; }, addCustomEmojiText: ((String singleEmojiName) { - String? emojiName = - singleEmojiName.split('.png')[0]; - final newText = TIM_t('[$emojiName]'); + String? emojiName = singleEmojiName.split('.png')[0]; + String compatibleEmojiName = emojiName; + if (widget.isCompatibleWithTencentCloudChatPackageOldKeys) { + compatibleEmojiName = EmojiUtil.getCompatibleEmojiName(emojiName); + } + + String newText = '[$compatibleEmojiName]'; widget.addStickerToText(newText); entry?.remove(); entry = null; @@ -468,17 +469,11 @@ class _TIMUIKitTextFieldLayoutWideState if (result != null && result.files.isNotEmpty) { if (PlatformUtils().isWeb) { html.Node? inputElem; - inputElem = html.document - .getElementById("__file_picker_web-file-input") - ?.querySelector("input"); + inputElem = html.document.getElementById("__file_picker_web-file-input")?.querySelector("input"); fileName = result.files.single.name; MessageUtils.handleMessageError( - model.sendFileMessage( - inputElement: inputElem, - fileName: fileName, - convID: convID, - convType: convType), + model.sendFileMessage(inputElement: inputElem, fileName: fileName, convID: convID, convType: convType), context); } else { File file = File(result.files.single.path!); @@ -486,12 +481,7 @@ class _TIMUIKitTextFieldLayoutWideState final String savePath = file.path; MessageUtils.handleMessageError( - model.sendFileMessage( - filePath: savePath, - size: size, - convID: convID, - convType: convType), - context); + model.sendFileMessage(filePath: savePath, size: size, convID: convID, convType: convType), context); } } else { throw TypeError(); @@ -502,8 +492,7 @@ class _TIMUIKitTextFieldLayoutWideState } } - List 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(); @@ -511,15 +500,12 @@ class _TIMUIKitTextFieldLayoutWideState margin: const EdgeInsets.only(right: 10), child: InkWell( onTap: () { - final alignBox = - key.currentContext?.findRenderObject() as RenderBox?; + final alignBox = key.currentContext?.findRenderObject() as RenderBox?; var offset = alignBox?.localToGlobal(Offset.zero); final double? dx = (offset?.dx != null) ? offset!.dx : null; - final double? dy = - (offset?.dy != null && alignBox?.size.height != null) - ? offset!.dy - - (widget.chatConfig.desktopStickerPanelHeight + 20) - : null; + final double? dy = (offset?.dy != null && alignBox?.size.height != null) + ? offset!.dy - (widget.chatConfig.desktopStickerPanelHeight + 20) + : null; e.onClick((dx != null && dy != null) ? Offset(dx, dy) : null); }, child: Tooltip( @@ -533,9 +519,7 @@ class _TIMUIKitTextFieldLayoutWideState if (TencentUtils.checkString(e.svgPath) != null) { return SvgPicture.asset( e.svgPath!, - package: defaultItems.contains(e.item) - ? 'tencent_cloud_chat_uikit' - : null, + package: defaultItems.contains(e.item) ? 'tencent_cloud_chat_uikit' : null, key: key, width: e.size ?? 16, height: e.size ?? 16, @@ -544,9 +528,7 @@ class _TIMUIKitTextFieldLayoutWideState if (TencentUtils.checkString(e.imgPath) != null) { return Image.asset( e.imgPath!, - package: defaultItems.contains(e.item) - ? 'tencent_cloud_chat_uikit' - : null, + package: defaultItems.contains(e.item) ? 'tencent_cloud_chat_uikit' : null, key: key, width: e.size ?? 16, height: e.size ?? 16, @@ -575,17 +557,12 @@ class _TIMUIKitTextFieldLayoutWideState fileContent = imageContent; html.Node? inputElem; - inputElem = html.document - .getElementById("__image_picker_web-file-input") - ?.querySelector("input"); + inputElem = html.document.getElementById("__image_picker_web-file-input")?.querySelector("input"); final convID = widget.conversationID; final convType = widget.conversationType; MessageUtils.handleMessageError( model.sendImageMessage( - inputElement: inputElem, - imagePath: tempFile?.path, - convID: convID, - convType: convType), + inputElement: inputElem, imagePath: tempFile?.path, convID: convID, convType: convType), context); } catch (e) { // ignore: avoid_print @@ -602,25 +579,18 @@ class _TIMUIKitTextFieldLayoutWideState fileContent = videoContent; if (fileName!.split(".")[fileName!.split(".").length - 1] != "mp4") { - onTIMCallback(TIMCallback( - type: TIMCallbackType.INFO, - infoRecommendText: TIM_t("视频消息仅限 mp4 格式"), - infoCode: 6660412)); + onTIMCallback( + TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频消息仅限 mp4 格式"), infoCode: 6660412)); return; } html.Node? inputElem; - inputElem = html.document - .getElementById("__image_picker_web-file-input") - ?.querySelector("input"); + inputElem = html.document.getElementById("__image_picker_web-file-input")?.querySelector("input"); final convID = widget.conversationID; final convType = widget.conversationType; MessageUtils.handleMessageError( model.sendVideoMessage( - inputElement: inputElem, - videoPath: tempFile?.path, - convID: convID, - convType: convType), + inputElement: inputElem, videoPath: tempFile?.path, convID: convID, convType: convType), context); } catch (e) { // ignore: avoid_print @@ -634,10 +604,8 @@ class _TIMUIKitTextFieldLayoutWideState final originFile = await asset.originFile; final size = await originFile!.length(); if (size >= 104857600) { - onTIMCallback(TIMCallback( - type: TIMCallbackType.INFO, - infoRecommendText: TIM_t("发送失败,视频不能大于100MB"), - infoCode: 6660405)); + onTIMCallback( + TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("发送失败,视频不能大于100MB"), infoCode: 6660405)); return; } @@ -646,9 +614,7 @@ class _TIMUIKitTextFieldLayoutWideState final convID = widget.conversationID; final convType = widget.conversationType; - String tempPath = (await getTemporaryDirectory()).path + - p.extension(originFile.path, 3) + - ".jpeg"; + String tempPath = (await getTemporaryDirectory()).path + p.extension(originFile.path, 3) + ".jpeg"; await plugin.getVideoThumbnail( srcFile: originFile.path, @@ -660,22 +626,14 @@ class _TIMUIKitTextFieldLayoutWideState ); MessageUtils.handleMessageError( model.sendVideoMessage( - videoPath: filePath, - duration: duration, - snapshotPath: tempPath, - convID: convID, - convType: convType), + videoPath: filePath, duration: duration, snapshotPath: tempPath, convID: convID, convType: convType), context); } catch (e) { - onTIMCallback(TIMCallback( - type: TIMCallbackType.INFO, - infoRecommendText: TIM_t("视频文件异常"), - infoCode: 6660415)); + onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频文件异常"), infoCode: 6660415)); } } - _sendMediaMessage( - TUIChatSeparateViewModel model, TUITheme theme, FileType fileType) async { + _sendMediaMessage(TUIChatSeparateViewModel model, TUITheme theme, FileType fileType) async { try { final convID = widget.conversationID; final convType = widget.conversationType; @@ -691,11 +649,7 @@ class _TIMUIKitTextFieldLayoutWideState if (filePath != null) { if (type == AssetType.image) { MessageUtils.handleMessageError( - model.sendImageMessage( - imagePath: filePath, - convID: convID, - convType: convType), - context); + model.sendImageMessage(imagePath: filePath, convID: convID, convType: convType), context); } if (type == AssetType.video) { @@ -707,26 +661,20 @@ class _TIMUIKitTextFieldLayoutWideState } else { final plugin = FcNativeVideoThumbnail(); _addGreyOverlay(); - FilePickerResult? result = - await FilePicker.platform.pickFiles(type: fileType); + FilePickerResult? result = await FilePicker.platform.pickFiles(type: fileType); _removeOverlay(); if (result != null && result.files.isNotEmpty) { File file = File(result.files.single.path!); final String savePath = file.path; - final String type = TencentUtils.getFileType( - (savePath.split(".")[savePath.split(".").length - 1]) - .toLowerCase()) - .split("/")[0]; + final String type = + TencentUtils.getFileType((savePath.split(".")[savePath.split(".").length - 1]).toLowerCase()) + .split("/")[0]; if (type == "image") { MessageUtils.handleMessageError( - model.sendImageMessage( - imagePath: savePath, convID: convID, convType: convType), - context); + model.sendImageMessage(imagePath: savePath, convID: convID, convType: convType), context); } else if (type == "video") { - String tempPath = (await getTemporaryDirectory()).path + - p.basename(savePath) + - ".jpeg"; + String tempPath = (await getTemporaryDirectory()).path + p.basename(savePath) + ".jpeg"; await plugin.getVideoThumbnail( srcFile: savePath, destFile: tempPath, @@ -736,11 +684,7 @@ class _TIMUIKitTextFieldLayoutWideState height: 128, ); MessageUtils.handleMessageError( - model.sendVideoMessage( - videoPath: savePath, - convID: convID, - convType: convType, - snapshotPath: tempPath), + model.sendVideoMessage(videoPath: savePath, convID: convID, convType: convType, snapshotPath: tempPath), context); } } else { @@ -750,17 +694,13 @@ class _TIMUIKitTextFieldLayoutWideState } catch (err) { // ignore: avoid_print outputLogger.i("send media err: $err"); - onTIMCallback(TIMCallback( - type: TIMCallbackType.INFO, - infoRecommendText: TIM_t("视频文件异常"), - infoCode: 6660415)); + onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频文件异常"), infoCode: 6660415)); } } - _sendImageWithConfirmation( - {String? fileName, Size? fileSize, required String filePath}) async { - final option1 = widget.currentConversation.showName ?? - (widget.conversationType == ConvType.group ? TIM_t("群聊") : TIM_t("对方")); + _sendImageWithConfirmation({String? fileName, Size? fileSize, required String filePath}) async { + final option1 = + widget.currentConversation.showName ?? (widget.conversationType == ConvType.group ? TIM_t("群聊") : TIM_t("对方")); final size = fileSize ?? await ScreenshotHelper.getImageSize(filePath); TUIKitWidePopup.showPopupWindow( @@ -779,9 +719,7 @@ class _TIMUIKitTextFieldLayoutWideState height: min(360, size.height / 2), child: InkWell( onTap: () { - launchUrl(PlatformUtils().isWeb - ? Uri.parse(filePath) - : Uri.file(filePath)); + launchUrl(PlatformUtils().isWeb ? Uri.parse(filePath) : Uri.file(filePath)); }, child: PlatformUtils().isWeb ? Image.network( @@ -834,8 +772,7 @@ class _TIMUIKitTextFieldLayoutWideState } generateDefaultControlBarItems() { - final DesktopControlBarConfig config = - widget.chatConfig.desktopControlBarConfig ?? DesktopControlBarConfig(); + final DesktopControlBarConfig config = widget.chatConfig.desktopControlBarConfig ?? DesktopControlBarConfig(); final List itemsList = [ if (config.showStickerPanel) DesktopControlBarItem( @@ -900,13 +837,9 @@ class _TIMUIKitTextFieldLayoutWideState keyword: '', initMessageList: widget.model .getOriginMessageList() - .getRange( - 0, - min(widget.model.getOriginMessageList().length, - 100)) + .getRange(0, min(widget.model.getOriginMessageList().length, 100)) .toList(), - onTapConversation: (V2TimConversation conversation, - V2TimMessage? message) {}, + onTapConversation: (V2TimConversation conversation, V2TimMessage? message) {}, ), theme: widget.theme); }, @@ -915,8 +848,7 @@ class _TIMUIKitTextFieldLayoutWideState defaultControlBarItems = itemsList; } - List generateControlBar( - TUIChatSeparateViewModel model, TUITheme theme) { + List generateControlBar(TUIChatSeparateViewModel model, TUITheme theme) { final List itemsList = [ ...defaultControlBarItems, ...(widget.chatConfig.additionalDesktopControlBarItems ?? []) @@ -930,29 +862,22 @@ class _TIMUIKitTextFieldLayoutWideState final type = mimeType[0]; final blobUrl = html.Url.createObjectUrl(file); if (type == 'image') { - _sendImageWithConfirmation( - filePath: blobUrl, - fileName: file.name, - fileSize: const Size(500, 500)); + _sendImageWithConfirmation(filePath: blobUrl, fileName: file.name, fileSize: const Size(500, 500)); } } Future _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; @@ -960,8 +885,7 @@ class _TIMUIKitTextFieldLayoutWideState const uuid = Uuid(); final fileName = 'paste_image_${uuid.v4()}.png'; final scDirectory = Directory(directory); - final filePath = - '${scDirectory.path}${PlatformUtils().isWindows ? "\\" : "/"}$fileName'; + final filePath = '${scDirectory.path}${PlatformUtils().isWindows ? "\\" : "/"}$fileName'; final file = File(filePath); if (!await scDirectory.exists()) { await scDirectory.create(recursive: true); @@ -1002,67 +926,57 @@ class _TIMUIKitTextFieldLayoutWideState child: Column( children: [ _buildRepliedMessage(widget.repliedMessage), - SizedBox( - height: 1, - child: Container( - color: theme.weakDividerColor ?? Colors.black12)), - Container( - padding: - const EdgeInsets.symmetric(vertical: 4, horizontal: 12), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: generateControlBar(widget.model, theme), + SizedBox(height: 1, child: Container(color: theme.weakDividerColor ?? Colors.black12)), + Container( + padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: generateControlBar(widget.model, theme), + ), ), - ), Container( padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 6), constraints: const BoxConstraints(minHeight: 50), child: Row( children: [ - Expanded( - child: ExtendedTextField( - scrollController: _scrollController, - autofocus: true, - maxLines: - widget.chatConfig.desktopMessageInputFieldLines, - minLines: - widget.chatConfig.desktopMessageInputFieldLines, - focusNode: widget.focusNode, - onChanged: debounceFunc, - keyboardType: TextInputType.multiline, - onEditingComplete: () { - // // widget.onSubmitted(); - }, - textAlignVertical: TextAlignVertical.top, - style: const TextStyle(fontSize: 14), - decoration: InputDecoration( - hoverColor: Colors.transparent, - border: InputBorder.none, - hintStyle: const TextStyle( - color: Color(0xffAEA4A3), + Expanded( + child: ExtendedTextField( + scrollController: _scrollController, + autofocus: true, + maxLines: widget.chatConfig.desktopMessageInputFieldLines, + minLines: widget.chatConfig.desktopMessageInputFieldLines, + focusNode: widget.focusNode, + onChanged: debounceFunc, + keyboardType: TextInputType.multiline, + onEditingComplete: () { + // // widget.onSubmitted(); + }, + textAlignVertical: TextAlignVertical.top, + style: const TextStyle(fontSize: 14), + decoration: InputDecoration( + hoverColor: Colors.transparent, + border: InputBorder.none, + hintStyle: const TextStyle( + color: Color(0xffAEA4A3), + ), + fillColor: widget.backgroundColor ?? + theme.desktopChatMessageInputBgColor ?? + hexToColor("fafafa"), + filled: true, + isDense: true, + hintText: widget.hintText ?? '', ), - fillColor: widget.backgroundColor ?? - theme.desktopChatMessageInputBgColor ?? - hexToColor("fafafa"), - filled: true, - isDense: true, - hintText: widget.hintText ?? '', - ), - controller: widget.textEditingController, - specialTextSpanBuilder: PlatformUtils().isWeb - ? null - : DefaultSpecialTextSpanBuilder( - isUseTencentCloudChatPackage: widget - .model - .chatConfig - .stickerPanelConfig - ?.useTencentCloudChatStickerPackage ?? - true, - customEmojiStickerList: - widget.customEmojiStickerList, - showAtBackground: true, - )), - ), + controller: widget.textEditingController, + specialTextSpanBuilder: PlatformUtils().isWeb + ? null + : DefaultSpecialTextSpanBuilder( + isUseTencentCloudChatPackage: + widget.model.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? + true, + customEmojiStickerList: widget.customEmojiStickerList, + showAtBackground: true, + )), + ), ], ), ), diff --git a/lib/ui/views/TIMUIKitChat/tim_uikit_chat_config.dart b/lib/ui/views/TIMUIKitChat/tim_uikit_chat_config.dart index 5e3378c..d530068 100644 --- a/lib/ui/views/TIMUIKitChat/tim_uikit_chat_config.dart +++ b/lib/ui/views/TIMUIKitChat/tim_uikit_chat_config.dart @@ -24,18 +24,34 @@ 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, and custom sticker packages. +/// message area, sticker packages, unicode emoji lists, 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; + /// Determines whether to compatible with the Tencent Cloud Chat Sticker Package 3.x version. + /// Default value : false + final bool useTencentCloudChatStickerPackageOldKeys; + + /// 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.useTencentCloudChatStickerPackageOldKeys = false, + this.unicodeEmojiList = TUIKitStickerConstData.defaultUnicodeEmojiList, this.customStickerPackages = const [], }); } 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 734d75c..9347f07 100644 --- a/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_last_msg.dart +++ b/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_last_msg.dart @@ -95,17 +95,11 @@ class _TIMUIKitLastMsgState extends TIMUIKitState { }); } } else { - String originalText = + String msgShowText = 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 = replaceText; + groupTipsAbstractText = msgShowText; }); } } @@ -228,31 +222,37 @@ class _TIMUIKitLastMsgState extends TIMUIKitState { 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), - ), + 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), - ), + 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, + )), ) ]); } diff --git a/lib/ui/widgets/link_preview/compiler/md_text.dart b/lib/ui/widgets/link_preview/compiler/md_text.dart index f62da8b..988add7 100644 --- a/lib/ui/widgets/link_preview/compiler/md_text.dart +++ b/lib/ui/widgets/link_preview/compiler/md_text.dart @@ -3,14 +3,17 @@ 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, { +String mdTextCompiler(String originalText, { + bool isUseQQPackage = false, bool isUseTencentCloudChatPackage = false, + bool isUseTencentCloudChatPackageOldKeys = false, List customEmojiStickerList = const [], }) { String text = originalText; final EmojiUtil emojiUtil = EmojiUtil( + isUseQQPackage: isUseQQPackage, isUseTencentCloudChatPackage: isUseTencentCloudChatPackage, + isUseTencentCloudChatPackageOldKeys: isUseTencentCloudChatPackageOldKeys, customEmojiStickerList: customEmojiStickerList); text = text.replaceAllMapped(emojiExp, (match) { @@ -25,4 +28,4 @@ String mdTextCompiler( }); 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 b01dd8d..aaeedeb 100644 --- a/lib/ui/widgets/link_preview/link_preview_entry.dart +++ b/lib/ui/widgets/link_preview/link_preview_entry.dart @@ -12,12 +12,17 @@ class LinkPreviewEntry { static LinkPreviewText? getHyperlinksText(String messageText, bool isMarkdown, {Function(String)? onLinkTap, bool isEnableTextSelection = false, + bool isUseQQPackage = false, bool isUseTencentCloudChatPackage = false, + bool isUseTencentCloudChatPackageOldKeys = false, List customEmojiStickerList = const []}) { return ({TextStyle? style}) { return isMarkdown ? LinkTextMarkdown( + isUseQQPackage: isUseQQPackage, isUseTencentCloudChatPackage: isUseTencentCloudChatPackage, + isUseTencentCloudChatPackageOldKeys: + isUseTencentCloudChatPackageOldKeys, customEmojiStickerList: customEmojiStickerList, isEnableTextSelection: isEnableTextSelection, messageText: addSpaceAfterLeftBracket( @@ -29,7 +34,10 @@ class LinkPreviewEntry { messageText: messageText, style: style, onLinkTap: onLinkTap, + isUseQQPackage: isUseQQPackage, isUseTencentCloudChatPackage: isUseTencentCloudChatPackage, + isUseTencentCloudChatPackageOldKeys: + isUseTencentCloudChatPackageOldKeys, 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 72f1c27..ab29357 100644 --- a/lib/ui/widgets/link_preview/widgets/link_text.dart +++ b/lib/ui/widgets/link_preview/widgets/link_text.dart @@ -28,14 +28,20 @@ class LinkTextMarkdown extends TIMStatelessWidget { final bool? isEnableTextSelection; + final bool isUseQQPackage; + final bool isUseTencentCloudChatPackage; + final bool isUseTencentCloudChatPackageOldKeys; + final List customEmojiStickerList; const LinkTextMarkdown( {Key? key, required this.messageText, + this.isUseQQPackage = false, this.isUseTencentCloudChatPackage = false, + this.isUseTencentCloudChatPackageOldKeys = false, this.customEmojiStickerList = const [], this.isEnableTextSelection, this.onLinkTap, @@ -81,8 +87,12 @@ class LinkText extends TIMStatelessWidget { /// text style for default words final TextStyle? style; + final bool isUseQQPackage; + final bool isUseTencentCloudChatPackage; + final bool isUseTencentCloudChatPackageOldKeys; + final List customEmojiStickerList; final bool? isEnableTextSelection; @@ -93,7 +103,9 @@ class LinkText extends TIMStatelessWidget { this.onLinkTap, this.isEnableTextSelection, this.style, + this.isUseQQPackage = false, this.isUseTencentCloudChatPackage = false, + this.isUseTencentCloudChatPackageOldKeys = false, this.customEmojiStickerList = const []}) : super(key: key); @@ -165,7 +177,10 @@ class LinkText extends TIMStatelessWidget { }, style: style ?? const TextStyle(fontSize: 16.0), specialTextSpanBuilder: DefaultSpecialTextSpanBuilder( + isUseQQPackage: isUseQQPackage, isUseTencentCloudChatPackage: isUseTencentCloudChatPackage, + isUseTencentCloudChatPackageOldKeys: + isUseTencentCloudChatPackageOldKeys, customEmojiStickerList: customEmojiStickerList, showAtBackground: true, )); diff --git a/pubspec.yaml b/pubspec.yaml index 65648a8..7682792 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: 4.0.0 +version: 4.0.1 homepage: https://trtc.io/products/chat?utm_source=gfs&utm_medium=link&utm_campaign=%E6%B8%A0%E9%81%93&_channel_track_key=k6WgfCKn repository: https://github.com/TencentCloud/chat-uikit-flutter documentation: https://comm.qq.com/im/doc/flutter/en/TUIKit/readme.html @@ -61,7 +61,7 @@ dependencies: uuid: ^3.0.6 open_file: ^3.3.2 tencent_keyboard_visibility: ^1.0.1 - tim_ui_kit_sticker_plugin: ^3.2.0 + tim_ui_kit_sticker_plugin: ^4.0.1 tencent_im_base: ^8.0.0 fc_native_video_thumbnail: ^0.16.0 path: ^1.8.1