tencent_cloud_chat_uikit source code update to version 4.0.5

This commit is contained in:
vinsonswang 2025-04-21 15:14:58 +08:00
parent ae3bf8be65
commit be9c53aa25
171 changed files with 2779 additions and 2367 deletions

View File

@ -1,3 +1,22 @@
# 4.0.5
* Upgrade tencent_cloud_chat_sdk to the minimum version 8.5.6864+6.
* Changed the SDK interface call from getConversationListByConversaionIds to getConversationListByConversationIds.
# 4.0.4
* Remove the import of tencent_im_base plugin.
* Upgrade tencent_cloud_chat_sdk to the minimum version 8.5.6864+4.
* Fix compilation issues in tim_uikit_group.dart, tui_group_listener_model.dart, tui_conversation_view_model.dart.
# 4.0.3
* Fix compilation issues on Flutter 3.27.1
# 4.0.2
* Optimize the display of group notification page.
* Optimize the display of read receipt page.
* TIMUIKitChatController sendMessage interface supports isExcludedFromContentModeration parameter.
* Fixed abnormal playback and recording of videos on Huawei P30.
* Optimize the display of tips messages when they are too long.
# 4.0.1 # 4.0.1
* Upgraded the plugin tim_ui_kit_sticker_plugin to 4.0.1. * Upgraded the plugin tim_ui_kit_sticker_plugin to 4.0.1.
* Use the 'useTencentCloudChatStickerPackageOldKeys' parameter in StickerPanelConfig to control whether the emoticon is compatible with version 3.x. * Use the 'useTencentCloudChatStickerPackageOldKeys' parameter in StickerPanelConfig to control whether the emoticon is compatible with version 3.x.

View File

@ -3,6 +3,7 @@
import 'package:example/TIMUIKitGroupProfileExample.dart'; import 'package:example/TIMUIKitGroupProfileExample.dart';
import 'package:example/TIMUIKitProfileExample.dart'; import 'package:example/TIMUIKitProfileExample.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
class TIMUIKitChatExample extends StatelessWidget { class TIMUIKitChatExample extends StatelessWidget {
@ -64,7 +65,6 @@ class TIMUIKitChatExample extends StatelessWidget {
config: const TIMUIKitChatConfig( config: const TIMUIKitChatConfig(
// 使 // 使
isAllowClickAvatar: true, isAllowClickAvatar: true,
isUseDefaultEmoji: true,
isAllowLongPressMessage: true, isAllowLongPressMessage: true,
isShowReadingStatus: true, isShowReadingStatus: true,
isShowGroupReadingStatus: true, isShowGroupReadingStatus: true,

View File

@ -1,6 +1,7 @@
// ignore_for_file: avoid_print, file_names, deprecated_member_use // ignore_for_file: avoid_print, file_names, deprecated_member_use
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
class TIMUIKitSearchExample extends StatelessWidget { class TIMUIKitSearchExample extends StatelessWidget {

View File

@ -1,14 +1,21 @@
// ignore_for_file: avoid_print // ignore_for_file: avoid_print
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_cloud_chat_sdk/enum/V2TimSDKListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/log_level_enum.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
import 'TIMUIKitAddFriendExample.dart'; import 'TIMUIKitAddFriendExample.dart';
import 'TIMUIKitAddGroupExample.dart'; import 'TIMUIKitAddGroupExample.dart';
import 'TIMUIKitBlackListExample.dart'; import 'TIMUIKitBlackListExample.dart';
import 'TIMUIKitChatExample.dart';
import 'TIMUIKitContactExample.dart'; import 'TIMUIKitContactExample.dart';
import 'TIMUIKitConversationExample.dart';
import 'TIMUIKitGroupExample.dart'; import 'TIMUIKitGroupExample.dart';
import 'TIMUIKitGroupProfileExample.dart'; import 'TIMUIKitGroupProfileExample.dart';
import 'TIMUIKitNewContactExample.dart'; import 'TIMUIKitNewContactExample.dart';
import 'TIMUIKitProfileExample.dart';
import 'TIMUIKitSearchExample.dart'; import 'TIMUIKitSearchExample.dart';
void main() { void main() {

View File

@ -8,7 +8,6 @@
#include <desktop_drop/desktop_drop_plugin.h> #include <desktop_drop/desktop_drop_plugin.h>
#include <file_selector_linux/file_selector_plugin.h> #include <file_selector_linux/file_selector_plugin.h>
#include <image_clipboard/image_clipboard_plugin.h>
#include <pasteboard/pasteboard_plugin.h> #include <pasteboard/pasteboard_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h> #include <url_launcher_linux/url_launcher_plugin.h>
@ -19,9 +18,6 @@ void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
file_selector_plugin_register_with_registrar(file_selector_linux_registrar); file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
g_autoptr(FlPluginRegistrar) image_clipboard_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "ImageClipboardPlugin");
image_clipboard_plugin_register_with_registrar(image_clipboard_registrar);
g_autoptr(FlPluginRegistrar) pasteboard_registrar = g_autoptr(FlPluginRegistrar) pasteboard_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "PasteboardPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "PasteboardPlugin");
pasteboard_plugin_register_with_registrar(pasteboard_registrar); pasteboard_plugin_register_with_registrar(pasteboard_registrar);

View File

@ -5,7 +5,6 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
desktop_drop desktop_drop
file_selector_linux file_selector_linux
image_clipboard
pasteboard pasteboard
url_launcher_linux url_launcher_linux
) )

View File

@ -10,7 +10,7 @@ import desktop_drop
import device_info_plus import device_info_plus
import fc_native_video_thumbnail import fc_native_video_thumbnail
import file_selector_macos import file_selector_macos
import image_clipboard import flutter_image_compress_macos
import just_audio import just_audio
import package_info_plus import package_info_plus
import pasteboard import pasteboard
@ -20,6 +20,7 @@ import shared_preferences_foundation
import sqflite import sqflite
import tencent_cloud_chat_sdk import tencent_cloud_chat_sdk
import url_launcher_macos import url_launcher_macos
import video_player_avfoundation
import wakelock_plus import wakelock_plus
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
@ -28,9 +29,9 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
FcNativeVideoThumbnailPlugin.register(with: registry.registrar(forPlugin: "FcNativeVideoThumbnailPlugin")) FcNativeVideoThumbnailPlugin.register(with: registry.registrar(forPlugin: "FcNativeVideoThumbnailPlugin"))
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
ImageClipboardPlugin.register(with: registry.registrar(forPlugin: "ImageClipboardPlugin")) FlutterImageCompressMacosPlugin.register(with: registry.registrar(forPlugin: "FlutterImageCompressMacosPlugin"))
JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin")) JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin"))
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PasteboardPlugin.register(with: registry.registrar(forPlugin: "PasteboardPlugin")) PasteboardPlugin.register(with: registry.registrar(forPlugin: "PasteboardPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
PhotoManagerPlugin.register(with: registry.registrar(forPlugin: "PhotoManagerPlugin")) PhotoManagerPlugin.register(with: registry.registrar(forPlugin: "PhotoManagerPlugin"))
@ -38,5 +39,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
TencentCloudChatSdkPlugin.register(with: registry.registrar(forPlugin: "TencentCloudChatSdkPlugin")) TencentCloudChatSdkPlugin.register(with: registry.registrar(forPlugin: "TencentCloudChatSdkPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
} }

View File

@ -35,10 +35,10 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
tencent_cloud_chat_uikit: tencent_cloud_chat_uikit:
path: ../../tim_ui_kit path: ../
tencent_cloud_chat_sdk: ^8.5.6864+6
tencent_im_sdk_plugin_web: ^0.3.9 tencent_im_sdk_plugin_web: ^0.3.9
archive: ^3.3.0 archive: ^3.3.0
tencent_im_sdk_plugin_desktop: ^0.1.13
# dependency_overrides: # dependency_overrides:
# tencent_cloud_chat_sdk: # tencent_cloud_chat_sdk:

View File

@ -9,7 +9,6 @@
#include <desktop_drop/desktop_drop_plugin.h> #include <desktop_drop/desktop_drop_plugin.h>
#include <fc_native_video_thumbnail/fc_native_video_thumbnail_plugin_c_api.h> #include <fc_native_video_thumbnail/fc_native_video_thumbnail_plugin_c_api.h>
#include <file_selector_windows/file_selector_windows.h> #include <file_selector_windows/file_selector_windows.h>
#include <image_clipboard/image_clipboard_plugin_c_api.h>
#include <pasteboard/pasteboard_plugin.h> #include <pasteboard/pasteboard_plugin.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h> #include <permission_handler_windows/permission_handler_windows_plugin.h>
#include <tencent_cloud_chat_sdk/tencent_cloud_chat_sdk_plugin_c_api.h> #include <tencent_cloud_chat_sdk/tencent_cloud_chat_sdk_plugin_c_api.h>
@ -22,8 +21,6 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("FcNativeVideoThumbnailPluginCApi")); registry->GetRegistrarForPlugin("FcNativeVideoThumbnailPluginCApi"));
FileSelectorWindowsRegisterWithRegistrar( FileSelectorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FileSelectorWindows")); registry->GetRegistrarForPlugin("FileSelectorWindows"));
ImageClipboardPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ImageClipboardPluginCApi"));
PasteboardPluginRegisterWithRegistrar( PasteboardPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PasteboardPlugin")); registry->GetRegistrarForPlugin("PasteboardPlugin"));
PermissionHandlerWindowsPluginRegisterWithRegistrar( PermissionHandlerWindowsPluginRegisterWithRegistrar(

View File

@ -6,7 +6,6 @@ list(APPEND FLUTTER_PLUGIN_LIST
desktop_drop desktop_drop
fc_native_video_thumbnail fc_native_video_thumbnail
file_selector_windows file_selector_windows
image_clipboard
pasteboard pasteboard
permission_handler_windows permission_handler_windows
tencent_cloud_chat_sdk tencent_cloud_chat_sdk

View File

@ -0,0 +1,22 @@
import 'package:flutter/cupertino.dart';
enum TIMCallbackType { API_ERROR, FLUTTER_ERROR, INFO }
class TIMCallback {
TIMCallbackType? type;
String? errorMsg;
int? errorCode;
StackTrace? stackTrace;
Object? catchError;
int? infoCode;
String? infoRecommendText;
TIMCallback(
{this.catchError,
this.infoRecommendText,
this.errorMsg,
this.errorCode,
this.stackTrace,
this.infoCode,
this.type});
}

View File

@ -0,0 +1,53 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'dart:io';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
abstract class TIMState<T extends StatefulWidget> extends State<T> {
@override
initState() {
super.initState();
}
// override这个函数来承接处理onTIMCallback回调
// base层`TIMCallbackType.FLUTTER_ERROR`Flutter Framework异常
// callback请自行处理
void onTIMCallback(TIMCallback callbackValue) {
// TODO:
}
bool isAndroidDevice(){
return !kIsWeb && Platform.isAndroid;
}
bool isIosDevice(){
return !kIsWeb && Platform.isIOS;
}
bool isWebDevice(){
return kIsWeb;
}
setTIMState(VoidCallback fn){
}
@override
Widget build(BuildContext context) {
final onFlutterError = FlutterError.onError;
FlutterError.onError = (FlutterErrorDetails details) {
FlutterError.presentError(details);
// onFlutterError?.call(details);
onTIMCallback(TIMCallback(
type: TIMCallbackType.FLUTTER_ERROR,
stackTrace: details.stack,
errorMsg: "Error from Flutter"));
};
return timBuild(context);
}
// override这个方法来render界面
Widget timBuild(BuildContext context);
}

View File

@ -0,0 +1,45 @@
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
abstract class TIMStatelessWidget extends StatelessWidget {
const TIMStatelessWidget({Key? key}) : super(key: key);
// override这个函数来承接处理onTIMCallback回调
// base层`TIMCallbackType.FLUTTER_ERROR`Flutter Framework异常
// callback请自行处理
void onTIMCallback(TIMCallback callbackValue) {
}
bool isAndroidDevice(){
return !kIsWeb && Platform.isAndroid;
}
bool isIosDevice(){
return !kIsWeb && Platform.isIOS;
}
bool isWebDevice(){
return kIsWeb;
}
@override
Widget build(BuildContext context) {
final onFlutterError = FlutterError.onError;
FlutterError.onError = (FlutterErrorDetails details) {
// onFlutterError?.call(details);
FlutterError.presentError(details);
onTIMCallback(TIMCallback(
type: TIMCallbackType.FLUTTER_ERROR,
stackTrace: details.stack,
errorMsg: "Error from Flutter"));
};
return timBuild(context);
}
// override这个方法来render界面
Widget timBuild(BuildContext context);
}

View File

@ -1,5 +1,4 @@
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
class TUIKitBuildValue { class TUIKitBuildValue {
// //

View File

@ -1,4 +1,4 @@
import 'package:tencent_im_base/base_widgets/tim_callback.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';

View File

@ -1,9 +1,11 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_state.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_base.dart';
import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme_view_model.dart';
class TIMUIKitState<T extends StatefulWidget> extends TIMState<T> { class TIMUIKitState<T extends StatefulWidget> extends TIMState<T> {
final CoreServicesImpl _coreServices = serviceLocator<CoreServicesImpl>(); final CoreServicesImpl _coreServices = serviceLocator<CoreServicesImpl>();

View File

@ -1,9 +1,11 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_stateless_widget.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_base.dart';
import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme_view_model.dart';
class TIMUIKitStatelessWidget extends TIMStatelessWidget { class TIMUIKitStatelessWidget extends TIMStatelessWidget {
final CoreServicesImpl _coreServices = serviceLocator<CoreServicesImpl>(); final CoreServicesImpl _coreServices = serviceLocator<CoreServicesImpl>();

View File

@ -1,6 +1,11 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_class.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_class.dart';
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
typedef MessageFunction = Future<V2TimMessage?> Function(V2TimMessage message); typedef MessageFunction = Future<V2TimMessage?> Function(V2TimMessage message);

View File

@ -1,3 +1,4 @@
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/base_life_cycle.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/base_life_cycle.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';

View File

@ -3,6 +3,17 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/V2TimGroupListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_change_info_type.dart';
import 'package:tencent_cloud_chat_sdk/manager/v2_tim_manager.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_change_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_topic_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
import 'package:tencent_cloud_chat_uikit/data_services/group/group_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/group/group_services.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
@ -135,7 +146,6 @@ class TUIGroupListenerModel extends ChangeNotifier {
addCategoryForTopic(String groupID, String categoryName) { addCategoryForTopic(String groupID, String categoryName) {
TencentImSDKPlugin.v2TIMManager.getGroupManager().setTopicInfo( TencentImSDKPlugin.v2TIMManager.getGroupManager().setTopicInfo(
topicInfo: V2TimTopicInfo(customString: categoryName), topicInfo: V2TimTopicInfo(customString: categoryName),
groupID: groupID, // id
); );
} }

View File

@ -1,3 +1,5 @@
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_info.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
class UserProfile { class UserProfile {

View File

@ -1,8 +1,11 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_elem_type.dart';
import 'package:tencent_cloud_chat_sdk/enum/offlinePushInfo.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/tim_uikit_cloud_custom_data.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/tim_uikit_cloud_custom_data.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';

View File

@ -7,6 +7,27 @@ import 'package:collection/collection.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart'; import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/get_group_message_read_member_list_filter.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_member_filter_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/history_msg_get_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_priority_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_status.dart';
import 'package:tencent_cloud_chat_sdk/enum/offlinePushInfo.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_custom_elem.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_info_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_message_read_member_list.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_change_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_receipt.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_msg_create_info_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/chat_life_cycle.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/chat_life_cycle.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_model_tools.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_model_tools.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
@ -32,8 +53,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
final TUIChatGlobalModel globalModel = serviceLocator<TUIChatGlobalModel>(); final TUIChatGlobalModel globalModel = serviceLocator<TUIChatGlobalModel>();
final TUIChatModelTools tools = serviceLocator<TUIChatModelTools>(); final TUIChatModelTools tools = serviceLocator<TUIChatModelTools>();
final TUISelfInfoViewModel selfModel = serviceLocator<TUISelfInfoViewModel>(); final TUISelfInfoViewModel selfModel = serviceLocator<TUISelfInfoViewModel>();
final TUIConversationViewModel conversationViewModel = final TUIConversationViewModel conversationViewModel = serviceLocator<TUIConversationViewModel>();
serviceLocator<TUIConversationViewModel>();
final _uuid = const Uuid(); final _uuid = const Uuid();
ChatLifeCycle? lifeCycle; ChatLifeCycle? lifeCycle;
@ -136,8 +156,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
List<V2TimMessage> currentHistoryMsgList = getOriginMessageList(); List<V2TimMessage> currentHistoryMsgList = getOriginMessageList();
for (var v2TimMessage in currentHistoryMsgList) { for (var v2TimMessage in currentHistoryMsgList) {
if (_selectedPositions.containsKey(v2TimMessage.msgID) && if (_selectedPositions.containsKey(v2TimMessage.msgID) && _selectedPositions[v2TimMessage.msgID]!) {
_selectedPositions[v2TimMessage.msgID]!) {
selectList.add(v2TimMessage); selectList.add(v2TimMessage);
} }
} }
@ -370,6 +389,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
? haveMoreLatestData = false ? haveMoreLatestData = false
: tempHaveMoreData = false; : tempHaveMoreData = false;
// //
final currentRecordList = globalModel.messageListMap[conversationID]; final currentRecordList = globalModel.messageListMap[conversationID];
@ -479,10 +499,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
_getMsgReadReceipt(List<V2TimMessage> message) async { _getMsgReadReceipt(List<V2TimMessage> message) async {
final msgID = message final msgID = message
.where((e) => .where((e) => (e.isSelf ?? true) && (e.needReadReceipt ?? false) && (e.status == MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC))
(e.isSelf ?? true) &&
(e.needReadReceipt ?? false) &&
(e.status == MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC))
.map((e) => e.msgID ?? '') .map((e) => e.msgID ?? '')
.toList(); .toList();
if (msgID.isNotEmpty) { if (msgID.isNotEmpty) {
@ -684,6 +701,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
String? cloudCustomData, String? cloudCustomData,
String? localCustomData, String? localCustomData,
bool? isEditStatusMessage = false, bool? isEditStatusMessage = false,
bool? isExcludedFromContentModeration,
}) async { }) async {
String receiver = convType == ConvType.c2c ? convID : ''; String receiver = convType == ConvType.c2c ? convID : '';
String groupID = convType == ConvType.group ? convID : ''; String groupID = convType == ConvType.group ? convID : '';
@ -703,6 +721,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
groupID: groupID, groupID: groupID,
offlinePushInfo: offlinePushInfo, offlinePushInfo: offlinePushInfo,
onlineUserOnly: onlineUserOnly ?? false, onlineUserOnly: onlineUserOnly ?? false,
isExcludedFromContentModeration: isExcludedFromContentModeration ?? false,
cloudCustomData: cloudCustomData ?? cloudCustomData: cloudCustomData ??
(showC2cMessageEditStatus == true (showC2cMessageEditStatus == true
? json.encode({ ? json.encode({
@ -924,8 +943,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
_repliedMessage = null; _repliedMessage = null;
final sendMsgRes = await _messageService.sendMessage( final sendMsgRes = await _messageService.sendMessage(
cloudCustomData: TencentUtils.checkString( cloudCustomData:
messageInfoWithSender?.cloudCustomData) ?? TencentUtils.checkString(messageInfoWithSender?.cloudCustomData) ??
json.encode(cloudCustomData), json.encode(cloudCustomData),
id: textMessageInfo.id as String, id: textMessageInfo.id as String,
offlinePushInfo: tools.buildMessagePushInfo( offlinePushInfo: tools.buildMessagePushInfo(
@ -1153,11 +1172,9 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
for (var conversation in conversationList) { for (var conversation in conversationList) {
final convID = conversation.groupID ?? conversation.userID ?? ""; final convID = conversation.groupID ?? conversation.userID ?? "";
final convType = conversation.type; final convType = conversation.type;
List<V2TimMessage> currentHistoryMsgList = List<V2TimMessage> currentHistoryMsgList = globalModel.messageListMap[conversationID] ?? [];
globalModel.messageListMap[conversationID] ?? [];
for (var message in selectedMessages) { for (var message in selectedMessages) {
final forwardMessageInfo = final forwardMessageInfo = await _messageService.createForwardMessage(msgID: message.msgID!);
await _messageService.createForwardMessage(msgID: message.msgID!);
final messageInfo = forwardMessageInfo!.messageInfo; final messageInfo = forwardMessageInfo!.messageInfo;
if (messageInfo != null) { if (messageInfo != null) {
tools.setUserInfoForMessage(messageInfo, forwardMessageInfo.id); tools.setUserInfoForMessage(messageInfo, forwardMessageInfo.id);
@ -1165,9 +1182,11 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
addSendingMessageID(messageInfo.id); addSendingMessageID(messageInfo.id);
// //
if (convID == conversationID) { if (convID == conversationID) {
if (globalModel.getMessageListPosition(convID) != if (globalModel.getMessageListPosition(convID) != HistoryMessagePosition.notShowLatest) {
HistoryMessagePosition.notShowLatest) { currentHistoryMsgList = [
currentHistoryMsgList = [messageInfo, ...currentHistoryMsgList]; messageInfo,
...currentHistoryMsgList
];
globalModel.setMessageList(conversationID, currentHistoryMsgList); globalModel.setMessageList(conversationID, currentHistoryMsgList);
_notify(); _notify();
} }
@ -1202,8 +1221,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
for (var conversation in conversationList) { for (var conversation in conversationList) {
final convID = conversation.groupID ?? conversation.userID ?? ""; final convID = conversation.groupID ?? conversation.userID ?? "";
final convType = conversation.type; final convType = conversation.type;
List<V2TimMessage> currentHistoryMsgList = List<V2TimMessage> currentHistoryMsgList = globalModel.messageListMap[conversationID] ?? [];
globalModel.messageListMap[conversationID] ?? [];
final mergerMessageInfo = await _messageService.createMergerMessage( final mergerMessageInfo = await _messageService.createMergerMessage(
msgIDList: msgIDList, msgIDList: msgIDList,
title: title, title: title,
@ -1216,9 +1234,11 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
addSendingMessageID(messageInfo.id); addSendingMessageID(messageInfo.id);
// //
if (convID == conversationID) { if (convID == conversationID) {
if (globalModel.getMessageListPosition(convID) != if (globalModel.getMessageListPosition(convID) != HistoryMessagePosition.notShowLatest) {
HistoryMessagePosition.notShowLatest) { currentHistoryMsgList = [
currentHistoryMsgList = [messageInfo, ...currentHistoryMsgList]; messageInfo,
...currentHistoryMsgList
];
globalModel.setMessageList(conversationID, currentHistoryMsgList); globalModel.setMessageList(conversationID, currentHistoryMsgList);
_notify(); _notify();
} }
@ -1247,14 +1267,16 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
return null; return null;
} }
currentHistoryMsgList currentHistoryMsgList.removeWhere((element) => element.msgID == message.msgID);
.removeWhere((element) => element.msgID == message.msgID);
message.status = MessageStatus.V2TIM_MSG_STATUS_SENDING; message.status = MessageStatus.V2TIM_MSG_STATUS_SENDING;
addSendingMessageID(message.msgID); addSendingMessageID(message.msgID);
globalModel.setMessageList(convID, currentHistoryMsgList); globalModel.setMessageList(convID, currentHistoryMsgList);
if (globalModel.getMessageListPosition(conversationID) != if (globalModel.getMessageListPosition(conversationID) !=
HistoryMessagePosition.notShowLatest) { HistoryMessagePosition.notShowLatest) {
currentHistoryMsgList = [message, ...currentHistoryMsgList]; currentHistoryMsgList = [
message,
...currentHistoryMsgList
];
globalModel.setMessageList(conversationID, currentHistoryMsgList); globalModel.setMessageList(conversationID, currentHistoryMsgList);
_notify(); _notify();
} }
@ -1312,7 +1334,6 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
Future<V2TimValueCallback<V2TimMessage>?>? sendMessageFromController({ Future<V2TimValueCallback<V2TimMessage>?>? sendMessageFromController({
required V2TimMessage? messageInfo, required V2TimMessage? messageInfo,
/// Offline push info /// Offline push info
OfflinePushInfo? offlinePushInfo, OfflinePushInfo? offlinePushInfo,
MessagePriorityEnum priority = MessagePriorityEnum.V2TIM_PRIORITY_NORMAL, MessagePriorityEnum priority = MessagePriorityEnum.V2TIM_PRIORITY_NORMAL,
@ -1351,6 +1372,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
offlinePushInfo: offlinePushInfo ?? offlinePushInfo: offlinePushInfo ??
tools.buildMessagePushInfo( tools.buildMessagePushInfo(
messageInfo, conversationID, conversationType ?? ConvType.c2c), messageInfo, conversationID, conversationType ?? ConvType.c2c),
isExcludedFromContentModeration: messageInfo.isExcludedFromContentModeration,
); );
} }
return null; return null;
@ -1427,8 +1449,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
for (var msgID in msgIDs) { for (var msgID in msgIDs) {
messageList.removeWhere((element) => element.msgID == msgID); messageList.removeWhere((element) => element.msgID == msgID);
} }
globalModel.setMessageList(conversationID, messageList, globalModel.setMessageList(conversationID, messageList, isDeleteMsg: true);
isDeleteMsg: true);
} }
} }

View File

@ -1,6 +1,20 @@
// ignore_for_file: unnecessary_getters_setters, avoid_print // ignore_for_file: unnecessary_getters_setters, avoid_print
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_member_filter_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_member_role.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_member_role_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_type.dart';
import 'package:tencent_cloud_chat_sdk/enum/receive_message_opt_enum.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_operation_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_search_param.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_search_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/group_profile_life_cycle.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/group_profile_life_cycle.dart';
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/core/core_services_implements.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart';
@ -9,7 +23,6 @@ import 'package:tencent_cloud_chat_uikit/data_services/group/group_services.dart
import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
class TUIGroupProfileModel extends ChangeNotifier { class TUIGroupProfileModel extends ChangeNotifier {
final CoreServicesImpl _coreServices = serviceLocator<CoreServicesImpl>(); final CoreServicesImpl _coreServices = serviceLocator<CoreServicesImpl>();

View File

@ -1,7 +1,13 @@
// ignore_for_file: avoid_print // ignore_for_file: avoid_print
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_sdk/enum/friend_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/receive_message_opt_enum.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_operation_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/profile_life_cycle.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/profile_life_cycle.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/model/profile_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/model/profile_model.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_friendship_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_friendship_view_model.dart';

View File

@ -1,5 +1,4 @@
// ignore_for_file: avoid_print, unnecessary_getters_setters, unused_element // ignore_for_file: avoid_print, unnecessary_getters_setters, unused_element
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
@ -7,6 +6,21 @@ import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:tencent_cloud_chat_sdk/enum/V2TimAdvancedMsgListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/history_msg_get_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_elem_type.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_priority_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_status.dart';
import 'package:tencent_cloud_chat_sdk/enum/offlinePushInfo.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_custom_elem.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_application.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_image.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_download_progress.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_receipt.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_msg_create_info_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_class.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_class.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/chat_life_cycle.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/chat_life_cycle.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_model_tools.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_model_tools.dart';
@ -773,6 +787,7 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass {
needReadReceipt: needReadReceipt, needReadReceipt: needReadReceipt,
cloudCustomData: cloudCustomData, cloudCustomData: cloudCustomData,
localCustomData: localCustomData, localCustomData: localCustomData,
isExcludedFromContentModeration: messageInfo.isExcludedFromContentModeration ?? false,
convID: convID, convID: convID,
setInputField: setInputField, setInputField: setInputField,
id: messageInfo.id as String, id: messageInfo.id as String,
@ -892,6 +907,7 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass {
bool? needReadReceipt, bool? needReadReceipt,
String? cloudCustomData, String? cloudCustomData,
String? localCustomData, String? localCustomData,
bool isExcludedFromContentModeration = false,
}) async { }) async {
String receiver = convType == ConvType.c2c ? convID : ''; String receiver = convType == ConvType.c2c ? convID : '';
String groupID = convType == ConvType.group ? convID : ''; String groupID = convType == ConvType.group ? convID : '';
@ -904,6 +920,7 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass {
localCustomData: localCustomData, localCustomData: localCustomData,
isExcludedFromUnreadCount: isExcludedFromUnreadCount ?? false, isExcludedFromUnreadCount: isExcludedFromUnreadCount ?? false,
offlinePushInfo: offlinePushInfo, offlinePushInfo: offlinePushInfo,
isExcludedFromContentModeration: isExcludedFromContentModeration,
onlineUserOnly: onlineUserOnly ?? false, onlineUserOnly: onlineUserOnly ?? false,
cloudCustomData: cloudCustomData ?? cloudCustomData: cloudCustomData ??
json.encode({ json.encode({

View File

@ -2,6 +2,11 @@
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_cloud_chat_sdk/enum/V2TimConversationListener.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_search_param.dart';
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/conversation_life_cycle.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/conversation_life_cycle.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart';
@ -12,8 +17,7 @@ import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
List<T> removeDuplicates<T>( List<T> removeDuplicates<T>(List<T> list, bool Function(T first, T second) isEqual) {
List<T> list, bool Function(T first, T second) isEqual) {
List<T> output = []; List<T> output = [];
for (var i = 0; i < list.length; i++) { for (var i = 0; i < list.length; i++) {
bool found = false; bool found = false;
@ -34,14 +38,10 @@ class TUIConversationViewModel extends ChangeNotifier {
static const String conversationC2CPrefix = "c2c_"; static const String conversationC2CPrefix = "c2c_";
static const String conversationGroupPrefix = "group_"; static const String conversationGroupPrefix = "group_";
final TUISelfInfoViewModel selfInfoViewModel = final TUISelfInfoViewModel selfInfoViewModel = serviceLocator<TUISelfInfoViewModel>();
serviceLocator<TUISelfInfoViewModel>(); final ConversationService _conversationService = serviceLocator<ConversationService>();
final ConversationService _conversationService = final FriendshipServices _friendshipServices = serviceLocator<FriendshipServices>();
serviceLocator<ConversationService>(); final TUIChatGlobalModel _chatGlobalModel = serviceLocator<TUIChatGlobalModel>();
final FriendshipServices _friendshipServices =
serviceLocator<FriendshipServices>();
final TUIChatGlobalModel _chatGlobalModel =
serviceLocator<TUIChatGlobalModel>();
final MessageService _messageService = serviceLocator<MessageService>(); final MessageService _messageService = serviceLocator<MessageService>();
late V2TimConversationListener _conversationListener; late V2TimConversationListener _conversationListener;
List<V2TimConversation?> _conversationList = []; List<V2TimConversation?> _conversationList = [];
@ -51,8 +51,7 @@ class TUIConversationViewModel extends ChangeNotifier {
bool _haveMoreData = true; bool _haveMoreData = true;
int _totalUnReadCount = 0; int _totalUnReadCount = 0;
String? _scrollToConversation; String? _scrollToConversation;
final TUIChatGlobalModel globalChatModel = final TUIChatGlobalModel globalChatModel = serviceLocator<TUIChatGlobalModel>();
serviceLocator<TUIChatGlobalModel>();
String _nextSeq = "0"; String _nextSeq = "0";
ConversationLifeCycle? _lifeCycle; ConversationLifeCycle? _lifeCycle;
@ -61,13 +60,10 @@ class TUIConversationViewModel extends ChangeNotifier {
if (PlatformUtils().isWeb) { if (PlatformUtils().isWeb) {
try { try {
_conversationList.sort((a, b) { _conversationList.sort((a, b) {
return b!.lastMessage!.timestamp! return b!.lastMessage!.timestamp!.compareTo(a!.lastMessage!.timestamp!);
.compareTo(a!.lastMessage!.timestamp!);
}); });
final pinnedConversation = _conversationList final pinnedConversation = _conversationList.where((element) => element?.isPinned == true).toList();
.where((element) => element?.isPinned == true)
.toList();
_conversationList.removeWhere((element) => element?.isPinned == true); _conversationList.removeWhere((element) => element?.isPinned == true);
_conversationList = [...pinnedConversation, ..._conversationList]; _conversationList = [...pinnedConversation, ..._conversationList];
// ignore: empty_catches // ignore: empty_catches
@ -79,8 +75,7 @@ class TUIConversationViewModel extends ChangeNotifier {
} }
V2TimConversation? getConversation(String conversationID) { V2TimConversation? getConversation(String conversationID) {
return _conversationList.firstWhereOrNull( return _conversationList.firstWhereOrNull((element) => element?.conversationID == conversationID);
(element) => element?.conversationID == conversationID);
} }
String? get scrollToConversation => _scrollToConversation; String? get scrollToConversation => _scrollToConversation;
@ -127,8 +122,7 @@ class TUIConversationViewModel extends ChangeNotifier {
} }
TUIConversationViewModel() { TUIConversationViewModel() {
_conversationListener = _conversationListener = V2TimConversationListener(onConversationChanged: (conversationList) {
V2TimConversationListener(onConversationChanged: (conversationList) {
_onConversationListChanged(conversationList); _onConversationListChanged(conversationList);
}, onNewConversation: (conversationList) { }, onNewConversation: (conversationList) {
_addNewConversation(conversationList); _addNewConversation(conversationList);
@ -174,8 +168,7 @@ class TUIConversationViewModel extends ChangeNotifier {
Future<void> loadData({required int count}) async { Future<void> loadData({required int count}) async {
_haveMoreData = true; _haveMoreData = true;
final isRefresh = _nextSeq == "0"; final isRefresh = _nextSeq == "0";
final conversationResult = await _conversationService.getConversationList( final conversationResult = await _conversationService.getConversationList(nextSeq: _nextSeq, count: count);
nextSeq: _nextSeq, count: count);
_nextSeq = conversationResult?.nextSeq ?? ""; _nextSeq = conversationResult?.nextSeq ?? "";
final conversationList = conversationResult?.conversationList; final conversationList = conversationResult?.conversationList;
if (conversationList != null) { if (conversationList != null) {
@ -188,12 +181,8 @@ class TUIConversationViewModel extends ChangeNotifier {
} else { } else {
combinedConversationList = [..._conversationList, ...conversationList]; combinedConversationList = [..._conversationList, ...conversationList];
} }
final List<V2TimConversation?> finalConversationList = await _lifeCycle final List<V2TimConversation?> finalConversationList = await _lifeCycle?.conversationListWillMount(combinedConversationList) ?? combinedConversationList;
?.conversationListWillMount(combinedConversationList) ?? _conversationList = removeDuplicates<V2TimConversation?>(finalConversationList, (item1, item2) => item1?.conversationID == item2?.conversationID);
combinedConversationList;
_conversationList = removeDuplicates<V2TimConversation?>(
finalConversationList,
(item1, item2) => item1?.conversationID == item2?.conversationID);
notifyListeners(); notifyListeners();
} }
_totalUnReadCount = await _conversationService.getTotalUnreadCount(); _totalUnReadCount = await _conversationService.getTotalUnreadCount();
@ -210,15 +199,11 @@ class TUIConversationViewModel extends ChangeNotifier {
required String conversationID, required String conversationID,
required bool isPinned, required bool isPinned,
}) { }) {
return _conversationService.pinConversation( return _conversationService.pinConversation(conversationID: conversationID, isPinned: isPinned);
conversationID: conversationID, isPinned: isPinned);
} }
Future<V2TimCallback?> clearHistoryMessage( Future<V2TimCallback?> clearHistoryMessage({required String convID, required int convType}) async {
{required String convID, required int convType}) async { if (_lifeCycle?.shouldClearHistoricalMessageForConversation != null && await _lifeCycle!.shouldClearHistoricalMessageForConversation(convID) == false) {
if (_lifeCycle?.shouldClearHistoricalMessageForConversation != null &&
await _lifeCycle!.shouldClearHistoricalMessageForConversation(convID) ==
false) {
return null; return null;
} }
@ -232,22 +217,17 @@ class TUIConversationViewModel extends ChangeNotifier {
} }
searchFriends(String searchKey) async { searchFriends(String searchKey) async {
final res = await _friendshipServices.searchFriends( final res = await _friendshipServices.searchFriends(searchParam: V2TimFriendSearchParam(keywordList: [searchKey]));
searchParam: V2TimFriendSearchParam(keywordList: [searchKey]));
return res; return res;
} }
Future<V2TimCallback?> deleteConversation( Future<V2TimCallback?> deleteConversation({required String conversationID}) async {
{required String conversationID}) async { if (_lifeCycle?.shouldDeleteConversation != null && await _lifeCycle!.shouldDeleteConversation(conversationID) == false) {
if (_lifeCycle?.shouldDeleteConversation != null &&
await _lifeCycle!.shouldDeleteConversation(conversationID) == false) {
return null; return null;
} }
final res = await _conversationService.deleteConversation( final res = await _conversationService.deleteConversation(conversationID: conversationID);
conversationID: conversationID);
if (res.code == 0) { if (res.code == 0) {
_conversationList _conversationList.removeWhere((element) => element?.conversationID == conversationID);
.removeWhere((element) => element?.conversationID == conversationID);
notifyListeners(); notifyListeners();
} }
return res; return res;
@ -255,11 +235,9 @@ class TUIConversationViewModel extends ChangeNotifier {
_onConversationListChanged(List<V2TimConversation> list) { _onConversationListChanged(List<V2TimConversation> list) {
for (int element = 0; element < list.length; element++) { for (int element = 0; element < list.length; element++) {
int index = _conversationList.indexWhere( int index = _conversationList.indexWhere((item) => item!.conversationID == list[element].conversationID);
(item) => item!.conversationID == list[element].conversationID);
if (index > -1) { if (index > -1) {
_conversationList.setAll( _conversationList.setAll(index, [list[element]] as List<V2TimConversation?>);
index, [list[element]] as List<V2TimConversation?>);
} else { } else {
_conversationList.add(list[element]); _conversationList.add(list[element]);
} }
@ -270,13 +248,10 @@ class TUIConversationViewModel extends ChangeNotifier {
_onConversationDeleted(List<String> list) { _onConversationDeleted(List<String> list) {
for (int i = 0; i < list.length; i++) { for (int i = 0; i < list.length; i++) {
int index = _conversationList int index = _conversationList.indexWhere((item) => item!.conversationID == list[i]);
.indexWhere((item) => item!.conversationID == list[i]);
if (index > -1) { if (index > -1) {
_conversationList.removeAt(index); _conversationList.removeAt(index);
_conversationList = removeDuplicates<V2TimConversation?>( _conversationList = removeDuplicates<V2TimConversation?>(_conversationList, (item1, item2) => item1?.conversationID == item2?.conversationID);
_conversationList,
(item1, item2) => item1?.conversationID == item2?.conversationID);
} }
} }
notifyListeners(); notifyListeners();
@ -284,19 +259,16 @@ class TUIConversationViewModel extends ChangeNotifier {
_addNewConversation(List<V2TimConversation> list) { _addNewConversation(List<V2TimConversation> list) {
_conversationList.addAll(list); _conversationList.addAll(list);
_conversationList = removeDuplicates<V2TimConversation?>(_conversationList, _conversationList = removeDuplicates<V2TimConversation?>(_conversationList, (item1, item2) => item1?.conversationID == item2?.conversationID);
(item1, item2) => item1?.conversationID == item2?.conversationID);
notifyListeners(); notifyListeners();
} }
setConversationListener() { setConversationListener() {
_conversationService.addConversationListener( _conversationService.addConversationListener(listener: _conversationListener);
listener: _conversationListener);
} }
removeConversationListener() { removeConversationListener() {
_conversationService.removeConversationListener( _conversationService.removeConversationListener(listener: _conversationListener);
listener: _conversationListener);
} }
Future<V2TimCallback> setConversationDraft({ Future<V2TimCallback> setConversationDraft({
@ -306,25 +278,19 @@ class TUIConversationViewModel extends ChangeNotifier {
String? groupID, String? groupID,
bool isAllowWeb = true, bool isAllowWeb = true,
}) async { }) async {
assert(!isTopic || (groupID != null && groupID.isNotEmpty), assert(!isTopic || (groupID != null && groupID.isNotEmpty), "When 'isTopic' is true, 'groupID' must not be null or empty.");
"When 'isTopic' is true, 'groupID' must not be null or empty.");
if (PlatformUtils().isWeb && isAllowWeb) { if (PlatformUtils().isWeb && isAllowWeb) {
webDraftMap[conversationID] = draftText ?? ""; webDraftMap[conversationID] = draftText ?? "";
return V2TimCallback(code: 0, desc: ""); return V2TimCallback(code: 0, desc: "");
} else { } else {
if (isTopic) { if (isTopic) {
final topicInfoList = await TencentImSDKPlugin.v2TIMManager final topicInfoList = await TencentImSDKPlugin.v2TIMManager.getGroupManager().getTopicInfoList(groupID: groupID!, topicIDList: [conversationID]);
.getGroupManager()
.getTopicInfoList(groupID: groupID!, topicIDList: [conversationID]);
final topicInfo = topicInfoList.data?.first.topicInfo; final topicInfo = topicInfoList.data?.first.topicInfo;
topicInfo?.draftText = draftText; topicInfo?.draftText = draftText;
final res = await TencentImSDKPlugin.v2TIMManager final res = await TencentImSDKPlugin.v2TIMManager.getGroupManager().setTopicInfo(topicInfo: topicInfo!);
.getGroupManager()
.setTopicInfo(groupID: groupID, topicInfo: topicInfo!);
return res; return res;
} else { } else {
return _conversationService.setConversationDraft( return _conversationService.setConversationDraft(conversationID: conversationID, draftText: draftText);
conversationID: conversationID, draftText: draftText);
} }
} }
} }

View File

@ -1,7 +1,15 @@
import 'dart:math'; import 'dart:math';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_sdk/enum/V2TimFriendshipListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/friend_application_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/friend_response_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_application.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_operation_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_status.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/block_list_life_cycle.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/block_list_life_cycle.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/friend_list_life_cycle.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/friend_list_life_cycle.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/new_contact_life_cycle.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/new_contact_life_cycle.dart';

View File

@ -2,13 +2,19 @@
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_info_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_search_param.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_search_param.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_search_param.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_search_result_item.dart';
import 'package:tencent_cloud_chat_uikit/data_services/friendShip/friendship_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/friendShip/friendship_services.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart';
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';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
enum KeywordListMatchType { enum KeywordListMatchType {
V2TIM_KEYWORD_LIST_MATCH_TYPE_OR, V2TIM_KEYWORD_LIST_MATCH_TYPE_OR,

View File

@ -1,5 +1,5 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart';
import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_config.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_config.dart';
class TUISelfInfoViewModel extends ChangeNotifier { class TUISelfInfoViewModel extends ChangeNotifier {

View File

@ -1,4 +1,7 @@
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_sdk/enum/V2TimConversationListener.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation_result.dart';
abstract class ConversationService { abstract class ConversationService {
Future<V2TimConversationResult?> getConversationList({ Future<V2TimConversationResult?> getConversationList({

View File

@ -1,7 +1,12 @@
import 'package:tencent_cloud_chat_sdk/enum/V2TimConversationListener.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation_result.dart';
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
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/core/core_services_implements.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
class ConversationServicesImpl extends ConversationService { class ConversationServicesImpl extends ConversationService {
final CoreServicesImpl _coreService = serviceLocator<CoreServicesImpl>(); final CoreServicesImpl _coreService = serviceLocator<CoreServicesImpl>();
@ -114,7 +119,7 @@ class ConversationServicesImpl extends ConversationService {
{required String convID}) async { {required String convID}) async {
final result = await TencentImSDKPlugin.v2TIMManager final result = await TencentImSDKPlugin.v2TIMManager
.getConversationManager() .getConversationManager()
.getConversationListByConversaionIds(conversationIDList: [convID]); .getConversationListByConversationIds(conversationIDList: [convID]);
if (result.code != 0) { if (result.code != 0) {
_coreService.callOnCallback(TIMCallback( _coreService.callOnCallback(TIMCallback(
type: TIMCallbackType.API_ERROR, type: TIMCallbackType.API_ERROR,

View File

@ -1,7 +1,13 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:tencent_cloud_chat_sdk/enum/V2TimSDKListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/log_level_enum.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_config.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_config.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
enum AppStatus { foreground, background } enum AppStatus { foreground, background }

View File

@ -2,11 +2,19 @@
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:tencent_chat_i18n_tool/tools/i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/V2TimSDKListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/log_level_enum.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_status.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_setting_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_setting_model.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/listener_model/tui_group_listener_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/listener_model/tui_group_listener_model.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_conversation_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_conversation_view_model.dart';
@ -18,6 +26,9 @@ import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
import 'package:tencent_cloud_chat_uikit/data_services/core/web_support/uikit_web_support.dart' import 'package:tencent_cloud_chat_uikit/data_services/core/web_support/uikit_web_support.dart'
if (dart.library.html) 'package:tencent_cloud_chat_uikit/data_services/core/web_support/uikit_web_support_implement.dart'; if (dart.library.html) 'package:tencent_cloud_chat_uikit/data_services/core/web_support/uikit_web_support_implement.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme_view_model.dart';
typedef EmptyAvatarBuilder = Widget Function(BuildContext context); typedef EmptyAvatarBuilder = Widget Function(BuildContext context);

View File

@ -1,6 +1,6 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart';
import 'package:tencent_im_base/theme/tui_theme.dart'; import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class TIMUIKitConfig { class TIMUIKitConfig {
/// Control if show online status of friends or contacts. /// Control if show online status of friends or contacts.

View File

@ -1,4 +1,17 @@
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_sdk/enum/V2TimFriendshipListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/friend_application_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/friend_response_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/friend_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_application_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_check_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_info_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_operation_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_search_param.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_status.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
abstract class FriendshipServices { abstract class FriendshipServices {
Future<List<V2TimFriendInfoResult>?> getFriendsInfo({ Future<List<V2TimFriendInfoResult>?> getFriendsInfo({

View File

@ -1,8 +1,24 @@
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/V2TimFriendshipListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/friend_application_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/friend_response_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/friend_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_application_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_check_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_info_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_operation_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_search_param.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_status.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart';
import 'package:tencent_cloud_chat_uikit/data_services/friendShip/friendship_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/friendShip/friendship_services.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/error_message_converter.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/error_message_converter.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
class FriendshipServicesImpl implements FriendshipServices { class FriendshipServicesImpl implements FriendshipServices {
final CoreServicesImpl _coreService = serviceLocator<CoreServicesImpl>(); final CoreServicesImpl _coreService = serviceLocator<CoreServicesImpl>();

View File

@ -1,4 +1,18 @@
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_sdk/enum/V2TimGroupListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_application_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_member_filter_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_member_role_enum.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_application_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_info_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_operation_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_search_param.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_search_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_search_param.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
abstract class GroupServices { abstract class GroupServices {
Future<List<V2TimGroupInfo>?> getJoinedGroupList(); Future<List<V2TimGroupInfo>?> getJoinedGroupList();

View File

@ -1,9 +1,25 @@
import 'package:tencent_cloud_chat_sdk/enum/V2TimGroupListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_application_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_member_filter_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_member_role_enum.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_application_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_info_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_operation_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_search_param.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_search_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_search_param.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.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';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/error_message_converter.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/error_message_converter.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/optimize_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/optimize_utils.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
class GroupServicesImpl extends GroupServices { class GroupServicesImpl extends GroupServices {
static List<Function?> groupInfoCallBackList = []; static List<Function?> groupInfoCallBackList = [];

View File

@ -3,13 +3,32 @@
import 'dart:math'; import 'dart:math';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:tencent_cloud_chat_sdk/enum/V2TimAdvancedMsgListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/V2TimSimpleMsgListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/get_group_message_read_member_list_filter.dart';
import 'package:tencent_cloud_chat_sdk/enum/history_msg_get_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_priority_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/offlinePushInfo.dart';
import 'package:tencent_cloud_chat_sdk/enum/receive_message_opt_enum.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_message_read_member_list.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_change_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_list_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_online_url.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_receipt.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_search_param.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_search_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_msg_create_info_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_conversation_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_conversation_view_model.dart';
import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart';
import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/error_message_converter.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/error_message_converter.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
class MessageServiceImpl extends MessageService { class MessageServiceImpl extends MessageService {
final CoreServicesImpl _coreService = serviceLocator<CoreServicesImpl>(); final CoreServicesImpl _coreService = serviceLocator<CoreServicesImpl>();
@ -349,6 +368,7 @@ class MessageServiceImpl extends MessageService {
OfflinePushInfo? offlinePushInfo, OfflinePushInfo? offlinePushInfo,
String? cloudCustomData, String? cloudCustomData,
String? localCustomData, String? localCustomData,
bool isExcludedFromContentModeration = false,
}) async { }) async {
final result = final result =
await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessage( await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessage(
@ -361,6 +381,7 @@ class MessageServiceImpl extends MessageService {
needReadReceipt: needReadReceipt, needReadReceipt: needReadReceipt,
localCustomData: localCustomData, localCustomData: localCustomData,
cloudCustomData: cloudCustomData, cloudCustomData: cloudCustomData,
isExcludedFromContentModeration: isExcludedFromContentModeration,
); );
if (result.code != 0) { if (result.code != 0) {
String recommendText = ErrorMessageConverter.getErrorMessage(result.code); String recommendText = ErrorMessageConverter.getErrorMessage(result.code);

View File

@ -1,4 +1,21 @@
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_sdk/enum/V2TimAdvancedMsgListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/V2TimSimpleMsgListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/get_group_message_read_member_list_filter.dart';
import 'package:tencent_cloud_chat_sdk/enum/history_msg_get_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_priority_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/offlinePushInfo.dart';
import 'package:tencent_cloud_chat_sdk/enum/receive_message_opt_enum.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_message_read_member_list.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_change_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_list_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_online_url.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_receipt.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_search_param.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_search_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_msg_create_info_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
class MessageListResponse { class MessageListResponse {
final bool haveMoreData; final bool haveMoreData;
@ -71,7 +88,8 @@ abstract class MessageService {
bool needReadReceipt = false, bool needReadReceipt = false,
OfflinePushInfo? offlinePushInfo, OfflinePushInfo? offlinePushInfo,
String? cloudCustomData, // String? cloudCustomData, //
String? localCustomData}); String? localCustomData,
bool isExcludedFromContentModeration});
Future<V2TimValueCallback<V2TimMessage>> sendReplyMessage({ Future<V2TimValueCallback<V2TimMessage>> sendReplyMessage({
required String id, // ID required String id, // ID

View File

@ -16,7 +16,7 @@ import 'package:tencent_cloud_chat_uikit/data_services/message/message_service_i
import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_search_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_search_view_model.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart';
import 'package:tencent_im_base/theme/tui_theme_view_model.dart'; import 'package:tencent_cloud_chat_uikit/theme/tui_theme_view_model.dart';
final serviceLocator = GetIt.instance; final serviceLocator = GetIt.instance;
bool boolIsInitailized = false; bool boolIsInitailized = false;

View File

@ -1,12 +1,10 @@
library tencent_cloud_chat_uikit; library tencent_cloud_chat_uikit;
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_sdk/manager/v2_tim_manager.dart';
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'data_services/core/core_services_implements.dart'; import 'data_services/core/core_services_implements.dart';
export 'data_services/core/core_services_implements.dart'; export 'data_services/core/core_services_implements.dart';
export 'package:tencent_im_base/theme/tui_theme.dart';
export 'package:tencent_im_base/theme/color.dart';
// Sticker // Sticker
export 'package:tim_ui_kit_sticker_plugin/tim_ui_kit_sticker_plugin.dart'; export 'package:tim_ui_kit_sticker_plugin/tim_ui_kit_sticker_plugin.dart';
@ -34,7 +32,6 @@ export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitAppBar/ti
export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list.dart'; export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list.dart';
export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field.dart'; export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field.dart';
export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroup/tim_uikit_group_application_list.dart'; export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroup/tim_uikit_group_application_list.dart';
export 'package:tencent_im_base/tencent_im_base.dart';
export 'package:tencent_cloud_chat_uikit/ui/widgets/link_preview/models/link_preview_content.dart'; export 'package:tencent_cloud_chat_uikit/ui/widgets/link_preview/models/link_preview_content.dart';
export 'package:tencent_cloud_chat_uikit/ui/widgets/column_menu.dart'; export 'package:tencent_cloud_chat_uikit/ui/widgets/column_menu.dart';
export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card.dart'; export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card.dart';

37
lib/theme/color.dart Normal file
View File

@ -0,0 +1,37 @@
import 'package:flutter/material.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
Color hexToColor(String hexString) {
return Color(int.parse(hexString, radix: 16)).withAlpha(255);
}
class CommonColor {
static const weakBackgroundColor = Color(0xFFEDEDED);
static const weakDividerColor = Color(0xFFE5E6E9);
static const primaryColor = Color(0xFF147AFF);
static const lightPrimaryColor = Color(0xFFC0E1FF);
static const secondaryColor = Color(0xFF147AFF);
static const weakTextColor = Color(0xFF999999);
static const infoColor = Color(0xFFFF9C19);
static const cautionColor = Color(0xFFFF584C);
static const ownerColor = Colors.orange;
static const adminColor = Colors.blue;
static const inputFillColor = Color.fromARGB(0, 242, 243, 245);
static const textgrey = Color(0xFFAEA4A3);
static const defaultTheme = TUITheme(
weakBackgroundColor: Color(0xFFEDEDED),
weakDividerColor: Color(0xFFE5E6E9),
primaryColor: Color(0xFF147AFF),
secondaryColor: Color(0xFF147AFF),
infoColor: Color(0xFFFF9C19),
lightPrimaryColor: Color(0xFFC0E1FF),
weakTextColor: Color(0xFF999999),
darkTextColor: Color(0xFF444444),
cautionColor: Color(0xFFFF584C),
ownerColor: Colors.orange,
adminColor: Colors.blue,
inputFillColor: Color.fromARGB(0, 242, 243, 245),
textgrey: Color(0xFFAEA4A3),
);
}

597
lib/theme/tui_theme.dart Normal file
View File

@ -0,0 +1,597 @@
import 'package:flutter/material.dart';
class TUITheme {
const TUITheme({
this.primaryColor = const Color(0xFF00449E),
this.secondaryColor = const Color(0xFF147AFF),
this.infoColor = const Color(0xFFFF9C19),
this.weakBackgroundColor = const Color(0xFFEDEDED),
this.wideBackgroundColor = Colors.white,
this.weakDividerColor = const Color(0xFFE5E6E9),
this.weakTextColor = const Color(0xFF999999),
this.darkTextColor = const Color(0xFF444444),
this.lightPrimaryColor = const Color(0xFF3371CD),
this.textColor,
this.cautionColor = const Color(0xFFFF584C),
this.ownerColor = Colors.orange,
this.adminColor = Colors.blue,
this.white = Colors.white,
this.black = Colors.black,
this.inputFillColor = const Color(0xFFEDEDED),
this.textgrey = const Color(0xFFAEA4A3),
///
this.selectPanelBgColor = const Color(0xFFF9F9FA),
/// icon颜色
this.selectPanelTextIconColor = const Color(0xFF37393F),
/// Appbar
this.appbarBgColor = const Color(0xFFF2F3F5),
/// Appbar
this.appbarTextColor = const Color(0xFF010000),
///
this.conversationItemBgColor = Colors.white, // 1
///
this.conversationItemBorderColor = const Color(0xFFE5E6E9), // 1
///
this.conversationItemActiveBgColor = const Color(0xFFEDEDED), // 1
///
this.conversationItemPinedBgColor = const Color(0xFFEDEDED), // 1
/// Title字体颜色
this.conversationItemTitleTextColor = Colors.black, // 1
/// LastMessage字体颜色
this.conversationItemLastMessageTextColor = const Color(0xFF999999), // 1
/// Time字体颜色
this.conversationItemTitmeTextColor = const Color(0xFF999999), // 1
/// 线
this.conversationItemOnlineStatusBgColor = Colors.green, // 1
/// 线
this.conversationItemOfflineStatusBgColor = Colors.grey, // 1
///
this.conversationItemUnreadCountBgColor = const Color(0xFFFF584C), // 1
///
this.conversationItemUnreadCountTextColor = Colors.white, // 1
/// 稿
this.conversationItemDraftTextColor = const Color(0xFFFF584C), // 1
/// Icon颜色
this.conversationItemNoNotificationIconColor = const Color(0xFF999999), // 1
///
this.conversationItemSliderTextColor = Colors.white, // 1
/// Clear背景颜色
this.conversationItemSliderClearBgColor = const Color(0xFF00449E), // 1
/// Pin背景颜色
this.conversationItemSliderPinBgColor = const Color(0xFFFF9C19), // 1
/// Delete背景颜色
this.conversationItemSliderDeleteBgColor = Colors.red, // 1
///
this.conversationItemChooseBgColor = const Color(0xFFE7F0FF), // 1
///
this.chatBgColor, // 1
///
this.desktopChatMessageInputBgColor, // 1
///
this.chatTimeDividerTextColor = const Color(0xFF999999), // 1
///
this.chatHeaderBgColor = const Color(0xFFF2F3F5),
/// Title字体颜色
this.chatHeaderTitleTextColor = const Color(0xFF010000),
/// Back字体颜色
this.chatHeaderBackTextColor = const Color(0xFF010000),
/// Action字体颜色
this.chatHeaderActionTextColor = const Color(0xFF010000),
///
this.chatMessageItemTextColor = Colors.black, // 1
///
this.chatMessageItemFromSelfBgColor = const Color(0xFFD1E3FF),
///
this.chatMessageItemFromOthersBgColor = const Color(0xFFEDEDED), // 1
///
this.chatMessageItemUnreadStatusTextColor = const Color(0xFF999999), // 1
///
this.chatMessageTongueBgColor = const Color(0xFFAEA4A3),
///
this.chatMessageTongueTextColor = const Color(0xFFAEA4A3),
});
//
// Primary Color For The App
final Color? primaryColor;
//
// Secondary Color For The App
final Color? secondaryColor;
//
// Info Color, Used For Secondary Action Or Info
final Color? infoColor;
//
// Weak Background Color, Lighter Than Main Background, Used For Marginal Space Or Shadowy Space
final Color? weakBackgroundColor;
//
// Weak Background Color, Lighter Than Main Background, Used For Marginal Space Or Shadowy Space
final Color? wideBackgroundColor;
// 线线
// Weak Divider Color, Used For Divider Or Border
final Color? weakDividerColor;
//
// Weak Text Color
final Color? weakTextColor;
//
// Dark Text Color
final Color? darkTextColor;
// AppBar或Panels
// Light Primary Color, Used For AppBar Or Several Panels
final Color? lightPrimaryColor;
//
// TextColor
final Color? textColor;
//
// Caution Color, Used For Warning Actions
final Color? cautionColor;
//
// Group Owner Identification Color
final Color? ownerColor;
//
// Group Admin Identification Color
final Color? adminColor;
//
// white
final Color? white;
//
// black
final Color? black;
//
// input fill color
final Color? inputFillColor;
//
// grey text color
final Color? textgrey;
///
///
/// Appbar
final Color? appbarBgColor;
/// Appbar
final Color? appbarTextColor;
///
final Color? selectPanelBgColor;
/// icon颜色
final Color? selectPanelTextIconColor;
///
final Color? conversationItemBgColor;
///
final Color? conversationItemBorderColor;
///
final Color? conversationItemActiveBgColor;
///
final Color? conversationItemPinedBgColor;
/// Title字体颜色
final Color? conversationItemTitleTextColor;
/// LastMessage字体颜色
final Color? conversationItemLastMessageTextColor;
/// Time字体颜色
final Color? conversationItemTitmeTextColor;
/// 线
final Color? conversationItemOnlineStatusBgColor;
/// 线
final Color? conversationItemOfflineStatusBgColor;
///
final Color? conversationItemUnreadCountBgColor;
///
final Color? conversationItemUnreadCountTextColor;
/// 稿
final Color? conversationItemDraftTextColor;
/// Icon颜色
final Color? conversationItemNoNotificationIconColor;
///
final Color? conversationItemSliderTextColor;
/// Clear背景颜色
final Color? conversationItemSliderClearBgColor;
/// Pin背景颜色
final Color? conversationItemSliderPinBgColor;
/// Delete背景颜色
final Color? conversationItemSliderDeleteBgColor;
///
final Color? conversationItemChooseBgColor;
///
final Color? chatBgColor;
///
final Color? desktopChatMessageInputBgColor;
///
final Color? chatTimeDividerTextColor;
///
final Color? chatHeaderBgColor;
/// Title字体颜色
final Color? chatHeaderTitleTextColor;
/// Back字体颜色
final Color? chatHeaderBackTextColor;
/// Action字体颜色
final Color? chatHeaderActionTextColor;
///
final Color? chatMessageItemTextColor;
///
final Color? chatMessageItemFromSelfBgColor;
///
final Color? chatMessageItemFromOthersBgColor;
///
final Color? chatMessageItemUnreadStatusTextColor;
///
final Color? chatMessageTongueBgColor;
///
final Color? chatMessageTongueTextColor;
static const TUITheme light = TUITheme();
static const TUITheme dark = TUITheme();
MaterialColor get primaryMaterialColor => createMaterialColor(primaryColor!);
MaterialColor get lightPrimaryMaterialColor =>
createMaterialColor(lightPrimaryColor!);
TUITheme.fromJson(Map<String, dynamic> json)
: primaryColor = json['primaryColor'] as Color?,
secondaryColor = json['secondaryColor'] as Color?,
infoColor = json['infoColor'] as Color?,
weakBackgroundColor = json['weakBackgroundColor'] as Color?,
wideBackgroundColor = json['wideBackgroundColor'] as Color?,
weakDividerColor = json['weakDividerColor'] as Color?,
weakTextColor = json['weakTextColor'] as Color?,
darkTextColor = json['darkTextColor'] as Color?,
lightPrimaryColor = json['lightPrimaryColor'] as Color?,
textColor = json['textColor'] as Color?,
cautionColor = json['cautionColor'] as Color?,
ownerColor = json['ownerColor'] as Color?,
white = json['white'] as Color?,
black = json['black'] as Color?,
inputFillColor = json["inputFillColor"] as Color?,
textgrey = json['textgrey'] as Color?,
adminColor = json['adminColor'] as Color?,
selectPanelBgColor = json['selectPanelBgColor'] as Color?,
selectPanelTextIconColor = json['selectPanelTextIconColor'] as Color?,
appbarBgColor = json['appbarBgColor'] as Color?,
appbarTextColor = json['appbarTextColor'] as Color?,
///
conversationItemBgColor = json['conversationItemBgColor'] as Color?,
///
conversationItemBorderColor =
json['conversationItemBorderColor'] as Color?,
///
conversationItemActiveBgColor =
json['conversationItemActiveBgColor'] as Color?,
///
conversationItemPinedBgColor =
json['conversationItemPinedBgColor'] as Color?,
/// Title字体颜色
conversationItemTitleTextColor =
json['conversationItemTitleTextColor'] as Color?,
/// LastMessage字体颜色
conversationItemLastMessageTextColor =
json['conversationItemLastMessageTextColor'] as Color?,
/// Time字体颜色
conversationItemTitmeTextColor =
json['conversationItemTitmeTextColor'] as Color?,
/// 线
conversationItemOnlineStatusBgColor =
json['conversationItemOnlineStatusBgColor'] as Color?,
/// 线
conversationItemOfflineStatusBgColor =
json['conversationItemOfflineStatusBgColor'] as Color?,
///
conversationItemUnreadCountBgColor =
json['conversationItemUnreadCountBgColor'] as Color?,
///
conversationItemUnreadCountTextColor =
json['conversationItemUnreadCountTextColor'] as Color?,
conversationItemChooseBgColor =
json['conversationItemChooseBgColor'] as Color?,
/// 稿
conversationItemDraftTextColor =
json['conversationItemDraftTextColor'] as Color?,
/// Icon颜色
conversationItemNoNotificationIconColor =
json['conversationItemNoNotificationIconColor'] as Color?,
///
conversationItemSliderTextColor =
json['conversationItemSliderTextColor'] as Color?,
/// Clear背景颜色
conversationItemSliderClearBgColor =
json['conversationItemSliderClearBgColor'] as Color?,
/// Pin背景颜色
conversationItemSliderPinBgColor =
json['conversationItemSliderPinBgColor'] as Color?,
/// Delete背景颜色
conversationItemSliderDeleteBgColor =
json['conversationItemSliderDeleteBgColor'] as Color?,
///
chatBgColor = json['chatBgColor'] as Color?,
///
desktopChatMessageInputBgColor =
json['desktopChatMessageInputBgColor'] as Color?,
///
chatTimeDividerTextColor = json['chatTimeDividerTextColor'] as Color?,
///
chatHeaderBgColor = json['chatHeaderBgColor'] as Color?,
/// Title字体颜色
chatHeaderTitleTextColor = json['chatHeaderTitleTextColor'] as Color?,
/// Back字体颜色
chatHeaderBackTextColor = json['chatHeaderBackTextColor'] as Color?,
/// Action字体颜色
chatHeaderActionTextColor = json['chatHeaderActionTextColor'] as Color?,
///
chatMessageItemTextColor = json['chatMessageItemTextColor'] as Color?,
///
chatMessageItemFromSelfBgColor =
json['chatMessageItemFromSelfBgColor'] as Color?,
///
chatMessageItemFromOthersBgColor =
json['chatMessageItemFromOthersBgColor'] as Color?,
///
chatMessageItemUnreadStatusTextColor =
json['chatMessageItemUnreadStatusTextColor'] as Color?,
///
chatMessageTongueBgColor = json['chatMessageTongueBgColor'] as Color?,
///
chatMessageTongueTextColor =
json['chatMessageTongueTextColor'] as Color?;
toJson() => <String, dynamic>{
'primaryColor': primaryColor,
'secondaryColor': secondaryColor,
'infoColor': infoColor,
'weakBackgroundColor': weakBackgroundColor,
'wideBackgroundColor': wideBackgroundColor,
'weakDividerColor': weakDividerColor,
'weakTextColor': weakTextColor,
'darkTextColor': darkTextColor,
'lightPrimaryColor': lightPrimaryColor,
'textColor': textColor,
'cautionColor': cautionColor,
'ownerColor': ownerColor,
'adminColor': adminColor,
'white': white,
'black': black,
'inputFillColor': inputFillColor,
'textgrey': textgrey,
"selectPanelBgColor": selectPanelBgColor,
"selectPanelTextIconColor": selectPanelTextIconColor,
"appbarBgColor": appbarBgColor,
"appbarTextColor": appbarTextColor,
///
"conversationItemBgColor": conversationItemBgColor,
///
"conversationItemBorderColor": conversationItemBorderColor,
///
"conversationItemActiveBgColor": conversationItemActiveBgColor,
///
"conversationItemPinedBgColor": conversationItemPinedBgColor,
/// Title字体颜色
"conversationItemTitleTextColor": conversationItemTitleTextColor,
/// LastMessage字体颜色
"conversationItemLastMessageTextColor":
conversationItemLastMessageTextColor,
/// Time字体颜色
"conversationItemTitmeTextColor": conversationItemTitmeTextColor,
/// 线
"conversationItemOnlineStatusBgColor":
conversationItemOnlineStatusBgColor,
/// 线
"conversationItemOfflineStatusBgColor":
conversationItemOfflineStatusBgColor,
///
"conversationItemUnreadCountBgColor":
conversationItemUnreadCountBgColor,
///
"conversationItemUnreadCountTextColor":
conversationItemUnreadCountTextColor,
/// 稿
"conversationItemDraftTextColor": conversationItemDraftTextColor,
/// Icon颜色
"conversationItemNoNotificationIconColor":
conversationItemNoNotificationIconColor,
///
"conversationItemSliderTextColor": conversationItemSliderTextColor,
/// Clear背景颜色
"conversationItemSliderClearBgColor":
conversationItemSliderClearBgColor,
/// Pin背景颜色
"conversationItemSliderPinBgColor": conversationItemSliderPinBgColor,
/// Delete背景颜色
"conversationItemSliderDeleteBgColor":
conversationItemSliderDeleteBgColor,
/// Delete背景颜色
"conversationItemChooseBgColor": conversationItemChooseBgColor,
///
"chatBgColor": chatBgColor,
///
"desktopChatMessageInputBgColor": desktopChatMessageInputBgColor,
///
"chatTimeDividerTextColor": chatTimeDividerTextColor,
///
"chatHeaderBgColor": chatHeaderBgColor,
/// Title字体颜色
"chatHeaderTitleTextColor": chatHeaderTitleTextColor,
/// Back字体颜色
"chatHeaderBackTextColor": chatHeaderBackTextColor,
/// Action字体颜色
"chatHeaderActionTextColor": chatHeaderActionTextColor,
///
"chatMessageItemTextColor": chatMessageItemTextColor,
///
"chatMessageItemFromSelfBgColor": chatMessageItemFromSelfBgColor,
///
"chatMessageItemFromOthersBgColor": chatMessageItemFromOthersBgColor,
///
"chatMessageItemUnreadStatusTextColor":
chatMessageItemUnreadStatusTextColor,
///
"chatMessageTongueBgColor": chatMessageTongueBgColor,
///
"chatMessageTongueTextColor": chatMessageTongueTextColor,
};
MaterialColor createMaterialColor(Color color) {
List strengths = <double>[.05];
Map<int, Color> swatch = <int, Color>{};
final int r = color.red, g = color.green, b = color.blue;
for (int i = 1; i < 10; i++) {
strengths.add(0.1 * i);
}
for (var strength in strengths) {
final double ds = 0.5 - strength;
swatch[(strength * 1000).round()] = Color.fromRGBO(
r + ((ds < 0 ? r : (255 - r)) * ds).round(),
g + ((ds < 0 ? g : (255 - g)) * ds).round(),
b + ((ds < 0 ? b : (255 - b)) * ds).round(),
1,
);
}
return MaterialColor(color.value, swatch);
}
}

View File

@ -0,0 +1,16 @@
import 'package:flutter/material.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
class TUIThemeViewModel extends ChangeNotifier {
TUITheme _theme = CommonColor.defaultTheme;
TUITheme get theme {
return _theme;
}
set theme(TUITheme theme) {
_theme = theme;
notifyListeners();
}
}

View File

@ -2,6 +2,13 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:scroll_to_index/scroll_to_index.dart'; import 'package:scroll_to_index/scroll_to_index.dart';
import 'package:tencent_cloud_chat_sdk/enum/history_msg_get_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_priority_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/offlinePushInfo.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';

View File

@ -1,4 +1,5 @@
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_conversation_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_conversation_view_model.dart';
class TIMUIKitConversationController { class TIMUIKitConversationController {

View File

@ -1,8 +1,11 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_operation_result.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_profile_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_profile_view_model.dart';
import 'package:tencent_cloud_chat_uikit/ui/widgets/text_input_bottom_sheet.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/text_input_bottom_sheet.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class TIMUIKitProfileController { class TIMUIKitProfileController {
late TUIProfileViewModel model; late TUIProfileViewModel model;

View File

@ -1,4 +1,4 @@
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
class ErrorMessageConverter { class ErrorMessageConverter {
static Map<int, String> errorCodeMap = { static Map<int, String> errorCodeMap = {

View File

@ -1,6 +1,4 @@
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
final outputLogger = TencentCloudChatLog(); final outputLogger = TencentCloudChatLog();

View File

@ -2,12 +2,25 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_change_info_type.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_tips_elem_type.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_elem_type.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_change_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_tips_elem.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_image.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
import 'package:tencent_cloud_chat_uikit/ui/constants/history_message_constant.dart'; import 'package:tencent_cloud_chat_uikit/ui/constants/history_message_constant.dart';
import 'package:tencent_cloud_chat_uikit/ui/constants/time.dart'; import 'package:tencent_cloud_chat_uikit/ui/constants/time.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class MessageUtils { class MessageUtils {
// CallingData的方式和Trtc的方法一致 // CallingData的方式和Trtc的方法一致
@ -274,7 +287,7 @@ class MessageUtils {
static Widget wrapMessageTips(Widget child, TUITheme? theme) { static Widget wrapMessageTips(Widget child, TUITheme? theme) {
return Container( return Container(
margin: const EdgeInsets.symmetric(vertical: 10), child: child); margin: const EdgeInsets.symmetric(vertical: 10, horizontal: 30), child: child);
} }
static String getAbstractMessageAsync(V2TimMessage message, static String getAbstractMessageAsync(V2TimMessage message,

View File

@ -7,11 +7,11 @@ import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.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_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class PermissionRequestInfo extends StatefulWidget { class PermissionRequestInfo extends StatefulWidget {
final Function removeOverLay; final Function removeOverLay;

View File

@ -1,7 +1,7 @@
// ignore_for_file: prefer_typing_uninitialized_variables // ignore_for_file: prefer_typing_uninitialized_variables
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
class TimeAgo { class TimeAgo {
List<String> dayMap() { List<String> dayMap() {

View File

@ -1,9 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/friend_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart';
import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/add_friend_life_cycle.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/add_friend_life_cycle.dart';
@ -11,9 +13,9 @@ import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_inf
import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart';
import 'package:tencent_cloud_chat_uikit/data_services/friendShip/friendship_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/friendShip/friendship_services.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitAddFriend/tim_uikit_send_application.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitAddFriend/tim_uikit_send_application.dart';
import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class TIMUIKitAddFriend extends StatefulWidget { class TIMUIKitAddFriend extends StatefulWidget {
final bool? isShowDefaultGroup; final bool? isShowDefaultGroup;

View File

@ -1,4 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/friend_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
@ -6,9 +9,9 @@ import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/add_friend_li
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart';
import 'package:tencent_cloud_chat_uikit/data_services/friendShip/friendship_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/friendShip/friendship_services.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class SendApplication extends StatefulWidget { class SendApplication extends StatefulWidget {
final V2TimUserFullInfo friendInfo; final V2TimUserFullInfo friendInfo;

View File

@ -1,18 +1,22 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_type.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info.dart';
import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart';
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/add_group_life_cycle.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/add_group_life_cycle.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_friendship_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_friendship_view_model.dart';
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';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitAddGroup/tim_uikit_send_application.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitAddGroup/tim_uikit_send_application.dart';
import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
class TIMUIKitAddGroup extends StatefulWidget { class TIMUIKitAddGroup extends StatefulWidget {
/// The life cycle hooks for adding group business logic /// The life cycle hooks for adding group business logic

View File

@ -1,14 +1,18 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_type.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/add_group_life_cycle.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/add_group_life_cycle.dart';
import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.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';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class SendJoinGroupApplication extends StatefulWidget { class SendJoinGroupApplication extends StatefulWidget {
final V2TimGroupInfo groupInfo; final V2TimGroupInfo groupInfo;

View File

@ -1,16 +1,17 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_slidable_plus_plus/flutter_slidable_plus_plus.dart'; import 'package:flutter_slidable_plus_plus/flutter_slidable_plus_plus.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_info.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/block_list_life_cycle.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/block_list_life_cycle.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_friendship_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_friendship_view_model.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.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_base.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme_view_model.dart';
typedef BlackListItemBuilder = Widget Function( typedef BlackListItemBuilder = Widget Function(
BuildContext context, V2TimFriendInfo friendInfo); BuildContext context, V2TimFriendInfo friendInfo);
@ -88,8 +89,7 @@ class _TIMUIKitBlackListState extends TIMUIKitState<TIMUIKitBlackList> {
child: Text( child: Text(
showName, showName,
style: TextStyle( style: TextStyle(
color: theme.black, color: theme.black, fontSize: isDesktopScreen ? 14 : 18),
fontSize: isDesktopScreen ? 14 : 18),
), ),
)), )),
if (isDesktopScreen) if (isDesktopScreen)
@ -133,6 +133,7 @@ class _TIMUIKitBlackListState extends TIMUIKitState<TIMUIKitBlackList> {
return widget.itemBuilder ?? _itemBuilder; return widget.itemBuilder ?? _itemBuilder;
} }
@override @override
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
return MultiProvider( return MultiProvider(

View File

@ -1,6 +1,8 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:scroll_to_index/scroll_to_index.dart'; import 'package:scroll_to_index/scroll_to_index.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_at_info.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_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
@ -8,7 +10,6 @@ import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_glo
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class TIMUIKitHistoryMessageListTongueContainer extends StatefulWidget { class TIMUIKitHistoryMessageListTongueContainer extends StatefulWidget {

View File

@ -1,10 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.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_base.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class TIMUIKitTongueItem extends TIMUIKitStatelessWidget { class TIMUIKitTongueItem extends TIMUIKitStatelessWidget {
/// the callback after clicking /// the callback after clicking

View File

@ -5,6 +5,11 @@ import 'package:flutter/material.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart'; import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:scroll_to_index/scroll_to_index.dart'; import 'package:scroll_to_index/scroll_to_index.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_elem_type.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_at_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.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_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
@ -18,6 +23,7 @@ import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageLi
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/utils.dart';
import 'package:tencent_cloud_chat_uikit/ui/widgets/keepalive_wrapper.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/keepalive_wrapper.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
import 'TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue.dart'; import 'TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue.dart';
import 'TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue_container.dart'; import 'TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue_container.dart';

View File

@ -6,6 +6,13 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart'; import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_elem_type.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_status.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_change_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.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_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
@ -36,6 +43,9 @@ import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart';
import 'package:tencent_super_tooltip/tencent_super_tooltip.dart'; import 'package:tencent_super_tooltip/tencent_super_tooltip.dart';
import 'package:visibility_detector/visibility_detector.dart'; import 'package:visibility_detector/visibility_detector.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme_view_model.dart';
import '../TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_select_emoji.dart'; import '../TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_select_emoji.dart';
typedef MessageRowBuilder = Widget? Function( typedef MessageRowBuilder = Widget? Function(
@ -58,8 +68,7 @@ typedef MessageRowBuilder = Widget? Function(
Function onScrollToIndexBegin, Function onScrollToIndexBegin,
); );
typedef MessageNickNameBuilder = Widget Function( typedef MessageNickNameBuilder = Widget Function(BuildContext context, V2TimMessage message, TUIChatSeparateViewModel model);
BuildContext context, V2TimMessage message, TUIChatSeparateViewModel model);
typedef MessageItemContent = Widget? Function( typedef MessageItemContent = Widget? Function(
V2TimMessage message, V2TimMessage message,
@ -72,8 +81,7 @@ class MessageHoverControlItem {
Widget icon; Widget icon;
ValueChanged<TapDownDetails> onClick; ValueChanged<TapDownDetails> onClick;
MessageHoverControlItem( MessageHoverControlItem({required this.name, required this.icon, required this.onClick});
{required this.name, required this.icon, required this.onClick});
} }
class MessageItemBuilder { class MessageItemBuilder {
@ -141,11 +149,7 @@ class MessageToolTipItem {
final String iconImageAsset; final String iconImageAsset;
final VoidCallback onClick; final VoidCallback onClick;
MessageToolTipItem( MessageToolTipItem({required this.label, required this.id, required this.iconImageAsset, required this.onClick});
{required this.label,
required this.id,
required this.iconImageAsset,
required this.onClick});
} }
class ToolTipsConfig { class ToolTipsConfig {
@ -171,12 +175,10 @@ class ToolTipsConfig {
bool showTranslation; bool showTranslation;
/// A builder for additional custom items. We recommend using `additionalMessageToolTips` instead of this field since version 2.0, as you only need to provide the data rather than the whole widget. This makes usage easier and you don't need to worry about the UI display. /// A builder for additional custom items. We recommend using `additionalMessageToolTips` instead of this field since version 2.0, as you only need to provide the data rather than the whole widget. This makes usage easier and you don't need to worry about the UI display.
final Widget? Function(V2TimMessage message, Function() closeTooltip, final Widget? Function(V2TimMessage message, Function() closeTooltip, [Key? key, BuildContext? context])? additionalItemBuilder;
[Key? key, BuildContext? context])? additionalItemBuilder;
/// A list of additional message tooltip menu items, provided with the data only. We recommend using this field instead of the previous `additionalItemBuilder`. /// A list of additional message tooltip menu items, provided with the data only. We recommend using this field instead of the previous `additionalItemBuilder`.
List<MessageToolTipItem> Function( List<MessageToolTipItem> Function(V2TimMessage message, Function() closeTooltip)? additionalMessageToolTips;
V2TimMessage message, Function() closeTooltip)? additionalMessageToolTips;
ToolTipsConfig( ToolTipsConfig(
{this.showDeleteMessage = true, {this.showDeleteMessage = true,
@ -187,8 +189,7 @@ class ToolTipsConfig {
this.showCopyMessage = true, this.showCopyMessage = true,
this.showForwardMessage = true, this.showForwardMessage = true,
this.additionalMessageToolTips, this.additionalMessageToolTips,
@Deprecated( @Deprecated("Please use `additionalMessageToolTips` instead. You are now only expected to specify the data, rather than providing a whole widget. This makes usage easier, as you no longer need to worry about the UI display.")
"Please use `additionalMessageToolTips` instead. You are now only expected to specify the data, rather than providing a whole widget. This makes usage easier, as you no longer need to worry about the UI display.")
this.additionalItemBuilder}); this.additionalItemBuilder});
} }
@ -197,12 +198,10 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget {
final V2TimMessage message; final V2TimMessage message;
/// tap remote user avatar callback function /// tap remote user avatar callback function
final void Function(String userID, TapDownDetails tapDetails)? final void Function(String userID, TapDownDetails tapDetails)? onTapForOthersPortrait;
onTapForOthersPortrait;
/// secondary tap remote user avatar callback function /// secondary tap remote user avatar callback function
final void Function(String userID, TapDownDetails tapDetails)? final void Function(String userID, TapDownDetails tapDetails)? onSecondaryTapForOthersPortrait;
onSecondaryTapForOthersPortrait;
/// the function use for reply message, when click replied message can scroll to it. /// the function use for reply message, when click replied message can scroll to it.
final Function? onScrollToIndex; final Function? onScrollToIndex;
@ -211,8 +210,7 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget {
final Function? onScrollToIndexBegin; final Function? onScrollToIndexBegin;
/// the callback for long press event, except myself avatar /// the callback for long press event, except myself avatar
final Function(String? userId, String? nickName)? final Function(String? userId, String? nickName)? onLongPressForOthersHeadPortrait;
onLongPressForOthersHeadPortrait;
/// message item builder, works for customize all message types and row layout. /// message item builder, works for customize all message types and row layout.
final MessageItemBuilder? messageItemBuilder; final MessageItemBuilder? messageItemBuilder;
@ -232,8 +230,7 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget {
/// Auto mention user when send reply message /// Auto mention user when send reply message
final bool allowAtUserWhenReply; final bool allowAtUserWhenReply;
@Deprecated( @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")
"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")
/// allow show user nick name /// allow show user nick name
final bool showNickName; final bool showNickName;
@ -254,19 +251,16 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget {
final EdgeInsetsGeometry? textPadding; final EdgeInsetsGeometry? textPadding;
/// avatar builder /// avatar builder
final Widget Function(BuildContext context, V2TimMessage message)? final Widget Function(BuildContext context, V2TimMessage message)? userAvatarBuilder;
userAvatarBuilder;
/// theme info for message and avatar /// theme info for message and avatar
final MessageThemeData? themeData; final MessageThemeData? themeData;
/// builder for nick name row /// builder for nick name row
final Widget Function(BuildContext context, V2TimMessage message)? final Widget Function(BuildContext context, V2TimMessage message)? topRowBuilder;
topRowBuilder;
/// builder for bottom raw which under message content /// builder for bottom raw which under message content
final Widget Function(BuildContext context, V2TimMessage message)? final Widget Function(BuildContext context, V2TimMessage message)? bottomRowBuilder;
bottomRowBuilder;
// open MessageReaction // open MessageReaction
final bool? isUseMessageReaction; final bool? isUseMessageReaction;
@ -284,9 +278,7 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget {
const TIMUIKitHistoryMessageListItem( const TIMUIKitHistoryMessageListItem(
{Key? key, {Key? key,
required this.message, required this.message,
@Deprecated( @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,
"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.onScrollToIndex, this.onScrollToIndex,
this.onScrollToIndexBegin, this.onScrollToIndexBegin,
this.onTapForOthersPortrait, this.onTapForOthersPortrait,
@ -322,9 +314,7 @@ class TipsActionItem extends TIMUIKitStatelessWidget {
final String icon; final String icon;
final String? package; final String? package;
TipsActionItem( TipsActionItem({Key? key, required this.label, required this.icon, this.package}) : super(key: key);
{Key? key, required this.label, required this.icon, this.package})
: super(key: key);
@override @override
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
@ -352,16 +342,13 @@ class TipsActionItem extends TIMUIKitStatelessWidget {
} }
} }
class _TIMUIKItHistoryMessageListItemState class _TIMUIKItHistoryMessageListItemState extends TIMUIKitState<TIMUIKitHistoryMessageListItem> with SingleTickerProviderStateMixin {
extends TIMUIKitState<TIMUIKitHistoryMessageListItem>
with SingleTickerProviderStateMixin {
SuperTooltip? tooltip; SuperTooltip? tooltip;
late AnimationController _animationController; late AnimationController _animationController;
// ignore: unused_field // ignore: unused_field
final MessageService _messageService = serviceLocator<MessageService>(); final MessageService _messageService = serviceLocator<MessageService>();
final TUISelfInfoViewModel selfInfoModel = final TUISelfInfoViewModel selfInfoModel = serviceLocator<TUISelfInfoViewModel>();
serviceLocator<TUISelfInfoViewModel>();
final TUIThemeViewModel themeModel = serviceLocator<TUIThemeViewModel>(); final TUIThemeViewModel themeModel = serviceLocator<TUIThemeViewModel>();
// bool isChecked = false; // bool isChecked = false;
@ -372,9 +359,7 @@ class _TIMUIKItHistoryMessageListItemState
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_animationController = _animationController = AnimationController(duration: const Duration(seconds: 1), vsync: this)..repeat();
AnimationController(duration: const Duration(seconds: 1), vsync: this)
..repeat();
} }
closeTooltip() { closeTooltip() {
@ -382,15 +367,10 @@ class _TIMUIKItHistoryMessageListItemState
} }
bool isReplyMessage(V2TimMessage message) { bool isReplyMessage(V2TimMessage message) {
final hasCustomData = final hasCustomData = message.cloudCustomData != null && message.cloudCustomData != "";
message.cloudCustomData != null && message.cloudCustomData != "";
if (hasCustomData) { if (hasCustomData) {
try { try {
final CloudCustomData messageCloudCustomData = CloudCustomData.fromJson( final CloudCustomData messageCloudCustomData = CloudCustomData.fromJson(json.decode(TencentUtils.checkString(message.cloudCustomData) != null ? message.cloudCustomData! : "{}"));
json.decode(
TencentUtils.checkString(message.cloudCustomData) != null
? message.cloudCustomData!
: "{}"));
if (messageCloudCustomData.messageReply != null) { if (messageCloudCustomData.messageReply != null) {
MessageRepliedData.fromJson(messageCloudCustomData.messageReply!); MessageRepliedData.fromJson(messageCloudCustomData.messageReply!);
return true; return true;
@ -403,8 +383,7 @@ class _TIMUIKItHistoryMessageListItemState
return false; return false;
} }
(bool isRevoke, bool isRevokeByAdmin) isRevokeMessage( (bool isRevoke, bool isRevokeByAdmin) isRevokeMessage(V2TimMessage message, TUIChatSeparateViewModel model) {
V2TimMessage message, TUIChatSeparateViewModel model) {
if (message.status == 6) { if (message.status == 6) {
return (true, false); return (true, false);
} else if (model.chatConfig.isGroupAdminRecallEnabled) { } else if (model.chatConfig.isGroupAdminRecallEnabled) {
@ -420,11 +399,9 @@ class _TIMUIKItHistoryMessageListItemState
return (false, false); return (false, false);
} }
Widget _messageItemBuilder( Widget _messageItemBuilder(V2TimMessage messageItem, TUIChatSeparateViewModel model) {
V2TimMessage messageItem, TUIChatSeparateViewModel model) {
final msgType = messageItem.elemType; final msgType = messageItem.elemType;
final isShowJump = (model.jumpMsgID == messageItem.msgID) && final isShowJump = (model.jumpMsgID == messageItem.msgID) && (messageItem.msgID?.isNotEmpty ?? false);
(messageItem.msgID?.isNotEmpty ?? false);
final MessageItemBuilder? messageItemBuilder = widget.messageItemBuilder; final MessageItemBuilder? messageItemBuilder = widget.messageItemBuilder;
final isFromSelf = messageItem.isSelf ?? true; final isFromSelf = messageItem.isSelf ?? true;
void clearJump() { void clearJump() {
@ -435,8 +412,7 @@ class _TIMUIKItHistoryMessageListItemState
switch (msgType) { switch (msgType) {
case MessageElemType.V2TIM_ELEM_TYPE_CUSTOM: case MessageElemType.V2TIM_ELEM_TYPE_CUSTOM:
final customWidget = final customWidget = messageItemBuilder?.customMessageItemBuilder != null
messageItemBuilder?.customMessageItemBuilder != null
? messageItemBuilder!.customMessageItemBuilder!( ? messageItemBuilder!.customMessageItemBuilder!(
messageItem, messageItem,
isShowJump, isShowJump,
@ -480,8 +456,7 @@ class _TIMUIKItHistoryMessageListItemState
); );
case MessageElemType.V2TIM_ELEM_TYPE_TEXT: case MessageElemType.V2TIM_ELEM_TYPE_TEXT:
if (isReplyMessage(messageItem)) { if (isReplyMessage(messageItem)) {
final customWidget = final customWidget = messageItemBuilder?.textReplyMessageItemBuilder != null
messageItemBuilder?.textReplyMessageItemBuilder != null
? messageItemBuilder!.textReplyMessageItemBuilder!( ? messageItemBuilder!.textReplyMessageItemBuilder!(
messageItem, messageItem,
isShowJump, isShowJump,
@ -561,8 +536,7 @@ class _TIMUIKItHistoryMessageListItemState
isShowMessageReaction: widget.isUseMessageReaction, isShowMessageReaction: widget.isUseMessageReaction,
); );
case MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS: case MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS:
final customWidget = final customWidget = messageItemBuilder?.groupTipsMessageItemBuilder != null
messageItemBuilder?.groupTipsMessageItemBuilder != null
? messageItemBuilder!.groupTipsMessageItemBuilder!( ? messageItemBuilder!.groupTipsMessageItemBuilder!(
messageItem, messageItem,
isShowJump, isShowJump,
@ -604,8 +578,7 @@ class _TIMUIKItHistoryMessageListItemState
isShowMessageReaction: widget.isUseMessageReaction, isShowMessageReaction: widget.isUseMessageReaction,
); );
case MessageElemType.V2TIM_ELEM_TYPE_LOCATION: case MessageElemType.V2TIM_ELEM_TYPE_LOCATION:
final customWidget = final customWidget = messageItemBuilder?.locationMessageItemBuilder != null
messageItemBuilder?.locationMessageItemBuilder != null
? messageItemBuilder!.locationMessageItemBuilder!( ? messageItemBuilder!.locationMessageItemBuilder!(
messageItem, messageItem,
isShowJump, isShowJump,
@ -614,8 +587,7 @@ class _TIMUIKItHistoryMessageListItemState
: null; : null;
return customWidget ?? Text(TIM_t("[位置]")); return customWidget ?? Text(TIM_t("[位置]"));
case MessageElemType.V2TIM_ELEM_TYPE_MERGER: case MessageElemType.V2TIM_ELEM_TYPE_MERGER:
final customWidget = final customWidget = messageItemBuilder?.mergerMessageItemBuilder != null
messageItemBuilder?.mergerMessageItemBuilder != null
? messageItemBuilder!.mergerMessageItemBuilder!( ? messageItemBuilder!.mergerMessageItemBuilder!(
messageItem, messageItem,
isShowJump, isShowJump,
@ -640,11 +612,7 @@ class _TIMUIKItHistoryMessageListItemState
Widget _groupTipsMessageBuilder(TUIChatSeparateViewModel model) { Widget _groupTipsMessageBuilder(TUIChatSeparateViewModel model) {
final messageItem = widget.message; final messageItem = widget.message;
return Container( return Container(padding: const EdgeInsets.only(bottom: 20), child: TIMUIKitGroupTipsElem(groupTipsElem: messageItem.groupTipsElem!, groupMemberList: model.groupMemberList ?? []));
padding: const EdgeInsets.only(bottom: 20),
child: TIMUIKitGroupTipsElem(
groupTipsElem: messageItem.groupTipsElem!,
groupMemberList: model.groupMemberList ?? []));
} }
Widget _selfRevokeEditMessageBuilder(theme, TUIChatSeparateViewModel model) { Widget _selfRevokeEditMessageBuilder(theme, TUIChatSeparateViewModel model) {
@ -660,8 +628,7 @@ class _TIMUIKItHistoryMessageListItemState
text: TIM_t("重新编辑"), text: TIM_t("重新编辑"),
recognizer: TapGestureRecognizer() recognizer: TapGestureRecognizer()
..onTap = () { ..onTap = () {
widget.textFieldController widget.textFieldController?.setTextField(widget.message.textElem?.text ?? "");
?.setTextField(widget.message.textElem?.text ?? "");
}, },
style: TextStyle(color: theme.primaryColor), style: TextStyle(color: theme.primaryColor),
) )
@ -678,15 +645,12 @@ class _TIMUIKItHistoryMessageListItemState
)); ));
} }
Widget _timeDividerBuilder( Widget _timeDividerBuilder(theme, int timeStamp, TUIChatSeparateViewModel model) {
theme, int timeStamp, TUIChatSeparateViewModel model) {
return Container( return Container(
alignment: Alignment.center, alignment: Alignment.center,
margin: const EdgeInsets.symmetric(vertical: 20), margin: const EdgeInsets.symmetric(vertical: 20),
child: Text( child: Text(
model.chatConfig.timeDividerConfig?.timestampParser != null model.chatConfig.timeDividerConfig?.timestampParser != null ? (model.chatConfig.timeDividerConfig?.timestampParser!(timeStamp))! : TimeAgo().getTimeForMessage(timeStamp),
? (model.chatConfig.timeDividerConfig?.timestampParser!(timeStamp))!
: TimeAgo().getTimeForMessage(timeStamp),
style: widget.themeData?.timelineTextStyle ?? style: widget.themeData?.timelineTextStyle ??
TextStyle( TextStyle(
fontSize: 12, fontSize: 12,
@ -710,10 +674,7 @@ class _TIMUIKItHistoryMessageListItemState
width: 100, width: 100,
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient(colors: [ gradient: LinearGradient(colors: [const Color(0x00C0E1FF), theme.primaryColor ?? CommonColor.lightPrimaryColor]),
const Color(0x00C0E1FF),
theme.primaryColor ?? CommonColor.lightPrimaryColor
]),
)), )),
), ),
), ),
@ -745,8 +706,7 @@ class _TIMUIKItHistoryMessageListItemState
); );
} }
bool isRevocable(int timestamp) => bool isRevocable(int timestamp) => (DateTime.now().millisecondsSinceEpoch / 1000).ceil() - timestamp < 120;
(DateTime.now().millisecondsSinceEpoch / 1000).ceil() - timestamp < 120;
// TODO : // TODO :
@ -767,38 +727,21 @@ class _TIMUIKItHistoryMessageListItemState
final screenHeight = MediaQuery.of(context).size.height; final screenHeight = MediaQuery.of(context).size.height;
final screenWidth = MediaQuery.of(context).size.width; final screenWidth = MediaQuery.of(context).size.width;
final isDesktopScreen = final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; final isLongMessage = context.size!.height + 350 > screenHeight && !(isDesktopScreen);
final isLongMessage = final tapDetails = (isDesktopScreen || isLongMessage) ? (details ?? _tapDetails) : details;
context.size!.height + 350 > screenHeight && !(isDesktopScreen);
final tapDetails =
(isDesktopScreen || isLongMessage) ? (details ?? _tapDetails) : details;
final isSelf = message.isSelf ?? true; final isSelf = message.isSelf ?? true;
final targetWidth = final targetWidth = min(MediaQuery.of(context).size.width * 0.84, 350).toDouble();
min(MediaQuery.of(context).size.width * 0.84, 350).toDouble(); final double dx = !isSelf ? min(tapDetails?.globalPosition.dx ?? targetWidth, screenWidth - targetWidth) : max(tapDetails?.globalPosition.dx ?? targetWidth, targetWidth).toDouble();
final double dx = !isSelf final double dy = min(tapDetails?.globalPosition.dy ?? MediaQuery.of(context).size.height, MediaQuery.of(context).size.height - 320).toDouble();
? min(tapDetails?.globalPosition.dx ?? targetWidth,
screenWidth - targetWidth)
: max(tapDetails?.globalPosition.dx ?? targetWidth, targetWidth)
.toDouble();
final double dy = min(
tapDetails?.globalPosition.dy ?? MediaQuery.of(context).size.height,
MediaQuery.of(context).size.height - 320)
.toDouble();
final finalTapDetail = tapDetails != null final finalTapDetail = tapDetails != null
? TapDownDetails( ? TapDownDetails(
globalPosition: Offset(dx, dy), globalPosition: Offset(dx, dy),
) )
: null; : null;
initTools( initTools(context: c, model: model, isShowMoreSticker: isShowMoreSticker, details: finalTapDetail, theme: theme, isFromWideToolTip: isFromWideTooltip);
context: c,
model: model,
isShowMoreSticker: isShowMoreSticker,
details: finalTapDetail,
theme: theme,
isFromWideToolTip: isFromWideTooltip);
tooltip!.show(c, targetCenter: finalTapDetail?.globalPosition); tooltip!.show(c, targetCenter: finalTapDetail?.globalPosition);
} }
@ -811,26 +754,15 @@ class _TIMUIKItHistoryMessageListItemState
} }
} }
Future<V2TimValueCallback<V2TimMessageChangeInfo>> _modifySticker( Future<V2TimValueCallback<V2TimMessageChangeInfo>> _modifySticker(int sticker) async {
int sticker) async {
return await Future.delayed(const Duration(milliseconds: 50), () async { return await Future.delayed(const Duration(milliseconds: 50), () async {
return await MessageReactionUtils.clickOnSticker(widget.message, sticker); return await MessageReactionUtils.clickOnSticker(widget.message, sticker);
}); });
} }
initTools( initTools({BuildContext? context, bool isLongMessage = false, required TUIChatSeparateViewModel model, TUITheme? theme, bool? isShowMoreSticker, TapDownDetails? details, bool? isFromWideToolTip}) {
{BuildContext? context, final isUseMessageReaction = widget.message.elemType == 2 ? false : model.chatConfig.isUseMessageReaction;
bool isLongMessage = false, final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
required TUIChatSeparateViewModel model,
TUITheme? theme,
bool? isShowMoreSticker,
TapDownDetails? details,
bool? isFromWideToolTip}) {
final isUseMessageReaction = widget.message.elemType == 2
? false
: model.chatConfig.isUseMessageReaction;
final isDesktopScreen =
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
final isSelf = widget.message.isSelf ?? true; final isSelf = widget.message.isSelf ?? true;
double arrowTipDistance = 30; double arrowTipDistance = 30;
double arrowBaseWidth = 10; double arrowBaseWidth = 10;
@ -839,8 +771,7 @@ class _TIMUIKItHistoryMessageListItemState
TooltipDirection popupDirection = TooltipDirection.up; TooltipDirection popupDirection = TooltipDirection.up;
double? left; double? left;
double? right; double? right;
SelectEmojiPanelPosition selectEmojiPanelPosition = SelectEmojiPanelPosition selectEmojiPanelPosition = SelectEmojiPanelPosition.down;
SelectEmojiPanelPosition.down;
if (context != null) { if (context != null) {
RenderBox? box = _key.currentContext?.findRenderObject() as RenderBox?; RenderBox? box = _key.currentContext?.findRenderObject() as RenderBox?;
if (details != null && box != null) { if (details != null && box != null) {
@ -863,9 +794,7 @@ class _TIMUIKItHistoryMessageListItemState
Offset offset = box.localToGlobal(Offset.zero); Offset offset = box.localToGlobal(Offset.zero);
double boxWidth = box.size.width; double boxWidth = box.size.width;
if (isSelf) { if (isSelf) {
right = screenWidth - right = screenWidth - offset.dx - ((isUseMessageReaction) ? boxWidth : (boxWidth / 1.3));
offset.dx -
((isUseMessageReaction) ? boxWidth : (boxWidth / 1.3));
} else { } else {
left = offset.dx; left = offset.dx;
} }
@ -877,8 +806,7 @@ class _TIMUIKItHistoryMessageListItemState
popupDirection = TooltipDirection.down; popupDirection = TooltipDirection.down;
} }
} }
arrowTipDistance = (context.size!.height / 2).roundToDouble() + arrowTipDistance = (context.size!.height / 2).roundToDouble() + (isLongMessage ? -120 : 10);
(isLongMessage ? -120 : 10);
} }
} }
@ -918,8 +846,7 @@ class _TIMUIKItHistoryMessageListItemState
showCloseButton: ShowCloseButton.none, showCloseButton: ShowCloseButton.none,
touchThroughAreaShape: ClipAreaShape.rectangle, touchThroughAreaShape: ClipAreaShape.rectangle,
content: TIMUIKitMessageTooltip( content: TIMUIKitMessageTooltip(
iSUseDefaultHoverBar: model.chatConfig.isUseMessageHoverBarOnDesktop && iSUseDefaultHoverBar: model.chatConfig.isUseMessageHoverBarOnDesktop && widget.customMessageHoverBarOnDesktop == null,
widget.customMessageHoverBarOnDesktop == null,
model: model, model: model,
groupMemberInfo: widget.groupMemberInfo, groupMemberInfo: widget.groupMemberInfo,
isShowMoreSticker: isShowMoreSticker ?? false, isShowMoreSticker: isShowMoreSticker ?? false,
@ -927,8 +854,7 @@ class _TIMUIKItHistoryMessageListItemState
isUseMessageReaction: isUseMessageReaction, isUseMessageReaction: isUseMessageReaction,
message: widget.message, message: widget.message,
allowAtUserWhenReply: widget.allowAtUserWhenReply, allowAtUserWhenReply: widget.allowAtUserWhenReply,
onLongPressForOthersHeadPortrait: onLongPressForOthersHeadPortrait: widget.onLongPressForOthersHeadPortrait,
widget.onLongPressForOthersHeadPortrait,
selectEmojiPanelPosition: selectEmojiPanelPosition, selectEmojiPanelPosition: selectEmojiPanelPosition,
onCloseTooltip: () => tooltip?.close(), onCloseTooltip: () => tooltip?.close(),
onSelectSticker: (int value) { onSelectSticker: (int value) {
@ -939,8 +865,7 @@ class _TIMUIKItHistoryMessageListItemState
); );
} }
Widget _getMessageItemBuilder(V2TimMessage message, int? messageStatues, Widget _getMessageItemBuilder(V2TimMessage message, int? messageStatues, TUIChatSeparateViewModel model) {
TUIChatSeparateViewModel model) {
final messageBuilder = _messageItemBuilder; final messageBuilder = _messageItemBuilder;
return messageBuilder(widget.message, model); return messageBuilder(widget.message, model);
@ -982,8 +907,7 @@ class _TIMUIKItHistoryMessageListItemState
} }
} }
List<MessageHoverControlItem> getWideMessageHoverControlBar( List<MessageHoverControlItem> getWideMessageHoverControlBar(TUIChatSeparateViewModel model, TUITheme theme) {
TUIChatSeparateViewModel model, TUITheme theme) {
return [ return [
if (widget.isUseMessageReaction ?? false) if (widget.isUseMessageReaction ?? false)
MessageHoverControlItem( MessageHoverControlItem(
@ -994,8 +918,7 @@ class _TIMUIKItHistoryMessageListItemState
color: hexToColor("8f959e"), color: hexToColor("8f959e"),
), ),
onClick: (details) { onClick: (details) {
_onOpenToolTip( _onOpenToolTip(context, widget.message, model, theme, details, true, true);
context, widget.message, model, theme, details, true, true);
}, },
), ),
if (widget.toolTipsConfig?.showReplyMessage ?? true) if (widget.toolTipsConfig?.showReplyMessage ?? true)
@ -1009,21 +932,14 @@ class _TIMUIKItHistoryMessageListItemState
onClick: (_) { onClick: (_) {
model.repliedMessage = widget.message; model.repliedMessage = widget.message;
final isSelf = widget.message.isSelf ?? true; final isSelf = widget.message.isSelf ?? true;
final isGroup = final isGroup = TencentUtils.checkString(widget.message.groupID) != null;
TencentUtils.checkString(widget.message.groupID) != null; final isAtWhenReply = !isSelf && isGroup && widget.allowAtUserWhenReply && widget.onLongPressForOthersHeadPortrait != null;
final isAtWhenReply = !isSelf &&
isGroup &&
widget.allowAtUserWhenReply &&
widget.onLongPressForOthersHeadPortrait != null;
/// If replying to a self message, do not add a at tag, only requestFocus. /// If replying to a self message, do not add a at tag, only requestFocus.
widget.onLongPressForOthersHeadPortrait!( widget.onLongPressForOthersHeadPortrait!(!isAtWhenReply ? null : widget.message.sender, !isAtWhenReply ? null : widget.message.nickName);
!isAtWhenReply ? null : widget.message.sender,
!isAtWhenReply ? null : widget.message.nickName);
}, },
), ),
if ((widget.toolTipsConfig?.showForwardMessage ?? true) && if ((widget.toolTipsConfig?.showForwardMessage ?? true) && !model.isVoteMessage(widget.message))
!model.isVoteMessage(widget.message))
MessageHoverControlItem( MessageHoverControlItem(
name: TIM_t("转发"), name: TIM_t("转发"),
icon: Icon( icon: Icon(
@ -1063,8 +979,7 @@ class _TIMUIKItHistoryMessageListItemState
color: hexToColor("8f959e"), color: hexToColor("8f959e"),
), ),
onClick: (details) { onClick: (details) {
_onOpenToolTip( _onOpenToolTip(context, widget.message, model, theme, details, true, false);
context, widget.message, model, theme, details, true, false);
}, },
), ),
...?model.chatConfig.additionalDesktopMessageHoverBarItem ...?model.chatConfig.additionalDesktopMessageHoverBarItem
@ -1074,37 +989,18 @@ class _TIMUIKItHistoryMessageListItemState
_onMsgSendFailIconTap(V2TimMessage message, TUIChatSeparateViewModel model) { _onMsgSendFailIconTap(V2TimMessage message, TUIChatSeparateViewModel model) {
final convID = model.conversationID; final convID = model.conversationID;
final convType = model.conversationType; final convType = model.conversationType;
MessageUtils.handleMessageError( MessageUtils.handleMessageError(model.reSendFailMessage(message: message, convType: convType ?? ConvType.c2c, convID: convID), context);
model.reSendFailMessage(
message: message,
convType: convType ?? ConvType.c2c,
convID: convID),
context);
} }
Widget renderHoverTipAndReadStatus( Widget renderHoverTipAndReadStatus(TUIChatSeparateViewModel model, bool isSelf, V2TimMessage message, bool isPeerRead, TUITheme theme, bool isDownloadWaiting) {
TUIChatSeparateViewModel model, final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
bool isSelf, final customHoverBar = widget.customMessageHoverBarOnDesktop != null ? widget.customMessageHoverBarOnDesktop!(message) : null;
V2TimMessage message, final wideHoverTipList = (model.chatConfig.isUseMessageHoverBarOnDesktop && customHoverBar == null) ? getWideMessageHoverControlBar(model, theme) : [];
bool isPeerRead, final lastItemName = wideHoverTipList.isNotEmpty ? wideHoverTipList.last.name : "";
TUITheme theme,
bool isDownloadWaiting) {
final isDesktopScreen =
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
final customHoverBar = widget.customMessageHoverBarOnDesktop != null
? widget.customMessageHoverBarOnDesktop!(message)
: null;
final wideHoverTipList = (model.chatConfig.isUseMessageHoverBarOnDesktop &&
customHoverBar == null)
? getWideMessageHoverControlBar(model, theme)
: [];
final lastItemName =
wideHoverTipList.isNotEmpty ? wideHoverTipList.last.name : "";
// 1 // 1
Future<void> _conditionalDelay() async { Future<void> _conditionalDelay() async {
if (!(model.hasDelayedRenderSendingStatus(message.id ?? message.msgID!) ?? if (!(model.hasDelayedRenderSendingStatus(message.id ?? message.msgID!) ?? true)) {
true)) {
model.setDelayedRenderSendingStatus(message.id ?? message.msgID!); model.setDelayedRenderSendingStatus(message.id ?? message.msgID!);
await Future.delayed(const Duration(seconds: 1)); await Future.delayed(const Duration(seconds: 1));
} }
@ -1115,14 +1011,9 @@ class _TIMUIKItHistoryMessageListItemState
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
if (isDesktopScreen && if (isDesktopScreen && isShowWideToolTip && customHoverBar == null && !((widget.message.elemType == 6 && isDownloadWaiting)))
isShowWideToolTip &&
customHoverBar == null &&
!((widget.message.elemType == 6 && isDownloadWaiting)))
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(borderRadius: BorderRadius.circular(4), border: Border.all(color: hexToColor("d9dde0"), width: 1)),
borderRadius: BorderRadius.circular(4),
border: Border.all(color: hexToColor("d9dde0"), width: 1)),
margin: const EdgeInsets.symmetric(horizontal: 4), margin: const EdgeInsets.symmetric(horizontal: 4),
child: Row( child: Row(
children: wideHoverTipList children: wideHoverTipList
@ -1154,17 +1045,12 @@ class _TIMUIKItHistoryMessageListItemState
.toList(), .toList(),
), ),
), ),
if (isDesktopScreen && isShowWideToolTip && customHoverBar != null) if (isDesktopScreen && isShowWideToolTip && customHoverBar != null) customHoverBar,
customHoverBar, if (!isDesktopScreen || (model.chatConfig.isUseMessageHoverBarOnDesktop && customHoverBar == null && !isShowWideToolTip))
if (!isDesktopScreen ||
(model.chatConfig.isUseMessageHoverBarOnDesktop &&
customHoverBar == null &&
!isShowWideToolTip))
const SizedBox( const SizedBox(
height: 20, height: 20,
), ),
if (isSelf && if (isSelf && message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_FAIL)
message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_FAIL)
Container( Container(
padding: const EdgeInsets.only(bottom: 3), padding: const EdgeInsets.only(bottom: 3),
margin: const EdgeInsets.only(right: 6), margin: const EdgeInsets.only(right: 6),
@ -1195,8 +1081,7 @@ class _TIMUIKItHistoryMessageListItemState
}, },
), ),
if (model.chatConfig.isShowReadingStatus && if (model.chatConfig.isShowReadingStatus &&
isSelf && isSelf && message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC &&
message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC &&
(message.needReadReceipt ?? false) && (message.needReadReceipt ?? false) &&
!model.isVoteMessage(widget.message)) !model.isVoteMessage(widget.message))
TIMUIKitMessageReadReceipt( TIMUIKitMessageReadReceipt(
@ -1209,16 +1094,13 @@ class _TIMUIKItHistoryMessageListItemState
@override @override
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
final TUIChatSeparateViewModel model = final TUIChatSeparateViewModel model = Provider.of<TUIChatSeparateViewModel>(context);
Provider.of<TUIChatSeparateViewModel>(context); final isDownloadWaiting = context.select<TUIChatGlobalModel, bool>((value) => value.isWaiting(widget.message.msgID ?? ""));
final isDownloadWaiting = context.select<TUIChatGlobalModel, bool>(
(value) => value.isWaiting(widget.message.msgID ?? ""));
final TUITheme theme = value.theme; final TUITheme theme = value.theme;
final message = widget.message; final message = widget.message;
final msgType = message.elemType; final msgType = message.elemType;
final isSelf = message.isSelf ?? true; final isSelf = message.isSelf ?? true;
final isGroupTipsMsg = final isGroupTipsMsg = msgType == MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS;
msgType == MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS;
final revokeStatus = isRevokeMessage(message, model); final revokeStatus = isRevokeMessage(message, model);
final isRevokedMsg = revokeStatus.$1; final isRevokedMsg = revokeStatus.$1;
@ -1228,14 +1110,10 @@ class _TIMUIKItHistoryMessageListItemState
final isLatestDivider = msgType == 101; final isLatestDivider = msgType == 101;
final isPeerRead = message.isPeerRead ?? false; final isPeerRead = message.isPeerRead ?? false;
final isGroupMessage = model.conversationType == ConvType.group; final isGroupMessage = model.conversationType == ConvType.group;
final bool isRevokeEditable = final bool isRevokeEditable = widget.message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT;
widget.message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT; final isShowNickNameForSelf = isGroupMessage && model.chatConfig.isShowSelfNameInGroup;
final isShowNickNameForSelf = final isShowNickNameForOthers = isGroupMessage && model.chatConfig.isShowOthersNameInGroup;
isGroupMessage && model.chatConfig.isShowSelfNameInGroup; final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
final isShowNickNameForOthers =
isGroupMessage && model.chatConfig.isShowOthersNameInGroup;
final isDesktopScreen =
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
if (isTimeDivider) { if (isTimeDivider) {
return _timeDividerBuilder(theme, message.timestamp ?? 0, model); return _timeDividerBuilder(theme, message.timestamp ?? 0, model);
} }
@ -1250,8 +1128,7 @@ class _TIMUIKItHistoryMessageListItemState
if (isGroupTipsMsg) { if (isGroupTipsMsg) {
if (widget.messageItemBuilder?.groupTipsMessageItemBuilder != null) { if (widget.messageItemBuilder?.groupTipsMessageItemBuilder != null) {
final groupTipsMessage = final groupTipsMessage = widget.messageItemBuilder!.groupTipsMessageItemBuilder!(
widget.messageItemBuilder!.groupTipsMessageItemBuilder!(
message, message,
(model.jumpMsgID == message.msgID), (model.jumpMsgID == message.msgID),
clearJump, clearJump,
@ -1262,16 +1139,8 @@ class _TIMUIKItHistoryMessageListItemState
} }
if (isRevokedMsg) { if (isRevokedMsg) {
final displayName = isAdminRevoke final displayName = isAdminRevoke ? TIM_t("管理员") : (isSelf ? TIM_t("") : TencentUtils.checkString(message.nickName) ?? TencentUtils.checkString(message.sender) ?? message.userID);
? TIM_t("管理员") return isSelf && isRevokeEditable && isRevocable(message.timestamp!) ? _selfRevokeEditMessageBuilder(theme, model) : _revokedMessageBuilder(theme, displayName ?? "");
: (isSelf
? TIM_t("")
: TencentUtils.checkString(message.nickName) ??
TencentUtils.checkString(message.sender) ??
message.userID);
return isSelf && isRevokeEditable && isRevocable(message.timestamp!)
? _selfRevokeEditMessageBuilder(theme, model)
: _revokedMessageBuilder(theme, displayName ?? "");
} }
// 使 // 使
@ -1300,8 +1169,7 @@ class _TIMUIKItHistoryMessageListItemState
}, },
child: LayoutBuilder( child: LayoutBuilder(
builder: (context, constraints) => Container( builder: (context, constraints) => Container(
padding: padding: EdgeInsets.only(left: isSelf ? 0 : 16, right: isSelf ? 16 : 0),
EdgeInsets.only(left: isSelf ? 0 : 16, right: isSelf ? 16 : 0),
margin: widget.padding ?? const EdgeInsets.only(bottom: 20), margin: widget.padding ?? const EdgeInsets.only(bottom: 20),
child: Row( child: Row(
key: _key, key: _key,
@ -1310,8 +1178,7 @@ class _TIMUIKItHistoryMessageListItemState
children: [ children: [
if (model.isMultiSelect) if (model.isMultiSelect)
Container( Container(
margin: EdgeInsets.only( margin: EdgeInsets.only(right: 12, top: 10, left: isSelf ? 16 : 0),
right: 12, top: 10, left: isSelf ? 16 : 0),
child: CheckBoxButton( child: CheckBoxButton(
isChecked: model.getSelectedMessageList().contains(message), isChecked: model.getSelectedMessageList().contains(message),
onChanged: (value) { onChanged: (value) {
@ -1322,16 +1189,14 @@ class _TIMUIKItHistoryMessageListItemState
Expanded( Expanded(
child: MouseRegion( child: MouseRegion(
onEnter: (_) { onEnter: (_) {
if (isDesktopScreen && if (isDesktopScreen && model.chatConfig.isUseMessageHoverBarOnDesktop) {
model.chatConfig.isUseMessageHoverBarOnDesktop) {
setState(() { setState(() {
isShowWideToolTip = true; isShowWideToolTip = true;
}); });
} }
}, },
onExit: (_) { onExit: (_) {
if (isDesktopScreen && if (isDesktopScreen && model.chatConfig.isUseMessageHoverBarOnDesktop) {
model.chatConfig.isUseMessageHoverBarOnDesktop) {
Tooltip.dismissAllToolTips(); Tooltip.dismissAllToolTips();
Future.delayed(const Duration(milliseconds: 100), () { Future.delayed(const Duration(milliseconds: 100), () {
setState(() { setState(() {
@ -1341,13 +1206,10 @@ class _TIMUIKItHistoryMessageListItemState
} }
}, },
child: GestureDetector( child: GestureDetector(
behavior: model.isMultiSelect behavior: model.isMultiSelect ? HitTestBehavior.translucent : null,
? HitTestBehavior.translucent
: null,
onTap: () { onTap: () {
if (model.isMultiSelect) { if (model.isMultiSelect) {
final checked = final checked = model.getSelectedMessageList().contains(message);
model.getSelectedMessageList().contains(message);
model.setMessageItemChecked(message, !checked); model.setMessageItemChecked(message, !checked);
} else { } else {
return; return;
@ -1355,81 +1217,59 @@ class _TIMUIKItHistoryMessageListItemState
}, },
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: isSelf mainAxisAlignment: isSelf ? MainAxisAlignment.end : MainAxisAlignment.start,
? MainAxisAlignment.end
: MainAxisAlignment.start,
children: [ children: [
if (!isSelf && widget.showAvatar) if (!isSelf && widget.showAvatar)
GestureDetector( GestureDetector(
onLongPress: () { onLongPress: () {
if (widget.onLongPressForOthersHeadPortrait != if (widget.onLongPressForOthersHeadPortrait != null) {}
null) {}
if (model.chatConfig.isAllowLongPressAvatarToAt) { if (model.chatConfig.isAllowLongPressAvatarToAt) {
widget.onLongPressForOthersHeadPortrait!( widget.onLongPressForOthersHeadPortrait!(message.sender, message.nickName);
message.sender, message.nickName);
} }
}, },
onTapDown: isDesktopScreen onTapDown: isDesktopScreen
? (details) { ? (details) {
if (widget.onTapForOthersPortrait != null && if (widget.onTapForOthersPortrait != null && widget.allowAvatarTap) {
widget.allowAvatarTap) { widget.onTapForOthersPortrait!(message.sender ?? "", details);
widget.onTapForOthersPortrait!(
message.sender ?? "", details);
} }
} }
: null, : null,
onTap: isDesktopScreen onTap: isDesktopScreen
? null ? null
: () { : () {
if (widget.onTapForOthersPortrait != null && if (widget.onTapForOthersPortrait != null && widget.allowAvatarTap) {
widget.allowAvatarTap) { widget.onTapForOthersPortrait!(message.sender ?? "", TapDownDetails());
widget.onTapForOthersPortrait!(
message.sender ?? "",
TapDownDetails());
} }
}, },
onSecondaryTap: isDesktopScreen onSecondaryTap: isDesktopScreen
? null ? null
: () { : () {
if (widget.onSecondaryTapForOthersPortrait != if (widget.onSecondaryTapForOthersPortrait != null && widget.allowAvatarTap) {
null && widget.onSecondaryTapForOthersPortrait!(message.sender ?? "", TapDownDetails());
widget.allowAvatarTap) {
widget.onSecondaryTapForOthersPortrait!(
message.sender ?? "",
TapDownDetails());
} }
}, },
onSecondaryTapDown: isDesktopScreen onSecondaryTapDown: isDesktopScreen
? (details) { ? (details) {
if (widget.onSecondaryTapForOthersPortrait != if (widget.onSecondaryTapForOthersPortrait != null && widget.allowAvatarTap) {
null && widget.onSecondaryTapForOthersPortrait!(message.sender ?? "", details);
widget.allowAvatarTap) {
widget.onSecondaryTapForOthersPortrait!(
message.sender ?? "", details);
} }
} }
: null, : null,
child: widget.userAvatarBuilder != null child: widget.userAvatarBuilder != null
? widget.userAvatarBuilder!(context, message) ? widget.userAvatarBuilder!(context, message)
: Container( : Container(
margin: (isSelf && isShowNickNameForSelf) || margin: (isSelf && isShowNickNameForSelf) || (!isSelf && isShowNickNameForOthers) ? const EdgeInsets.only(top: 2) : null,
(!isSelf && isShowNickNameForOthers)
? const EdgeInsets.only(top: 2)
: null,
child: SizedBox( child: SizedBox(
width: 40, width: 40,
height: 40, height: 40,
child: Avatar( child: Avatar(
faceUrl: message.faceUrl ?? "", faceUrl: message.faceUrl ?? "",
showName: MessageUtils.getDisplayName( showName: MessageUtils.getDisplayName(message),
message),
), ),
), ),
), ),
), ),
if (isSelf && if (isSelf && widget.message.elemType == 6 && isDownloadWaiting)
widget.message.elemType == 6 &&
isDownloadWaiting)
Container( Container(
margin: const EdgeInsets.only(top: 46, right: 10), margin: const EdgeInsets.only(top: 46, right: 10),
child: LoadingAnimationWidget.threeArchedCircle( child: LoadingAnimationWidget.threeArchedCircle(
@ -1438,96 +1278,52 @@ class _TIMUIKItHistoryMessageListItemState
), ),
), ),
Container( Container(
margin: widget.showAvatar margin: widget.showAvatar ? (isSelf ? const EdgeInsets.only(right: 13) : const EdgeInsets.only(left: 13)) : null,
? (isSelf
? const EdgeInsets.only(right: 13)
: const EdgeInsets.only(left: 13))
: null,
child: Column( child: Column(
crossAxisAlignment: isSelf crossAxisAlignment: isSelf ? CrossAxisAlignment.end : CrossAxisAlignment.start,
? CrossAxisAlignment.end
: CrossAxisAlignment.start,
children: [ children: [
if ((isSelf && isShowNickNameForSelf) || if ((isSelf && isShowNickNameForSelf) || (!isSelf && isShowNickNameForOthers))
(!isSelf && isShowNickNameForOthers))
widget.topRowBuilder != null widget.topRowBuilder != null
? widget.topRowBuilder!(context, message) ? widget.topRowBuilder!(context, message)
: Container( : Container(
// margin: const EdgeInsets.only(bottom: 4), // margin: const EdgeInsets.only(bottom: 4),
child: ConstrainedBox( child: ConstrainedBox(
constraints: BoxConstraints( constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width / 1.7),
maxWidth: MediaQuery.of(context)
.size
.width /
1.7),
child: Text( child: Text(
MessageUtils.getDisplayName(message), MessageUtils.getDisplayName(message),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: widget.themeData style: widget.themeData?.nickNameTextStyle ?? TextStyle(fontSize: 12, color: theme.weakTextColor),
?.nickNameTextStyle ??
TextStyle(
fontSize: 12,
color: theme.weakTextColor),
), ),
)), )),
Row( Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
if (isSelf) if (isSelf) renderHoverTipAndReadStatus(model, isSelf, message, isPeerRead, theme, isDownloadWaiting),
renderHoverTipAndReadStatus(
model,
isSelf,
message,
isPeerRead,
theme,
isDownloadWaiting),
Container( Container(
constraints: BoxConstraints( constraints: BoxConstraints(
maxWidth: constraints.maxWidth * 0.77, maxWidth: constraints.maxWidth * 0.77,
), ),
child: Builder(builder: (context) { child: Builder(builder: (context) {
return GestureDetector( return GestureDetector(
child: IgnorePointer( child: IgnorePointer(ignoring: model.isMultiSelect, child: _getMessageItemBuilder(message, message.status, model)),
ignoring: model.isMultiSelect,
child: _getMessageItemBuilder(
message,
message.status,
model)),
onSecondaryTapDown: (details) { onSecondaryTapDown: (details) {
if (widget.onLongPress != null) { if (widget.onLongPress != null) {
widget.onLongPress!( widget.onLongPress!(context, message);
context, message);
return; return;
} }
if (!PlatformUtils().isMobile) { if (!PlatformUtils().isMobile) {
if (widget.allowLongPress) { if (widget.allowLongPress) {
_onOpenToolTip( _onOpenToolTip(context, message, model, theme, details, false, false);
context,
message,
model,
theme,
details,
false,
false);
} }
} }
}, },
onLongPress: () { onLongPress: () {
if (widget.onLongPress != null) { if (widget.onLongPress != null) {
widget.onLongPress!( widget.onLongPress!(context, message);
context, message);
return; return;
} }
if (widget.allowLongPress && if (widget.allowLongPress && !isDesktopScreen) {
!isDesktopScreen) { _onOpenToolTip(context, message, model, theme, null, false, false);
_onOpenToolTip(
context,
message,
model,
theme,
null,
false,
false);
} }
}, },
onTapDown: (details) { onTapDown: (details) {
@ -1536,45 +1332,23 @@ class _TIMUIKItHistoryMessageListItemState
); );
}), }),
), ),
if (!isSelf && if (!isSelf && message.elemType == MessageElemType.V2TIM_ELEM_TYPE_SOUND && message.localCustomInt != null && message.localCustomInt != HistoryMessageDartConstant.read)
message.elemType == Padding(padding: const EdgeInsets.only(left: 5, bottom: 12), child: Icon(Icons.circle, color: theme.cautionColor, size: 10)),
MessageElemType if (!isSelf) renderHoverTipAndReadStatus(model, isSelf, message, isPeerRead, theme, isDownloadWaiting),
.V2TIM_ELEM_TYPE_SOUND &&
message.localCustomInt != null &&
message.localCustomInt !=
HistoryMessageDartConstant.read)
Padding(
padding: const EdgeInsets.only(
left: 5, bottom: 12),
child: Icon(Icons.circle,
color: theme.cautionColor,
size: 10)),
if (!isSelf)
renderHoverTipAndReadStatus(
model,
isSelf,
message,
isPeerRead,
theme,
isDownloadWaiting),
], ],
), ),
TIMUIKitTextTranslationElem( TIMUIKitTextTranslationElem(
message: message, message: message,
customEmojiStickerList: customEmojiStickerList: widget.customEmojiStickerList,
widget.customEmojiStickerList,
isFromSelf: message.isSelf ?? true, isFromSelf: message.isSelf ?? true,
isShowJump: false, isShowJump: false,
clearJump: () {}, clearJump: () {},
chatModel: model), chatModel: model),
if (widget.bottomRowBuilder != null) if (widget.bottomRowBuilder != null) widget.bottomRowBuilder!(context, message)
widget.bottomRowBuilder!(context, message)
], ],
), ),
), ),
if (!isSelf && if (!isSelf && widget.message.elemType == 6 && isDownloadWaiting)
widget.message.elemType == 6 &&
isDownloadWaiting)
Container( Container(
margin: const EdgeInsets.only(top: 46, left: 10), margin: const EdgeInsets.only(top: 46, left: 10),
child: LoadingAnimationWidget.threeArchedCircle( child: LoadingAnimationWidget.threeArchedCircle(
@ -1590,17 +1364,11 @@ class _TIMUIKItHistoryMessageListItemState
height: 40, height: 40,
child: InkWell( child: InkWell(
onTapDown: (details) { onTapDown: (details) {
if (widget.onTapForOthersPortrait != if (widget.onTapForOthersPortrait != null && widget.allowAvatarTap) {
null && widget.onTapForOthersPortrait!(message.sender ?? "", details);
widget.allowAvatarTap) {
widget.onTapForOthersPortrait!(
message.sender ?? "", details);
} }
}, },
child: Avatar( child: Avatar(faceUrl: message.faceUrl ?? "", showName: MessageUtils.getDisplayName(message)),
faceUrl: message.faceUrl ?? "",
showName: MessageUtils.getDisplayName(
message)),
), ),
), ),
], ],

View File

@ -7,13 +7,18 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:open_file/open_file.dart'; import 'package:open_file/open_file.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_member_role.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_elem_type.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_status.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.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/message.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_select_emoji.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_select_emoji.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
@ -25,6 +30,10 @@ import 'package:tencent_cloud_chat_uikit/ui/widgets/forward_message_screen.dart'
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class TIMUIKitMessageTooltip extends StatefulWidget { class TIMUIKitMessageTooltip extends StatefulWidget {
/// tool tips panel configuration, long press message will show tool tips panel /// tool tips panel configuration, long press message will show tool tips panel
final ToolTipsConfig? toolTipsConfig; final ToolTipsConfig? toolTipsConfig;
@ -195,15 +204,13 @@ class TIMUIKitMessageTooltipState
bool showTranslation = true; bool showTranslation = true;
if (widget.message.localCustomData != null) { if (widget.message.localCustomData != null) {
final LocalCustomDataModel localCustomData = LocalCustomDataModel.fromMap( final LocalCustomDataModel localCustomData = LocalCustomDataModel.fromMap(
json.decode( json.decode(TencentUtils.checkString(widget.message.localCustomData) ?? "{}"));
TencentUtils.checkString(widget.message.localCustomData) ?? if (localCustomData.translatedText != null && localCustomData.translatedText != "") {
"{}"));
if (localCustomData.translatedText != null &&
localCustomData.translatedText != "") {
showTranslation = false; showTranslation = false;
} }
} }
final dynamicQuote = final dynamicQuote =
model.chatConfig.isAtWhenReplyDynamic?.call(widget.message); model.chatConfig.isAtWhenReplyDynamic?.call(widget.message);

View File

@ -4,8 +4,11 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:scroll_to_index/scroll_to_index.dart'; import 'package:scroll_to_index/scroll_to_index.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_at_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_controller.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_controller.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
@ -130,8 +133,7 @@ class _TIMUIKitHistoryMessageListContainerState
direction: direction, direction: direction,
count: count ?? (kIsWeb ? 15 : HistoryMessageDartConstant.getCount), count: count ?? (kIsWeb ? 15 : HistoryMessageDartConstant.getCount),
lastMsgID: lastMsgID, lastMsgID: lastMsgID,
lastMsgSeq: lastSeq ?? -1, lastMsgSeq: lastSeq ?? -1,);
);
} else { } else {
return false; return false;
} }
@ -202,8 +204,7 @@ class _TIMUIKitHistoryMessageListContainerState
tongueItemBuilder: widget.tongueItemBuilder, tongueItemBuilder: widget.tongueItemBuilder,
initFindingMsg: widget.initFindingMsg, initFindingMsg: widget.initFindingMsg,
messageList: messageList, messageList: messageList,
onLoadMore: (String? a, LoadDirection direction, onLoadMore: (String? a, LoadDirection direction, [int? b, int? lastSeq]) async {
[int? b, int? lastSeq]) async {
return await requestForData(a, direction, model, b, lastSeq); return await requestForData(a, direction, model, b, lastSeq);
}, },
); );

View File

@ -1,13 +1,16 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_receipt.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:tencent_cloud_chat_uikit/ui/widgets/message_read_receipt.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/message_read_receipt.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_base.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart';
class TIMUIKitMessageReadReceipt extends TIMUIKitStatelessWidget { class TIMUIKitMessageReadReceipt extends TIMUIKitStatelessWidget {

View File

@ -1,4 +1,4 @@
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
class TIMUIKitChatUtils { class TIMUIKitChatUtils {
static String? getMessageIDWithinIndex( static String? getMessageIDWithinIndex(

View File

@ -2,17 +2,22 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/V2TimFriendshipListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/V2TimGroupListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_change_info_type.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
import 'package:tencent_cloud_chat_uikit/data_services/friendShip/friendship_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/friendShip/friendship_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';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitAppBar/tim_uikit_appbar_title.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitAppBar/tim_uikit_appbar_title.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.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_base.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class TIMUIKitAppBar extends StatefulWidget implements PreferredSizeWidget { class TIMUIKitAppBar extends StatefulWidget implements PreferredSizeWidget {
/// Appbar config /// Appbar config

View File

@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
class TIMUIKitAppBarTitle extends StatelessWidget { class TIMUIKitAppBarTitle extends StatelessWidget {
final Widget? title; final Widget? title;

View File

@ -1,11 +1,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.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_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class TIMUIKitMessageReactionDetail extends StatefulWidget { class TIMUIKitMessageReactionDetail extends StatefulWidget {
/// the index of the current emoji sticker /// the index of the current emoji sticker

View File

@ -1,13 +1,14 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.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_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.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/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/message_reaction_emoji.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/message_reaction_emoji.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_emoji_panel.dart' import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_emoji_panel.dart'
as emoji; as emoji;
import 'package:tencent_cloud_chat_uikit/ui/widgets/emoji.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/emoji.dart';
import 'package:tencent_cloud_chat_uikit/ui/widgets/extended_wrap/extended_wrap.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/extended_wrap/extended_wrap.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
enum SelectEmojiPanelPosition { up, down } enum SelectEmojiPanelPosition { up, down }

View File

@ -3,6 +3,11 @@
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_change_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.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_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
@ -10,10 +15,10 @@ import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart';
import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_utils.dart';
import 'package:tencent_cloud_chat_uikit/ui/widgets/extended_wrap/extended_wrap.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/extended_wrap/extended_wrap.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
class TIMUIKitMessageReactionShowItem extends TIMUIKitStatelessWidget { class TIMUIKitMessageReactionShowItem extends TIMUIKitStatelessWidget {
/// the unicode of the emoji /// the unicode of the emoji

View File

@ -1,5 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.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_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';

View File

@ -1,5 +1,8 @@
import 'dart:convert'; import 'dart:convert';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_change_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart';
import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart';

View File

@ -2,8 +2,8 @@ import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';

View File

@ -1,12 +1,12 @@
// ignore_for_file: unrelated_type_equality_checks // ignore_for_file: unrelated_type_equality_checks
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_custom_elem.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.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_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
class TIMUIKitCustomElem extends TIMUIKitStatelessWidget { class TIMUIKitCustomElem extends TIMUIKitStatelessWidget {
final V2TimCustomElem? customElem; final V2TimCustomElem? customElem;
final bool isFromSelf; final bool isFromSelf;

View File

@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';

View File

@ -8,12 +8,21 @@ import 'package:flutter/material.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:loading_animation_widget/loading_animation_widget.dart'; import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:open_file/open_file.dart'; import 'package:open_file/open_file.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/V2TimAdvancedMsgListener.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_file_elem.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_download_progress.dart';
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.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_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/permission.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/permission.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_wrapper.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_wrapper.dart';

View File

@ -1,8 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_tips_elem.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/message.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_base.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class TIMUIKitGroupTipsElem extends StatefulWidget { class TIMUIKitGroupTipsElem extends StatefulWidget {
final V2TimGroupTipsElem groupTipsElem; final V2TimGroupTipsElem groupTipsElem;
@ -39,7 +42,8 @@ class _TIMUIKitGroupTipsElemState extends TIMUIKitState<TIMUIKitGroupTipsElem> {
return MessageUtils.wrapMessageTips( return MessageUtils.wrapMessageTips(
Text( Text(
groupTipsAbstractText, groupTipsAbstractText,
softWrap: true, maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,

View File

@ -17,6 +17,10 @@ import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:open_file/open_file.dart'; import 'package:open_file/open_file.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_image.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.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_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
@ -24,6 +28,7 @@ import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_glo
import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
import 'package:tencent_cloud_chat_uikit/ui/constants/history_message_constant.dart'; import 'package:tencent_cloud_chat_uikit/ui/constants/history_message_constant.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart';
@ -172,8 +177,7 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
if (model.getMessageProgress(widget.message.msgID) == 100) { if (model.getMessageProgress(widget.message.msgID) == 100) {
String savePath; String savePath;
if (widget.message.imageElem!.path != null && if (widget.message.imageElem!.path != null &&
widget.message.imageElem!.path != '' && widget.message.imageElem!.path != '' && File(widget.message.imageElem!.path!).existsSync()) {
File(widget.message.imageElem!.path!).existsSync()) {
savePath = widget.message.imageElem!.path!; savePath = widget.message.imageElem!.path!;
} else { } else {
savePath = model.getFileMessageLocation(widget.message.msgID); savePath = model.getFileMessageLocation(widget.message.msgID);
@ -594,6 +598,7 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
Widget? _renderImage(dynamic heroTag, TUITheme theme, Widget? _renderImage(dynamic heroTag, TUITheme theme,
{V2TimImage? originalImg, V2TimImage? smallImg}) { {V2TimImage? originalImg, V2TimImage? smallImg}) {
double positionRadio = 1.0; double positionRadio = 1.0;
if (smallImg?.width != null && if (smallImg?.width != null &&
smallImg?.height != null && smallImg?.height != null &&

View File

@ -3,18 +3,23 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_elem_type.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_status.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_model_tools.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_model_tools.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart';
import 'package:extended_text/extended_text.dart'; import 'package:extended_text/extended_text.dart';
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.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_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_show_panel.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_show_panel.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/main.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/main.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_face_elem.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_face_elem.dart';
@ -66,14 +71,10 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
MessageRepliedData? _getRepliedMessage() { MessageRepliedData? _getRepliedMessage() {
try { try {
final CloudCustomData messageCloudCustomData = CloudCustomData.fromJson( final CloudCustomData messageCloudCustomData = CloudCustomData.fromJson(json.decode(
json.decode( TencentUtils.checkString(widget.message.cloudCustomData) != null ? widget.message.cloudCustomData! : "{}"));
TencentUtils.checkString(widget.message.cloudCustomData) != null
? widget.message.cloudCustomData!
: "{}"));
if (messageCloudCustomData.messageReply != null) { if (messageCloudCustomData.messageReply != null) {
final MessageRepliedData repliedMessage = final MessageRepliedData repliedMessage = MessageRepliedData.fromJson(messageCloudCustomData.messageReply!);
MessageRepliedData.fromJson(messageCloudCustomData.messageReply!);
return repliedMessage; return repliedMessage;
} }
return null; return null;
@ -99,8 +100,7 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
if (message == null) { if (message == null) {
try { try {
final RepliedMessageAbstract repliedMessageAbstract = final RepliedMessageAbstract repliedMessageAbstract =
RepliedMessageAbstract.fromJson( RepliedMessageAbstract.fromJson(jsonDecode(cloudCustomData.messageAbstract));
jsonDecode(cloudCustomData.messageAbstract));
if (repliedMessageAbstract.isNotEmpty) { if (repliedMessageAbstract.isNotEmpty) {
message = V2TimMessage( message = V2TimMessage(
elemType: 0, elemType: 0,
@ -127,25 +127,19 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
return Text(text, return Text(text,
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: TextStyle( style: TextStyle(fontSize: 12, color: theme?.weakTextColor, fontWeight: FontWeight.w400));
fontSize: 12,
color: theme?.weakTextColor,
fontWeight: FontWeight.w400));
} }
_renderMessageSummary(TUITheme? theme) { _renderMessageSummary(TUITheme? theme) {
try { try {
final RepliedMessageAbstract repliedMessageAbstract = final RepliedMessageAbstract repliedMessageAbstract =
RepliedMessageAbstract.fromJson( RepliedMessageAbstract.fromJson(jsonDecode(repliedMessage?.messageAbstract ?? ""));
jsonDecode(repliedMessage?.messageAbstract ?? ""));
if (TencentUtils.checkString(repliedMessageAbstract.summary) != null) { if (TencentUtils.checkString(repliedMessageAbstract.summary) != null) {
return _defaultRawMessageText(repliedMessageAbstract.summary!, theme); return _defaultRawMessageText(repliedMessageAbstract.summary!, theme);
} }
return _defaultRawMessageText( return _defaultRawMessageText(repliedMessage?.messageAbstract ?? TIM_t("[未知消息]"), theme);
repliedMessage?.messageAbstract ?? TIM_t("[未知消息]"), theme);
} catch (e) { } catch (e) {
return _defaultRawMessageText( return _defaultRawMessageText(repliedMessage?.messageAbstract ?? TIM_t("[未知消息]"), theme);
repliedMessage?.messageAbstract ?? TIM_t("[未知消息]"), theme);
} }
} }
@ -180,16 +174,13 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
final isAdminRevoke = revokeStatus.$2; final isAdminRevoke = revokeStatus.$2;
if (isRevokedMsg) { if (isRevokedMsg) {
return _defaultRawMessageText( return _defaultRawMessageText(isAdminRevoke ? TIM_t("[消息被管理员撤回]") : TIM_t("[消息被撤回]"), theme);
isAdminRevoke ? TIM_t("[消息被管理员撤回]") : TIM_t("[消息被撤回]"), theme);
} }
final messageType = message.elemType; final messageType = message.elemType;
final isSelf = message.isSelf ?? true; final isSelf = message.isSelf ?? true;
final customAbstractMessage = final customAbstractMessage =
widget.chatModel.abstractMessageBuilder != null widget.chatModel.abstractMessageBuilder != null ? widget.chatModel.abstractMessageBuilder!(message) : null;
? widget.chatModel.abstractMessageBuilder!(message)
: null;
if (customAbstractMessage != null) { if (customAbstractMessage != null) {
return _defaultRawMessageText( return _defaultRawMessageText(
customAbstractMessage, customAbstractMessage,
@ -222,15 +213,9 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
isShowJump: false); isShowJump: false);
case MessageElemType.V2TIM_ELEM_TYPE_IMAGE: case MessageElemType.V2TIM_ELEM_TYPE_IMAGE:
return TIMUIKitImageElem( return TIMUIKitImageElem(
chatModel: widget.chatModel, chatModel: widget.chatModel, message: message, isFrom: "reply", isShowMessageReaction: false);
message: message,
isFrom: "reply",
isShowMessageReaction: false);
case MessageElemType.V2TIM_ELEM_TYPE_VIDEO: case MessageElemType.V2TIM_ELEM_TYPE_VIDEO:
return TIMUIKitVideoElem(message, return TIMUIKitVideoElem(message, chatModel: widget.chatModel, isFrom: "reply", isShowMessageReaction: false);
chatModel: widget.chatModel,
isFrom: "reply",
isShowMessageReaction: false);
case MessageElemType.V2TIM_ELEM_TYPE_LOCATION: case MessageElemType.V2TIM_ELEM_TYPE_LOCATION:
return _defaultRawMessageText(TIM_t("[位置]"), theme); return _defaultRawMessageText(TIM_t("[位置]"), theme);
case MessageElemType.V2TIM_ELEM_TYPE_MERGER: case MessageElemType.V2TIM_ELEM_TYPE_MERGER:
@ -262,8 +247,7 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
} }
_showJumpColor() { _showJumpColor() {
if ((widget.chatModel.jumpMsgID != widget.message.msgID) && if ((widget.chatModel.jumpMsgID != widget.message.msgID) && (widget.message.msgID?.isNotEmpty ?? true)) {
(widget.message.msgID?.isNotEmpty ?? true)) {
return; return;
} }
isShining = true; isShining = true;
@ -287,26 +271,21 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
} }
void _jumpToRawMsg() { void _jumpToRawMsg() {
if (rawMessage?.status != MessageStatus.V2TIM_MSG_STATUS_LOCAL_REVOKED && if (rawMessage?.status != MessageStatus.V2TIM_MSG_STATUS_LOCAL_REVOKED && rawMessage?.timestamp != null) {
rawMessage?.timestamp != null) {
widget.scrollToIndex(rawMessage); widget.scrollToIndex(rawMessage);
} else { } else {
onTIMCallback(TIMCallback( onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("无法定位到原消息")));
type: TIMCallbackType.INFO, infoRecommendText: TIM_t("无法定位到原消息")));
} }
} }
Widget? _renderPreviewWidget() { Widget? _renderPreviewWidget() {
// If the link preview info from [localCustomData] is available, use it to render the preview card. // If the link preview info from [localCustomData] is available, use it to render the preview card.
// Otherwise, it will returns null. // Otherwise, it will returns null.
if (widget.message.localCustomData != null && if (widget.message.localCustomData != null && widget.message.localCustomData!.isNotEmpty) {
widget.message.localCustomData!.isNotEmpty) {
try { try {
final String localJSON = widget.message.localCustomData!; final String localJSON = widget.message.localCustomData!;
final LocalCustomDataModel? localPreviewInfo = final LocalCustomDataModel? localPreviewInfo = LocalCustomDataModel.fromMap(json.decode(localJSON));
LocalCustomDataModel.fromMap(json.decode(localJSON)); if (localPreviewInfo != null && !localPreviewInfo.isLinkPreviewEmpty()) {
if (localPreviewInfo != null &&
!localPreviewInfo.isLinkPreviewEmpty()) {
return Container( return Container(
margin: const EdgeInsets.only(top: 8), margin: const EdgeInsets.only(top: 8),
child: child:
@ -327,16 +306,14 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
@override @override
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
final theme = value.theme; final theme = value.theme;
final isDesktopScreen = final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
if (widget.isShowJump) { if (widget.isShowJump) {
if (!isShining) { if (!isShining) {
Future.delayed(Duration.zero, () { Future.delayed(Duration.zero, () {
_showJumpColor(); _showJumpColor();
}); });
} else { } else {
if ((widget.chatModel.jumpMsgID == widget.message.msgID) && if ((widget.chatModel.jumpMsgID == widget.message.msgID) && (widget.message.msgID?.isNotEmpty ?? false)) {
(widget.message.msgID?.isNotEmpty ?? false)) {
widget.clearJump(); widget.clearJump();
} }
} }
@ -345,13 +322,11 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
final isFromSelf = widget.message.isSelf ?? true; final isFromSelf = widget.message.isSelf ?? true;
final defaultStyle = isFromSelf final defaultStyle = isFromSelf
? (theme.chatMessageItemFromSelfBgColor ?? ? (theme.chatMessageItemFromSelfBgColor ?? theme.lightPrimaryMaterialColor.shade50)
theme.lightPrimaryMaterialColor.shade50)
: (theme.chatMessageItemFromOthersBgColor); : (theme.chatMessageItemFromOthersBgColor);
final backgroundColor = isShowJumpState final backgroundColor =
? const Color.fromRGBO(245, 166, 35, 1) isShowJumpState ? const Color.fromRGBO(245, 166, 35, 1) : (defaultStyle ?? widget.backgroundColor);
: (defaultStyle ?? widget.backgroundColor);
final borderRadius = isFromSelf final borderRadius = isFromSelf
? const BorderRadius.only( ? const BorderRadius.only(
@ -365,29 +340,22 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
bottomLeft: Radius.circular(10), bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10)); bottomRight: Radius.circular(10));
final textWithLink = LinkPreviewEntry.getHyperlinksText( final textWithLink = LinkPreviewEntry.getHyperlinksText(
widget.message.textElem?.text ?? "", widget.message.textElem?.text ?? "", widget.chatModel.chatConfig.isSupportMarkdownForTextMessage,
widget.chatModel.chatConfig.isSupportMarkdownForTextMessage,
onLinkTap: widget.chatModel.chatConfig.onTapLink, onLinkTap: widget.chatModel.chatConfig.onTapLink,
isUseQQPackage: widget isUseQQPackage: widget.chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? true,
.chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? isUseTencentCloudChatPackage:
true, widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true,
isUseTencentCloudChatPackage: widget.chatModel.chatConfig isUseTencentCloudChatPackageOldKeys:
.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ?? false,
true,
isUseTencentCloudChatPackageOldKeys: widget.chatModel.chatConfig
.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ??
false,
customEmojiStickerList: widget.customEmojiStickerList, customEmojiStickerList: widget.customEmojiStickerList,
isEnableTextSelection: isEnableTextSelection: widget.chatModel.chatConfig.isEnableTextSelection ?? false);
widget.chatModel.chatConfig.isEnableTextSelection ?? false);
return Container( return Container(
padding: widget.textPadding ?? EdgeInsets.all(isDesktopScreen ? 12 : 10), padding: widget.textPadding ?? EdgeInsets.all(isDesktopScreen ? 12 : 10),
decoration: BoxDecoration( decoration: BoxDecoration(
color: backgroundColor, color: backgroundColor,
borderRadius: widget.borderRadius ?? borderRadius, borderRadius: widget.borderRadius ?? borderRadius,
), ),
constraints: constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.6),
BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.6),
child: GestureDetector( child: GestureDetector(
onTap: _jumpToRawMsg, onTap: _jumpToRawMsg,
child: Column( child: Column(
@ -399,20 +367,13 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
constraints: const BoxConstraints(minWidth: 120), constraints: const BoxConstraints(minWidth: 120),
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: Color.fromRGBO(68, 68, 68, 0.05), color: Color.fromRGBO(68, 68, 68, 0.05),
border: Border( border: Border(left: BorderSide(color: Color.fromRGBO(68, 68, 68, 0.1), width: 2))),
left: BorderSide(
color: Color.fromRGBO(68, 68, 68, 0.1), width: 2))),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
repliedMessage != null repliedMessage != null ? "${repliedMessage!.messageSender}:" : "",
? "${repliedMessage!.messageSender}:" style: TextStyle(fontSize: 12, color: theme.weakTextColor, fontWeight: FontWeight.w500),
: "",
style: TextStyle(
fontSize: 12,
color: theme.weakTextColor,
fontWeight: FontWeight.w500),
), ),
const SizedBox( const SizedBox(
height: 4, height: 4,
@ -436,35 +397,22 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
: ExtendedText(widget.message.textElem?.text ?? "", : ExtendedText(widget.message.textElem?.text ?? "",
softWrap: true, softWrap: true,
style: widget.fontStyle ?? style: widget.fontStyle ??
TextStyle( TextStyle(fontSize: isDesktopScreen ? 14 : 16, height: widget.chatModel.chatConfig.textHeight),
fontSize: isDesktopScreen ? 14 : 16,
height: widget.chatModel.chatConfig.textHeight),
specialTextSpanBuilder: DefaultSpecialTextSpanBuilder( specialTextSpanBuilder: DefaultSpecialTextSpanBuilder(
isUseQQPackage: widget.chatModel.chatConfig isUseQQPackage: widget.chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? true,
.stickerPanelConfig?.useQQStickerPackage ?? isUseTencentCloudChatPackage:
true, widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true,
isUseTencentCloudChatPackage: widget isUseTencentCloudChatPackageOldKeys:
.chatModel widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ??
.chatConfig
.stickerPanelConfig
?.useTencentCloudChatStickerPackage ??
true,
isUseTencentCloudChatPackageOldKeys: widget
.chatModel
.chatConfig
.stickerPanelConfig
?.useTencentCloudChatStickerPackageOldKeys ??
false, false,
customEmojiStickerList: widget.customEmojiStickerList, customEmojiStickerList: widget.customEmojiStickerList,
showAtBackground: true, showAtBackground: true,
)), )),
// If the link preview info is available, render the preview card. // If the link preview info is available, render the preview card.
if (_renderPreviewWidget() != null && if (_renderPreviewWidget() != null &&
widget.chatModel.chatConfig.urlPreviewType == widget.chatModel.chatConfig.urlPreviewType == UrlPreviewType.previewCardAndHyperlink)
UrlPreviewType.previewCardAndHyperlink)
_renderPreviewWidget()!, _renderPreviewWidget()!,
if (widget.isShowMessageReaction ?? true) if (widget.isShowMessageReaction ?? true) TIMUIKitMessageReactionShowPanel(message: widget.message)
TIMUIKitMessageReactionShowPanel(message: widget.message)
], ],
), ),
), ),

View File

@ -3,6 +3,8 @@ import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart'; import 'package:just_audio/just_audio.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_sound_elem.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_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
@ -12,8 +14,6 @@ import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/ui/constants/history_message_constant.dart'; import 'package:tencent_cloud_chat_uikit/ui/constants/history_message_constant.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/sound_record.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/sound_record.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
import 'TIMUIKitMessageReaction/tim_uikit_message_reaction_show_panel.dart'; import 'TIMUIKitMessageReaction/tim_uikit_message_reaction_show_panel.dart';
class TIMUIKitSoundElem extends StatefulWidget { class TIMUIKitSoundElem extends StatefulWidget {

View File

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:extended_text/extended_text.dart'; import 'package:extended_text/extended_text.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -65,8 +66,7 @@ class _TIMUIKitTextElemState extends TIMUIKitState<TIMUIKitTextElem> {
} }
_showJumpColor() { _showJumpColor() {
if ((widget.chatModel.jumpMsgID != widget.message.msgID) && if ((widget.chatModel.jumpMsgID != widget.message.msgID) && (widget.message.msgID?.isNotEmpty ?? true)) {
(widget.message.msgID?.isNotEmpty ?? true)) {
return; return;
} }
isShining = true; isShining = true;
@ -93,16 +93,13 @@ class _TIMUIKitTextElemState extends TIMUIKitState<TIMUIKitTextElem> {
// get the link preview info // get the link preview info
_getLinkPreview() { _getLinkPreview() {
if (widget.chatModel.chatConfig.urlPreviewType != if (widget.chatModel.chatConfig.urlPreviewType != UrlPreviewType.previewCardAndHyperlink) {
UrlPreviewType.previewCardAndHyperlink) {
return; return;
} }
try { try {
if (widget.message.localCustomData != null && if (widget.message.localCustomData != null && widget.message.localCustomData!.isNotEmpty) {
widget.message.localCustomData!.isNotEmpty) {
final String localJSON = widget.message.localCustomData!; final String localJSON = widget.message.localCustomData!;
final LocalCustomDataModel? localPreviewInfo = final LocalCustomDataModel? localPreviewInfo = LocalCustomDataModel.fromMap(json.decode(localJSON));
LocalCustomDataModel.fromMap(json.decode(localJSON));
// If [localCustomData] is not empty, check if the link preview info exists // If [localCustomData] is not empty, check if the link preview info exists
if (localPreviewInfo == null || localPreviewInfo.isLinkPreviewEmpty()) { if (localPreviewInfo == null || localPreviewInfo.isLinkPreviewEmpty()) {
// If not exists, get it // If not exists, get it
@ -123,22 +120,18 @@ class _TIMUIKitTextElemState extends TIMUIKitState<TIMUIKitTextElem> {
LinkPreviewEntry.getFirstLinkPreviewContent( LinkPreviewEntry.getFirstLinkPreviewContent(
message: widget.message, message: widget.message,
onUpdateMessage: (message) { onUpdateMessage: (message) {
widget.chatModel.updateMessageFromController( widget.chatModel.updateMessageFromController(msgID: widget.message.msgID!, message: message);
msgID: widget.message.msgID!, message: message);
}); });
} }
Widget? _renderPreviewWidget() { Widget? _renderPreviewWidget() {
// If the link preview info from [localCustomData] is available, use it to render the preview card. // If the link preview info from [localCustomData] is available, use it to render the preview card.
// Otherwise, it will returns null. // Otherwise, it will returns null.
if (widget.message.localCustomData != null && if (widget.message.localCustomData != null && widget.message.localCustomData!.isNotEmpty) {
widget.message.localCustomData!.isNotEmpty) {
try { try {
final String localJSON = widget.message.localCustomData!; final String localJSON = widget.message.localCustomData!;
final LocalCustomDataModel? localPreviewInfo = final LocalCustomDataModel? localPreviewInfo = LocalCustomDataModel.fromMap(json.decode(localJSON));
LocalCustomDataModel.fromMap(json.decode(localJSON)); if (localPreviewInfo != null && !localPreviewInfo.isLinkPreviewEmpty()) {
if (localPreviewInfo != null &&
!localPreviewInfo.isLinkPreviewEmpty()) {
return Container( return Container(
margin: const EdgeInsets.only(top: 8), margin: const EdgeInsets.only(top: 8),
child: child:
@ -159,24 +152,17 @@ class _TIMUIKitTextElemState extends TIMUIKitState<TIMUIKitTextElem> {
@override @override
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
final theme = value.theme; final theme = value.theme;
final isDesktopScreen = final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
final textWithLink = LinkPreviewEntry.getHyperlinksText( final textWithLink = LinkPreviewEntry.getHyperlinksText(
widget.message.textElem?.text ?? "", widget.message.textElem?.text ?? "", widget.chatModel.chatConfig.isSupportMarkdownForTextMessage,
widget.chatModel.chatConfig.isSupportMarkdownForTextMessage,
onLinkTap: widget.chatModel.chatConfig.onTapLink, onLinkTap: widget.chatModel.chatConfig.onTapLink,
isUseQQPackage: widget isUseQQPackage: widget.chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? true,
.chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? isUseTencentCloudChatPackage:
true, widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true,
isUseTencentCloudChatPackage: widget.chatModel.chatConfig isUseTencentCloudChatPackageOldKeys:
.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ?? false,
true,
isUseTencentCloudChatPackageOldKeys: widget.chatModel.chatConfig
.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ??
false,
customEmojiStickerList: widget.customEmojiStickerList, customEmojiStickerList: widget.customEmojiStickerList,
isEnableTextSelection: isEnableTextSelection: widget.chatModel.chatConfig.isEnableTextSelection ?? false);
widget.chatModel.chatConfig.isEnableTextSelection ?? false);
final borderRadius = widget.isFromSelf final borderRadius = widget.isFromSelf
? const BorderRadius.only( ? const BorderRadius.only(
topLeft: Radius.circular(10), topLeft: Radius.circular(10),
@ -195,21 +181,18 @@ class _TIMUIKitTextElemState extends TIMUIKitState<TIMUIKitTextElem> {
_showJumpColor(); _showJumpColor();
}); });
} else { } else {
if ((widget.chatModel.jumpMsgID == widget.message.msgID) && if ((widget.chatModel.jumpMsgID == widget.message.msgID) && (widget.message.msgID?.isNotEmpty ?? false)) {
(widget.message.msgID?.isNotEmpty ?? false)) {
widget.clearJump(); widget.clearJump();
} }
} }
} }
final defaultStyle = widget.isFromSelf final defaultStyle = widget.isFromSelf
? (theme.chatMessageItemFromSelfBgColor ?? ? (theme.chatMessageItemFromSelfBgColor ?? theme.lightPrimaryMaterialColor.shade50)
theme.lightPrimaryMaterialColor.shade50)
: (theme.chatMessageItemFromOthersBgColor); : (theme.chatMessageItemFromOthersBgColor);
final backgroundColor = isShowJumpState final backgroundColor =
? const Color.fromRGBO(245, 166, 35, 1) isShowJumpState ? const Color.fromRGBO(245, 166, 35, 1) : (defaultStyle ?? widget.backgroundColor);
: (defaultStyle ?? widget.backgroundColor);
return Container( return Container(
padding: widget.textPadding ?? EdgeInsets.all(isDesktopScreen ? 12 : 10), padding: widget.textPadding ?? EdgeInsets.all(isDesktopScreen ? 12 : 10),
@ -217,8 +200,7 @@ class _TIMUIKitTextElemState extends TIMUIKitState<TIMUIKitTextElem> {
color: backgroundColor, color: backgroundColor,
borderRadius: widget.borderRadius ?? borderRadius, borderRadius: widget.borderRadius ?? borderRadius,
), ),
constraints: constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.6),
BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.6),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -234,24 +216,13 @@ class _TIMUIKitTextElemState extends TIMUIKitState<TIMUIKitTextElem> {
: ExtendedText(widget.message.textElem?.text ?? "", : ExtendedText(widget.message.textElem?.text ?? "",
softWrap: true, softWrap: true,
style: widget.fontStyle ?? style: widget.fontStyle ??
TextStyle( TextStyle(fontSize: isDesktopScreen ? 14 : 16, height: widget.chatModel.chatConfig.textHeight),
fontSize: isDesktopScreen ? 14 : 16,
height: widget.chatModel.chatConfig.textHeight),
specialTextSpanBuilder: DefaultSpecialTextSpanBuilder( specialTextSpanBuilder: DefaultSpecialTextSpanBuilder(
isUseQQPackage: widget.chatModel.chatConfig isUseQQPackage: widget.chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? true,
.stickerPanelConfig?.useQQStickerPackage ?? isUseTencentCloudChatPackage:
true, widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true,
isUseTencentCloudChatPackage: widget isUseTencentCloudChatPackageOldKeys:
.chatModel widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ??
.chatConfig
.stickerPanelConfig
?.useTencentCloudChatStickerPackage ??
true,
isUseTencentCloudChatPackageOldKeys: widget
.chatModel
.chatConfig
.stickerPanelConfig
?.useTencentCloudChatStickerPackageOldKeys ??
false, false,
customEmojiStickerList: widget.customEmojiStickerList, customEmojiStickerList: widget.customEmojiStickerList,
showAtBackground: true, showAtBackground: true,
@ -259,11 +230,9 @@ class _TIMUIKitTextElemState extends TIMUIKitState<TIMUIKitTextElem> {
)), )),
// If the link preview info is available, render the preview card. // If the link preview info is available, render the preview card.
if (_renderPreviewWidget() != null && if (_renderPreviewWidget() != null &&
widget.chatModel.chatConfig.urlPreviewType == widget.chatModel.chatConfig.urlPreviewType == UrlPreviewType.previewCardAndHyperlink)
UrlPreviewType.previewCardAndHyperlink)
_renderPreviewWidget()!, _renderPreviewWidget()!,
if (widget.isShowMessageReaction ?? true) if (widget.isShowMessageReaction ?? true) TIMUIKitMessageReactionShowPanel(message: widget.message)
TIMUIKitMessageReactionShowPanel(message: widget.message)
], ],
), ),
); );

View File

@ -1,6 +1,8 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:extended_text/extended_text.dart'; import 'package:extended_text/extended_text.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -43,14 +45,12 @@ class TIMUIKitTextTranslationElem extends StatefulWidget {
State<StatefulWidget> createState() => _TIMUIKitTextTranslationElemState(); State<StatefulWidget> createState() => _TIMUIKitTextTranslationElemState();
} }
class _TIMUIKitTextTranslationElemState class _TIMUIKitTextTranslationElemState extends TIMUIKitState<TIMUIKitTextTranslationElem> {
extends TIMUIKitState<TIMUIKitTextTranslationElem> {
bool isShowJumpState = false; bool isShowJumpState = false;
bool isShining = false; bool isShining = false;
_showJumpColor() { _showJumpColor() {
if ((widget.chatModel.jumpMsgID != widget.message.msgID) && if ((widget.chatModel.jumpMsgID != widget.message.msgID) && (widget.message.msgID?.isNotEmpty ?? true)) {
(widget.message.msgID?.isNotEmpty ?? true)) {
return; return;
} }
isShining = true; isShining = true;
@ -78,8 +78,7 @@ class _TIMUIKitTextTranslationElemState
@override @override
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
final theme = value.theme; final theme = value.theme;
final isDesktopScreen = final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
final borderRadius = widget.isFromSelf final borderRadius = widget.isFromSelf
? const BorderRadius.only( ? const BorderRadius.only(
topLeft: Radius.circular(10), topLeft: Radius.circular(10),
@ -98,61 +97,49 @@ class _TIMUIKitTextTranslationElemState
_showJumpColor(); _showJumpColor();
}); });
} else { } else {
if ((widget.chatModel.jumpMsgID == widget.message.msgID) && if ((widget.chatModel.jumpMsgID == widget.message.msgID) && (widget.message.msgID?.isNotEmpty ?? false)) {
(widget.message.msgID?.isNotEmpty ?? false)) {
widget.clearJump(); widget.clearJump();
} }
} }
} }
final defaultStyle = widget.isFromSelf final defaultStyle = widget.isFromSelf
? (theme.chatMessageItemFromSelfBgColor ?? ? (theme.chatMessageItemFromSelfBgColor ?? theme.lightPrimaryMaterialColor.shade50)
theme.lightPrimaryMaterialColor.shade50)
: (theme.chatMessageItemFromOthersBgColor); : (theme.chatMessageItemFromOthersBgColor);
final backgroundColor = isShowJumpState final backgroundColor =
? const Color.fromRGBO(245, 166, 35, 1) isShowJumpState ? const Color.fromRGBO(245, 166, 35, 1) : (defaultStyle ?? widget.backgroundColor);
: (defaultStyle ?? widget.backgroundColor);
final LocalCustomDataModel localCustomData = LocalCustomDataModel.fromMap( final LocalCustomDataModel localCustomData =
json.decode( LocalCustomDataModel.fromMap(json.decode(TencentUtils.checkString(widget.message.localCustomData) ?? "{}"));
TencentUtils.checkString(widget.message.localCustomData) ?? "{}"));
final String? translateText = localCustomData.translatedText; final String? translateText = localCustomData.translatedText;
final textWithLink = LinkPreviewEntry.getHyperlinksText(translateText ?? "", final textWithLink = LinkPreviewEntry.getHyperlinksText(
widget.chatModel.chatConfig.isSupportMarkdownForTextMessage, translateText ?? "", widget.chatModel.chatConfig.isSupportMarkdownForTextMessage,
onLinkTap: widget.chatModel.chatConfig.onTapLink, onLinkTap: widget.chatModel.chatConfig.onTapLink,
isUseQQPackage: widget isUseQQPackage: widget.chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? true,
.chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? isUseTencentCloudChatPackage:
true, widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true,
isUseTencentCloudChatPackage: widget.chatModel.chatConfig isUseTencentCloudChatPackageOldKeys:
.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ?? false,
true,
isUseTencentCloudChatPackageOldKeys: widget.chatModel.chatConfig
.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ??
false,
customEmojiStickerList: widget.customEmojiStickerList, customEmojiStickerList: widget.customEmojiStickerList,
isEnableTextSelection: isEnableTextSelection: widget.chatModel.chatConfig.isEnableTextSelection ?? false);
widget.chatModel.chatConfig.isEnableTextSelection ?? false);
return TencentUtils.checkString(translateText) != null return TencentUtils.checkString(translateText) != null
? Container( ? Container(
margin: const EdgeInsets.only(top: 6), margin: const EdgeInsets.only(top: 6),
padding: padding: widget.textPadding ?? EdgeInsets.all(isDesktopScreen ? 12 : 10),
widget.textPadding ?? EdgeInsets.all(isDesktopScreen ? 12 : 10),
decoration: BoxDecoration( decoration: BoxDecoration(
color: backgroundColor, color: backgroundColor,
borderRadius: widget.borderRadius ?? borderRadius, borderRadius: widget.borderRadius ?? borderRadius,
), ),
constraints: BoxConstraints( constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.6),
maxWidth: MediaQuery.of(context).size.width * 0.6),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// If the [elemType] is text message, it will not be null here. // If the [elemType] is text message, it will not be null here.
// You can render the widget from extension directly, with a [TextStyle] optionally. // You can render the widget from extension directly, with a [TextStyle] optionally.
widget.chatModel.chatConfig.urlPreviewType != widget.chatModel.chatConfig.urlPreviewType != UrlPreviewType.none
UrlPreviewType.none
? textWithLink!( ? textWithLink!(
style: widget.fontStyle ?? style: widget.fontStyle ??
TextStyle( TextStyle(
@ -163,23 +150,13 @@ class _TIMUIKitTextTranslationElemState
softWrap: true, softWrap: true,
style: widget.fontStyle ?? style: widget.fontStyle ??
TextStyle( TextStyle(
fontSize: isDesktopScreen ? 14 : 16, fontSize: isDesktopScreen ? 14 : 16, height: widget.chatModel.chatConfig.textHeight),
height: widget.chatModel.chatConfig.textHeight),
specialTextSpanBuilder: DefaultSpecialTextSpanBuilder( specialTextSpanBuilder: DefaultSpecialTextSpanBuilder(
isUseQQPackage: widget.chatModel.chatConfig isUseQQPackage: widget.chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? true,
.stickerPanelConfig?.useQQStickerPackage ?? isUseTencentCloudChatPackage:
true, widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true,
isUseTencentCloudChatPackage: widget
.chatModel
.chatConfig
.stickerPanelConfig
?.useTencentCloudChatStickerPackage ??
true,
isUseTencentCloudChatPackageOldKeys: widget isUseTencentCloudChatPackageOldKeys: widget
.chatModel .chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ??
.chatConfig
.stickerPanelConfig
?.useTencentCloudChatStickerPackageOldKeys ??
false, false,
customEmojiStickerList: widget.customEmojiStickerList, customEmojiStickerList: widget.customEmojiStickerList,
showAtBackground: true, showAtBackground: true,
@ -200,8 +177,7 @@ class _TIMUIKitTextTranslationElemState
), ),
Text( Text(
TIM_t("翻译完成"), TIM_t("翻译完成"),
style: const TextStyle( style: const TextStyle(color: Color(0x72282c34), fontSize: 10),
color: Color(0x72282c34), fontSize: 10),
) )
], ],
) )

View File

@ -4,12 +4,18 @@ import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart'; import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:open_file/open_file.dart'; import 'package:open_file/open_file.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_status.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_video_elem.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_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.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/tencent_cloud_chat_uikit.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_wrapper.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_wrapper.dart';

View File

@ -0,0 +1,202 @@
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:better_player_plus/better_player_plus.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_elem_type.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_online_url.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
class TIMUIKitVideoPlayer extends StatefulWidget {
final V2TimMessage message;
final bool controller;
final bool isSending;
const TIMUIKitVideoPlayer({
super.key,
required this.message,
required this.controller,
required this.isSending,
});
@override
State<StatefulWidget> createState() => TIMUIKitVideoPlayerState();
}
enum CurrentVideoType {
online,
local,
}
class CurrentVideoInfo {
final String path;
final CurrentVideoType type;
final double aspectRatio;
CurrentVideoInfo({
required this.path,
required this.type,
required this.aspectRatio,
});
}
class TIMUIKitVideoPlayerState extends State<TIMUIKitVideoPlayer> {
final String _tag = "TencentCloudChatMessageVideoPlayer";
BetterPlayerController? _betterPlayerController;
@override
void initState() {
super.initState();
_initializePlayer();
}
Future<void> _initializePlayer() async {
try {
final info = await getMessageInfo();
if (info != null && mounted) {
BetterPlayerDataSource dataSource;
if (info.type == CurrentVideoType.online) {
dataSource = BetterPlayerDataSource(
BetterPlayerDataSourceType.network,
info.path,
);
} else {
dataSource = BetterPlayerDataSource(
BetterPlayerDataSourceType.file,
info.path,
);
}
final betterPlayerConfiguration = BetterPlayerConfiguration(
aspectRatio: info.aspectRatio,
fit: BoxFit.contain,
autoPlay: true,
allowedScreenSleep: false,
fullScreenByDefault: false,
controlsConfiguration: const BetterPlayerControlsConfiguration(
enableFullscreen: false,
enablePlayPause: true,
enableProgressBar: true,
enableProgressText: true,
showControlsOnInitialize: false,
enableMute:false,
enableOverflowMenu:false,
enableSkips:false,
),
);
_betterPlayerController = BetterPlayerController(
betterPlayerConfiguration,
betterPlayerDataSource: dataSource,
);
if (mounted) {
setState(() {
});
}
}
} catch (e) {
debugPrint("Video initialization error: $e");
}
}
@override
void dispose() {
_betterPlayerController?.dispose();
super.dispose();
}
Future<CurrentVideoInfo?> getMessageInfo() async {
if (widget.message.elemType == MessageElemType.V2TIM_ELEM_TYPE_VIDEO) {
double aspectRatio = (9 / 16);
if (widget.isSending) {
var lp = widget.message.videoElem!.videoPath ?? "";
if (lp.isNotEmpty) {
console("view sending message video path");
if (File(lp).existsSync() && !kIsWeb) {
return CurrentVideoInfo(path: lp, type: CurrentVideoType.local, aspectRatio: aspectRatio);
}
}
}
if (widget.message.videoElem!.snapshotWidth != null && widget.message.videoElem!.snapshotHeight != null) {
if (widget.message.videoElem!.snapshotHeight != 0) {
aspectRatio = (widget.message.videoElem!.snapshotWidth!) / (widget.message.videoElem!.snapshotHeight!);
}
}
if (TencentUtils.checkString(widget.message.videoElem!.videoPath) != null) {
//
if (File(widget.message.videoElem!.videoPath!).existsSync()) {
console("video: local video path exists");
return CurrentVideoInfo(path: widget.message.videoElem!.videoPath!, type: CurrentVideoType.local, aspectRatio: aspectRatio);
}
} else if (TencentUtils.checkString(widget.message.videoElem!.localVideoUrl) != null) {
//
if (File(widget.message.videoElem!.localVideoUrl!).existsSync()) {
console("video: local url exists");
return CurrentVideoInfo(path: widget.message.videoElem!.localVideoUrl!, type: CurrentVideoType.local, aspectRatio: aspectRatio);
}
} else {
// 线(todo 使 getMessageOnlineUrl )
if (widget.message.videoElem != null) {
if (widget.message.videoElem!.snapshotUrl != null) {
console("video: online url ${widget.message.videoElem!.videoUrl}");
return CurrentVideoInfo(
path: widget.message.videoElem!.videoUrl!,
type: CurrentVideoType.online,
aspectRatio: aspectRatio,
);
}
}
if (!kIsWeb) {
V2TimValueCallback<V2TimMessageOnlineUrl> urlres = await TencentImSDKPlugin.v2TIMManager.getMessageManager().getMessageOnlineUrl(msgID: widget.message.msgID ?? "");
if (urlres.data != null) {
if (urlres.data?.videoElem != null) {
if (TencentUtils.checkString(urlres.data?.videoElem?.videoUrl) != null) {
console("view video online url ${urlres.data?.videoElem?.videoUrl}");
return CurrentVideoInfo(path: urlres.data!.videoElem!.videoUrl!, type: CurrentVideoType.online, aspectRatio: aspectRatio);
}
}
}
}
}
} else {
console("The component received a non-video message parameter. please check");
}
console("has no view video source. please check");
return null;
}
console(String log) {
print("$_tag, $log");
}
@override
Widget build(BuildContext context) {
if (widget.message.hasRiskContent == true) {
return const Center(
child: Text(
"Risk Video",
style: TextStyle(color: Colors.white),
),
);
}
if (_betterPlayerController == null) {
return Container();
}
return AspectRatio(
aspectRatio: _betterPlayerController!.videoPlayerController?.value.aspectRatio ?? 9 / 16,
child: BetterPlayer(
controller: _betterPlayerController!,
),
);
}
}

View File

@ -1,15 +1,20 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_merger_elem.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart';
import 'package:tencent_cloud_chat_uikit/ui/widgets/merger_message_screen.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/merger_message_screen.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.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_base.dart';
import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart';
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/theme/color.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
import 'TIMUIKitMessageReaction/tim_uikit_message_reaction_show_panel.dart'; import 'TIMUIKitMessageReaction/tim_uikit_message_reaction_show_panel.dart';
class TIMUIKitMergerElem extends StatefulWidget { class TIMUIKitMergerElem extends StatefulWidget {

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:scroll_to_index/scroll_to_index.dart'; import 'package:scroll_to_index/scroll_to_index.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.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_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';

View File

@ -1,105 +0,0 @@
import 'package:tencent_im_base/tencent_im_base.dart';
import 'package:wechat_camera_picker/wechat_camera_picker.dart';
class IntlCameraPickerTextDelegate extends CameraPickerTextDelegate {
/// Confirm string for the confirm button.
///
@override
String get confirm => TIM_t('确认');
/// Tips string above the shooting button before shooting.
///
@override
String get shootingTips => TIM_t('轻触拍照,长按摄像');
/// Tips string above the shooting button before shooting.
///
@override
String get shootingWithRecordingTips => TIM_t('轻触拍照,长按摄像');
/// Load failed string for item.
///
@override
String get loadFailed => TIM_t('加载失败');
/// Default loading string for the dialog.
///
@override
String get loading => TIM_t('加载中…');
/// Saving string for the dialog.
///
@override
String get saving => TIM_t('保存中…');
/// Semantics fields.
///
/// Fields below are only for semantics usage. For customizable these fields,
/// head over to [EnglishCameraPickerTextDelegate] for better understanding.
@override
String get sActionManuallyFocusHint => TIM_t('手动聚焦');
@override
String get sActionPreviewHint => TIM_t('预览');
@override
String get sActionRecordHint => TIM_t('录像');
@override
String get sActionShootHint => TIM_t('拍照');
@override
String get sActionShootingButtonTooltip => TIM_t('拍照按钮');
@override
String get sActionStopRecordingHint => TIM_t('停止录像');
@override
String sCameraLensDirectionLabel(CameraLensDirection value) {
switch (value) {
case CameraLensDirection.front:
return TIM_t('前置');
case CameraLensDirection.back:
return TIM_t('后置');
case CameraLensDirection.external:
return TIM_t('外置');
}
}
@override
String? sCameraPreviewLabel(CameraLensDirection? value) {
if (value == null) {
return null;
}
final option1 = sCameraLensDirectionLabel(value);
return TIM_t_para("{{option1}} 画面预览", "$option1 画面预览")(option1: option1);
}
@override
String sFlashModeLabel(FlashMode mode) {
final String _modeString;
switch (mode) {
case FlashMode.off:
_modeString = TIM_t('关闭');
break;
case FlashMode.auto:
_modeString = TIM_t('自动');
break;
case FlashMode.always:
_modeString = TIM_t('拍照时闪光');
break;
case FlashMode.torch:
_modeString = TIM_t('始终闪光');
break;
}
final option2 = _modeString;
return TIM_t_para("闪光模式: {{option2}}", "闪光模式: $option2")(option2: option2);
}
@override
String sSwitchCameraLensDirectionLabel(CameraLensDirection value) {
final option3 = sCameraLensDirectionLabel(value);
return TIM_t_para("切换至 {{option3}} 摄像头", "切换至 $option3 摄像头")(
option3: option3);
}
}

View File

@ -32,9 +32,7 @@ class DefaultSpecialTextSpanBuilder extends SpecialTextSpanBuilder {
@override @override
SpecialText? createSpecialText(String flag, SpecialText? createSpecialText(String flag,
{TextStyle? textStyle, {TextStyle? textStyle, SpecialTextGestureTapCallback? onTap, int? index}) {
SpecialTextGestureTapCallback? onTap,
int? index}) {
if (flag == '') { if (flag == '') {
return null; return null;
} }
@ -43,14 +41,12 @@ class DefaultSpecialTextSpanBuilder extends SpecialTextSpanBuilder {
if (isStart(flag, EmojiText.flag)) { if (isStart(flag, EmojiText.flag)) {
return EmojiText(textStyle, return EmojiText(textStyle,
isUseTencentCloudChatPackage: isUseTencentCloudChatPackage, isUseTencentCloudChatPackage: isUseTencentCloudChatPackage,
isUseTencentCloudChatPackageOldKeys: isUseTencentCloudChatPackageOldKeys: isUseTencentCloudChatPackageOldKeys,
isUseTencentCloudChatPackageOldKeys,
isUseQQPackage: isUseQQPackage, isUseQQPackage: isUseQQPackage,
start: index! - (EmojiText.flag.length - 1), start: index! - (EmojiText.flag.length - 1),
customEmojiStickerList: customEmojiStickerList); customEmojiStickerList: customEmojiStickerList);
} else if (isStart(flag, HttpText.flag) && checkHttpLink) { } else if (isStart(flag, HttpText.flag) && checkHttpLink) {
return HttpText(textStyle, onTap, return HttpText(textStyle, onTap, start: index! - (HttpText.flag.length - 1));
start: index! - (HttpText.flag.length - 1));
} }
return null; return null;
} }

View File

@ -111,7 +111,7 @@ class EmojiUtil {
String emojiName = emoji.split('.png')[0]; String emojiName = emoji.split('.png')[0];
String compatibleEmojiName = emojiName; String compatibleEmojiName = emojiName;
if (isUseTencentCloudChatPackageOldKeys) { if (isUseTencentCloudChatPackageOldKeys) {
// key // use old emoji keys in 3.x version
compatibleEmojiName = getCompatibleEmojiName(emojiName); compatibleEmojiName = getCompatibleEmojiName(emojiName);
} }

View File

@ -1,17 +1,21 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_search_param.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_search_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.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';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_member_search.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_member_search.dart';
import 'package:tencent_cloud_chat_uikit/ui/widgets/group_member_list.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/group_member_list.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_base.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class AtText extends StatefulWidget { class AtText extends StatefulWidget {
final String? groupID; final String? groupID;

View File

@ -1,5 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart'; import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_member_filter_enum.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_search_param.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_search_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.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';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
@ -10,6 +16,8 @@ import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/t
import 'package:tencent_cloud_chat_uikit/ui/widgets/group_member_list.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/group_member_list.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_base.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class SelectCallInviter extends StatefulWidget { class SelectCallInviter extends StatefulWidget {
final String? groupID; final String? groupID;
const SelectCallInviter({ const SelectCallInviter({

View File

@ -1,11 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.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_base.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
class EmojiPanel extends TIMUIKitStatelessWidget { class EmojiPanel extends TIMUIKitStatelessWidget {
final void Function(int unicode) onTapEmoji; final void Function(int unicode) onTapEmoji;
final void Function() onSubmitted; final void Function() onSubmitted;

View File

@ -1,6 +1,7 @@
// ignore_for_file: unused_field, avoid_print, unused_import // ignore_for_file: unused_field, avoid_print, unused_import
import 'dart:io'; import 'dart:io';
import 'package:better_player_plus/better_player_plus.dart';
import 'package:device_info_plus/device_info_plus.dart'; import 'package:device_info_plus/device_info_plus.dart';
import 'package:fc_native_video_thumbnail/fc_native_video_thumbnail.dart'; import 'package:fc_native_video_thumbnail/fc_native_video_thumbnail.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -10,9 +11,11 @@ import 'package:image_picker/image_picker.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_call_invite_list.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_call_invite_list.dart';
import 'package:wechat_camera_picker/wechat_camera_picker.dart'; import 'package:video_player/video_player.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
@ -22,7 +25,6 @@ import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/permission.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/permission.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/intl_camer_picker.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart'; import 'package:wechat_assets_picker/wechat_assets_picker.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_base.dart';
@ -31,6 +33,10 @@ import 'dart:typed_data';
import 'package:universal_html/html.dart' as html; import 'package:universal_html/html.dart' as html;
import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class MorePanelConfig { class MorePanelConfig {
static final int FILE_MAX_SIZE = 100 * 1024 * 1024; static final int FILE_MAX_SIZE = 100 * 1024 * 1024;
static final int VIDEO_MAX_SIZE = 100 * 1024 * 1024; static final int VIDEO_MAX_SIZE = 100 * 1024 * 1024;
@ -65,8 +71,7 @@ class MorePanelItem {
final Widget icon; final Widget icon;
final Function(BuildContext context)? onTap; final Function(BuildContext context)? onTap;
MorePanelItem( MorePanelItem({this.onTap, required this.icon, required this.id, required this.title});
{this.onTap, required this.icon, required this.id, required this.title});
} }
class MorePanel extends StatefulWidget { class MorePanel extends StatefulWidget {
@ -78,11 +83,7 @@ class MorePanel extends StatefulWidget {
final MorePanelConfig? morePanelConfig; final MorePanelConfig? morePanelConfig;
const MorePanel( const MorePanel({required this.conversationID, required this.conversationType, Key? key, this.morePanelConfig})
{required this.conversationID,
required this.conversationType,
Key? key,
this.morePanelConfig})
: super(key: key); : super(key: key);
@override @override
@ -91,8 +92,7 @@ class MorePanel extends StatefulWidget {
class _MorePanelState extends TIMUIKitState<MorePanel> { class _MorePanelState extends TIMUIKitState<MorePanel> {
final ImagePicker _picker = ImagePicker(); final ImagePicker _picker = ImagePicker();
final TUISelfInfoViewModel _selfInfoViewModel = final TUISelfInfoViewModel _selfInfoViewModel = serviceLocator<TUISelfInfoViewModel>();
serviceLocator<TUISelfInfoViewModel>();
Uint8List? fileContent; Uint8List? fileContent;
String? fileName; String? fileName;
File? tempFile; File? tempFile;
@ -102,6 +102,8 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
final ScrollController _scrollController = ScrollController(); final ScrollController _scrollController = ScrollController();
final DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); final DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
late BetterPlayerController _betterPlayerController;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -111,33 +113,13 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
isInstallCallkit = value; isInstallCallkit = value;
}); });
}); });
_betterPlayerController = BetterPlayerController(const BetterPlayerConfiguration());
} }
} }
List<MorePanelItem> itemList(TUIChatSeparateViewModel model, TUITheme theme) { List<MorePanelItem> itemList(TUIChatSeparateViewModel model, TUITheme theme) {
final config = widget.morePanelConfig ?? MorePanelConfig(); final config = widget.morePanelConfig ?? MorePanelConfig();
return [ return [
if (PlatformUtils().isMobile)
MorePanelItem(
id: "screen",
title: TIM_t("拍摄"),
onTap: (c) {
_onFeatureTap("screen", c, model, theme);
},
icon: Container(
height: 64,
width: 64,
margin: const EdgeInsets.only(bottom: 4),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(5))),
child: SvgPicture.asset(
"images/screen.svg",
package: 'tencent_cloud_chat_uikit',
height: 64,
width: 64,
),
)),
if (!PlatformUtils().isWeb) if (!PlatformUtils().isWeb)
MorePanelItem( MorePanelItem(
id: "photo", id: "photo",
@ -154,9 +136,7 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
height: 64, height: 64,
width: 64, width: 64,
margin: const EdgeInsets.only(bottom: 4), margin: const EdgeInsets.only(bottom: 4),
decoration: const BoxDecoration( decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(5))),
child: SvgPicture.asset( child: SvgPicture.asset(
"images/photo.svg", "images/photo.svg",
package: 'tencent_cloud_chat_uikit', package: 'tencent_cloud_chat_uikit',
@ -164,6 +144,44 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
width: 64, width: 64,
), ),
)), )),
if (PlatformUtils().isMobile)
MorePanelItem(
id: "take_photo",
title: TIM_t("拍照"),
onTap: (c) {
_onFeatureTap("take_photo", c, model, theme);
},
icon: Container(
height: 64,
width: 64,
margin: const EdgeInsets.only(bottom: 4),
decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
child: SvgPicture.asset(
"images/screen.svg",
package: 'tencent_cloud_chat_uikit',
height: 64,
width: 64,
),
)),
if (PlatformUtils().isMobile)
MorePanelItem(
id: "take_video",
title: TIM_t("录像"),
onTap: (c) {
_onFeatureTap("take_video", c, model, theme);
},
icon: Container(
height: 64,
width: 64,
margin: const EdgeInsets.only(bottom: 4),
decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
child: Image.asset(
"images/take_video.png",
package: 'tencent_cloud_chat_uikit',
height: 64,
width: 64,
),
)),
if (PlatformUtils().isWeb) if (PlatformUtils().isWeb)
MorePanelItem( MorePanelItem(
id: "image", id: "image",
@ -180,9 +198,7 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
height: 64, height: 64,
width: 64, width: 64,
margin: const EdgeInsets.only(bottom: 4), margin: const EdgeInsets.only(bottom: 4),
decoration: const BoxDecoration( decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(5))),
child: SvgPicture.asset( child: SvgPicture.asset(
"images/photo.svg", "images/photo.svg",
package: 'tencent_cloud_chat_uikit', package: 'tencent_cloud_chat_uikit',
@ -206,11 +222,8 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
height: 64, height: 64,
width: 64, width: 64,
margin: const EdgeInsets.only(bottom: 4), margin: const EdgeInsets.only(bottom: 4),
decoration: const BoxDecoration( decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
color: Colors.white, child: Icon(Icons.video_file, color: hexToColor("5c6168"), size: 26),
borderRadius: BorderRadius.all(Radius.circular(5))),
child:
Icon(Icons.video_file, color: hexToColor("5c6168"), size: 26),
)), )),
MorePanelItem( MorePanelItem(
id: "file", id: "file",
@ -227,9 +240,7 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
height: 64, height: 64,
width: 64, width: 64,
margin: const EdgeInsets.only(bottom: 4), margin: const EdgeInsets.only(bottom: 4),
decoration: const BoxDecoration( decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(5))),
child: SvgPicture.asset( child: SvgPicture.asset(
"images/file.svg", "images/file.svg",
package: 'tencent_cloud_chat_uikit', package: 'tencent_cloud_chat_uikit',
@ -253,9 +264,7 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
height: 64, height: 64,
width: 64, width: 64,
margin: const EdgeInsets.only(bottom: 4), margin: const EdgeInsets.only(bottom: 4),
decoration: const BoxDecoration( decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(5))),
child: SvgPicture.asset( child: SvgPicture.asset(
"images/video-call.svg", "images/video-call.svg",
package: 'tencent_cloud_chat_uikit', package: 'tencent_cloud_chat_uikit',
@ -279,9 +288,7 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
height: 64, height: 64,
width: 64, width: 64,
margin: const EdgeInsets.only(bottom: 4), margin: const EdgeInsets.only(bottom: 4),
decoration: const BoxDecoration( decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(5))),
child: SvgPicture.asset( child: SvgPicture.asset(
"images/voice-call.svg", "images/voice-call.svg",
package: 'tencent_cloud_chat_uikit', package: 'tencent_cloud_chat_uikit',
@ -320,28 +327,21 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
}).toList(); }).toList();
} }
_sendVideoMessage(AssetEntity asset, int size, TUIChatSeparateViewModel model) async { _sendVideoMessage(String originFilePath, int duration, int size, TUIChatSeparateViewModel model) async {
if (size >= MorePanelConfig.VIDEO_MAX_SIZE) { if (size >= MorePanelConfig.VIDEO_MAX_SIZE) {
onTIMCallback(TIMCallback( onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("文件大小超出了限制")));
type: TIMCallbackType.INFO,
infoRecommendText: TIM_t("文件大小超出了限制")));
return; return;
} }
final plugin = FcNativeVideoThumbnail(); final plugin = FcNativeVideoThumbnail();
final originFile = await asset.originFile;
final duration = asset.videoDuration.inSeconds;
final filePath = originFile!.path;
final convID = widget.conversationID; final convID = widget.conversationID;
final convType = widget.conversationType; final convType = widget.conversationType;
String tempPath = (await getTemporaryDirectory()).path + String tempPath = (await getTemporaryDirectory()).path + p.basename(originFilePath) + ".jpeg";
p.basename(originFile.path) +
".jpeg";
await plugin.getVideoThumbnail( await plugin.getVideoThumbnail(
srcFile: originFile.path, srcFile: originFilePath,
destFile: tempPath, destFile: tempPath,
format: 'jpeg', format: 'jpeg',
width: 1280, width: 1280,
@ -350,11 +350,7 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
); );
MessageUtils.handleMessageError( MessageUtils.handleMessageError(
model.sendVideoMessage( model.sendVideoMessage(
videoPath: filePath, videoPath: originFilePath, duration: duration, snapshotPath: tempPath, convID: convID, convType: convType),
duration: duration,
snapshotPath: tempPath,
convID: convID,
convType: convType),
context); context);
} }
@ -414,46 +410,34 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
if (filePath != null) { if (filePath != null) {
if (type == AssetType.image) { if (type == AssetType.image) {
if (size >= MorePanelConfig.IMAGE_MAX_SIZE) { if (size >= MorePanelConfig.IMAGE_MAX_SIZE) {
onTIMCallback(TIMCallback( onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("文件大小超出了限制")));
type: TIMCallbackType.INFO,
infoRecommendText: TIM_t("文件大小超出了限制")));
return; return;
} }
MessageUtils.handleMessageError( MessageUtils.handleMessageError(
model.sendImageMessage( model.sendImageMessage(imagePath: filePath, convID: convID, convType: convType), context);
imagePath: filePath,
convID: convID,
convType: convType),
context);
} }
if (type == AssetType.video) { if (type == AssetType.video) {
_sendVideoMessage(asset, size, model); _sendVideoMessage(originFile!.path, asset.videoDuration.inSeconds, size, model);
} }
} }
} }
} }
} else { } else {
FilePickerResult? result = FilePickerResult? result = await FilePicker.platform.pickFiles(type: FileType.media);
await FilePicker.platform.pickFiles(type: FileType.media);
if (result != null && result.files.isNotEmpty) { if (result != null && result.files.isNotEmpty) {
File file = File(result.files.single.path!); File file = File(result.files.single.path!);
final String savePath = file.path; final String savePath = file.path;
final String type = TencentUtils.getFileType( final String type =
savePath.split(".")[savePath.split(".").length - 1]) TencentUtils.getFileType(savePath.split(".")[savePath.split(".").length - 1]).split("/")[0];
.split("/")[0];
if (type == "image") { if (type == "image") {
MessageUtils.handleMessageError( MessageUtils.handleMessageError(
model.sendImageMessage( model.sendImageMessage(imagePath: savePath, convID: convID, convType: convType), context);
imagePath: savePath, convID: convID, convType: convType),
context);
} else if (type == "video") { } else if (type == "video") {
MessageUtils.handleMessageError( MessageUtils.handleMessageError(
model.sendVideoMessage( model.sendVideoMessage(videoPath: savePath, convID: convID, convType: convType), context);
videoPath: savePath, convID: convID, convType: convType),
context);
} }
} else { } else {
throw TypeError(); throw TypeError();
@ -464,10 +448,7 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
} }
} }
_sendImageFromCamera( _sendImageFromCamera(TUIChatSeparateViewModel model, TUITheme theme, {required isVideo}) async {
TUIChatSeparateViewModel model,
TUITheme theme,
) async {
try { try {
if (!await Permissions.checkPermission( if (!await Permissions.checkPermission(
context, context,
@ -484,34 +465,41 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
final convID = widget.conversationID; final convID = widget.conversationID;
final convType = widget.conversationType; final convType = widget.conversationType;
final pickedFile = await CameraPicker.pickFromCamera(context, final ImagePicker picker = ImagePicker();
pickerConfig: CameraPickerConfig( XFile? originFile;
enableRecording: true, if (isVideo) {
textDelegate: IntlCameraPickerTextDelegate())); originFile = await picker.pickVideo(source: ImageSource.camera);
final originFile = await pickedFile?.originFile; } else {
if (originFile != null) { originFile = await picker.pickImage(source: ImageSource.camera);
final type = pickedFile!.type; }
final size = await originFile!.length(); final size = await originFile!.length();
if (type == AssetType.image) { if (!isVideo) {
if (size >= MorePanelConfig.IMAGE_MAX_SIZE) { if (size >= MorePanelConfig.IMAGE_MAX_SIZE) {
onTIMCallback(TIMCallback( onTIMCallback(
type: TIMCallbackType.INFO, TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("文件大小超出了限制")));
infoRecommendText: TIM_t("文件大小超出了限制")));
return; return;
} }
MessageUtils.handleMessageError( MessageUtils.handleMessageError(
model.sendImageMessage( model.sendImageMessage(imagePath: originFile.path, convID: convID, convType: convType),
imagePath: originFile.path,
convID: convID,
convType: convType),
context); context);
}
if (type == AssetType.video) {
_sendVideoMessage(pickedFile, size, model);
}
} else { } else {
// Toast.showToast(ToastType.fail, TIM_t("图片不能为空"), context); //
_betterPlayerController.addEventsListener((event) {
if (event.betterPlayerEventType == BetterPlayerEventType.initialized) {
//
int durationInSeconds = _betterPlayerController.videoPlayerController?.value.duration?.inSeconds ?? 0;
_sendVideoMessage(originFile!.path, durationInSeconds, size, model);
}
});
//
_betterPlayerController.setupDataSource(
BetterPlayerDataSource(
BetterPlayerDataSourceType.file,
originFile.path, // URL
),
);
} }
} catch (error) { } catch (error) {
outputLogger.i("err: $error"); outputLogger.i("err: $error");
@ -527,17 +515,12 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
fileContent = imageContent; fileContent = imageContent;
html.Node? inputElem; html.Node? inputElem;
inputElem = html.document inputElem = html.document.getElementById("__image_picker_web-file-input")?.querySelector("input");
.getElementById("__image_picker_web-file-input")
?.querySelector("input");
final convID = widget.conversationID; final convID = widget.conversationID;
final convType = widget.conversationType; final convType = widget.conversationType;
MessageUtils.handleMessageError( MessageUtils.handleMessageError(
model.sendImageMessage( model.sendImageMessage(
inputElement: inputElem, inputElement: inputElem, imagePath: tempFile?.path, convID: convID, convType: convType),
imagePath: tempFile?.path,
convID: convID,
convType: convType),
context); context);
} catch (e) { } catch (e) {
outputLogger.i("_sendFileErr: ${e.toString()}"); outputLogger.i("_sendFileErr: ${e.toString()}");
@ -553,25 +536,18 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
fileContent = videoContent; fileContent = videoContent;
if (fileName!.split(".")[fileName!.split(".").length - 1] != "mp4") { if (fileName!.split(".")[fileName!.split(".").length - 1] != "mp4") {
onTIMCallback(TIMCallback( onTIMCallback(
type: TIMCallbackType.INFO, TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频消息仅限 mp4 格式"), infoCode: 6660412));
infoRecommendText: TIM_t("视频消息仅限 mp4 格式"),
infoCode: 6660412));
return; return;
} }
html.Node? inputElem; html.Node? inputElem;
inputElem = html.document inputElem = html.document.getElementById("__image_picker_web-file-input")?.querySelector("input");
.getElementById("__image_picker_web-file-input")
?.querySelector("input");
final convID = widget.conversationID; final convID = widget.conversationID;
final convType = widget.conversationType; final convType = widget.conversationType;
MessageUtils.handleMessageError( MessageUtils.handleMessageError(
model.sendVideoMessage( model.sendVideoMessage(
inputElement: inputElem, inputElement: inputElem, videoPath: tempFile?.path, convID: convID, convType: convType),
videoPath: tempFile?.path,
convID: convID,
convType: convType),
context); context);
} catch (e) { } catch (e) {
outputLogger.i("_sendFileErr: ${e.toString()}"); outputLogger.i("_sendFileErr: ${e.toString()}");
@ -589,43 +565,29 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
if (result != null && result.files.isNotEmpty) { if (result != null && result.files.isNotEmpty) {
if (PlatformUtils().isWeb) { if (PlatformUtils().isWeb) {
html.Node? inputElem; html.Node? inputElem;
inputElem = html.document inputElem = html.document.getElementById("__file_picker_web-file-input")?.querySelector("input");
.getElementById("__file_picker_web-file-input")
?.querySelector("input");
fileName = result.files.single.name; fileName = result.files.single.name;
MessageUtils.handleMessageError( MessageUtils.handleMessageError(
model.sendFileMessage( model.sendFileMessage(inputElement: inputElem, fileName: fileName, convID: convID, convType: convType),
inputElement: inputElem,
fileName: fileName,
convID: convID,
convType: convType),
context); context);
return; return;
} }
String? option2 = result.files.single.path ?? ""; String? option2 = result.files.single.path ?? "";
outputLogger outputLogger.i(TIM_t_para("选择成功{{option2}}", "选择成功$option2")(option2: option2));
.i(TIM_t_para("选择成功{{option2}}", "选择成功$option2")(option2: option2));
File file = File(result.files.single.path!); File file = File(result.files.single.path!);
final int size = file.lengthSync(); final int size = file.lengthSync();
if (size >= MorePanelConfig.FILE_MAX_SIZE) { if (size >= MorePanelConfig.FILE_MAX_SIZE) {
onTIMCallback(TIMCallback( onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("文件大小超出了限制")));
type: TIMCallbackType.INFO,
infoRecommendText: TIM_t("文件大小超出了限制")));
return; return;
} }
final String savePath = file.path; final String savePath = file.path;
MessageUtils.handleMessageError( MessageUtils.handleMessageError(
model.sendFileMessage( model.sendFileMessage(filePath: savePath, size: size, convID: convID, convType: convType), context);
filePath: savePath,
size: size,
convID: convID,
convType: convType),
context);
} else { } else {
throw TypeError(); throw TypeError();
} }
@ -644,8 +606,11 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
case "photo": case "photo":
_sendImageMessage(model, theme); _sendImageMessage(model, theme);
break; break;
case "screen": case "take_photo":
_sendImageFromCamera(model, theme); _sendImageFromCamera(model, theme, isVideo: false);
break;
case "take_video":
_sendImageFromCamera(model, theme, isVideo: true);
break; break;
case "file": case "file":
_sendFile(model, theme); _sendFile(model, theme);
@ -673,14 +638,12 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
bool hasMicrophonePermission = false; bool hasMicrophonePermission = false;
if (type == TYPE_VIDEO) { if (type == TYPE_VIDEO) {
hasCameraPermission = await Permissions.checkPermission(context, Permission.camera.value); hasCameraPermission = await Permissions.checkPermission(context, Permission.camera.value);
hasMicrophonePermission = await Permissions.checkPermission( hasMicrophonePermission = await Permissions.checkPermission(context, Permission.microphone.value);
context, Permission.microphone.value);
if (!hasCameraPermission || !hasMicrophonePermission) { if (!hasCameraPermission || !hasMicrophonePermission) {
return; return;
} }
} else { } else {
hasMicrophonePermission = await Permissions.checkPermission( hasMicrophonePermission = await Permissions.checkPermission(context, Permission.microphone.value);
context, Permission.microphone.value);
if (!hasMicrophonePermission) { if (!hasMicrophonePermission) {
return; return;
} }
@ -702,9 +665,7 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
_tUICore.callService(TUICALLKIT_SERVICE_NAME, METHOD_NAME_CALL, { _tUICore.callService(TUICALLKIT_SERVICE_NAME, METHOD_NAME_CALL, {
PARAM_NAME_TYPE: type, PARAM_NAME_TYPE: type,
PARAM_NAME_USERIDS: inviteMember, PARAM_NAME_USERIDS: inviteMember,
PARAM_NAME_GROUPID: widget.conversationType == ConvType.group PARAM_NAME_GROUPID: widget.conversationType == ConvType.group ? widget.conversationID : ""
? widget.conversationID
: ""
}); });
} }
} else { } else {
@ -716,11 +677,16 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
} }
} }
@override
void dispose() {
_betterPlayerController?.dispose();
super.dispose();
}
@override @override
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
final TUITheme theme = value.theme; final TUITheme theme = value.theme;
final TUIChatSeparateViewModel model = final TUIChatSeparateViewModel model = Provider.of<TUIChatSeparateViewModel>(context);
Provider.of<TUIChatSeparateViewModel>(context);
final screenWidth = MediaQuery.of(context).size.width; final screenWidth = MediaQuery.of(context).size.width;
return Container( return Container(
height: 248, height: 248,
@ -757,15 +723,12 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
height: 64, height: 64,
width: 64, width: 64,
margin: const EdgeInsets.only(bottom: 4), margin: const EdgeInsets.only(bottom: 4),
decoration: const BoxDecoration( decoration: const BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5))),
borderRadius:
BorderRadius.all(Radius.circular(5))),
child: item.icon, child: item.icon,
), ),
Text( Text(
item.title, item.title,
style: TextStyle( style: TextStyle(fontSize: 12, color: theme.darkTextColor),
fontSize: 12, color: theme.darkTextColor),
) )
], ],
), ),

View File

@ -5,8 +5,8 @@ import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
@ -16,6 +16,8 @@ import 'package:tencent_cloud_chat_uikit/ui/utils/permission.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/sound_record.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/sound_record.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_base.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class SendSoundMessage extends StatefulWidget { class SendSoundMessage extends StatefulWidget {
/// conversation ID /// conversation ID

View File

@ -7,6 +7,11 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:scroll_to_index/scroll_to_index.dart'; import 'package:scroll_to_index/scroll_to_index.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/enum/group_member_role.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.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_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
@ -142,8 +147,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;
@ -155,28 +159,42 @@ 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}",
isEmoji: tccEmojiSet.isEmoji, isEmoji: tccEmojiSet.isEmoji,
isDefaultEmoji: true, isDefaultEmoji: true,
stickerList: tccEmojiSet.list stickerList: tccEmojiSet.list.asMap().keys.map((idx) => CustomSticker(index: idx, name: tccEmojiSet.list[idx])).toList(),
.asMap()
.keys
.map((idx) =>
CustomSticker(index: idx, name: tccEmojiSet.list[idx]))
.toList(),
menuItem: CustomSticker( menuItem: CustomSticker(
index: 0, index: 0,
name: tccEmojiSet.icon, 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; return stickerPackageList;
} }
@ -204,8 +222,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
@ -214,23 +231,18 @@ 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 = TextSelection.fromPosition(TextPosition(offset: currentCursor ?? textEditingController.text.length));
TextPosition(
offset: currentCursor ?? textEditingController.text.length));
focusNode.requestFocus(); focusNode.requestFocus();
} }
} }
@ -250,9 +262,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;
@ -263,8 +273,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
} }
if (TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop) { if (TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop) {
textEditingController.selection = TextSelection.fromPosition(TextPosition( textEditingController.selection = TextSelection.fromPosition(TextPosition(offset: currentCursor ?? textEditingController.text.length));
offset: currentCursor ?? textEditingController.text.length));
focusNode.requestFocus(); focusNode.requestFocus();
} }
} }
@ -273,23 +282,13 @@ 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#");
String conversationID = isTopic String conversationID = isTopic ? convID : ((convType ?? widget.conversationType) == ConvType.c2c ? "${TUIConversationViewModel.conversationC2CPrefix}$convID" : "${TUIConversationViewModel.conversationGroupPrefix}$convID");
? convID
: ((convType ?? widget.conversationType) == ConvType.c2c
? "${TUIConversationViewModel.conversationC2CPrefix}$convID"
: "${TUIConversationViewModel.conversationGroupPrefix}$convID");
String draftText = _filterU200b(text); String draftText = _filterU200b(text);
return await conversationModel.setConversationDraft( return await conversationModel.setConversationDraft(groupID: groupID ?? widget.groupID, isTopic: isTopic, isAllowWeb: widget.model.chatConfig.isUseDraftOnWeb, conversationID: conversationID, draftText: draftText);
groupID: groupID ?? widget.groupID,
isTopic: isTopic,
isAllowWeb: widget.model.chatConfig.isUseDraftOnWeb,
conversationID: conversationID,
draftText: draftText);
} }
// onSubmitted一样 // onSubmitted一样
@ -330,28 +329,26 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
// This part of the code is written to adapt to the Native side requirements. // This part of the code is written to adapt to the Native side requirements.
// It extracts the substring needed to interact with Native side by splitting // It extracts the substring needed to interact with Native side by splitting
// and parsing the given data value. // and parsing the given data value.
int groupID = 1;
if (data.contains("yz")) {
groupID = 1;
}
if (data.contains("ys")) {
groupID = 2;
}
if (data.contains("gcs")) {
groupID = 3;
}
RegExp regex = RegExp(r'assets\/custom_face_resource\/(4350|4351|4352)'); RegExp regex = RegExp(r'assets\/custom_face_resource\/(4350|4351|4352)');
if (regex.hasMatch(data)) { if (regex.hasMatch(data)) {
index += 1;
data = (data.split("/")[3]).split("@")[0]; data = (data.split("/")[3]).split("@")[0];
} }
if (widget.model.repliedMessage != null) { if (widget.model.repliedMessage != null) {
MessageUtils.handleMessageError( MessageUtils.handleMessageError(widget.model.sendFaceMessage(index: groupID, data: data, convID: widget.conversationID, convType: convType), context);
widget.model.sendFaceMessage(
index: index,
data: data,
convID: widget.conversationID,
convType: convType),
context);
} else { } else {
MessageUtils.handleMessageError( MessageUtils.handleMessageError(widget.model.sendFaceMessage(index: groupID, data: data, convID: widget.conversationID, convType: convType), context);
widget.model.sendFaceMessage(
index: index,
data: data,
convID: widget.conversationID,
convType: convType),
context);
} }
} }
@ -371,24 +368,11 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
final convType = widget.conversationType; final convType = widget.conversationType;
if (text.isNotEmpty && text != zeroWidthSpace) { if (text.isNotEmpty && text != zeroWidthSpace) {
if (widget.model.repliedMessage != null) { if (widget.model.repliedMessage != null) {
MessageUtils.handleMessageError( MessageUtils.handleMessageError(widget.model.sendReplyMessage(text: text, convID: widget.conversationID, convType: convType, atUserIDList: getUserIdFromMemberInfoMap()), context);
widget.model.sendReplyMessage(
text: text,
convID: widget.conversationID,
convType: convType,
atUserIDList: getUserIdFromMemberInfoMap()),
context);
} else if (mentionedMembersMap.isNotEmpty) { } else if (mentionedMembersMap.isNotEmpty) {
widget.model.sendTextAtMessage( widget.model.sendTextAtMessage(text: text, convType: widget.conversationType, convID: widget.conversationID, atUserList: getUserIdFromMemberInfoMap());
text: text,
convType: widget.conversationType,
convID: widget.conversationID,
atUserList: getUserIdFromMemberInfoMap());
} else { } else {
MessageUtils.handleMessageError( MessageUtils.handleMessageError(widget.model.sendTextMessage(text: text, convID: widget.conversationID, convType: convType), context);
widget.model.sendTextMessage(
text: text, convID: widget.conversationID, convType: convType),
context);
} }
textEditingController.clear(); textEditingController.clear();
currentCursor = null; currentCursor = null;
@ -401,8 +385,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), () {
@ -431,18 +414,14 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
} }
String _getShowName(V2TimGroupMemberFullInfo? item) { String _getShowName(V2TimGroupMemberFullInfo? item) {
return TencentUtils.checkStringWithoutSpace(item?.nameCard) ?? return TencentUtils.checkStringWithoutSpace(item?.nameCard) ?? TencentUtils.checkStringWithoutSpace(item?.nickName) ?? TencentUtils.checkStringWithoutSpace(item?.userID) ?? "";
TencentUtils.checkStringWithoutSpace(item?.nickName) ??
TencentUtils.checkStringWithoutSpace(item?.userID) ??
"";
} }
mentionMemberInMessage(String? userID, String? nickName) { mentionMemberInMessage(String? userID, String? nickName) {
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,
@ -453,8 +432,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;
@ -482,16 +460,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);
} }
@ -528,19 +500,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);
@ -559,11 +525,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;
@ -583,11 +546,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;
@ -597,14 +558,13 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
} }
final int selfRole = widget.model.selfMemberInfo?.role ?? 0; final int selfRole = widget.model.selfMemberInfo?.role ?? 0;
final bool canAtAll = widget.model.chatConfig.isMemberCanAtAll final bool canAtAll = widget.model.chatConfig.isMemberCanAtAll ? true : (selfRole == GroupMemberRoleType
? true .V2TIM_GROUP_MEMBER_ROLE_ADMIN || selfRole
: (selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN || ==
selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER); 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;
@ -613,13 +573,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;
@ -632,28 +589,21 @@ 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) ??
"") "")
.toLowerCase(); .toLowerCase();
keyword ??= ""; keyword ??= "";
return element != null && return element != null && showName.contains(keyword!.toLowerCase()) && TencentUtils.checkString(showName) != null && element.userID != widget.model.selfMemberInfo?.userID;
showName.contains(keyword!.toLowerCase()) &&
TencentUtils.checkString(showName) != null &&
element.userID != widget.model.selfMemberInfo?.userID;
}) })
.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;
@ -676,11 +626,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
keyword ??= ""; keyword ??= "";
if (canAtAll && showAtMemberList.isNotEmpty && keyword!.isEmpty) { if (canAtAll && showAtMemberList.isNotEmpty && keyword!.isEmpty) {
showAtMemberList = [ showAtMemberList = [V2TimGroupMemberFullInfo(userID: "__kImSDK_MesssageAtALL__", nickName: TIM_t("所有人")), ...showAtMemberList];
V2TimGroupMemberFullInfo(
userID: "__kImSDK_MesssageAtALL__", nickName: TIM_t("所有人")),
...showAtMemberList
];
} }
model.activeAtIndex = 0; model.activeAtIndex = 0;
@ -692,19 +638,11 @@ 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) {
List<V2TimGroupMemberFullInfo> selectedAtMemberList =
await Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => AtText( builder: (context) => AtText(groupMemberList: model.groupMemberList, groupInfo: model.groupInfo, groupID: groupID, canAtAll: canAtAll, groupType: widget.groupType),
groupMemberList: model.groupMemberList,
groupInfo: model.groupInfo,
groupID: groupID,
canAtAll: canAtAll,
groupType: widget.groupType),
), ),
); );
@ -714,8 +652,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
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 ";
} }
} }
@ -726,22 +663,17 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
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;
@ -755,24 +687,17 @@ 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.enter) || (event.physicalKey == PhysicalKeyboardKey.numpadEnter);
(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) && isPressEnter) {
event.isAltPressed ||
event.isControlPressed ||
event.isMetaPressed) &&
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;
@ -782,34 +707,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;
} }
} }
@ -827,8 +744,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!;
} }
@ -836,10 +752,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;
}); });
@ -849,13 +762,11 @@ 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 = TextSelection.fromPosition(TextPosition(offset: textEditingController.text.length));
TextPosition(offset: textEditingController.text.length));
lastText = textEditingController.text; lastText = textEditingController.text;
focusNode.requestFocus(); focusNode.requestFocus();
return; return;
@ -873,18 +784,14 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
if (widget.conversationID != oldWidget.conversationID) { if (widget.conversationID != oldWidget.conversationID) {
mentionedMembersMap.clear(); mentionedMembersMap.clear();
handleSetDraftText( handleSetDraftText(id: oldWidget.conversationID, convType: oldWidget.conversationType, groupID: oldWidget.groupID);
id: oldWidget.conversationID,
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();
} }
@ -902,12 +809,8 @@ 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 = widget.model.groupMemberList?.firstWhere((item) => (item?.userID == userID))?.muteUntil ?? 0;
final int muteUntil = widget.model.groupMemberList
?.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;
@ -920,30 +823,22 @@ 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_OWNER);
(selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN ||
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;
}); });
}); });
} else if (selfModel.loginInfo?.userID != null && } else if (selfModel.loginInfo?.userID != null && await getMemberMuteStatus(selfModel.loginInfo!.userID!) && muteStatus != MuteStatus.me) {
await getMemberMuteStatus(selfModel.loginInfo!.userID!) &&
muteStatus != MuteStatus.me) {
Future.delayed(const Duration(seconds: 0), () { Future.delayed(const Duration(seconds: 0), () {
setState(() { setState(() {
muteStatus = MuteStatus.me; muteStatus = MuteStatus.me;
}); });
}); });
} else if (!(model.groupInfo?.isAllMuted ?? false) && } else if (!(model.groupInfo?.isAllMuted ?? false) && !(selfModel.loginInfo?.userID != null && await getMemberMuteStatus(selfModel.loginInfo!.userID!)) && muteStatus != MuteStatus.none) {
!(selfModel.loginInfo?.userID != null &&
await getMemberMuteStatus(selfModel.loginInfo!.userID!)) &&
muteStatus != MuteStatus.none) {
Future.delayed(const Duration(seconds: 0), () { Future.delayed(const Duration(seconds: 0), () {
setState(() { setState(() {
muteStatus = MuteStatus.none; muteStatus = MuteStatus.none;
@ -972,8 +867,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);
@ -993,8 +887,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

@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
enum ActionType { enum ActionType {
hideAllPanel, hideAllPanel,

View File

@ -5,6 +5,8 @@ import 'package:extended_text_field/extended_text_field.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.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_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
@ -12,6 +14,8 @@ import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_glo
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_setting_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_setting_model.dart';
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/optimize_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/optimize_utils.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/permission.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/permission.dart';

View File

@ -16,6 +16,9 @@ import 'package:package_info_plus/package_info_plus.dart';
import 'package:pasteboard/pasteboard.dart'; import 'package:pasteboard/pasteboard.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.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_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
@ -37,6 +40,9 @@ import 'package:universal_html/html.dart' as html;
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart'; import 'package:wechat_assets_picker/wechat_assets_picker.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class DesktopControlBarItem { class DesktopControlBarItem {
final String item; final String item;

Some files were not shown because too many files have changed in this diff Show More