style: format code with line length 120

This commit is contained in:
Max 2026-01-07 20:53:52 +08:00
parent 0d58276ff6
commit 5ccb5adb79
5 changed files with 165 additions and 232 deletions

26
.editorconfig Normal file
View File

@ -0,0 +1,26 @@
# 这是一个顶级配置文件,停止向父目录查找
root = true
# === 全局通用设置 (所有文件) ===
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
# === Dart 文件专用设置 ===
[*.dart]
# SDK 原始代码使用较长的行宽,设置为 120 以保持一致
max_line_length = 120
indent_size = 2
# === YAML/JSON 文件 (配置文件) ===
[*.{yaml,yml,json}]
indent_size = 2
# === Markdown 文件 (文档) ===
[*.md]
trim_trailing_whitespace = false
max_line_length = 0

View File

@ -24,17 +24,12 @@ import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.
import 'package:tencent_cloud_chat_uikit/data_services/conversation/conversation_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/conversation/conversation_services.dart';
import 'package:tencent_cloud_chat_uikit/data_services/group/group_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/group/group_services.dart';
enum KeywordListMatchType { enum KeywordListMatchType { V2TIM_KEYWORD_LIST_MATCH_TYPE_OR, V2TIM_KEYWORD_LIST_MATCH_TYPE_AND }
V2TIM_KEYWORD_LIST_MATCH_TYPE_OR,
V2TIM_KEYWORD_LIST_MATCH_TYPE_AND
}
class TUISearchViewModel extends ChangeNotifier { class TUISearchViewModel extends ChangeNotifier {
final FriendshipServices _friendshipServices = final FriendshipServices _friendshipServices = serviceLocator<FriendshipServices>();
serviceLocator<FriendshipServices>();
final MessageService _messageService = serviceLocator<MessageService>(); final MessageService _messageService = serviceLocator<MessageService>();
final ConversationService _conversationService = final ConversationService _conversationService = serviceLocator<ConversationService>();
serviceLocator<ConversationService>();
final GroupServices _groupServices = serviceLocator<GroupServices>(); final GroupServices _groupServices = serviceLocator<GroupServices>();
List<V2TimFriendInfoResult>? friendList = []; List<V2TimFriendInfoResult>? friendList = [];
@ -51,8 +46,7 @@ class TUISearchViewModel extends ChangeNotifier {
List<V2TimConversation?> conversationList = []; List<V2TimConversation?> conversationList = [];
Future<List<V2TimConversation?>?> initConversationMsg() async { Future<List<V2TimConversation?>?> initConversationMsg() async {
final conversationResult = await _conversationService.getConversationList( final conversationResult = await _conversationService.getConversationList(nextSeq: "0", count: 500);
nextSeq: "0", count: 500);
final conversationListData = conversationResult?.conversationList; final conversationListData = conversationResult?.conversationList;
conversationList = conversationListData ?? []; conversationList = conversationListData ?? [];
notifyListeners(); notifyListeners();
@ -74,8 +68,8 @@ class TUISearchViewModel extends ChangeNotifier {
notifyListeners(); notifyListeners();
return; return;
} }
final searchResult = await _friendshipServices.searchFriends( final searchResult =
searchParam: V2TimFriendSearchParam(keywordList: [searchKey])); await _friendshipServices.searchFriends(searchParam: V2TimFriendSearchParam(keywordList: [searchKey]));
friendList = searchResult; friendList = searchResult;
notifyListeners(); notifyListeners();
} }
@ -87,14 +81,13 @@ class TUISearchViewModel extends ChangeNotifier {
notifyListeners(); notifyListeners();
return; return;
} }
final searchResult = await _groupServices.searchGroups( final searchResult =
searchParam: V2TimGroupSearchParam(keywordList: [searchKey])); await _groupServices.searchGroups(searchParam: V2TimGroupSearchParam(keywordList: [searchKey]));
groupList = searchResult.data ?? []; groupList = searchResult.data ?? [];
notifyListeners(); notifyListeners();
} }
void getMsgForConversation( void getMsgForConversation(String keyword, String conversationId, int page) async {
String keyword, String conversationId, int page) async {
void clearData() { void clearData() {
currentMsgListForConversation = []; currentMsgListForConversation = [];
totalMsgInConversationCount = 0; totalMsgInConversationCount = 0;
@ -118,9 +111,8 @@ class TUISearchViewModel extends ChangeNotifier {
type: KeywordListMatchType.V2TIM_KEYWORD_LIST_MATCH_TYPE_OR.index, type: KeywordListMatchType.V2TIM_KEYWORD_LIST_MATCH_TYPE_OR.index,
)); ));
if (searchResult.code == 0 && searchResult.data != null) { if (searchResult.code == 0 && searchResult.data != null) {
final messageSearchResultItems = final messageSearchResultItems = searchResult.data!.messageSearchResultItems!
searchResult.data!.messageSearchResultItems!.firstWhereOrNull( .firstWhereOrNull((element) => element.conversationID == conversationId);
(element) => element.conversationID == conversationId);
totalMsgInConversationCount = messageSearchResultItems?.messageCount ?? 0; totalMsgInConversationCount = messageSearchResultItems?.messageCount ?? 0;
currentMsgListForConversation = [ currentMsgListForConversation = [
...currentMsgListForConversation, ...currentMsgListForConversation,

View File

@ -150,8 +150,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
double inputWidth = 900; double inputWidth = 900;
Map<String, V2TimGroupMemberFullInfo> mentionedMembersMap = {}; Map<String, V2TimGroupMemberFullInfo> mentionedMembersMap = {};
late TextEditingController textEditingController; late TextEditingController textEditingController;
final TUIConversationViewModel conversationModel = final TUIConversationViewModel conversationModel = serviceLocator<TUIConversationViewModel>();
serviceLocator<TUIConversationViewModel>();
final TUISelfInfoViewModel selfModel = serviceLocator<TUISelfInfoViewModel>(); final TUISelfInfoViewModel selfModel = serviceLocator<TUISelfInfoViewModel>();
MuteStatus muteStatus = MuteStatus.none; MuteStatus muteStatus = MuteStatus.none;
bool _isComposingText = false; bool _isComposingText = false;
@ -163,11 +162,9 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
// Keep using original scheme. // Keep using original scheme.
return; return;
} }
final stickerConfig = final stickerConfig = widget.model.chatConfig.stickerPanelConfig ?? StickerPanelConfig();
widget.model.chatConfig.stickerPanelConfig ?? StickerPanelConfig();
if (stickerConfig.useTencentCloudChatStickerPackage) { if (stickerConfig.useTencentCloudChatStickerPackage) {
final tccEmojiSet = TUIKitStickerConstData.emojiList final tccEmojiSet = TUIKitStickerConstData.emojiList.firstWhere((element) => element.name == "tcc1");
.firstWhere((element) => element.name == "tcc1");
stickerPackageList.add(CustomStickerPackage( stickerPackageList.add(CustomStickerPackage(
name: tccEmojiSet.name, name: tccEmojiSet.name,
baseUrl: "assets/custom_face_resource/${tccEmojiSet.name}", baseUrl: "assets/custom_face_resource/${tccEmojiSet.name}",
@ -176,8 +173,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
stickerList: tccEmojiSet.list stickerList: tccEmojiSet.list
.asMap() .asMap()
.keys .keys
.map((idx) => .map((idx) => CustomSticker(index: idx, name: tccEmojiSet.list[idx]))
CustomSticker(index: idx, name: tccEmojiSet.list[idx]))
.toList(), .toList(),
menuItem: CustomSticker( menuItem: CustomSticker(
index: 0, index: 0,
@ -186,19 +182,14 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
} }
if (stickerConfig.useQQStickerPackage) { if (stickerConfig.useQQStickerPackage) {
final qqEmojiSet = TUIKitStickerConstData.emojiList final qqEmojiSet = TUIKitStickerConstData.emojiList.firstWhere((element) => element.name == "4349");
.firstWhere((element) => element.name == "4349");
stickerPackageList.add(CustomStickerPackage( stickerPackageList.add(CustomStickerPackage(
name: qqEmojiSet.name, name: qqEmojiSet.name,
baseUrl: "assets/custom_face_resource/${qqEmojiSet.name}", baseUrl: "assets/custom_face_resource/${qqEmojiSet.name}",
isEmoji: qqEmojiSet.isEmoji, isEmoji: qqEmojiSet.isEmoji,
isDefaultEmoji: true, isDefaultEmoji: true,
stickerList: qqEmojiSet.list stickerList:
.asMap() qqEmojiSet.list.asMap().keys.map((idx) => CustomSticker(index: idx, name: qqEmojiSet.list[idx])).toList(),
.keys
.map((idx) =>
CustomSticker(index: idx, name: qqEmojiSet.list[idx]))
.toList(),
menuItem: CustomSticker( menuItem: CustomSticker(
index: 0, index: 0,
name: qqEmojiSet.icon, name: qqEmojiSet.icon,
@ -206,15 +197,11 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
} }
if (stickerConfig.unicodeEmojiList.isNotEmpty) { if (stickerConfig.unicodeEmojiList.isNotEmpty) {
final defEmojiList = final defEmojiList = TUIKitStickerConstData.defaultUnicodeEmojiList.map((emojiItem) {
TUIKitStickerConstData.defaultUnicodeEmojiList.map((emojiItem) { return CustomSticker(index: 0, name: emojiItem.toString(), unicode: emojiItem);
return CustomSticker(
index: 0, name: emojiItem.toString(), unicode: emojiItem);
}).toList(); }).toList();
stickerPackageList.add(CustomStickerPackage( stickerPackageList
name: "defaultEmoji", .add(CustomStickerPackage(name: "defaultEmoji", stickerList: defEmojiList, menuItem: defEmojiList[0]));
stickerList: defEmojiList,
menuItem: defEmojiList[0]));
} }
stickerPackageList.addAll(stickerConfig.customStickerPackages); stickerPackageList.addAll(stickerConfig.customStickerPackages);
@ -244,8 +231,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
if (cursorPosition > 0) { if (cursorPosition > 0) {
final EmojiUtil emojiUtil = EmojiUtil(); final EmojiUtil emojiUtil = EmojiUtil();
int removeLength = 1; int removeLength = 1;
int openBracketIndex = int openBracketIndex = originalText.lastIndexOf('[', cursorPosition - 1);
originalText.lastIndexOf('[', cursorPosition - 1);
if (openBracketIndex != -1 && originalText[cursorPosition - 1] == ']') { if (openBracketIndex != -1 && originalText[cursorPosition - 1] == ']') {
// Small png emoji // Small png emoji
@ -254,23 +240,19 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
if (emojiUtil.emojiMap.containsKey(key)) { if (emojiUtil.emojiMap.containsKey(key)) {
removeLength = cursorPosition - openBracketIndex; removeLength = cursorPosition - openBracketIndex;
} }
} else if (cursorPosition > 1 && } else if (cursorPosition > 1 && isEmoji(originalText.substring(cursorPosition - 2, cursorPosition))) {
isEmoji(
originalText.substring(cursorPosition - 2, cursorPosition))) {
removeLength = 2; removeLength = 2;
} }
text = originalText.substring(0, cursorPosition - removeLength) + text = originalText.substring(0, cursorPosition - removeLength) + originalText.substring(cursorPosition);
originalText.substring(cursorPosition);
currentCursor = (currentCursor ?? removeLength) - removeLength; currentCursor = (currentCursor ?? removeLength) - removeLength;
} }
textEditingController.text = text; textEditingController.text = text;
if (TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop) { if (TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop) {
textEditingController.selection = TextSelection.fromPosition( textEditingController.selection =
TextPosition( TextSelection.fromPosition(TextPosition(offset: currentCursor ?? textEditingController.text.length));
offset: currentCursor ?? textEditingController.text.length));
focusNode.requestFocus(); focusNode.requestFocus();
} }
} }
@ -290,9 +272,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
void _addStickerToText(String sticker) { void _addStickerToText(String sticker) {
final currentText = textEditingController.text; final currentText = textEditingController.text;
if (currentCursor != null && if (currentCursor != null && currentCursor! > -1 && currentCursor! < currentText.length + 1) {
currentCursor! > -1 &&
currentCursor! < currentText.length + 1) {
final firstString = currentText.substring(0, currentCursor); final firstString = currentText.substring(0, currentCursor);
final secondString = currentText.substring(currentCursor!); final secondString = currentText.substring(currentCursor!);
currentCursor = currentCursor! + sticker.length; currentCursor = currentCursor! + sticker.length;
@ -303,8 +283,8 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
} }
if (TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop) { if (TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop) {
textEditingController.selection = TextSelection.fromPosition(TextPosition( textEditingController.selection =
offset: currentCursor ?? textEditingController.text.length)); TextSelection.fromPosition(TextPosition(offset: currentCursor ?? textEditingController.text.length));
focusNode.requestFocus(); focusNode.requestFocus();
} }
} }
@ -313,8 +293,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
return text.replaceAll(RegExp(r'\ufeff'), ""); return text.replaceAll(RegExp(r'\ufeff'), "");
} }
Future handleSetDraftText( Future handleSetDraftText({String? id, ConvType? convType, String? groupID}) async {
{String? id, ConvType? convType, String? groupID}) async {
String text = textEditingController.text; String text = textEditingController.text;
String convID = id ?? widget.conversationID; String convID = id ?? widget.conversationID;
final isTopic = convID.contains("@TOPIC#"); final isTopic = convID.contains("@TOPIC#");
@ -388,19 +367,11 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
if (widget.model.repliedMessage != null) { if (widget.model.repliedMessage != null) {
MessageUtils.handleMessageError( MessageUtils.handleMessageError(
widget.model.sendFaceMessage( widget.model.sendFaceMessage(index: groupID, data: data, convID: widget.conversationID, convType: convType),
index: groupID,
data: data,
convID: widget.conversationID,
convType: convType),
context); context);
} else { } else {
MessageUtils.handleMessageError( MessageUtils.handleMessageError(
widget.model.sendFaceMessage( widget.model.sendFaceMessage(index: groupID, data: data, convID: widget.conversationID, convType: convType),
index: groupID,
data: data,
convID: widget.conversationID,
convType: convType),
context); context);
} }
} }
@ -436,9 +407,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
atUserList: getUserIdFromMemberInfoMap()); atUserList: getUserIdFromMemberInfoMap());
} else { } else {
MessageUtils.handleMessageError( MessageUtils.handleMessageError(
widget.model.sendTextMessage( widget.model.sendTextMessage(text: text, convID: widget.conversationID, convType: convType), context);
text: text, convID: widget.conversationID, convType: convType),
context);
} }
textEditingController.clear(); textEditingController.clear();
currentCursor = null; currentCursor = null;
@ -451,8 +420,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
} }
void goDownBottom() { void goDownBottom() {
if (globalModel.getMessageListPosition(widget.conversationID) == if (globalModel.getMessageListPosition(widget.conversationID) == HistoryMessagePosition.notShowLatest) {
HistoryMessagePosition.notShowLatest) {
return; return;
} }
Future.delayed(const Duration(milliseconds: 50), () { Future.delayed(const Duration(milliseconds: 50), () {
@ -491,8 +459,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
if (TencentUtils.checkString(userID) == null) { if (TencentUtils.checkString(userID) == null) {
focusNode.requestFocus(); focusNode.requestFocus();
} else { } else {
final memberInfo = widget.model.groupMemberList final memberInfo = widget.model.groupMemberList?.firstWhereOrNull((element) => element?.userID == userID) ??
?.firstWhereOrNull((element) => element?.userID == userID) ??
V2TimGroupMemberFullInfo( V2TimGroupMemberFullInfo(
userID: userID ?? "", userID: userID ?? "",
nickName: nickName, nickName: nickName,
@ -503,8 +470,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
//please do not delete space //please do not delete space
focusNode.requestFocus(); focusNode.requestFocus();
textEditingController.text = text; textEditingController.text = text;
textEditingController.selection = textEditingController.selection = TextSelection.fromPosition(TextPosition(offset: text.length));
TextSelection.fromPosition(TextPosition(offset: text.length));
lastText = text; lastText = text;
_isComposingText = false; _isComposingText = false;
narrowTextFieldKey.currentState?.showKeyboard = true; narrowTextFieldKey.currentState?.showKeyboard = true;
@ -532,16 +498,10 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
maxLines: null, maxLines: null,
); );
textPainter.layout(maxWidth: inputWidth); textPainter.layout(maxWidth: inputWidth);
final TextPosition lastLineOffset = textPainter final TextPosition lastLineOffset = textPainter.getPositionForOffset(Offset(textPainter.width, textPainter.height));
.getPositionForOffset(Offset(textPainter.width, textPainter.height)); final Offset caretPosition = textPainter.getOffsetForCaret(lastLineOffset, Rect.zero);
final Offset caretPosition =
textPainter.getOffsetForCaret(lastLineOffset, Rect.zero);
final dx = min(inputWidth - 180, caretPosition.dx + 16); final dx = min(inputWidth - 180, caretPosition.dx + 16);
final dy = max( final dy = max(24, 21 * widget.model.chatConfig.desktopMessageInputFieldLines - caretPosition.dy).toDouble();
24,
21 * widget.model.chatConfig.desktopMessageInputFieldLines -
caretPosition.dy)
.toDouble();
return Offset(dx, dy); return Offset(dx, dy);
} }
@ -578,19 +538,13 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
mentionedMembersMap = map; mentionedMembersMap = map;
} }
(int, String, bool)? findChangedCharacter( (int, String, bool)? findChangedCharacter(String originalString, String newString) {
String originalString, String newString) {
if (newString.length < originalString.length) { if (newString.length < originalString.length) {
final originalStringLength = originalString.length; final originalStringLength = originalString.length;
final newStringLength = newString.length; final newStringLength = newString.length;
for (int i = 0; i < newString.length; ++i) { for (int i = 0; i < newString.length; ++i) {
if (originalString[originalStringLength - i - 1] != if (originalString[originalStringLength - i - 1] != newString[newStringLength - i - 1]) {
newString[newStringLength - i - 1]) { return (newStringLength - i, originalString[originalStringLength - i - 1], false);
return (
newStringLength - i,
originalString[originalStringLength - i - 1],
false
);
} }
} }
return (newString.length, originalString[newString.length], false); return (newString.length, originalString[newString.length], false);
@ -609,11 +563,8 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
_handleAtText(String text, TUIChatSeparateViewModel model) async { _handleAtText(String text, TUIChatSeparateViewModel model) async {
final text = textEditingController.text; final text = textEditingController.text;
final String originalText = lastText; final String originalText = lastText;
String? groupID = widget.conversationType == ConvType.group String? groupID = widget.conversationType == ConvType.group ? widget.conversationID : null;
? widget.conversationID final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
: null;
final isDesktopScreen =
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
if (groupID == null) { if (groupID == null) {
lastText = text; lastText = text;
@ -633,11 +584,9 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
String atTag = originalText.substring(atIndex, spaceIndex); String atTag = originalText.substring(atIndex, spaceIndex);
String deletedChar = originalText[diffIndex]; String deletedChar = originalText[diffIndex];
if (shouldRemoveAtTag(atTag, deletedChar)) { if (shouldRemoveAtTag(atTag, deletedChar)) {
final newText = originalText.substring(0, atIndex) + final newText = originalText.substring(0, atIndex) + originalText.substring(spaceIndex + 1);
originalText.substring(spaceIndex + 1);
textEditingController.text = newText; textEditingController.text = newText;
textEditingController.selection = textEditingController.selection = TextSelection.collapsed(offset: atIndex);
TextSelection.collapsed(offset: atIndex);
lastText = newText; lastText = newText;
updateMentionedMap(); updateMentionedMap();
return; return;
@ -653,8 +602,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER); selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER);
if (isDesktopScreen) { if (isDesktopScreen) {
(int, String, bool)? changedCharacterRecord = (int, String, bool)? changedCharacterRecord = findChangedCharacter(originalText, text);
findChangedCharacter(originalText, text);
int? changedTextPosition = changedCharacterRecord?.$1; int? changedTextPosition = changedCharacterRecord?.$1;
String? changedCharacter = changedCharacterRecord?.$2; String? changedCharacter = changedCharacterRecord?.$2;
bool isAdded = changedCharacterRecord?.$3 ?? false; bool isAdded = changedCharacterRecord?.$3 ?? false;
@ -663,13 +611,10 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
int? atPlace; int? atPlace;
if (changedTextPosition != null) { if (changedTextPosition != null) {
subText = isAdded == true subText = isAdded == true ? text.substring(0, changedTextPosition + 1) : text.substring(0, changedTextPosition);
? text.substring(0, changedTextPosition + 1)
: text.substring(0, changedTextPosition);
atPlace = subText.lastIndexOf('@'); atPlace = subText.lastIndexOf('@');
if (atPlace != -1) { if (atPlace != -1) {
keyword = text.substring( keyword = text.substring(atPlace + 1, changedTextPosition + (isAdded ? 1 : 0));
atPlace + 1, changedTextPosition + (isAdded ? 1 : 0));
} }
} else { } else {
atPlace = -1; atPlace = -1;
@ -682,12 +627,9 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
model.atPositionY = atPosition.dy; model.atPositionY = atPosition.dy;
isAddingAtSearchWords = true; isAddingAtSearchWords = true;
} }
List<V2TimGroupMemberFullInfo> showAtMemberList = (model List<V2TimGroupMemberFullInfo> showAtMemberList = (model.groupMemberList ?? [])
.groupMemberList ??
[])
.where((element) { .where((element) {
final showName = (TencentUtils.checkStringWithoutSpace( final showName = (TencentUtils.checkStringWithoutSpace(element?.friendRemark) ??
element?.friendRemark) ??
TencentUtils.checkStringWithoutSpace(element?.nameCard) ?? TencentUtils.checkStringWithoutSpace(element?.nameCard) ??
TencentUtils.checkStringWithoutSpace(element?.nickName) ?? TencentUtils.checkStringWithoutSpace(element?.nickName) ??
TencentUtils.checkStringWithoutSpace(element?.userID) ?? TencentUtils.checkStringWithoutSpace(element?.userID) ??
@ -702,8 +644,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
.whereType<V2TimGroupMemberFullInfo>() .whereType<V2TimGroupMemberFullInfo>()
.toList(); .toList();
showAtMemberList.sort( showAtMemberList.sort((V2TimGroupMemberFullInfo userA, V2TimGroupMemberFullInfo userB) {
(V2TimGroupMemberFullInfo userA, V2TimGroupMemberFullInfo userB) {
final isUserAIsGroupAdmin = userA.role == 300; final isUserAIsGroupAdmin = userA.role == 300;
final isUserAIsGroupOwner = userA.role == 400; final isUserAIsGroupOwner = userA.role == 400;
@ -727,8 +668,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
keyword ??= ""; keyword ??= "";
if (canAtAll && showAtMemberList.isNotEmpty && keyword!.isEmpty) { if (canAtAll && showAtMemberList.isNotEmpty && keyword!.isEmpty) {
showAtMemberList = [ showAtMemberList = [
V2TimGroupMemberFullInfo( V2TimGroupMemberFullInfo(userID: "__kImSDK_MesssageAtALL__", nickName: TIM_t("所有人")),
userID: "__kImSDK_MesssageAtALL__", nickName: TIM_t("所有人")),
...showAtMemberList ...showAtMemberList
]; ];
} }
@ -742,12 +682,8 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
model.showAtMemberList = []; model.showAtMemberList = [];
isAddingAtSearchWords = false; isAddingAtSearchWords = false;
} }
} else if (textLength > 0 && } else if (textLength > 0 && text[textLength - 1] == "@" && lastText.length < textLength) {
text[textLength - 1] == "@" && List<V2TimGroupMemberFullInfo>? selectedAtMemberList = await Navigator.push(
lastText.length < textLength) {
// Navigator.push null
List<V2TimGroupMemberFullInfo>? selectedAtMemberList =
await Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => AtText( builder: (context) => AtText(
@ -759,43 +695,35 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
), ),
); );
// selectedAtMemberList null if (selectedAtMemberList == null) return;
if (selectedAtMemberList != null) {
for (int i = 0; i < selectedAtMemberList.length; ++i) { for (int i = 0; i < selectedAtMemberList.length; ++i) {
V2TimGroupMemberFullInfo memberInfo = selectedAtMemberList[i]; V2TimGroupMemberFullInfo memberInfo = selectedAtMemberList[i];
final showName = _getShowName(memberInfo); final showName = _getShowName(memberInfo);
if (memberInfo != null) { if (memberInfo != null) {
mentionedMembersMap["@$showName"] = memberInfo; mentionedMembersMap["@$showName"] = memberInfo;
String addAtCharacter = i == 0 ? "" : "@"; String addAtCharacter = i == 0 ? "" : "@";
textEditingController.text = textEditingController.text = "${textEditingController.text}$addAtCharacter$showName ";
"${textEditingController.text}$addAtCharacter$showName ";
lastText = "${textEditingController.text}$addAtCharacter$showName "; lastText = "${textEditingController.text}$addAtCharacter$showName ";
} }
} }
} }
}
lastText = textEditingController.text; lastText = textEditingController.text;
} }
void replaceAtTag(String selectedMember) { void replaceAtTag(String selectedMember) {
int cursorPosition = textEditingController.selection.baseOffset; int cursorPosition = textEditingController.selection.baseOffset;
int atIndex = int atIndex = textEditingController.text.lastIndexOf('@', cursorPosition - 1);
textEditingController.text.lastIndexOf('@', cursorPosition - 1);
if (atIndex >= 0) { if (atIndex >= 0) {
String beforeAt = textEditingController.text.substring(0, atIndex); String beforeAt = textEditingController.text.substring(0, atIndex);
String afterAt = textEditingController.text.substring(cursorPosition); String afterAt = textEditingController.text.substring(cursorPosition);
textEditingController.text = textEditingController.text = beforeAt + '@' + selectedMember + ' ' + afterAt;
beforeAt + '@' + selectedMember + ' ' + afterAt; textEditingController.selection = TextSelection.collapsed(offset: atIndex + selectedMember.length + 2);
textEditingController.selection =
TextSelection.collapsed(offset: atIndex + selectedMember.length + 2);
lastText = beforeAt + '@' + selectedMember + ' ' + afterAt; lastText = beforeAt + '@' + selectedMember + ' ' + afterAt;
} }
} }
void handleAtMember( void handleAtMember({V2TimGroupMemberFullInfo? memberInfo, bool? isAddToCursorPosition = false}) {
{V2TimGroupMemberFullInfo? memberInfo,
bool? isAddToCursorPosition = false}) {
if (memberInfo != null) { if (memberInfo != null) {
final String showName = _getShowName(memberInfo); final String showName = _getShowName(memberInfo);
mentionedMembersMap["@$showName"] = memberInfo; mentionedMembersMap["@$showName"] = memberInfo;
@ -809,24 +737,19 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
KeyEventResult handleDesktopKeyEvent(FocusNode node, RawKeyEvent event) { KeyEventResult handleDesktopKeyEvent(FocusNode node, RawKeyEvent event) {
final activeIndex = widget.model.activeAtIndex; final activeIndex = widget.model.activeAtIndex;
final showMemberList = widget.model.showAtMemberList; final showMemberList = widget.model.showAtMemberList;
final isPressEnter = (event.physicalKey == PhysicalKeyboardKey.enter) || final isPressEnter =
(event.physicalKey == PhysicalKeyboardKey.numpadEnter); (event.physicalKey == PhysicalKeyboardKey.enter) || (event.physicalKey == PhysicalKeyboardKey.numpadEnter);
if (event.runtimeType == RawKeyDownEvent) { if (event.runtimeType == RawKeyDownEvent) {
if (event.physicalKey == PhysicalKeyboardKey.backspace) { if (event.physicalKey == PhysicalKeyboardKey.backspace) {
if (textEditingController.text.isEmpty && lastText.isEmpty) { if (textEditingController.text.isEmpty && lastText.isEmpty) {
widget.model.repliedMessage = null; widget.model.repliedMessage = null;
return KeyEventResult.handled; return KeyEventResult.handled;
} }
} else if ((event.isShiftPressed || } else if ((event.isShiftPressed || event.isAltPressed || event.isControlPressed || event.isMetaPressed) &&
event.isAltPressed ||
event.isControlPressed ||
event.isMetaPressed) &&
isPressEnter) { isPressEnter) {
final offset = textEditingController.selection.baseOffset; final offset = textEditingController.selection.baseOffset;
textEditingController.text = textEditingController.text = '${lastText.substring(0, offset)}\n${lastText.substring(offset)}';
'${lastText.substring(0, offset)}\n${lastText.substring(offset)}'; textEditingController.selection = TextSelection.fromPosition(TextPosition(offset: offset + 1));
textEditingController.selection =
TextSelection.fromPosition(TextPosition(offset: offset + 1));
lastText = textEditingController.text; lastText = textEditingController.text;
return KeyEventResult.handled; return KeyEventResult.handled;
@ -836,34 +759,26 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
onSubmitted(); onSubmitted();
} else { } else {
isAddingAtSearchWords = false; isAddingAtSearchWords = false;
final V2TimGroupMemberFullInfo? memberInfo = final V2TimGroupMemberFullInfo? memberInfo = showMemberList[activeIndex];
showMemberList[activeIndex];
if (memberInfo != null) { if (memberInfo != null) {
handleAtMember( handleAtMember(memberInfo: memberInfo, isAddToCursorPosition: true);
memberInfo: memberInfo, isAddToCursorPosition: true);
} }
} }
return KeyEventResult.handled; return KeyEventResult.handled;
} }
} }
if (event.isKeyPressed(LogicalKeyboardKey.arrowUp) && if (event.isKeyPressed(LogicalKeyboardKey.arrowUp) && isAddingAtSearchWords && showMemberList.isNotEmpty) {
isAddingAtSearchWords &&
showMemberList.isNotEmpty) {
final newIndex = max(activeIndex - 1, 0); final newIndex = max(activeIndex - 1, 0);
widget.model.activeAtIndex = newIndex; widget.model.activeAtIndex = newIndex;
widget.atMemberPanelScroll?.scrollToIndex(newIndex, widget.atMemberPanelScroll?.scrollToIndex(newIndex, preferPosition: AutoScrollPosition.middle);
preferPosition: AutoScrollPosition.middle);
return KeyEventResult.handled; return KeyEventResult.handled;
} }
if (event.isKeyPressed(LogicalKeyboardKey.arrowDown) && if (event.isKeyPressed(LogicalKeyboardKey.arrowDown) && isAddingAtSearchWords && showMemberList.isNotEmpty) {
isAddingAtSearchWords &&
showMemberList.isNotEmpty) {
final newIndex = min(activeIndex + 1, showMemberList.length - 1); final newIndex = min(activeIndex + 1, showMemberList.length - 1);
widget.model.activeAtIndex = newIndex; widget.model.activeAtIndex = newIndex;
widget.atMemberPanelScroll?.scrollToIndex(newIndex, widget.atMemberPanelScroll?.scrollToIndex(newIndex, preferPosition: AutoScrollPosition.middle);
preferPosition: AutoScrollPosition.middle);
return KeyEventResult.handled; return KeyEventResult.handled;
} }
} }
@ -881,8 +796,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
} else { } else {
focusNode = FocusNode(); focusNode = FocusNode();
} }
textEditingController = textEditingController = widget.controller?.textEditingController ?? TextEditingController();
widget.controller?.textEditingController ?? TextEditingController();
if (widget.initText != null) { if (widget.initText != null) {
textEditingController.text = widget.initText!; textEditingController.text = widget.initText!;
} }
@ -890,10 +804,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
widget.controller?.addListener(controllerHandler); widget.controller?.addListener(controllerHandler);
} }
final AppLocale appLocale = I18nUtils.findDeviceLocale(null); final AppLocale appLocale = I18nUtils.findDeviceLocale(null);
languageType = languageType = (appLocale == AppLocale.zhHans || appLocale == AppLocale.zhHant) ? 'zh' : 'en';
(appLocale == AppLocale.zhHans || appLocale == AppLocale.zhHant)
? 'zh'
: 'en';
textEditingController.addListener(() { textEditingController.addListener(() {
_isComposingText = textEditingController.value.composing.start != -1; _isComposingText = textEditingController.value.composing.start != -1;
}); });
@ -903,13 +814,12 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
controllerHandler() { controllerHandler() {
final actionType = widget.controller?.actionType; final actionType = widget.controller?.actionType;
if (actionType == ActionType.longPressToAt) { if (actionType == ActionType.longPressToAt) {
mentionMemberInMessage( mentionMemberInMessage(widget.controller?.atUserID, widget.controller?.atUserName);
widget.controller?.atUserID, widget.controller?.atUserName);
} else if (actionType == ActionType.setTextField) { } else if (actionType == ActionType.setTextField) {
final newText = widget.controller?.inputText ?? ""; final newText = widget.controller?.inputText ?? "";
textEditingController.text = newText; textEditingController.text = newText;
textEditingController.selection = TextSelection.fromPosition( textEditingController.selection =
TextPosition(offset: textEditingController.text.length)); TextSelection.fromPosition(TextPosition(offset: textEditingController.text.length));
lastText = textEditingController.text; lastText = textEditingController.text;
focusNode.requestFocus(); focusNode.requestFocus();
return; return;
@ -928,17 +838,14 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
if (widget.conversationID != oldWidget.conversationID) { if (widget.conversationID != oldWidget.conversationID) {
mentionedMembersMap.clear(); mentionedMembersMap.clear();
handleSetDraftText( handleSetDraftText(
id: oldWidget.conversationID, id: oldWidget.conversationID, convType: oldWidget.conversationType, groupID: oldWidget.groupID);
convType: oldWidget.conversationType,
groupID: oldWidget.groupID);
if (oldWidget.initText != widget.initText) { if (oldWidget.initText != widget.initText) {
textEditingController.text = widget.initText ?? ""; textEditingController.text = widget.initText ?? "";
} else { } else {
textEditingController.clear(); textEditingController.clear();
} }
} }
if (widget.initText != oldWidget.initText && if (widget.initText != oldWidget.initText && TencentUtils.checkString(widget.initText) != null) {
TencentUtils.checkString(widget.initText) != null) {
textEditingController.text = widget.initText!; textEditingController.text = widget.initText!;
focusNode.requestFocus(); focusNode.requestFocus();
} }
@ -956,12 +863,9 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
Future<bool> getMemberMuteStatus(String userID) async { Future<bool> getMemberMuteStatus(String userID) async {
// Get the mute state of the members recursively // Get the mute state of the members recursively
if (widget.model.groupMemberList?.any((item) => (item?.userID == userID)) ?? if (widget.model.groupMemberList?.any((item) => (item?.userID == userID)) ?? false) {
false) { final int muteUntil =
final int muteUntil = widget.model.groupMemberList widget.model.groupMemberList?.firstWhere((item) => (item?.userID == userID))?.muteUntil ?? 0;
?.firstWhere((item) => (item?.userID == userID))
?.muteUntil ??
0;
return muteUntil * 1000 > DateTime.now().millisecondsSinceEpoch; return muteUntil * 1000 > DateTime.now().millisecondsSinceEpoch;
} else { } else {
return false; return false;
@ -974,13 +878,11 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
} }
final int selfRole = widget.model.selfMemberInfo?.role ?? 0; final int selfRole = widget.model.selfMemberInfo?.role ?? 0;
final bool willNotBeenMuted = final bool willNotBeenMuted = (selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN ||
(selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN ||
selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER); selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER);
if (widget.conversationType == ConvType.group && !willNotBeenMuted) { if (widget.conversationType == ConvType.group && !willNotBeenMuted) {
if ((model.groupInfo?.isAllMuted ?? false) && if ((model.groupInfo?.isAllMuted ?? false) && muteStatus != MuteStatus.all) {
muteStatus != MuteStatus.all) {
Future.delayed(const Duration(seconds: 0), () { Future.delayed(const Duration(seconds: 0), () {
setState(() { setState(() {
muteStatus = MuteStatus.all; muteStatus = MuteStatus.all;
@ -995,8 +897,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
}); });
}); });
} else if (!(model.groupInfo?.isAllMuted ?? false) && } else if (!(model.groupInfo?.isAllMuted ?? false) &&
!(selfModel.loginInfo?.userID != null && !(selfModel.loginInfo?.userID != null && await getMemberMuteStatus(selfModel.loginInfo!.userID!)) &&
await getMemberMuteStatus(selfModel.loginInfo!.userID!)) &&
muteStatus != MuteStatus.none) { muteStatus != MuteStatus.none) {
Future.delayed(const Duration(seconds: 0), () { Future.delayed(const Duration(seconds: 0), () {
setState(() { setState(() {
@ -1026,8 +927,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
@override @override
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
final theme = value.theme; final theme = value.theme;
final TUIChatSeparateViewModel model = final TUIChatSeparateViewModel model = Provider.of<TUIChatSeparateViewModel>(context);
Provider.of<TUIChatSeparateViewModel>(context);
_getMuteType(model); _getMuteType(model);
@ -1047,8 +947,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
} }
final forbiddenText = getForbiddenText(); final forbiddenText = getForbiddenText();
return LayoutBuilder( return LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
builder: (BuildContext context, BoxConstraints constraints) {
inputWidth = constraints.maxWidth; inputWidth = constraints.maxWidth;
return TUIKitScreenUtils.getDeviceWidget( return TUIKitScreenUtils.getDeviceWidget(
context: context, context: context,

View File

@ -23,7 +23,6 @@ class TUIKitColumnMenu extends StatefulWidget {
} }
class TUIKitColumnMenuState extends TIMUIKitState<TUIKitColumnMenu> { class TUIKitColumnMenuState extends TIMUIKitState<TUIKitColumnMenu> {
List<Widget> renderMenuItems(TUITheme theme) { List<Widget> renderMenuItems(TUITheme theme) {
return widget.data return widget.data
.map( .map(
@ -39,7 +38,8 @@ class TUIKitColumnMenuState extends TIMUIKitState<TUIKitColumnMenu> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
if (item.icon != null) item.icon!, if (item.icon != null) item.icon!,
if (item.icon != null) const SizedBox( if (item.icon != null)
const SizedBox(
height: 4, height: 4,
width: 6, width: 6,
), ),
@ -73,18 +73,11 @@ class TUIKitColumnMenuState extends TIMUIKitState<TUIKitColumnMenu> {
constraints: BoxConstraints( constraints: BoxConstraints(
maxWidth: min(MediaQuery.of(context).size.width * 0.7, 350), maxWidth: min(MediaQuery.of(context).size.width * 0.7, 350),
), ),
child: Table( child: Table(columnWidths: const <int, TableColumnWidth>{
columnWidths: const <int, TableColumnWidth>{
0: IntrinsicColumnWidth(), 0: IntrinsicColumnWidth(),
}, }, children: <TableRow>[
children: <TableRow>[ ...renderMenuItems(theme).map((e) => TableRow(children: <Widget>[e]))
...renderMenuItems(theme).map((e) => TableRow( ]),
children: <Widget>[
e
]
))
]
),
), ),
); );
} }

View File

@ -16,7 +16,8 @@ import 'package:video_player/video_player.dart';
import 'center_play_button.dart'; import 'center_play_button.dart';
class VideoCustomControls extends StatefulWidget { class VideoCustomControls extends StatefulWidget {
const VideoCustomControls({required this.downloadFn, Key? key}) : super(key: key); const VideoCustomControls({required this.downloadFn, Key? key})
: super(key: key);
final Future<void> Function() downloadFn; final Future<void> Function() downloadFn;
@override @override
@ -25,7 +26,8 @@ class VideoCustomControls extends StatefulWidget {
} }
} }
class _VideoCustomControlsState extends TIMUIKitState<VideoCustomControls> with SingleTickerProviderStateMixin { class _VideoCustomControlsState extends TIMUIKitState<VideoCustomControls>
with SingleTickerProviderStateMixin {
late VideoPlayerValue _latestValue; late VideoPlayerValue _latestValue;
bool _hideStuff = true; bool _hideStuff = true;
Timer? _hideTimer; Timer? _hideTimer;
@ -74,11 +76,18 @@ class _VideoCustomControlsState extends TIMUIKitState<VideoCustomControls> with
child: Stack( child: Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: <Widget>[ children: <Widget>[
if (_latestValue.isBuffering) const Center(child: CircularProgressIndicator(color: Colors.white)) else _buildHitArea(), if (_latestValue.isBuffering)
const Center(
child: CircularProgressIndicator(color: Colors.white))
else
_buildHitArea(),
Positioned( Positioned(
bottom: 0, bottom: 0,
width: MediaQuery.of(context).size.width, width: MediaQuery.of(context).size.width,
child: Column(children: [_buildVideoControlBar(context), _buildBottomBar()]), child: Column(children: [
_buildVideoControlBar(context),
_buildBottomBar()
]),
), ),
if (isLoading) if (isLoading)
Container( Container(
@ -198,8 +207,14 @@ class _VideoCustomControlsState extends TIMUIKitState<VideoCustomControls> with
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
_buildPlayPause(controller, iconColor), _buildPlayPause(controller, iconColor),
if (chewieController.isLive) const Expanded(child: Text('LIVE')) else _buildPositionStart(iconColor), if (chewieController.isLive)
if (chewieController.isLive) const SizedBox() else _buildProgressBar(), const Expanded(child: Text('LIVE'))
else
_buildPositionStart(iconColor),
if (chewieController.isLive)
const SizedBox()
else
_buildProgressBar(),
if (!chewieController.isLive) _buildPositionEnd(iconColor), if (!chewieController.isLive) _buildPositionEnd(iconColor),
], ],
), ),
@ -235,7 +250,8 @@ class _VideoCustomControlsState extends TIMUIKitState<VideoCustomControls> with
)); ));
} }
GestureDetector _buildPlayPause(VideoPlayerController controller, Color color) { GestureDetector _buildPlayPause(
VideoPlayerController controller, Color color) {
return GestureDetector( return GestureDetector(
onTap: _playPause, onTap: _playPause,
child: Container( child: Container(
@ -311,7 +327,8 @@ class _VideoCustomControlsState extends TIMUIKitState<VideoCustomControls> with
_hideStuff = true; _hideStuff = true;
chewieController.toggleFullScreen(); chewieController.toggleFullScreen();
_showAfterExpandCollapseTimer = Timer(const Duration(milliseconds: 300), () { _showAfterExpandCollapseTimer =
Timer(const Duration(milliseconds: 300), () {
setState(() { setState(() {
_cancelAndRestartTimer(); _cancelAndRestartTimer();
}); });
@ -379,7 +396,12 @@ class _VideoCustomControlsState extends TIMUIKitState<VideoCustomControls> with
_startHideTimer(); _startHideTimer();
}, },
colors: chewieController.materialProgressColors ?? ChewieProgressColors(playedColor: Colors.white, handleColor: Colors.white, bufferedColor: Colors.white38, backgroundColor: Colors.white24), colors: chewieController.materialProgressColors ??
ChewieProgressColors(
playedColor: Colors.white,
handleColor: Colors.white,
bufferedColor: Colors.white38,
backgroundColor: Colors.white24),
), ),
), ),
); );
@ -402,7 +424,8 @@ class _PlaybackSpeedDialog extends TIMUIKitStatelessWidget {
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
final TUITheme theme = value.theme; final TUITheme theme = value.theme;
final Color selectedColor = theme.primaryColor ?? Theme.of(context).primaryColor; final Color selectedColor =
theme.primaryColor ?? Theme.of(context).primaryColor;
return ListView.builder( return ListView.builder(
shrinkWrap: true, shrinkWrap: true,