tencent_cloud_chat_uikit source code update to version 4.0.0.
This commit is contained in:
parent
763cf3f750
commit
7a2d31ea71
10
CHANGELOG.md
10
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.
|
||||
|
||||
|
|
|
|||
|
|
@ -271,9 +271,6 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget {
|
|||
// open MessageReaction
|
||||
final bool? isUseMessageReaction;
|
||||
|
||||
/// Whether to use the default emoji
|
||||
final bool isUseDefaultEmoji;
|
||||
|
||||
final List<CustomEmojiFaceData> 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,
|
||||
|
|
|
|||
|
|
@ -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<CustomEmojiFaceData> 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);
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
}
|
||||
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<TIMUIKitImageElem> {
|
|||
return;
|
||||
}
|
||||
|
||||
var result = await ImageGallerySaver.saveFile(imageUrl);
|
||||
var result = await ImageGallerySaverPlus.saveFile(imageUrl);
|
||||
|
||||
if (PlatformUtils().isIOS) {
|
||||
if (result['isSuccess']) {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ class TIMUIKitReplyElem extends StatefulWidget {
|
|||
final EdgeInsetsGeometry? textPadding;
|
||||
final TUIChatSeparateViewModel chatModel;
|
||||
final bool? isShowMessageReaction;
|
||||
final bool isUseDefaultEmoji;
|
||||
final List<CustomEmojiFaceData> 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<TIMUIKitReplyElem> {
|
|||
}
|
||||
|
||||
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<TIMUIKitReplyElem> {
|
|||
}
|
||||
|
||||
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<TIMUIKitReplyElem> {
|
|||
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<TIMUIKitReplyElem> {
|
|||
fontSize: isDesktopScreen ? 14 : 16,
|
||||
height: widget.chatModel.chatConfig.textHeight),
|
||||
specialTextSpanBuilder: DefaultSpecialTextSpanBuilder(
|
||||
isUseQQPackage: (widget
|
||||
.chatModel
|
||||
.chatConfig
|
||||
.stickerPanelConfig
|
||||
?.useTencentCloudChatStickerPackage ??
|
||||
true) ||
|
||||
widget.isUseDefaultEmoji,
|
||||
isUseTencentCloudChatPackage: widget
|
||||
.chatModel
|
||||
.chatConfig
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ class TIMUIKitTextElem extends StatefulWidget {
|
|||
final EdgeInsetsGeometry? textPadding;
|
||||
final TUIChatSeparateViewModel chatModel;
|
||||
final bool? isShowMessageReaction;
|
||||
final bool isUseDefaultEmoji;
|
||||
final List<CustomEmojiFaceData> 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<TIMUIKitTextElem> {
|
|||
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<TIMUIKitTextElem> {
|
|||
fontSize: isDesktopScreen ? 14 : 16,
|
||||
height: widget.chatModel.chatConfig.textHeight),
|
||||
specialTextSpanBuilder: DefaultSpecialTextSpanBuilder(
|
||||
isUseQQPackage: (widget
|
||||
.chatModel
|
||||
.chatConfig
|
||||
.stickerPanelConfig
|
||||
?.useTencentCloudChatStickerPackage ??
|
||||
true) ||
|
||||
widget.isUseDefaultEmoji,
|
||||
isUseTencentCloudChatPackage: widget
|
||||
.chatModel
|
||||
.chatConfig
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ class TIMUIKitTextTranslationElem extends StatefulWidget {
|
|||
final EdgeInsetsGeometry? textPadding;
|
||||
final TUIChatSeparateViewModel chatModel;
|
||||
final bool? isShowMessageReaction;
|
||||
final bool isUseDefaultEmoji;
|
||||
final List<CustomEmojiFaceData> 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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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<CustomEmojiFaceData> 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<CustomEmojiFaceData> 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<CustomEmojiFaceData> customEmojiStickerList = const []}) {
|
||||
return _instance ??= EmojiUtil._internal(
|
||||
isUseQQPackage: isUseQQPackage,
|
||||
customEmojiStickerList: customEmojiStickerList,
|
||||
isUseTencentCloudChatPackage: isUseTencentCloudChatPackage);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,7 +142,8 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
double inputWidth = 900;
|
||||
Map<String, V2TimGroupMemberFullInfo> mentionedMembersMap = {};
|
||||
late TextEditingController textEditingController;
|
||||
final TUIConversationViewModel conversationModel = serviceLocator<TUIConversationViewModel>();
|
||||
final TUIConversationViewModel conversationModel =
|
||||
serviceLocator<TUIConversationViewModel>();
|
||||
final TUISelfInfoViewModel selfModel = serviceLocator<TUISelfInfoViewModel>();
|
||||
MuteStatus muteStatus = MuteStatus.none;
|
||||
bool _isComposingText = false;
|
||||
|
|
@ -154,41 +155,29 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
// 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<TIMUIKitInputTextField> {
|
|||
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<TIMUIKitInputTextField> {
|
|||
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<TIMUIKitInputTextField> {
|
|||
|
||||
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<TIMUIKitInputTextField> {
|
|||
}
|
||||
|
||||
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<TIMUIKitInputTextField> {
|
|||
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<TIMUIKitInputTextField> {
|
|||
}
|
||||
|
||||
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<TIMUIKitInputTextField> {
|
|||
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<TIMUIKitInputTextField> {
|
|||
}
|
||||
|
||||
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<TIMUIKitInputTextField> {
|
|||
}
|
||||
|
||||
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<TIMUIKitInputTextField> {
|
|||
//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<TIMUIKitInputTextField> {
|
|||
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<TIMUIKitInputTextField> {
|
|||
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<TIMUIKitInputTextField> {
|
|||
_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<TIMUIKitInputTextField> {
|
|||
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<TIMUIKitInputTextField> {
|
|||
}
|
||||
|
||||
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<TIMUIKitInputTextField> {
|
|||
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<TIMUIKitInputTextField> {
|
|||
model.atPositionY = atPosition.dy;
|
||||
isAddingAtSearchWords = true;
|
||||
}
|
||||
List<V2TimGroupMemberFullInfo> showAtMemberList = (model.groupMemberList ?? [])
|
||||
List<V2TimGroupMemberFullInfo> 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<V2TimGroupMemberFullInfo>()
|
||||
.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<TIMUIKitInputTextField> {
|
|||
|
||||
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<TIMUIKitInputTextField> {
|
|||
model.showAtMemberList = [];
|
||||
isAddingAtSearchWords = false;
|
||||
}
|
||||
} else if (textLength > 0 && text[textLength - 1] == "@" && lastText.length < textLength) {
|
||||
List<V2TimGroupMemberFullInfo> selectedAtMemberList = await Navigator.push(
|
||||
} else if (textLength > 0 &&
|
||||
text[textLength - 1] == "@" &&
|
||||
lastText.length < textLength) {
|
||||
List<V2TimGroupMemberFullInfo> 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<TIMUIKitInputTextField> {
|
|||
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<TIMUIKitInputTextField> {
|
|||
|
||||
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<TIMUIKitInputTextField> {
|
|||
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<TIMUIKitInputTextField> {
|
|||
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<TIMUIKitInputTextField> {
|
|||
} 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<TIMUIKitInputTextField> {
|
|||
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<TIMUIKitInputTextField> {
|
|||
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<TIMUIKitInputTextField> {
|
|||
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<TIMUIKitInputTextField> {
|
|||
|
||||
Future<bool> 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<TIMUIKitInputTextField> {
|
|||
}
|
||||
|
||||
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<TIMUIKitInputTextField> {
|
|||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final theme = value.theme;
|
||||
final TUIChatSeparateViewModel model = Provider.of<TUIChatSeparateViewModel>(context);
|
||||
final TUIChatSeparateViewModel model =
|
||||
Provider.of<TUIChatSeparateViewModel>(context);
|
||||
|
||||
_getMuteType(model);
|
||||
|
||||
|
|
@ -870,7 +993,8 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
}
|
||||
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -132,10 +132,12 @@ class TIMUIKitTextFieldLayoutNarrow extends StatefulWidget {
|
|||
: super(key: key);
|
||||
|
||||
@override
|
||||
State<TIMUIKitTextFieldLayoutNarrow> createState() => _TIMUIKitTextFieldLayoutNarrowState();
|
||||
State<TIMUIKitTextFieldLayoutNarrow> createState() =>
|
||||
_TIMUIKitTextFieldLayoutNarrowState();
|
||||
}
|
||||
|
||||
class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState<TIMUIKitTextFieldLayoutNarrow> {
|
||||
class _TIMUIKitTextFieldLayoutNarrowState
|
||||
extends TIMUIKitState<TIMUIKitTextFieldLayoutNarrow> {
|
||||
final TUISettingModel settingModel = serviceLocator<TUISettingModel>();
|
||||
|
||||
bool showMore = false;
|
||||
|
|
@ -209,14 +211,13 @@ class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState<TIMUIKitTextFiel
|
|||
},
|
||||
addCustomEmojiText: ((String singleEmojiName) {
|
||||
String? emojiName = singleEmojiName.split('.png')[0];
|
||||
if (widget.isUseDefaultEmoji && widget.languageType == 'zh' && TUIKitStickerConstData.emojiMapList[emojiName] != null && TUIKitStickerConstData.emojiMapList[emojiName] != '') {
|
||||
emojiName = TUIKitStickerConstData.emojiMapList[emojiName];
|
||||
}
|
||||
final newText = '[$emojiName]';
|
||||
final newText = TIM_t('[$emojiName]');
|
||||
widget.addStickerToText(newText);
|
||||
setSendButton();
|
||||
}),
|
||||
defaultCustomEmojiStickerList: widget.isUseDefaultEmoji ? TUIKitStickerConstData.emojiList : [])
|
||||
defaultCustomEmojiStickerList: widget.isUseDefaultEmoji
|
||||
? TUIKitStickerConstData.emojiList
|
||||
: [])
|
||||
: StickerPanel(
|
||||
isWideScreen: false,
|
||||
sendTextMsg: () {
|
||||
|
|
@ -236,10 +237,7 @@ class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState<TIMUIKitTextFiel
|
|||
},
|
||||
addCustomEmojiText: ((String singleEmojiName) {
|
||||
String? emojiName = singleEmojiName.split('.png')[0];
|
||||
if (widget.isUseDefaultEmoji && widget.languageType == 'zh' && TUIKitStickerConstData.emojiMapList[emojiName] != null && TUIKitStickerConstData.emojiMapList[emojiName] != '') {
|
||||
emojiName = TUIKitStickerConstData.emojiMapList[emojiName];
|
||||
}
|
||||
final newText = '[$emojiName]';
|
||||
final newText = TIM_t('[$emojiName]');
|
||||
widget.addStickerToText(newText);
|
||||
setSendButton();
|
||||
}),
|
||||
|
|
@ -248,7 +246,10 @@ class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState<TIMUIKitTextFiel
|
|||
}
|
||||
|
||||
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);
|
||||
|
|
@ -270,7 +271,8 @@ class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState<TIMUIKitTextFiel
|
|||
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;
|
||||
|
|
@ -323,14 +325,20 @@ class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState<TIMUIKitTextFiel
|
|||
}
|
||||
|
||||
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,
|
||||
|
|
@ -411,7 +419,8 @@ class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState<TIMUIKitTextFiel
|
|||
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: [
|
||||
|
|
@ -435,24 +444,28 @@ class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState<TIMUIKitTextFiel
|
|||
}
|
||||
},
|
||||
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,
|
||||
|
|
@ -466,19 +479,24 @@ class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState<TIMUIKitTextFiel
|
|||
});
|
||||
},
|
||||
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(
|
||||
|
|
@ -489,41 +507,52 @@ class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState<TIMUIKitTextFiel
|
|||
filled: true,
|
||||
isDense: true,
|
||||
hintText: widget.hintText ?? ''),
|
||||
controller: widget.textEditingController,
|
||||
specialTextSpanBuilder: PlatformUtils().isWeb
|
||||
controller:
|
||||
widget.textEditingController,
|
||||
specialTextSpanBuilder: PlatformUtils()
|
||||
.isWeb
|
||||
? null
|
||||
: DefaultSpecialTextSpanBuilder(
|
||||
isUseQQPackage: (widget.model.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true) || widget.isUseDefaultEmoji,
|
||||
isUseTencentCloudChatPackage: widget.model.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true,
|
||||
customEmojiStickerList: widget.customEmojiStickerList,
|
||||
isUseTencentCloudChatPackage:
|
||||
widget
|
||||
.model
|
||||
.chatConfig
|
||||
.stickerPanelConfig
|
||||
?.useTencentCloudChatStickerPackage ??
|
||||
true,
|
||||
customEmojiStickerList: widget
|
||||
.customEmojiStickerList,
|
||||
showAtBackground: true,
|
||||
checkHttpLink: false,
|
||||
)),
|
||||
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);
|
||||
}
|
||||
onChanged: (bool visibility) {
|
||||
if (showKeyboard != visibility) {
|
||||
setState(() {
|
||||
showKeyboard = visibility;
|
||||
});
|
||||
}
|
||||
}, child: Container(),
|
||||
),
|
||||
]
|
||||
}),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
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,
|
||||
),
|
||||
if (widget.showSendEmoji)
|
||||
InkWell(
|
||||
onTap: () {
|
||||
|
|
@ -531,18 +560,25 @@ class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState<TIMUIKitTextFiel
|
|||
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: () {
|
||||
|
|
@ -551,7 +587,8 @@ class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState<TIMUIKitTextFiel
|
|||
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',
|
||||
|
|
@ -560,7 +597,8 @@ class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState<TIMUIKitTextFiel
|
|||
width: 28,
|
||||
),
|
||||
),
|
||||
if ((isAndroidDevice() || isWebDevice()) && !showMoreButton)
|
||||
if ((isAndroidDevice() || isWebDevice()) &&
|
||||
!showMoreButton)
|
||||
SizedBox(
|
||||
height: 32.0,
|
||||
child: ElevatedButton(
|
||||
|
|
@ -582,7 +620,10 @@ class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState<TIMUIKitTextFiel
|
|||
),
|
||||
),
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -56,7 +56,9 @@ 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 {
|
||||
|
|
@ -188,10 +190,12 @@ class TIMUIKitTextFieldLayoutWide extends StatefulWidget {
|
|||
: super(key: key);
|
||||
|
||||
@override
|
||||
State<TIMUIKitTextFieldLayoutWide> createState() => _TIMUIKitTextFieldLayoutWideState();
|
||||
State<TIMUIKitTextFieldLayoutWide> createState() =>
|
||||
_TIMUIKitTextFieldLayoutWideState();
|
||||
}
|
||||
|
||||
class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldLayoutWide> {
|
||||
class _TIMUIKitTextFieldLayoutWideState
|
||||
extends TIMUIKitState<TIMUIKitTextFieldLayoutWide> {
|
||||
final TUISettingModel settingModel = serviceLocator<TUISettingModel>();
|
||||
OverlayEntry? entry;
|
||||
final ImagePicker _picker = ImagePicker();
|
||||
|
|
@ -265,11 +269,13 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
}
|
||||
|
||||
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) {
|
||||
|
|
@ -292,7 +298,10 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
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(
|
||||
|
|
@ -337,7 +346,8 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
},
|
||||
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)),
|
||||
|
|
@ -375,18 +385,14 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
},
|
||||
addCustomEmojiText: ((String singleEmojiName) {
|
||||
String? emojiName = singleEmojiName.split('.png')[0];
|
||||
if (widget.isUseDefaultEmoji &&
|
||||
widget.languageType == 'zh' &&
|
||||
TUIKitStickerConstData.emojiMapList[emojiName] != null &&
|
||||
TUIKitStickerConstData.emojiMapList[emojiName] != '') {
|
||||
emojiName = TUIKitStickerConstData.emojiMapList[emojiName];
|
||||
}
|
||||
final newText = '[$emojiName]';
|
||||
final newText = TIM_t('[$emojiName]');
|
||||
widget.addStickerToText(newText);
|
||||
entry?.remove();
|
||||
entry = null;
|
||||
}),
|
||||
defaultCustomEmojiStickerList: widget.isUseDefaultEmoji ? TUIKitStickerConstData.emojiList : [])
|
||||
defaultCustomEmojiStickerList: widget.isUseDefaultEmoji
|
||||
? TUIKitStickerConstData.emojiList
|
||||
: [])
|
||||
: Material(
|
||||
color: Colors.transparent,
|
||||
child: StickerPanel(
|
||||
|
|
@ -409,14 +415,9 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
entry = null;
|
||||
},
|
||||
addCustomEmojiText: ((String singleEmojiName) {
|
||||
String? emojiName = singleEmojiName.split('.png')[0];
|
||||
if (widget.isUseDefaultEmoji &&
|
||||
widget.languageType == 'zh' &&
|
||||
TUIKitStickerConstData.emojiMapList[emojiName] != null &&
|
||||
TUIKitStickerConstData.emojiMapList[emojiName] != '') {
|
||||
emojiName = TUIKitStickerConstData.emojiMapList[emojiName];
|
||||
}
|
||||
final newText = '[$emojiName]';
|
||||
String? emojiName =
|
||||
singleEmojiName.split('.png')[0];
|
||||
final newText = TIM_t('[$emojiName]');
|
||||
widget.addStickerToText(newText);
|
||||
entry?.remove();
|
||||
entry = null;
|
||||
|
|
@ -467,11 +468,17 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
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!);
|
||||
|
|
@ -479,7 +486,12 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
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();
|
||||
|
|
@ -490,7 +502,8 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
}
|
||||
}
|
||||
|
||||
List<Widget> generateBarIcons(List<DesktopControlBarItem> items, TUITheme theme) {
|
||||
List<Widget> generateBarIcons(
|
||||
List<DesktopControlBarItem> 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<TIMUIKitTextFieldL
|
|||
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(
|
||||
|
|
@ -517,7 +533,9 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
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,
|
||||
|
|
@ -526,7 +544,9 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
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,
|
||||
|
|
@ -555,12 +575,17 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
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
|
||||
|
|
@ -577,18 +602,25 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
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
|
||||
|
|
@ -602,8 +634,10 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
@ -612,7 +646,9 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
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,
|
||||
|
|
@ -624,14 +660,22 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
);
|
||||
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;
|
||||
|
|
@ -647,7 +691,11 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
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) {
|
||||
|
|
@ -659,20 +707,26 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
} 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,
|
||||
|
|
@ -682,7 +736,11 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
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 {
|
||||
|
|
@ -692,13 +750,17 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
} 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(
|
||||
|
|
@ -717,7 +779,9 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
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(
|
||||
|
|
@ -770,7 +834,8 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
}
|
||||
|
||||
generateDefaultControlBarItems() {
|
||||
final DesktopControlBarConfig config = widget.chatConfig.desktopControlBarConfig ?? DesktopControlBarConfig();
|
||||
final DesktopControlBarConfig config =
|
||||
widget.chatConfig.desktopControlBarConfig ?? DesktopControlBarConfig();
|
||||
final List<DesktopControlBarItem> itemsList = [
|
||||
if (config.showStickerPanel)
|
||||
DesktopControlBarItem(
|
||||
|
|
@ -835,9 +900,13 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
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);
|
||||
},
|
||||
|
|
@ -846,7 +915,8 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
defaultControlBarItems = itemsList;
|
||||
}
|
||||
|
||||
List<Widget> generateControlBar(TUIChatSeparateViewModel model, TUITheme theme) {
|
||||
List<Widget> generateControlBar(
|
||||
TUIChatSeparateViewModel model, TUITheme theme) {
|
||||
final List<DesktopControlBarItem> itemsList = [
|
||||
...defaultControlBarItems,
|
||||
...(widget.chatConfig.additionalDesktopControlBarItems ?? [])
|
||||
|
|
@ -860,22 +930,29 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
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<void> _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<TIMUIKitTextFieldL
|
|||
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);
|
||||
|
|
@ -924,61 +1002,67 @@ class _TIMUIKitTextFieldLayoutWideState extends TIMUIKitState<TIMUIKitTextFieldL
|
|||
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),
|
||||
),
|
||||
fillColor: widget.backgroundColor ??
|
||||
theme.desktopChatMessageInputBgColor ??
|
||||
hexToColor("fafafa"),
|
||||
filled: true,
|
||||
isDense: true,
|
||||
hintText: widget.hintText ?? '',
|
||||
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),
|
||||
),
|
||||
controller: widget.textEditingController,
|
||||
specialTextSpanBuilder: PlatformUtils().isWeb
|
||||
? null
|
||||
: DefaultSpecialTextSpanBuilder(
|
||||
isUseQQPackage: (widget.model.chatConfig.stickerPanelConfig
|
||||
?.useTencentCloudChatStickerPackage ??
|
||||
true) ||
|
||||
widget.isUseDefaultEmoji,
|
||||
isUseTencentCloudChatPackage:
|
||||
widget.model.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ??
|
||||
true,
|
||||
customEmojiStickerList: widget.customEmojiStickerList,
|
||||
showAtBackground: true,
|
||||
)),
|
||||
),
|
||||
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,
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@ class TIMUIKitChat extends StatefulWidget {
|
|||
final ConvType? conversationType;
|
||||
|
||||
/// use for customize avatar
|
||||
final Widget Function(BuildContext context, V2TimMessage message)? userAvatarBuilder;
|
||||
final Widget Function(BuildContext context, V2TimMessage message)?
|
||||
userAvatarBuilder;
|
||||
|
||||
/// Use for show conversation name.
|
||||
/// This field is not necessary to be provided, when `conversation` is provided, unless you want to cover this field manually.
|
||||
|
|
@ -64,9 +65,11 @@ class TIMUIKitChat extends StatefulWidget {
|
|||
final void Function(String userID, TapDownDetails tapDetails)? onTapAvatar;
|
||||
|
||||
/// Avatar and name in message reaction secondary tap callback.
|
||||
final void Function(String userID, TapDownDetails tapDetails)? onSecondaryTapAvatar;
|
||||
final void Function(String userID, TapDownDetails tapDetails)?
|
||||
onSecondaryTapAvatar;
|
||||
|
||||
@Deprecated("Nickname will not shows in one-to-one chat, if you tend to control it in group chat, please use `isShowSelfNameInGroup` and `isShowOthersNameInGroup` from `config: TIMUIKitChatConfig` instead")
|
||||
@Deprecated(
|
||||
"Nickname will not shows in one-to-one chat, if you tend to control it in group chat, please use `isShowSelfNameInGroup` and `isShowOthersNameInGroup` from `config: TIMUIKitChatConfig` instead")
|
||||
|
||||
/// Should show the nick name.
|
||||
final bool showNickName;
|
||||
|
|
@ -78,10 +81,12 @@ class TIMUIKitChat extends StatefulWidget {
|
|||
final bool showTotalUnReadCount;
|
||||
|
||||
/// Deprecated("Please use [extraTipsActionItemBuilder] instead")
|
||||
final Widget? Function(V2TimMessage message, Function() closeTooltip, [Key? key, BuildContext? context])? exteraTipsActionItemBuilder;
|
||||
final Widget? Function(V2TimMessage message, Function() closeTooltip,
|
||||
[Key? key, BuildContext? context])? exteraTipsActionItemBuilder;
|
||||
|
||||
/// The builder for extra tips action.
|
||||
final Widget? Function(V2TimMessage message, Function() closeTooltip, [Key? key, BuildContext? context])? extraTipsActionItemBuilder;
|
||||
final Widget? Function(V2TimMessage message, Function() closeTooltip,
|
||||
[Key? key, BuildContext? context])? extraTipsActionItemBuilder;
|
||||
|
||||
/// The text of draft shows in TextField.
|
||||
/// [Recommend]: You can specify this field with the draftText from V2TimConversation.
|
||||
|
|
@ -172,10 +177,13 @@ class TIMUIKitChat extends StatefulWidget {
|
|||
this.conversationShowName,
|
||||
this.abstractMessageBuilder,
|
||||
this.onTapAvatar,
|
||||
@Deprecated("Nickname will not show in one-to-one chat, if you tend to control it in group chat, please use `isShowSelfNameInGroup` and `isShowOthersNameInGroup` from `config: TIMUIKitChatConfig` instead") this.showNickName = false,
|
||||
@Deprecated(
|
||||
"Nickname will not show in one-to-one chat, if you tend to control it in group chat, please use `isShowSelfNameInGroup` and `isShowOthersNameInGroup` from `config: TIMUIKitChatConfig` instead")
|
||||
this.showNickName = false,
|
||||
this.showTotalUnReadCount = false,
|
||||
this.messageItemBuilder,
|
||||
@Deprecated("Please use [extraTipsActionItemBuilder] instead") this.exteraTipsActionItemBuilder,
|
||||
@Deprecated("Please use [extraTipsActionItemBuilder] instead")
|
||||
this.exteraTipsActionItemBuilder,
|
||||
this.extraTipsActionItemBuilder,
|
||||
this.draftText,
|
||||
this.textFieldHintText,
|
||||
|
|
@ -209,24 +217,30 @@ class TIMUIKitChat extends StatefulWidget {
|
|||
|
||||
class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
||||
TUIChatSeparateViewModel model = TUIChatSeparateViewModel();
|
||||
final TUISelfInfoViewModel selfInfoViewModel = serviceLocator<TUISelfInfoViewModel>();
|
||||
final TUISelfInfoViewModel selfInfoViewModel =
|
||||
serviceLocator<TUISelfInfoViewModel>();
|
||||
final TUIThemeViewModel themeViewModel = serviceLocator<TUIThemeViewModel>();
|
||||
final TUIConversationViewModel conversationViewModel = serviceLocator<TUIConversationViewModel>();
|
||||
TIMUIKitInputTextFieldController textFieldController = TIMUIKitInputTextFieldController();
|
||||
final TUIConversationViewModel conversationViewModel =
|
||||
serviceLocator<TUIConversationViewModel>();
|
||||
TIMUIKitInputTextFieldController textFieldController =
|
||||
TIMUIKitInputTextFieldController();
|
||||
bool isInit = false;
|
||||
final TUIChatGlobalModel chatGlobalModel = serviceLocator<TUIChatGlobalModel>();
|
||||
final TUIChatGlobalModel chatGlobalModel =
|
||||
serviceLocator<TUIChatGlobalModel>();
|
||||
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<TIMUIKitChat> {
|
|||
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<TIMUIKitChat> {
|
|||
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<TIMUIKitChat> {
|
|||
}
|
||||
|
||||
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<TIMUIKitChat> {
|
|||
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<TIMUIKitChat> {
|
|||
Provider(create: (_) => widget.config),
|
||||
],
|
||||
builder: (context, model, w) {
|
||||
final TUIChatGlobalModel chatGlobalModel = Provider.of<TUIChatGlobalModel>(context, listen: true);
|
||||
final TUIChatGlobalModel chatGlobalModel =
|
||||
Provider.of<TUIChatGlobalModel>(context, listen: true);
|
||||
|
||||
widget.controller?.model = model;
|
||||
widget.controller?.textFieldController = textFieldController;
|
||||
widget.controller?.scrollController = autoController;
|
||||
List<V2TimGroupApplication> 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<TUIGroupListenerModel>(context, listen: true);
|
||||
final TUIGroupListenerModel groupListenerModel =
|
||||
Provider.of<TUIGroupListenerModel>(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<TIMUIKitChat> {
|
|||
}
|
||||
|
||||
List<CustomEmojiFaceData> 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<TIMUIKitChat> {
|
|||
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<TIMUIKitChat> {
|
|||
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<TIMUIKitChat> {
|
|||
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<TIMUIKitChat> {
|
|||
: 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<TIMUIKitChat> {
|
|||
),
|
||||
AtMemberPanel(
|
||||
atMemberPanelScroll: atMemberPanelScroll,
|
||||
onSelectMember: (member) => textFieldController.handleAtMember(member),
|
||||
onSelectMember: (member) =>
|
||||
textFieldController.handleAtMember(member),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
|
@ -562,12 +646,14 @@ class _TUIChatState extends TIMUIKitState<TIMUIKitChat> {
|
|||
class TIMUIKitChatProviderScope extends StatelessWidget {
|
||||
final TUIChatGlobalModel globalModel = serviceLocator<TUIChatGlobalModel>();
|
||||
TUIChatSeparateViewModel? model;
|
||||
final TUIGroupListenerModel groupListenerModel = serviceLocator<TUIGroupListenerModel>();
|
||||
final TUIGroupListenerModel groupListenerModel =
|
||||
serviceLocator<TUIGroupListenerModel>();
|
||||
final TUIThemeViewModel themeViewModel = serviceLocator<TUIThemeViewModel>();
|
||||
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<SingleChildWidget>? 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);
|
||||
// }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<int> unicodeEmojiList;
|
||||
|
||||
/// A list of CustomStickerPackage instances, where each instance represents a sticker package.
|
||||
/// Default value: an empty list.
|
||||
final List<CustomStickerPackage> 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});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<TIMUIKitLastMsg> {
|
|||
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<TIMUIKitLastMsg> {
|
|||
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<String?> _getLastMsgShowText(V2TimMessage? message, BuildContext context) async {
|
||||
Future<String?> _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<TIMUIKitLastMsg> {
|
|||
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<TIMUIKitLastMsg> {
|
|||
|
||||
@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<TIMUIKitLastMsg> {
|
|||
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),
|
||||
),
|
||||
)
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -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<CustomEmojiFaceData> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<CustomEmojiFaceData> 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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@ class LinkTextMarkdown extends TIMStatelessWidget {
|
|||
|
||||
final bool? isEnableTextSelection;
|
||||
|
||||
final bool isUseQQPackage;
|
||||
|
||||
final bool isUseTencentCloudChatPackage;
|
||||
|
||||
final List<CustomEmojiFaceData> 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<CustomEmojiFaceData> 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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue