tencent_cloud_chat_uikit source code update to version 4.0.5
This commit is contained in:
parent
ae3bf8be65
commit
be9c53aa25
19
CHANGELOG.md
19
CHANGELOG.md
|
|
@ -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
|
||||
* 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.
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
import 'package:example/TIMUIKitGroupProfileExample.dart';
|
||||
import 'package:example/TIMUIKitProfileExample.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';
|
||||
|
||||
class TIMUIKitChatExample extends StatelessWidget {
|
||||
|
|
@ -64,7 +65,6 @@ class TIMUIKitChatExample extends StatelessWidget {
|
|||
config: const TIMUIKitChatConfig(
|
||||
// 仅供演示,非全部配置项,实际使用中,可只传和默认项不同的参数,无需传入所有开关
|
||||
isAllowClickAvatar: true,
|
||||
isUseDefaultEmoji: true,
|
||||
isAllowLongPressMessage: true,
|
||||
isShowReadingStatus: true,
|
||||
isShowGroupReadingStatus: true,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// ignore_for_file: avoid_print, file_names, deprecated_member_use
|
||||
|
||||
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';
|
||||
|
||||
class TIMUIKitSearchExample extends StatelessWidget {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,21 @@
|
|||
// ignore_for_file: avoid_print
|
||||
|
||||
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 'TIMUIKitAddFriendExample.dart';
|
||||
import 'TIMUIKitAddGroupExample.dart';
|
||||
import 'TIMUIKitBlackListExample.dart';
|
||||
import 'TIMUIKitChatExample.dart';
|
||||
import 'TIMUIKitContactExample.dart';
|
||||
import 'TIMUIKitConversationExample.dart';
|
||||
import 'TIMUIKitGroupExample.dart';
|
||||
import 'TIMUIKitGroupProfileExample.dart';
|
||||
import 'TIMUIKitNewContactExample.dart';
|
||||
import 'TIMUIKitProfileExample.dart';
|
||||
import 'TIMUIKitSearchExample.dart';
|
||||
|
||||
void main() {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include <desktop_drop/desktop_drop_plugin.h>
|
||||
#include <file_selector_linux/file_selector_plugin.h>
|
||||
#include <image_clipboard/image_clipboard_plugin.h>
|
||||
#include <pasteboard/pasteboard_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 =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
|
||||
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 =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "PasteboardPlugin");
|
||||
pasteboard_plugin_register_with_registrar(pasteboard_registrar);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
desktop_drop
|
||||
file_selector_linux
|
||||
image_clipboard
|
||||
pasteboard
|
||||
url_launcher_linux
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import desktop_drop
|
|||
import device_info_plus
|
||||
import fc_native_video_thumbnail
|
||||
import file_selector_macos
|
||||
import image_clipboard
|
||||
import flutter_image_compress_macos
|
||||
import just_audio
|
||||
import package_info_plus
|
||||
import pasteboard
|
||||
|
|
@ -20,6 +20,7 @@ import shared_preferences_foundation
|
|||
import sqflite
|
||||
import tencent_cloud_chat_sdk
|
||||
import url_launcher_macos
|
||||
import video_player_avfoundation
|
||||
import wakelock_plus
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
|
|
@ -28,9 +29,9 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||
FcNativeVideoThumbnailPlugin.register(with: registry.registrar(forPlugin: "FcNativeVideoThumbnailPlugin"))
|
||||
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"))
|
||||
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
||||
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
|
||||
PasteboardPlugin.register(with: registry.registrar(forPlugin: "PasteboardPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
PhotoManagerPlugin.register(with: registry.registrar(forPlugin: "PhotoManagerPlugin"))
|
||||
|
|
@ -38,5 +39,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||
TencentCloudChatSdkPlugin.register(with: registry.registrar(forPlugin: "TencentCloudChatSdkPlugin"))
|
||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||
FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))
|
||||
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@ dependencies:
|
|||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^1.0.2
|
||||
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
|
||||
archive: ^3.3.0
|
||||
tencent_im_sdk_plugin_desktop: ^0.1.13
|
||||
|
||||
# dependency_overrides:
|
||||
# tencent_cloud_chat_sdk:
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
#include <desktop_drop/desktop_drop_plugin.h>
|
||||
#include <fc_native_video_thumbnail/fc_native_video_thumbnail_plugin_c_api.h>
|
||||
#include <file_selector_windows/file_selector_windows.h>
|
||||
#include <image_clipboard/image_clipboard_plugin_c_api.h>
|
||||
#include <pasteboard/pasteboard_plugin.h>
|
||||
#include <permission_handler_windows/permission_handler_windows_plugin.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"));
|
||||
FileSelectorWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
||||
ImageClipboardPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("ImageClipboardPluginCApi"));
|
||||
PasteboardPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("PasteboardPlugin"));
|
||||
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
|||
desktop_drop
|
||||
fc_native_video_thumbnail
|
||||
file_selector_windows
|
||||
image_clipboard
|
||||
pasteboard
|
||||
permission_handler_windows
|
||||
tencent_cloud_chat_sdk
|
||||
|
|
|
|||
|
|
@ -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});
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
class TUIKitBuildValue {
|
||||
// 这里预留以后可以扩展全局通用能力
|
||||
|
|
|
|||
|
|
@ -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/services_locatar.dart';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import 'package:flutter/cupertino.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/data_services/core/core_services_implements.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> {
|
||||
final CoreServicesImpl _coreServices = serviceLocator<CoreServicesImpl>();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import 'package:flutter/cupertino.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/data_services/core/core_services_implements.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 {
|
||||
final CoreServicesImpl _coreServices = serviceLocator<CoreServicesImpl>();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
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_im_base/tencent_im_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
|
||||
|
||||
typedef MessageFunction = Future<V2TimMessage?> Function(V2TimMessage message);
|
||||
|
||||
|
|
|
|||
|
|
@ -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/tencent_cloud_chat_uikit.dart';
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,17 @@
|
|||
import 'dart:convert';
|
||||
|
||||
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/data_services/group/group_services.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) {
|
||||
TencentImSDKPlugin.v2TIMManager.getGroupManager().setTopicInfo(
|
||||
topicInfo: V2TimTopicInfo(customString: categoryName),
|
||||
groupID: groupID, // 话题所在的群组id
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
class UserProfile {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
import 'dart:convert';
|
||||
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_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/data_services/core/core_services_implements.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
|
||||
|
|
|
|||
|
|
@ -7,6 +7,27 @@ import 'package:collection/collection.dart';
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_image_compress/flutter_image_compress.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/separate_models/tui_chat_model_tools.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 TUIChatModelTools tools = serviceLocator<TUIChatModelTools>();
|
||||
final TUISelfInfoViewModel selfModel = serviceLocator<TUISelfInfoViewModel>();
|
||||
final TUIConversationViewModel conversationViewModel =
|
||||
serviceLocator<TUIConversationViewModel>();
|
||||
final TUIConversationViewModel conversationViewModel = serviceLocator<TUIConversationViewModel>();
|
||||
final _uuid = const Uuid();
|
||||
|
||||
ChatLifeCycle? lifeCycle;
|
||||
|
|
@ -136,8 +156,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
|
||||
List<V2TimMessage> currentHistoryMsgList = getOriginMessageList();
|
||||
for (var v2TimMessage in currentHistoryMsgList) {
|
||||
if (_selectedPositions.containsKey(v2TimMessage.msgID) &&
|
||||
_selectedPositions[v2TimMessage.msgID]!) {
|
||||
if (_selectedPositions.containsKey(v2TimMessage.msgID) && _selectedPositions[v2TimMessage.msgID]!) {
|
||||
selectList.add(v2TimMessage);
|
||||
}
|
||||
}
|
||||
|
|
@ -370,6 +389,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
? haveMoreLatestData = false
|
||||
: tempHaveMoreData = false;
|
||||
|
||||
|
||||
// 获取当前聊天对话的历史消息列表
|
||||
final currentRecordList = globalModel.messageListMap[conversationID];
|
||||
|
||||
|
|
@ -479,10 +499,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
|
||||
_getMsgReadReceipt(List<V2TimMessage> message) async {
|
||||
final msgID = message
|
||||
.where((e) =>
|
||||
(e.isSelf ?? true) &&
|
||||
(e.needReadReceipt ?? false) &&
|
||||
(e.status == MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC))
|
||||
.where((e) => (e.isSelf ?? true) && (e.needReadReceipt ?? false) && (e.status == MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC))
|
||||
.map((e) => e.msgID ?? '')
|
||||
.toList();
|
||||
if (msgID.isNotEmpty) {
|
||||
|
|
@ -592,10 +609,10 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
}
|
||||
}
|
||||
|
||||
void _notify() {
|
||||
try {
|
||||
void _notify(){
|
||||
try{
|
||||
notifyListeners();
|
||||
} catch (e) {
|
||||
}catch(e){
|
||||
debugPrint(e.toString());
|
||||
}
|
||||
}
|
||||
|
|
@ -684,6 +701,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
String? cloudCustomData,
|
||||
String? localCustomData,
|
||||
bool? isEditStatusMessage = false,
|
||||
bool? isExcludedFromContentModeration,
|
||||
}) async {
|
||||
String receiver = convType == ConvType.c2c ? convID : '';
|
||||
String groupID = convType == ConvType.group ? convID : '';
|
||||
|
|
@ -703,6 +721,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
groupID: groupID,
|
||||
offlinePushInfo: offlinePushInfo,
|
||||
onlineUserOnly: onlineUserOnly ?? false,
|
||||
isExcludedFromContentModeration: isExcludedFromContentModeration ?? false,
|
||||
cloudCustomData: cloudCustomData ??
|
||||
(showC2cMessageEditStatus == true
|
||||
? json.encode({
|
||||
|
|
@ -924,8 +943,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
|
||||
_repliedMessage = null;
|
||||
final sendMsgRes = await _messageService.sendMessage(
|
||||
cloudCustomData: TencentUtils.checkString(
|
||||
messageInfoWithSender?.cloudCustomData) ??
|
||||
cloudCustomData:
|
||||
TencentUtils.checkString(messageInfoWithSender?.cloudCustomData) ??
|
||||
json.encode(cloudCustomData),
|
||||
id: textMessageInfo.id as String,
|
||||
offlinePushInfo: tools.buildMessagePushInfo(
|
||||
|
|
@ -1153,11 +1172,9 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
for (var conversation in conversationList) {
|
||||
final convID = conversation.groupID ?? conversation.userID ?? "";
|
||||
final convType = conversation.type;
|
||||
List<V2TimMessage> currentHistoryMsgList =
|
||||
globalModel.messageListMap[conversationID] ?? [];
|
||||
List<V2TimMessage> currentHistoryMsgList = globalModel.messageListMap[conversationID] ?? [];
|
||||
for (var message in selectedMessages) {
|
||||
final forwardMessageInfo =
|
||||
await _messageService.createForwardMessage(msgID: message.msgID!);
|
||||
final forwardMessageInfo = await _messageService.createForwardMessage(msgID: message.msgID!);
|
||||
final messageInfo = forwardMessageInfo!.messageInfo;
|
||||
if (messageInfo != null) {
|
||||
tools.setUserInfoForMessage(messageInfo, forwardMessageInfo.id);
|
||||
|
|
@ -1165,9 +1182,11 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
addSendingMessageID(messageInfo.id);
|
||||
// 如果转发的会话是当前会话,则直接添加到当前会话的消息列表中
|
||||
if (convID == conversationID) {
|
||||
if (globalModel.getMessageListPosition(convID) !=
|
||||
HistoryMessagePosition.notShowLatest) {
|
||||
currentHistoryMsgList = [messageInfo, ...currentHistoryMsgList];
|
||||
if (globalModel.getMessageListPosition(convID) != HistoryMessagePosition.notShowLatest) {
|
||||
currentHistoryMsgList = [
|
||||
messageInfo,
|
||||
...currentHistoryMsgList
|
||||
];
|
||||
globalModel.setMessageList(conversationID, currentHistoryMsgList);
|
||||
_notify();
|
||||
}
|
||||
|
|
@ -1202,8 +1221,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
for (var conversation in conversationList) {
|
||||
final convID = conversation.groupID ?? conversation.userID ?? "";
|
||||
final convType = conversation.type;
|
||||
List<V2TimMessage> currentHistoryMsgList =
|
||||
globalModel.messageListMap[conversationID] ?? [];
|
||||
List<V2TimMessage> currentHistoryMsgList = globalModel.messageListMap[conversationID] ?? [];
|
||||
final mergerMessageInfo = await _messageService.createMergerMessage(
|
||||
msgIDList: msgIDList,
|
||||
title: title,
|
||||
|
|
@ -1216,9 +1234,11 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
addSendingMessageID(messageInfo.id);
|
||||
// 如果转发的会话是当前会话,则直接添加到当前会话的消息列表中
|
||||
if (convID == conversationID) {
|
||||
if (globalModel.getMessageListPosition(convID) !=
|
||||
HistoryMessagePosition.notShowLatest) {
|
||||
currentHistoryMsgList = [messageInfo, ...currentHistoryMsgList];
|
||||
if (globalModel.getMessageListPosition(convID) != HistoryMessagePosition.notShowLatest) {
|
||||
currentHistoryMsgList = [
|
||||
messageInfo,
|
||||
...currentHistoryMsgList
|
||||
];
|
||||
globalModel.setMessageList(conversationID, currentHistoryMsgList);
|
||||
_notify();
|
||||
}
|
||||
|
|
@ -1247,14 +1267,16 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
return null;
|
||||
}
|
||||
|
||||
currentHistoryMsgList
|
||||
.removeWhere((element) => element.msgID == message.msgID);
|
||||
currentHistoryMsgList.removeWhere((element) => element.msgID == message.msgID);
|
||||
message.status = MessageStatus.V2TIM_MSG_STATUS_SENDING;
|
||||
addSendingMessageID(message.msgID);
|
||||
globalModel.setMessageList(convID, currentHistoryMsgList);
|
||||
if (globalModel.getMessageListPosition(conversationID) !=
|
||||
HistoryMessagePosition.notShowLatest) {
|
||||
currentHistoryMsgList = [message, ...currentHistoryMsgList];
|
||||
currentHistoryMsgList = [
|
||||
message,
|
||||
...currentHistoryMsgList
|
||||
];
|
||||
globalModel.setMessageList(conversationID, currentHistoryMsgList);
|
||||
_notify();
|
||||
}
|
||||
|
|
@ -1312,7 +1334,6 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
|
||||
Future<V2TimValueCallback<V2TimMessage>?>? sendMessageFromController({
|
||||
required V2TimMessage? messageInfo,
|
||||
|
||||
/// Offline push info
|
||||
OfflinePushInfo? offlinePushInfo,
|
||||
MessagePriorityEnum priority = MessagePriorityEnum.V2TIM_PRIORITY_NORMAL,
|
||||
|
|
@ -1351,6 +1372,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
offlinePushInfo: offlinePushInfo ??
|
||||
tools.buildMessagePushInfo(
|
||||
messageInfo, conversationID, conversationType ?? ConvType.c2c),
|
||||
isExcludedFromContentModeration: messageInfo.isExcludedFromContentModeration,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
|
|
@ -1427,8 +1449,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier {
|
|||
for (var msgID in msgIDs) {
|
||||
messageList.removeWhere((element) => element.msgID == msgID);
|
||||
}
|
||||
globalModel.setMessageList(conversationID, messageList,
|
||||
isDeleteMsg: true);
|
||||
globalModel.setMessageList(conversationID, messageList, isDeleteMsg: true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,20 @@
|
|||
// ignore_for_file: unnecessary_getters_setters, avoid_print
|
||||
|
||||
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/data_services/conversation/conversation_services.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/services_locatar.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/logger.dart';
|
||||
import 'package:tencent_im_base/tencent_im_base.dart';
|
||||
|
||||
class TUIGroupProfileModel extends ChangeNotifier {
|
||||
final CoreServicesImpl _coreServices = serviceLocator<CoreServicesImpl>();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
// ignore_for_file: avoid_print
|
||||
|
||||
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/model/profile_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_friendship_view_model.dart';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
// ignore_for_file: avoid_print, unnecessary_getters_setters, unused_element
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
|
@ -7,6 +6,21 @@ import 'dart:math';
|
|||
|
||||
import 'package:flutter/material.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/business_logic/life_cycle/chat_life_cycle.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,
|
||||
cloudCustomData: cloudCustomData,
|
||||
localCustomData: localCustomData,
|
||||
isExcludedFromContentModeration: messageInfo.isExcludedFromContentModeration ?? false,
|
||||
convID: convID,
|
||||
setInputField: setInputField,
|
||||
id: messageInfo.id as String,
|
||||
|
|
@ -892,6 +907,7 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass {
|
|||
bool? needReadReceipt,
|
||||
String? cloudCustomData,
|
||||
String? localCustomData,
|
||||
bool isExcludedFromContentModeration = false,
|
||||
}) async {
|
||||
String receiver = convType == ConvType.c2c ? convID : '';
|
||||
String groupID = convType == ConvType.group ? convID : '';
|
||||
|
|
@ -904,6 +920,7 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass {
|
|||
localCustomData: localCustomData,
|
||||
isExcludedFromUnreadCount: isExcludedFromUnreadCount ?? false,
|
||||
offlinePushInfo: offlinePushInfo,
|
||||
isExcludedFromContentModeration: isExcludedFromContentModeration,
|
||||
onlineUserOnly: onlineUserOnly ?? false,
|
||||
cloudCustomData: cloudCustomData ??
|
||||
json.encode({
|
||||
|
|
|
|||
|
|
@ -2,6 +2,11 @@
|
|||
|
||||
import 'package:collection/collection.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/view_models/tui_chat_global_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/ui/utils/platform.dart';
|
||||
|
||||
List<T> removeDuplicates<T>(
|
||||
List<T> list, bool Function(T first, T second) isEqual) {
|
||||
List<T> removeDuplicates<T>(List<T> list, bool Function(T first, T second) isEqual) {
|
||||
List<T> output = [];
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
bool found = false;
|
||||
|
|
@ -34,14 +38,10 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
static const String conversationC2CPrefix = "c2c_";
|
||||
static const String conversationGroupPrefix = "group_";
|
||||
|
||||
final TUISelfInfoViewModel selfInfoViewModel =
|
||||
serviceLocator<TUISelfInfoViewModel>();
|
||||
final ConversationService _conversationService =
|
||||
serviceLocator<ConversationService>();
|
||||
final FriendshipServices _friendshipServices =
|
||||
serviceLocator<FriendshipServices>();
|
||||
final TUIChatGlobalModel _chatGlobalModel =
|
||||
serviceLocator<TUIChatGlobalModel>();
|
||||
final TUISelfInfoViewModel selfInfoViewModel = serviceLocator<TUISelfInfoViewModel>();
|
||||
final ConversationService _conversationService = serviceLocator<ConversationService>();
|
||||
final FriendshipServices _friendshipServices = serviceLocator<FriendshipServices>();
|
||||
final TUIChatGlobalModel _chatGlobalModel = serviceLocator<TUIChatGlobalModel>();
|
||||
final MessageService _messageService = serviceLocator<MessageService>();
|
||||
late V2TimConversationListener _conversationListener;
|
||||
List<V2TimConversation?> _conversationList = [];
|
||||
|
|
@ -51,8 +51,7 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
bool _haveMoreData = true;
|
||||
int _totalUnReadCount = 0;
|
||||
String? _scrollToConversation;
|
||||
final TUIChatGlobalModel globalChatModel =
|
||||
serviceLocator<TUIChatGlobalModel>();
|
||||
final TUIChatGlobalModel globalChatModel = serviceLocator<TUIChatGlobalModel>();
|
||||
|
||||
String _nextSeq = "0";
|
||||
ConversationLifeCycle? _lifeCycle;
|
||||
|
|
@ -61,13 +60,10 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
if (PlatformUtils().isWeb) {
|
||||
try {
|
||||
_conversationList.sort((a, b) {
|
||||
return b!.lastMessage!.timestamp!
|
||||
.compareTo(a!.lastMessage!.timestamp!);
|
||||
return b!.lastMessage!.timestamp!.compareTo(a!.lastMessage!.timestamp!);
|
||||
});
|
||||
|
||||
final pinnedConversation = _conversationList
|
||||
.where((element) => element?.isPinned == true)
|
||||
.toList();
|
||||
final pinnedConversation = _conversationList.where((element) => element?.isPinned == true).toList();
|
||||
_conversationList.removeWhere((element) => element?.isPinned == true);
|
||||
_conversationList = [...pinnedConversation, ..._conversationList];
|
||||
// ignore: empty_catches
|
||||
|
|
@ -79,8 +75,7 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
}
|
||||
|
||||
V2TimConversation? getConversation(String conversationID) {
|
||||
return _conversationList.firstWhereOrNull(
|
||||
(element) => element?.conversationID == conversationID);
|
||||
return _conversationList.firstWhereOrNull((element) => element?.conversationID == conversationID);
|
||||
}
|
||||
|
||||
String? get scrollToConversation => _scrollToConversation;
|
||||
|
|
@ -127,8 +122,7 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
}
|
||||
|
||||
TUIConversationViewModel() {
|
||||
_conversationListener =
|
||||
V2TimConversationListener(onConversationChanged: (conversationList) {
|
||||
_conversationListener = V2TimConversationListener(onConversationChanged: (conversationList) {
|
||||
_onConversationListChanged(conversationList);
|
||||
}, onNewConversation: (conversationList) {
|
||||
_addNewConversation(conversationList);
|
||||
|
|
@ -141,7 +135,7 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
if (!PlatformUtils().isWeb) {
|
||||
loadInitConversation();
|
||||
}
|
||||
}, onConversationDeleted: (List<String> conversationIDList) {
|
||||
}, onConversationDeleted:(List<String> conversationIDList) {
|
||||
_onConversationDeleted(conversationIDList);
|
||||
for (var conversationID in conversationIDList) {
|
||||
String resultID = "";
|
||||
|
|
@ -174,8 +168,7 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
Future<void> loadData({required int count}) async {
|
||||
_haveMoreData = true;
|
||||
final isRefresh = _nextSeq == "0";
|
||||
final conversationResult = await _conversationService.getConversationList(
|
||||
nextSeq: _nextSeq, count: count);
|
||||
final conversationResult = await _conversationService.getConversationList(nextSeq: _nextSeq, count: count);
|
||||
_nextSeq = conversationResult?.nextSeq ?? "";
|
||||
final conversationList = conversationResult?.conversationList;
|
||||
if (conversationList != null) {
|
||||
|
|
@ -188,12 +181,8 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
} else {
|
||||
combinedConversationList = [..._conversationList, ...conversationList];
|
||||
}
|
||||
final List<V2TimConversation?> finalConversationList = await _lifeCycle
|
||||
?.conversationListWillMount(combinedConversationList) ??
|
||||
combinedConversationList;
|
||||
_conversationList = removeDuplicates<V2TimConversation?>(
|
||||
finalConversationList,
|
||||
(item1, item2) => item1?.conversationID == item2?.conversationID);
|
||||
final List<V2TimConversation?> finalConversationList = await _lifeCycle?.conversationListWillMount(combinedConversationList) ?? combinedConversationList;
|
||||
_conversationList = removeDuplicates<V2TimConversation?>(finalConversationList, (item1, item2) => item1?.conversationID == item2?.conversationID);
|
||||
notifyListeners();
|
||||
}
|
||||
_totalUnReadCount = await _conversationService.getTotalUnreadCount();
|
||||
|
|
@ -210,15 +199,11 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
required String conversationID,
|
||||
required bool isPinned,
|
||||
}) {
|
||||
return _conversationService.pinConversation(
|
||||
conversationID: conversationID, isPinned: isPinned);
|
||||
return _conversationService.pinConversation(conversationID: conversationID, isPinned: isPinned);
|
||||
}
|
||||
|
||||
Future<V2TimCallback?> clearHistoryMessage(
|
||||
{required String convID, required int convType}) async {
|
||||
if (_lifeCycle?.shouldClearHistoricalMessageForConversation != null &&
|
||||
await _lifeCycle!.shouldClearHistoricalMessageForConversation(convID) ==
|
||||
false) {
|
||||
Future<V2TimCallback?> clearHistoryMessage({required String convID, required int convType}) async {
|
||||
if (_lifeCycle?.shouldClearHistoricalMessageForConversation != null && await _lifeCycle!.shouldClearHistoricalMessageForConversation(convID) == false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -232,22 +217,17 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
}
|
||||
|
||||
searchFriends(String searchKey) async {
|
||||
final res = await _friendshipServices.searchFriends(
|
||||
searchParam: V2TimFriendSearchParam(keywordList: [searchKey]));
|
||||
final res = await _friendshipServices.searchFriends(searchParam: V2TimFriendSearchParam(keywordList: [searchKey]));
|
||||
return res;
|
||||
}
|
||||
|
||||
Future<V2TimCallback?> deleteConversation(
|
||||
{required String conversationID}) async {
|
||||
if (_lifeCycle?.shouldDeleteConversation != null &&
|
||||
await _lifeCycle!.shouldDeleteConversation(conversationID) == false) {
|
||||
Future<V2TimCallback?> deleteConversation({required String conversationID}) async {
|
||||
if (_lifeCycle?.shouldDeleteConversation != null && await _lifeCycle!.shouldDeleteConversation(conversationID) == false) {
|
||||
return null;
|
||||
}
|
||||
final res = await _conversationService.deleteConversation(
|
||||
conversationID: conversationID);
|
||||
final res = await _conversationService.deleteConversation(conversationID: conversationID);
|
||||
if (res.code == 0) {
|
||||
_conversationList
|
||||
.removeWhere((element) => element?.conversationID == conversationID);
|
||||
_conversationList.removeWhere((element) => element?.conversationID == conversationID);
|
||||
notifyListeners();
|
||||
}
|
||||
return res;
|
||||
|
|
@ -255,11 +235,9 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
|
||||
_onConversationListChanged(List<V2TimConversation> list) {
|
||||
for (int element = 0; element < list.length; element++) {
|
||||
int index = _conversationList.indexWhere(
|
||||
(item) => item!.conversationID == list[element].conversationID);
|
||||
int index = _conversationList.indexWhere((item) => item!.conversationID == list[element].conversationID);
|
||||
if (index > -1) {
|
||||
_conversationList.setAll(
|
||||
index, [list[element]] as List<V2TimConversation?>);
|
||||
_conversationList.setAll(index, [list[element]] as List<V2TimConversation?>);
|
||||
} else {
|
||||
_conversationList.add(list[element]);
|
||||
}
|
||||
|
|
@ -270,13 +248,10 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
|
||||
_onConversationDeleted(List<String> list) {
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
int index = _conversationList
|
||||
.indexWhere((item) => item!.conversationID == list[i]);
|
||||
int index = _conversationList.indexWhere((item) => item!.conversationID == list[i]);
|
||||
if (index > -1) {
|
||||
_conversationList.removeAt(index);
|
||||
_conversationList = removeDuplicates<V2TimConversation?>(
|
||||
_conversationList,
|
||||
(item1, item2) => item1?.conversationID == item2?.conversationID);
|
||||
_conversationList = removeDuplicates<V2TimConversation?>(_conversationList, (item1, item2) => item1?.conversationID == item2?.conversationID);
|
||||
}
|
||||
}
|
||||
notifyListeners();
|
||||
|
|
@ -284,19 +259,16 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
|
||||
_addNewConversation(List<V2TimConversation> list) {
|
||||
_conversationList.addAll(list);
|
||||
_conversationList = removeDuplicates<V2TimConversation?>(_conversationList,
|
||||
(item1, item2) => item1?.conversationID == item2?.conversationID);
|
||||
_conversationList = removeDuplicates<V2TimConversation?>(_conversationList, (item1, item2) => item1?.conversationID == item2?.conversationID);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
setConversationListener() {
|
||||
_conversationService.addConversationListener(
|
||||
listener: _conversationListener);
|
||||
_conversationService.addConversationListener(listener: _conversationListener);
|
||||
}
|
||||
|
||||
removeConversationListener() {
|
||||
_conversationService.removeConversationListener(
|
||||
listener: _conversationListener);
|
||||
_conversationService.removeConversationListener(listener: _conversationListener);
|
||||
}
|
||||
|
||||
Future<V2TimCallback> setConversationDraft({
|
||||
|
|
@ -306,25 +278,19 @@ class TUIConversationViewModel extends ChangeNotifier {
|
|||
String? groupID,
|
||||
bool isAllowWeb = true,
|
||||
}) async {
|
||||
assert(!isTopic || (groupID != null && groupID.isNotEmpty),
|
||||
"When 'isTopic' is true, 'groupID' must not be null or empty.");
|
||||
assert(!isTopic || (groupID != null && groupID.isNotEmpty), "When 'isTopic' is true, 'groupID' must not be null or empty.");
|
||||
if (PlatformUtils().isWeb && isAllowWeb) {
|
||||
webDraftMap[conversationID] = draftText ?? "";
|
||||
return V2TimCallback(code: 0, desc: "");
|
||||
} else {
|
||||
if (isTopic) {
|
||||
final topicInfoList = await TencentImSDKPlugin.v2TIMManager
|
||||
.getGroupManager()
|
||||
.getTopicInfoList(groupID: groupID!, topicIDList: [conversationID]);
|
||||
final topicInfoList = await TencentImSDKPlugin.v2TIMManager.getGroupManager().getTopicInfoList(groupID: groupID!, topicIDList: [conversationID]);
|
||||
final topicInfo = topicInfoList.data?.first.topicInfo;
|
||||
topicInfo?.draftText = draftText;
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getGroupManager()
|
||||
.setTopicInfo(groupID: groupID, topicInfo: topicInfo!);
|
||||
final res = await TencentImSDKPlugin.v2TIMManager.getGroupManager().setTopicInfo(topicInfo: topicInfo!);
|
||||
return res;
|
||||
} else {
|
||||
return _conversationService.setConversationDraft(
|
||||
conversationID: conversationID, draftText: draftText);
|
||||
return _conversationService.setConversationDraft(conversationID: conversationID, draftText: draftText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,15 @@
|
|||
import 'dart:math';
|
||||
|
||||
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/friend_list_life_cycle.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/new_contact_life_cycle.dart';
|
||||
|
|
|
|||
|
|
@ -2,13 +2,19 @@
|
|||
|
||||
import 'package:collection/collection.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/services_locatar.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/group/group_services.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
|
||||
|
||||
enum KeywordListMatchType {
|
||||
V2TIM_KEYWORD_LIST_MATCH_TYPE_OR,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
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';
|
||||
|
||||
class TUISelfInfoViewModel extends ChangeNotifier {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
Future<V2TimConversationResult?> getConversationList({
|
||||
|
|
|
|||
|
|
@ -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/core/core_services_implements.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 {
|
||||
final CoreServicesImpl _coreService = serviceLocator<CoreServicesImpl>();
|
||||
|
|
@ -114,7 +119,7 @@ class ConversationServicesImpl extends ConversationService {
|
|||
{required String convID}) async {
|
||||
final result = await TencentImSDKPlugin.v2TIMManager
|
||||
.getConversationManager()
|
||||
.getConversationListByConversaionIds(conversationIDList: [convID]);
|
||||
.getConversationListByConversationIds(conversationIDList: [convID]);
|
||||
if (result.code != 0) {
|
||||
_coreService.callOnCallback(TIMCallback(
|
||||
type: TIMCallbackType.API_ERROR,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
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_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/theme/tui_theme.dart';
|
||||
|
||||
|
||||
enum AppStatus { foreground, background }
|
||||
|
|
|
|||
|
|
@ -2,11 +2,19 @@
|
|||
|
||||
import 'package:collection/collection.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/ui/utils/common_utils.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_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/view_models/tui_chat_global_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/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';
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:flutter/cupertino.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 {
|
||||
/// Control if show online status of friends or contacts.
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
Future<List<V2TimFriendInfoResult>?> getFriendsInfo({
|
||||
|
|
|
|||
|
|
@ -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/friendShip/friendship_services.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_im_base/tencent_im_base.dart';
|
||||
|
||||
class FriendshipServicesImpl implements FriendshipServices {
|
||||
final CoreServicesImpl _coreService = serviceLocator<CoreServicesImpl>();
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
Future<List<V2TimGroupInfo>?> getJoinedGroupList();
|
||||
|
|
|
|||
|
|
@ -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/group/group_services.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/optimize_utils.dart';
|
||||
import 'package:tencent_im_base/tencent_im_base.dart';
|
||||
|
||||
class GroupServicesImpl extends GroupServices {
|
||||
static List<Function?> groupInfoCallBackList = [];
|
||||
|
|
|
|||
|
|
@ -3,13 +3,32 @@
|
|||
import 'dart:math';
|
||||
|
||||
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/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/services_locatar.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_im_base/tencent_im_base.dart';
|
||||
|
||||
class MessageServiceImpl extends MessageService {
|
||||
final CoreServicesImpl _coreService = serviceLocator<CoreServicesImpl>();
|
||||
|
|
@ -349,6 +368,7 @@ class MessageServiceImpl extends MessageService {
|
|||
OfflinePushInfo? offlinePushInfo,
|
||||
String? cloudCustomData,
|
||||
String? localCustomData,
|
||||
bool isExcludedFromContentModeration = false,
|
||||
}) async {
|
||||
final result =
|
||||
await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessage(
|
||||
|
|
@ -361,6 +381,7 @@ class MessageServiceImpl extends MessageService {
|
|||
needReadReceipt: needReadReceipt,
|
||||
localCustomData: localCustomData,
|
||||
cloudCustomData: cloudCustomData,
|
||||
isExcludedFromContentModeration: isExcludedFromContentModeration,
|
||||
);
|
||||
if (result.code != 0) {
|
||||
String recommendText = ErrorMessageConverter.getErrorMessage(result.code);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
final bool haveMoreData;
|
||||
|
|
@ -71,7 +88,8 @@ abstract class MessageService {
|
|||
bool needReadReceipt = false,
|
||||
OfflinePushInfo? offlinePushInfo,
|
||||
String? cloudCustomData, // 云自定义消息字段,只能在消息发送前添加
|
||||
String? localCustomData});
|
||||
String? localCustomData,
|
||||
bool isExcludedFromContentModeration});
|
||||
|
||||
Future<V2TimValueCallback<V2TimMessage>> sendReplyMessage({
|
||||
required String id, // 自己创建的ID
|
||||
|
|
|
|||
|
|
@ -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/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_im_base/theme/tui_theme_view_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme_view_model.dart';
|
||||
|
||||
final serviceLocator = GetIt.instance;
|
||||
bool boolIsInitailized = false;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
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 '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
|
||||
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/TIMUIKitTextField/tim_uikit_text_field.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/column_menu.dart';
|
||||
export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card.dart';
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,13 @@
|
|||
|
||||
import 'package:flutter/cupertino.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/view_models/tui_chat_global_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
class TIMUIKitConversationController {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
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/ui/widgets/text_input_bottom_sheet.dart';
|
||||
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
class TIMUIKitProfileController {
|
||||
late TUIProfileViewModel model;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
static Map<int, String> errorCodeMap = {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
|
||||
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
|
||||
|
||||
final outputLogger = TencentCloudChatLog();
|
||||
|
|
|
|||
|
|
@ -2,12 +2,25 @@
|
|||
|
||||
import 'dart:convert';
|
||||
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/time.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/logger.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
class MessageUtils {
|
||||
// 判断CallingData的方式和Trtc的方法一致
|
||||
|
|
@ -274,7 +287,7 @@ class MessageUtils {
|
|||
|
||||
static Widget wrapMessageTips(Widget child, TUITheme? theme) {
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ import 'package:flutter/material.dart';
|
|||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:permission_handler/permission_handler.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_state.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 {
|
||||
final Function removeOverLay;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// ignore_for_file: prefer_typing_uninitialized_variables
|
||||
|
||||
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 {
|
||||
List<String> dayMap() {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import 'package:flutter/material.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/ui/utils/screen_utils.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_state.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/friendShip/friendship_services.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/widgets/avatar.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
class TIMUIKitAddFriend extends StatefulWidget {
|
||||
final bool? isShowDefaultGroup;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
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/ui/utils/screen_utils.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/data_services/friendShip/friendship_services.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/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
class SendApplication extends StatefulWidget {
|
||||
final V2TimUserFullInfo friendInfo;
|
||||
|
|
|
|||
|
|
@ -1,18 +1,22 @@
|
|||
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/ui/utils/screen_utils.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_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/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/group/group_services.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/widgets/avatar.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
|
||||
class TIMUIKitAddGroup extends StatefulWidget {
|
||||
/// The life cycle hooks for adding group business logic
|
||||
|
|
|
|||
|
|
@ -1,14 +1,18 @@
|
|||
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_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/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/group/group_services.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/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 {
|
||||
final V2TimGroupInfo groupInfo;
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_slidable_plus_plus/flutter_slidable_plus_plus.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/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/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/widgets/avatar.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(
|
||||
BuildContext context, V2TimFriendInfo friendInfo);
|
||||
|
|
@ -88,8 +89,7 @@ class _TIMUIKitBlackListState extends TIMUIKitState<TIMUIKitBlackList> {
|
|||
child: Text(
|
||||
showName,
|
||||
style: TextStyle(
|
||||
color: theme.black,
|
||||
fontSize: isDesktopScreen ? 14 : 18),
|
||||
color: theme.black, fontSize: isDesktopScreen ? 14 : 18),
|
||||
),
|
||||
)),
|
||||
if (isDesktopScreen)
|
||||
|
|
@ -133,6 +133,7 @@ class _TIMUIKitBlackListState extends TIMUIKitState<TIMUIKitBlackList> {
|
|||
return widget.itemBuilder ?? _itemBuilder;
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
return MultiProvider(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:provider/provider.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_state.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/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_im_base/tencent_im_base.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
class TIMUIKitHistoryMessageListTongueContainer extends StatefulWidget {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
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_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/theme/color.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
class TIMUIKitTongueItem extends TIMUIKitStatelessWidget {
|
||||
/// the callback after clicking
|
||||
|
|
|
|||
|
|
@ -5,6 +5,11 @@ import 'package:flutter/material.dart';
|
|||
import 'package:loading_animation_widget/loading_animation_widget.dart';
|
||||
import 'package:provider/provider.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_state.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/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_container.dart';
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,13 @@ import 'package:flutter/gestures.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:loading_animation_widget/loading_animation_widget.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_state.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: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';
|
||||
|
||||
typedef MessageRowBuilder = Widget? Function(
|
||||
|
|
@ -58,8 +68,7 @@ typedef MessageRowBuilder = Widget? Function(
|
|||
Function onScrollToIndexBegin,
|
||||
);
|
||||
|
||||
typedef MessageNickNameBuilder = Widget Function(
|
||||
BuildContext context, V2TimMessage message, TUIChatSeparateViewModel model);
|
||||
typedef MessageNickNameBuilder = Widget Function(BuildContext context, V2TimMessage message, TUIChatSeparateViewModel model);
|
||||
|
||||
typedef MessageItemContent = Widget? Function(
|
||||
V2TimMessage message,
|
||||
|
|
@ -72,8 +81,7 @@ class MessageHoverControlItem {
|
|||
Widget icon;
|
||||
ValueChanged<TapDownDetails> onClick;
|
||||
|
||||
MessageHoverControlItem(
|
||||
{required this.name, required this.icon, required this.onClick});
|
||||
MessageHoverControlItem({required this.name, required this.icon, required this.onClick});
|
||||
}
|
||||
|
||||
class MessageItemBuilder {
|
||||
|
|
@ -141,11 +149,7 @@ class MessageToolTipItem {
|
|||
final String iconImageAsset;
|
||||
final VoidCallback onClick;
|
||||
|
||||
MessageToolTipItem(
|
||||
{required this.label,
|
||||
required this.id,
|
||||
required this.iconImageAsset,
|
||||
required this.onClick});
|
||||
MessageToolTipItem({required this.label, required this.id, required this.iconImageAsset, required this.onClick});
|
||||
}
|
||||
|
||||
class ToolTipsConfig {
|
||||
|
|
@ -171,12 +175,10 @@ class ToolTipsConfig {
|
|||
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.
|
||||
final Widget? Function(V2TimMessage message, Function() closeTooltip,
|
||||
[Key? key, BuildContext? context])? additionalItemBuilder;
|
||||
final Widget? Function(V2TimMessage message, Function() closeTooltip, [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`.
|
||||
List<MessageToolTipItem> Function(
|
||||
V2TimMessage message, Function() closeTooltip)? additionalMessageToolTips;
|
||||
List<MessageToolTipItem> Function(V2TimMessage message, Function() closeTooltip)? additionalMessageToolTips;
|
||||
|
||||
ToolTipsConfig(
|
||||
{this.showDeleteMessage = true,
|
||||
|
|
@ -187,8 +189,7 @@ class ToolTipsConfig {
|
|||
this.showCopyMessage = true,
|
||||
this.showForwardMessage = true,
|
||||
this.additionalMessageToolTips,
|
||||
@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.")
|
||||
@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.")
|
||||
this.additionalItemBuilder});
|
||||
}
|
||||
|
||||
|
|
@ -197,12 +198,10 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget {
|
|||
final V2TimMessage message;
|
||||
|
||||
/// tap remote user avatar callback function
|
||||
final void Function(String userID, TapDownDetails tapDetails)?
|
||||
onTapForOthersPortrait;
|
||||
final void Function(String userID, TapDownDetails tapDetails)? onTapForOthersPortrait;
|
||||
|
||||
/// secondary tap remote user avatar callback function
|
||||
final void Function(String userID, TapDownDetails tapDetails)?
|
||||
onSecondaryTapForOthersPortrait;
|
||||
final void Function(String userID, TapDownDetails tapDetails)? onSecondaryTapForOthersPortrait;
|
||||
|
||||
/// the function use for reply message, when click replied message can scroll to it.
|
||||
final Function? onScrollToIndex;
|
||||
|
|
@ -211,8 +210,7 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget {
|
|||
final Function? onScrollToIndexBegin;
|
||||
|
||||
/// the callback for long press event, except myself avatar
|
||||
final Function(String? userId, String? nickName)?
|
||||
onLongPressForOthersHeadPortrait;
|
||||
final Function(String? userId, String? nickName)? onLongPressForOthersHeadPortrait;
|
||||
|
||||
/// message item builder, works for customize all message types and row layout.
|
||||
final MessageItemBuilder? messageItemBuilder;
|
||||
|
|
@ -232,8 +230,7 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget {
|
|||
/// Auto mention user when send reply message
|
||||
final bool allowAtUserWhenReply;
|
||||
|
||||
@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")
|
||||
@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")
|
||||
|
||||
/// allow show user nick name
|
||||
final bool showNickName;
|
||||
|
|
@ -254,19 +251,16 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget {
|
|||
final EdgeInsetsGeometry? textPadding;
|
||||
|
||||
/// avatar builder
|
||||
final Widget Function(BuildContext context, V2TimMessage message)?
|
||||
userAvatarBuilder;
|
||||
final Widget Function(BuildContext context, V2TimMessage message)? userAvatarBuilder;
|
||||
|
||||
/// theme info for message and avatar
|
||||
final MessageThemeData? themeData;
|
||||
|
||||
/// builder for nick name row
|
||||
final Widget Function(BuildContext context, V2TimMessage message)?
|
||||
topRowBuilder;
|
||||
final Widget Function(BuildContext context, V2TimMessage message)? topRowBuilder;
|
||||
|
||||
/// builder for bottom raw which under message content
|
||||
final Widget Function(BuildContext context, V2TimMessage message)?
|
||||
bottomRowBuilder;
|
||||
final Widget Function(BuildContext context, V2TimMessage message)? bottomRowBuilder;
|
||||
|
||||
// open MessageReaction
|
||||
final bool? isUseMessageReaction;
|
||||
|
|
@ -284,9 +278,7 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget {
|
|||
const TIMUIKitHistoryMessageListItem(
|
||||
{Key? key,
|
||||
required this.message,
|
||||
@Deprecated(
|
||||
"Nickname will not show in one-to-one chat, if you tend to control it in group chat, please use `isShowSelfNameInGroup` and `isShowOthersNameInGroup` from `config: TIMUIKitChatConfig` instead")
|
||||
this.showNickName = false,
|
||||
@Deprecated("Nickname will not show in one-to-one chat, if you tend to control it in group chat, please use `isShowSelfNameInGroup` and `isShowOthersNameInGroup` from `config: TIMUIKitChatConfig` instead") this.showNickName = false,
|
||||
this.onScrollToIndex,
|
||||
this.onScrollToIndexBegin,
|
||||
this.onTapForOthersPortrait,
|
||||
|
|
@ -322,9 +314,7 @@ class TipsActionItem extends TIMUIKitStatelessWidget {
|
|||
final String icon;
|
||||
final String? package;
|
||||
|
||||
TipsActionItem(
|
||||
{Key? key, required this.label, required this.icon, this.package})
|
||||
: super(key: key);
|
||||
TipsActionItem({Key? key, required this.label, required this.icon, this.package}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
|
|
@ -352,16 +342,13 @@ class TipsActionItem extends TIMUIKitStatelessWidget {
|
|||
}
|
||||
}
|
||||
|
||||
class _TIMUIKItHistoryMessageListItemState
|
||||
extends TIMUIKitState<TIMUIKitHistoryMessageListItem>
|
||||
with SingleTickerProviderStateMixin {
|
||||
class _TIMUIKItHistoryMessageListItemState extends TIMUIKitState<TIMUIKitHistoryMessageListItem> with SingleTickerProviderStateMixin {
|
||||
SuperTooltip? tooltip;
|
||||
late AnimationController _animationController;
|
||||
|
||||
// ignore: unused_field
|
||||
final MessageService _messageService = serviceLocator<MessageService>();
|
||||
final TUISelfInfoViewModel selfInfoModel =
|
||||
serviceLocator<TUISelfInfoViewModel>();
|
||||
final TUISelfInfoViewModel selfInfoModel = serviceLocator<TUISelfInfoViewModel>();
|
||||
final TUIThemeViewModel themeModel = serviceLocator<TUIThemeViewModel>();
|
||||
|
||||
// bool isChecked = false;
|
||||
|
|
@ -372,9 +359,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_animationController =
|
||||
AnimationController(duration: const Duration(seconds: 1), vsync: this)
|
||||
..repeat();
|
||||
_animationController = AnimationController(duration: const Duration(seconds: 1), vsync: this)..repeat();
|
||||
}
|
||||
|
||||
closeTooltip() {
|
||||
|
|
@ -382,15 +367,10 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
}
|
||||
|
||||
bool isReplyMessage(V2TimMessage message) {
|
||||
final hasCustomData =
|
||||
message.cloudCustomData != null && message.cloudCustomData != "";
|
||||
final hasCustomData = message.cloudCustomData != null && message.cloudCustomData != "";
|
||||
if (hasCustomData) {
|
||||
try {
|
||||
final CloudCustomData messageCloudCustomData = CloudCustomData.fromJson(
|
||||
json.decode(
|
||||
TencentUtils.checkString(message.cloudCustomData) != null
|
||||
? message.cloudCustomData!
|
||||
: "{}"));
|
||||
final CloudCustomData messageCloudCustomData = CloudCustomData.fromJson(json.decode(TencentUtils.checkString(message.cloudCustomData) != null ? message.cloudCustomData! : "{}"));
|
||||
if (messageCloudCustomData.messageReply != null) {
|
||||
MessageRepliedData.fromJson(messageCloudCustomData.messageReply!);
|
||||
return true;
|
||||
|
|
@ -403,8 +383,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
return false;
|
||||
}
|
||||
|
||||
(bool isRevoke, bool isRevokeByAdmin) isRevokeMessage(
|
||||
V2TimMessage message, TUIChatSeparateViewModel model) {
|
||||
(bool isRevoke, bool isRevokeByAdmin) isRevokeMessage(V2TimMessage message, TUIChatSeparateViewModel model) {
|
||||
if (message.status == 6) {
|
||||
return (true, false);
|
||||
} else if (model.chatConfig.isGroupAdminRecallEnabled) {
|
||||
|
|
@ -420,11 +399,9 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
return (false, false);
|
||||
}
|
||||
|
||||
Widget _messageItemBuilder(
|
||||
V2TimMessage messageItem, TUIChatSeparateViewModel model) {
|
||||
Widget _messageItemBuilder(V2TimMessage messageItem, TUIChatSeparateViewModel model) {
|
||||
final msgType = messageItem.elemType;
|
||||
final isShowJump = (model.jumpMsgID == messageItem.msgID) &&
|
||||
(messageItem.msgID?.isNotEmpty ?? false);
|
||||
final isShowJump = (model.jumpMsgID == messageItem.msgID) && (messageItem.msgID?.isNotEmpty ?? false);
|
||||
final MessageItemBuilder? messageItemBuilder = widget.messageItemBuilder;
|
||||
final isFromSelf = messageItem.isSelf ?? true;
|
||||
void clearJump() {
|
||||
|
|
@ -435,8 +412,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
|
||||
switch (msgType) {
|
||||
case MessageElemType.V2TIM_ELEM_TYPE_CUSTOM:
|
||||
final customWidget =
|
||||
messageItemBuilder?.customMessageItemBuilder != null
|
||||
final customWidget = messageItemBuilder?.customMessageItemBuilder != null
|
||||
? messageItemBuilder!.customMessageItemBuilder!(
|
||||
messageItem,
|
||||
isShowJump,
|
||||
|
|
@ -480,8 +456,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
);
|
||||
case MessageElemType.V2TIM_ELEM_TYPE_TEXT:
|
||||
if (isReplyMessage(messageItem)) {
|
||||
final customWidget =
|
||||
messageItemBuilder?.textReplyMessageItemBuilder != null
|
||||
final customWidget = messageItemBuilder?.textReplyMessageItemBuilder != null
|
||||
? messageItemBuilder!.textReplyMessageItemBuilder!(
|
||||
messageItem,
|
||||
isShowJump,
|
||||
|
|
@ -561,8 +536,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
isShowMessageReaction: widget.isUseMessageReaction,
|
||||
);
|
||||
case MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS:
|
||||
final customWidget =
|
||||
messageItemBuilder?.groupTipsMessageItemBuilder != null
|
||||
final customWidget = messageItemBuilder?.groupTipsMessageItemBuilder != null
|
||||
? messageItemBuilder!.groupTipsMessageItemBuilder!(
|
||||
messageItem,
|
||||
isShowJump,
|
||||
|
|
@ -604,8 +578,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
isShowMessageReaction: widget.isUseMessageReaction,
|
||||
);
|
||||
case MessageElemType.V2TIM_ELEM_TYPE_LOCATION:
|
||||
final customWidget =
|
||||
messageItemBuilder?.locationMessageItemBuilder != null
|
||||
final customWidget = messageItemBuilder?.locationMessageItemBuilder != null
|
||||
? messageItemBuilder!.locationMessageItemBuilder!(
|
||||
messageItem,
|
||||
isShowJump,
|
||||
|
|
@ -614,8 +587,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
: null;
|
||||
return customWidget ?? Text(TIM_t("[位置]"));
|
||||
case MessageElemType.V2TIM_ELEM_TYPE_MERGER:
|
||||
final customWidget =
|
||||
messageItemBuilder?.mergerMessageItemBuilder != null
|
||||
final customWidget = messageItemBuilder?.mergerMessageItemBuilder != null
|
||||
? messageItemBuilder!.mergerMessageItemBuilder!(
|
||||
messageItem,
|
||||
isShowJump,
|
||||
|
|
@ -640,11 +612,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
|
||||
Widget _groupTipsMessageBuilder(TUIChatSeparateViewModel model) {
|
||||
final messageItem = widget.message;
|
||||
return Container(
|
||||
padding: const EdgeInsets.only(bottom: 20),
|
||||
child: TIMUIKitGroupTipsElem(
|
||||
groupTipsElem: messageItem.groupTipsElem!,
|
||||
groupMemberList: model.groupMemberList ?? []));
|
||||
return Container(padding: const EdgeInsets.only(bottom: 20), child: TIMUIKitGroupTipsElem(groupTipsElem: messageItem.groupTipsElem!, groupMemberList: model.groupMemberList ?? []));
|
||||
}
|
||||
|
||||
Widget _selfRevokeEditMessageBuilder(theme, TUIChatSeparateViewModel model) {
|
||||
|
|
@ -660,8 +628,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
text: TIM_t("重新编辑"),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
widget.textFieldController
|
||||
?.setTextField(widget.message.textElem?.text ?? "");
|
||||
widget.textFieldController?.setTextField(widget.message.textElem?.text ?? "");
|
||||
},
|
||||
style: TextStyle(color: theme.primaryColor),
|
||||
)
|
||||
|
|
@ -678,15 +645,12 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
));
|
||||
}
|
||||
|
||||
Widget _timeDividerBuilder(
|
||||
theme, int timeStamp, TUIChatSeparateViewModel model) {
|
||||
Widget _timeDividerBuilder(theme, int timeStamp, TUIChatSeparateViewModel model) {
|
||||
return Container(
|
||||
alignment: Alignment.center,
|
||||
margin: const EdgeInsets.symmetric(vertical: 20),
|
||||
child: Text(
|
||||
model.chatConfig.timeDividerConfig?.timestampParser != null
|
||||
? (model.chatConfig.timeDividerConfig?.timestampParser!(timeStamp))!
|
||||
: TimeAgo().getTimeForMessage(timeStamp),
|
||||
model.chatConfig.timeDividerConfig?.timestampParser != null ? (model.chatConfig.timeDividerConfig?.timestampParser!(timeStamp))! : TimeAgo().getTimeForMessage(timeStamp),
|
||||
style: widget.themeData?.timelineTextStyle ??
|
||||
TextStyle(
|
||||
fontSize: 12,
|
||||
|
|
@ -710,10 +674,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
width: 100,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(colors: [
|
||||
const Color(0x00C0E1FF),
|
||||
theme.primaryColor ?? CommonColor.lightPrimaryColor
|
||||
]),
|
||||
gradient: LinearGradient(colors: [const Color(0x00C0E1FF), theme.primaryColor ?? CommonColor.lightPrimaryColor]),
|
||||
)),
|
||||
),
|
||||
),
|
||||
|
|
@ -745,8 +706,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
);
|
||||
}
|
||||
|
||||
bool isRevocable(int timestamp) =>
|
||||
(DateTime.now().millisecondsSinceEpoch / 1000).ceil() - timestamp < 120;
|
||||
bool isRevocable(int timestamp) => (DateTime.now().millisecondsSinceEpoch / 1000).ceil() - timestamp < 120;
|
||||
|
||||
// TODO : 继续看这里
|
||||
|
||||
|
|
@ -767,38 +727,21 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
|
||||
final screenHeight = MediaQuery.of(context).size.height;
|
||||
final screenWidth = MediaQuery.of(context).size.width;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final isLongMessage =
|
||||
context.size!.height + 350 > screenHeight && !(isDesktopScreen);
|
||||
final tapDetails =
|
||||
(isDesktopScreen || isLongMessage) ? (details ?? _tapDetails) : details;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final isLongMessage = context.size!.height + 350 > screenHeight && !(isDesktopScreen);
|
||||
final tapDetails = (isDesktopScreen || isLongMessage) ? (details ?? _tapDetails) : details;
|
||||
final isSelf = message.isSelf ?? true;
|
||||
|
||||
final targetWidth =
|
||||
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 dy = min(
|
||||
tapDetails?.globalPosition.dy ?? MediaQuery.of(context).size.height,
|
||||
MediaQuery.of(context).size.height - 320)
|
||||
.toDouble();
|
||||
final targetWidth = 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 dy = min(tapDetails?.globalPosition.dy ?? MediaQuery.of(context).size.height, MediaQuery.of(context).size.height - 320).toDouble();
|
||||
final finalTapDetail = tapDetails != null
|
||||
? TapDownDetails(
|
||||
globalPosition: Offset(dx, dy),
|
||||
)
|
||||
: null;
|
||||
|
||||
initTools(
|
||||
context: c,
|
||||
model: model,
|
||||
isShowMoreSticker: isShowMoreSticker,
|
||||
details: finalTapDetail,
|
||||
theme: theme,
|
||||
isFromWideToolTip: isFromWideTooltip);
|
||||
initTools(context: c, model: model, isShowMoreSticker: isShowMoreSticker, details: finalTapDetail, theme: theme, isFromWideToolTip: isFromWideTooltip);
|
||||
tooltip!.show(c, targetCenter: finalTapDetail?.globalPosition);
|
||||
}
|
||||
|
||||
|
|
@ -811,26 +754,15 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
}
|
||||
}
|
||||
|
||||
Future<V2TimValueCallback<V2TimMessageChangeInfo>> _modifySticker(
|
||||
int sticker) async {
|
||||
Future<V2TimValueCallback<V2TimMessageChangeInfo>> _modifySticker(int sticker) async {
|
||||
return await Future.delayed(const Duration(milliseconds: 50), () async {
|
||||
return await MessageReactionUtils.clickOnSticker(widget.message, sticker);
|
||||
});
|
||||
}
|
||||
|
||||
initTools(
|
||||
{BuildContext? context,
|
||||
bool isLongMessage = false,
|
||||
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;
|
||||
initTools({BuildContext? context, bool isLongMessage = false, 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;
|
||||
double arrowTipDistance = 30;
|
||||
double arrowBaseWidth = 10;
|
||||
|
|
@ -839,8 +771,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
TooltipDirection popupDirection = TooltipDirection.up;
|
||||
double? left;
|
||||
double? right;
|
||||
SelectEmojiPanelPosition selectEmojiPanelPosition =
|
||||
SelectEmojiPanelPosition.down;
|
||||
SelectEmojiPanelPosition selectEmojiPanelPosition = SelectEmojiPanelPosition.down;
|
||||
if (context != null) {
|
||||
RenderBox? box = _key.currentContext?.findRenderObject() as RenderBox?;
|
||||
if (details != null && box != null) {
|
||||
|
|
@ -863,9 +794,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
Offset offset = box.localToGlobal(Offset.zero);
|
||||
double boxWidth = box.size.width;
|
||||
if (isSelf) {
|
||||
right = screenWidth -
|
||||
offset.dx -
|
||||
((isUseMessageReaction) ? boxWidth : (boxWidth / 1.3));
|
||||
right = screenWidth - offset.dx - ((isUseMessageReaction) ? boxWidth : (boxWidth / 1.3));
|
||||
} else {
|
||||
left = offset.dx;
|
||||
}
|
||||
|
|
@ -877,8 +806,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
popupDirection = TooltipDirection.down;
|
||||
}
|
||||
}
|
||||
arrowTipDistance = (context.size!.height / 2).roundToDouble() +
|
||||
(isLongMessage ? -120 : 10);
|
||||
arrowTipDistance = (context.size!.height / 2).roundToDouble() + (isLongMessage ? -120 : 10);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -918,8 +846,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
showCloseButton: ShowCloseButton.none,
|
||||
touchThroughAreaShape: ClipAreaShape.rectangle,
|
||||
content: TIMUIKitMessageTooltip(
|
||||
iSUseDefaultHoverBar: model.chatConfig.isUseMessageHoverBarOnDesktop &&
|
||||
widget.customMessageHoverBarOnDesktop == null,
|
||||
iSUseDefaultHoverBar: model.chatConfig.isUseMessageHoverBarOnDesktop && widget.customMessageHoverBarOnDesktop == null,
|
||||
model: model,
|
||||
groupMemberInfo: widget.groupMemberInfo,
|
||||
isShowMoreSticker: isShowMoreSticker ?? false,
|
||||
|
|
@ -927,8 +854,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
isUseMessageReaction: isUseMessageReaction,
|
||||
message: widget.message,
|
||||
allowAtUserWhenReply: widget.allowAtUserWhenReply,
|
||||
onLongPressForOthersHeadPortrait:
|
||||
widget.onLongPressForOthersHeadPortrait,
|
||||
onLongPressForOthersHeadPortrait: widget.onLongPressForOthersHeadPortrait,
|
||||
selectEmojiPanelPosition: selectEmojiPanelPosition,
|
||||
onCloseTooltip: () => tooltip?.close(),
|
||||
onSelectSticker: (int value) {
|
||||
|
|
@ -939,8 +865,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
);
|
||||
}
|
||||
|
||||
Widget _getMessageItemBuilder(V2TimMessage message, int? messageStatues,
|
||||
TUIChatSeparateViewModel model) {
|
||||
Widget _getMessageItemBuilder(V2TimMessage message, int? messageStatues, TUIChatSeparateViewModel model) {
|
||||
final messageBuilder = _messageItemBuilder;
|
||||
|
||||
return messageBuilder(widget.message, model);
|
||||
|
|
@ -982,8 +907,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
}
|
||||
}
|
||||
|
||||
List<MessageHoverControlItem> getWideMessageHoverControlBar(
|
||||
TUIChatSeparateViewModel model, TUITheme theme) {
|
||||
List<MessageHoverControlItem> getWideMessageHoverControlBar(TUIChatSeparateViewModel model, TUITheme theme) {
|
||||
return [
|
||||
if (widget.isUseMessageReaction ?? false)
|
||||
MessageHoverControlItem(
|
||||
|
|
@ -994,8 +918,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
color: hexToColor("8f959e"),
|
||||
),
|
||||
onClick: (details) {
|
||||
_onOpenToolTip(
|
||||
context, widget.message, model, theme, details, true, true);
|
||||
_onOpenToolTip(context, widget.message, model, theme, details, true, true);
|
||||
},
|
||||
),
|
||||
if (widget.toolTipsConfig?.showReplyMessage ?? true)
|
||||
|
|
@ -1009,21 +932,14 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
onClick: (_) {
|
||||
model.repliedMessage = widget.message;
|
||||
final isSelf = widget.message.isSelf ?? true;
|
||||
final isGroup =
|
||||
TencentUtils.checkString(widget.message.groupID) != null;
|
||||
final isAtWhenReply = !isSelf &&
|
||||
isGroup &&
|
||||
widget.allowAtUserWhenReply &&
|
||||
widget.onLongPressForOthersHeadPortrait != null;
|
||||
final isGroup = TencentUtils.checkString(widget.message.groupID) != null;
|
||||
final isAtWhenReply = !isSelf && isGroup && widget.allowAtUserWhenReply && widget.onLongPressForOthersHeadPortrait != null;
|
||||
|
||||
/// If replying to a self message, do not add a at tag, only requestFocus.
|
||||
widget.onLongPressForOthersHeadPortrait!(
|
||||
!isAtWhenReply ? null : widget.message.sender,
|
||||
!isAtWhenReply ? null : widget.message.nickName);
|
||||
widget.onLongPressForOthersHeadPortrait!(!isAtWhenReply ? null : widget.message.sender, !isAtWhenReply ? null : widget.message.nickName);
|
||||
},
|
||||
),
|
||||
if ((widget.toolTipsConfig?.showForwardMessage ?? true) &&
|
||||
!model.isVoteMessage(widget.message))
|
||||
if ((widget.toolTipsConfig?.showForwardMessage ?? true) && !model.isVoteMessage(widget.message))
|
||||
MessageHoverControlItem(
|
||||
name: TIM_t("转发"),
|
||||
icon: Icon(
|
||||
|
|
@ -1063,8 +979,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
color: hexToColor("8f959e"),
|
||||
),
|
||||
onClick: (details) {
|
||||
_onOpenToolTip(
|
||||
context, widget.message, model, theme, details, true, false);
|
||||
_onOpenToolTip(context, widget.message, model, theme, details, true, false);
|
||||
},
|
||||
),
|
||||
...?model.chatConfig.additionalDesktopMessageHoverBarItem
|
||||
|
|
@ -1074,37 +989,18 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
_onMsgSendFailIconTap(V2TimMessage message, TUIChatSeparateViewModel model) {
|
||||
final convID = model.conversationID;
|
||||
final convType = model.conversationType;
|
||||
MessageUtils.handleMessageError(
|
||||
model.reSendFailMessage(
|
||||
message: message,
|
||||
convType: convType ?? ConvType.c2c,
|
||||
convID: convID),
|
||||
context);
|
||||
MessageUtils.handleMessageError(model.reSendFailMessage(message: message, convType: convType ?? ConvType.c2c, convID: convID), context);
|
||||
}
|
||||
|
||||
Widget renderHoverTipAndReadStatus(
|
||||
TUIChatSeparateViewModel model,
|
||||
bool isSelf,
|
||||
V2TimMessage message,
|
||||
bool isPeerRead,
|
||||
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 : "";
|
||||
Widget renderHoverTipAndReadStatus(TUIChatSeparateViewModel model, bool isSelf, V2TimMessage message, bool isPeerRead, 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 秒渲染,否则立即渲染
|
||||
Future<void> _conditionalDelay() async {
|
||||
if (!(model.hasDelayedRenderSendingStatus(message.id ?? message.msgID!) ??
|
||||
true)) {
|
||||
if (!(model.hasDelayedRenderSendingStatus(message.id ?? message.msgID!) ?? true)) {
|
||||
model.setDelayedRenderSendingStatus(message.id ?? message.msgID!);
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
}
|
||||
|
|
@ -1115,14 +1011,9 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
if (isDesktopScreen &&
|
||||
isShowWideToolTip &&
|
||||
customHoverBar == null &&
|
||||
!((widget.message.elemType == 6 && isDownloadWaiting)))
|
||||
if (isDesktopScreen && isShowWideToolTip && customHoverBar == null && !((widget.message.elemType == 6 && isDownloadWaiting)))
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
border: Border.all(color: hexToColor("d9dde0"), width: 1)),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(4), border: Border.all(color: hexToColor("d9dde0"), width: 1)),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 4),
|
||||
child: Row(
|
||||
children: wideHoverTipList
|
||||
|
|
@ -1154,17 +1045,12 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
.toList(),
|
||||
),
|
||||
),
|
||||
if (isDesktopScreen && isShowWideToolTip && customHoverBar != null)
|
||||
customHoverBar,
|
||||
if (!isDesktopScreen ||
|
||||
(model.chatConfig.isUseMessageHoverBarOnDesktop &&
|
||||
customHoverBar == null &&
|
||||
!isShowWideToolTip))
|
||||
if (isDesktopScreen && isShowWideToolTip && customHoverBar != null) customHoverBar,
|
||||
if (!isDesktopScreen || (model.chatConfig.isUseMessageHoverBarOnDesktop && customHoverBar == null && !isShowWideToolTip))
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
if (isSelf &&
|
||||
message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_FAIL)
|
||||
if (isSelf && message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_FAIL)
|
||||
Container(
|
||||
padding: const EdgeInsets.only(bottom: 3),
|
||||
margin: const EdgeInsets.only(right: 6),
|
||||
|
|
@ -1195,8 +1081,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
},
|
||||
),
|
||||
if (model.chatConfig.isShowReadingStatus &&
|
||||
isSelf &&
|
||||
message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC &&
|
||||
isSelf && message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC &&
|
||||
(message.needReadReceipt ?? false) &&
|
||||
!model.isVoteMessage(widget.message))
|
||||
TIMUIKitMessageReadReceipt(
|
||||
|
|
@ -1209,16 +1094,13 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUIChatSeparateViewModel model =
|
||||
Provider.of<TUIChatSeparateViewModel>(context);
|
||||
final isDownloadWaiting = context.select<TUIChatGlobalModel, bool>(
|
||||
(value) => value.isWaiting(widget.message.msgID ?? ""));
|
||||
final TUIChatSeparateViewModel model = Provider.of<TUIChatSeparateViewModel>(context);
|
||||
final isDownloadWaiting = context.select<TUIChatGlobalModel, bool>((value) => value.isWaiting(widget.message.msgID ?? ""));
|
||||
final TUITheme theme = value.theme;
|
||||
final message = widget.message;
|
||||
final msgType = message.elemType;
|
||||
final isSelf = message.isSelf ?? true;
|
||||
final isGroupTipsMsg =
|
||||
msgType == MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS;
|
||||
final isGroupTipsMsg = msgType == MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS;
|
||||
|
||||
final revokeStatus = isRevokeMessage(message, model);
|
||||
final isRevokedMsg = revokeStatus.$1;
|
||||
|
|
@ -1228,14 +1110,10 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
final isLatestDivider = msgType == 101;
|
||||
final isPeerRead = message.isPeerRead ?? false;
|
||||
final isGroupMessage = model.conversationType == ConvType.group;
|
||||
final bool isRevokeEditable =
|
||||
widget.message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT;
|
||||
final isShowNickNameForSelf =
|
||||
isGroupMessage && model.chatConfig.isShowSelfNameInGroup;
|
||||
final isShowNickNameForOthers =
|
||||
isGroupMessage && model.chatConfig.isShowOthersNameInGroup;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final bool isRevokeEditable = widget.message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT;
|
||||
final isShowNickNameForSelf = isGroupMessage && model.chatConfig.isShowSelfNameInGroup;
|
||||
final isShowNickNameForOthers = isGroupMessage && model.chatConfig.isShowOthersNameInGroup;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
if (isTimeDivider) {
|
||||
return _timeDividerBuilder(theme, message.timestamp ?? 0, model);
|
||||
}
|
||||
|
|
@ -1250,8 +1128,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
|
||||
if (isGroupTipsMsg) {
|
||||
if (widget.messageItemBuilder?.groupTipsMessageItemBuilder != null) {
|
||||
final groupTipsMessage =
|
||||
widget.messageItemBuilder!.groupTipsMessageItemBuilder!(
|
||||
final groupTipsMessage = widget.messageItemBuilder!.groupTipsMessageItemBuilder!(
|
||||
message,
|
||||
(model.jumpMsgID == message.msgID),
|
||||
clearJump,
|
||||
|
|
@ -1262,16 +1139,8 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
}
|
||||
|
||||
if (isRevokedMsg) {
|
||||
final displayName = isAdminRevoke
|
||||
? TIM_t("管理员")
|
||||
: (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 ?? "");
|
||||
final displayName = isAdminRevoke ? TIM_t("管理员") : (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(
|
||||
builder: (context, constraints) => Container(
|
||||
padding:
|
||||
EdgeInsets.only(left: isSelf ? 0 : 16, right: isSelf ? 16 : 0),
|
||||
padding: EdgeInsets.only(left: isSelf ? 0 : 16, right: isSelf ? 16 : 0),
|
||||
margin: widget.padding ?? const EdgeInsets.only(bottom: 20),
|
||||
child: Row(
|
||||
key: _key,
|
||||
|
|
@ -1310,8 +1178,7 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
children: [
|
||||
if (model.isMultiSelect)
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
right: 12, top: 10, left: isSelf ? 16 : 0),
|
||||
margin: EdgeInsets.only(right: 12, top: 10, left: isSelf ? 16 : 0),
|
||||
child: CheckBoxButton(
|
||||
isChecked: model.getSelectedMessageList().contains(message),
|
||||
onChanged: (value) {
|
||||
|
|
@ -1322,16 +1189,14 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
Expanded(
|
||||
child: MouseRegion(
|
||||
onEnter: (_) {
|
||||
if (isDesktopScreen &&
|
||||
model.chatConfig.isUseMessageHoverBarOnDesktop) {
|
||||
if (isDesktopScreen && model.chatConfig.isUseMessageHoverBarOnDesktop) {
|
||||
setState(() {
|
||||
isShowWideToolTip = true;
|
||||
});
|
||||
}
|
||||
},
|
||||
onExit: (_) {
|
||||
if (isDesktopScreen &&
|
||||
model.chatConfig.isUseMessageHoverBarOnDesktop) {
|
||||
if (isDesktopScreen && model.chatConfig.isUseMessageHoverBarOnDesktop) {
|
||||
Tooltip.dismissAllToolTips();
|
||||
Future.delayed(const Duration(milliseconds: 100), () {
|
||||
setState(() {
|
||||
|
|
@ -1341,13 +1206,10 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
}
|
||||
},
|
||||
child: GestureDetector(
|
||||
behavior: model.isMultiSelect
|
||||
? HitTestBehavior.translucent
|
||||
: null,
|
||||
behavior: model.isMultiSelect ? HitTestBehavior.translucent : null,
|
||||
onTap: () {
|
||||
if (model.isMultiSelect) {
|
||||
final checked =
|
||||
model.getSelectedMessageList().contains(message);
|
||||
final checked = model.getSelectedMessageList().contains(message);
|
||||
model.setMessageItemChecked(message, !checked);
|
||||
} else {
|
||||
return;
|
||||
|
|
@ -1355,81 +1217,59 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
},
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: isSelf
|
||||
? MainAxisAlignment.end
|
||||
: MainAxisAlignment.start,
|
||||
mainAxisAlignment: isSelf ? MainAxisAlignment.end : MainAxisAlignment.start,
|
||||
children: [
|
||||
if (!isSelf && widget.showAvatar)
|
||||
GestureDetector(
|
||||
onLongPress: () {
|
||||
if (widget.onLongPressForOthersHeadPortrait !=
|
||||
null) {}
|
||||
if (widget.onLongPressForOthersHeadPortrait != null) {}
|
||||
if (model.chatConfig.isAllowLongPressAvatarToAt) {
|
||||
widget.onLongPressForOthersHeadPortrait!(
|
||||
message.sender, message.nickName);
|
||||
widget.onLongPressForOthersHeadPortrait!(message.sender, message.nickName);
|
||||
}
|
||||
},
|
||||
onTapDown: isDesktopScreen
|
||||
? (details) {
|
||||
if (widget.onTapForOthersPortrait != null &&
|
||||
widget.allowAvatarTap) {
|
||||
widget.onTapForOthersPortrait!(
|
||||
message.sender ?? "", details);
|
||||
if (widget.onTapForOthersPortrait != null && widget.allowAvatarTap) {
|
||||
widget.onTapForOthersPortrait!(message.sender ?? "", details);
|
||||
}
|
||||
}
|
||||
: null,
|
||||
onTap: isDesktopScreen
|
||||
? null
|
||||
: () {
|
||||
if (widget.onTapForOthersPortrait != null &&
|
||||
widget.allowAvatarTap) {
|
||||
widget.onTapForOthersPortrait!(
|
||||
message.sender ?? "",
|
||||
TapDownDetails());
|
||||
if (widget.onTapForOthersPortrait != null && widget.allowAvatarTap) {
|
||||
widget.onTapForOthersPortrait!(message.sender ?? "", TapDownDetails());
|
||||
}
|
||||
},
|
||||
onSecondaryTap: isDesktopScreen
|
||||
? null
|
||||
: () {
|
||||
if (widget.onSecondaryTapForOthersPortrait !=
|
||||
null &&
|
||||
widget.allowAvatarTap) {
|
||||
widget.onSecondaryTapForOthersPortrait!(
|
||||
message.sender ?? "",
|
||||
TapDownDetails());
|
||||
if (widget.onSecondaryTapForOthersPortrait != null && widget.allowAvatarTap) {
|
||||
widget.onSecondaryTapForOthersPortrait!(message.sender ?? "", TapDownDetails());
|
||||
}
|
||||
},
|
||||
onSecondaryTapDown: isDesktopScreen
|
||||
? (details) {
|
||||
if (widget.onSecondaryTapForOthersPortrait !=
|
||||
null &&
|
||||
widget.allowAvatarTap) {
|
||||
widget.onSecondaryTapForOthersPortrait!(
|
||||
message.sender ?? "", details);
|
||||
if (widget.onSecondaryTapForOthersPortrait != null && widget.allowAvatarTap) {
|
||||
widget.onSecondaryTapForOthersPortrait!(message.sender ?? "", details);
|
||||
}
|
||||
}
|
||||
: null,
|
||||
child: widget.userAvatarBuilder != null
|
||||
? widget.userAvatarBuilder!(context, message)
|
||||
: Container(
|
||||
margin: (isSelf && isShowNickNameForSelf) ||
|
||||
(!isSelf && isShowNickNameForOthers)
|
||||
? const EdgeInsets.only(top: 2)
|
||||
: null,
|
||||
margin: (isSelf && isShowNickNameForSelf) || (!isSelf && isShowNickNameForOthers) ? const EdgeInsets.only(top: 2) : null,
|
||||
child: SizedBox(
|
||||
width: 40,
|
||||
height: 40,
|
||||
child: Avatar(
|
||||
faceUrl: message.faceUrl ?? "",
|
||||
showName: MessageUtils.getDisplayName(
|
||||
message),
|
||||
showName: MessageUtils.getDisplayName(message),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isSelf &&
|
||||
widget.message.elemType == 6 &&
|
||||
isDownloadWaiting)
|
||||
if (isSelf && widget.message.elemType == 6 && isDownloadWaiting)
|
||||
Container(
|
||||
margin: const EdgeInsets.only(top: 46, right: 10),
|
||||
child: LoadingAnimationWidget.threeArchedCircle(
|
||||
|
|
@ -1438,96 +1278,52 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
),
|
||||
),
|
||||
Container(
|
||||
margin: widget.showAvatar
|
||||
? (isSelf
|
||||
? const EdgeInsets.only(right: 13)
|
||||
: const EdgeInsets.only(left: 13))
|
||||
: null,
|
||||
margin: widget.showAvatar ? (isSelf ? const EdgeInsets.only(right: 13) : const EdgeInsets.only(left: 13)) : null,
|
||||
child: Column(
|
||||
crossAxisAlignment: isSelf
|
||||
? CrossAxisAlignment.end
|
||||
: CrossAxisAlignment.start,
|
||||
crossAxisAlignment: isSelf ? CrossAxisAlignment.end : CrossAxisAlignment.start,
|
||||
children: [
|
||||
if ((isSelf && isShowNickNameForSelf) ||
|
||||
(!isSelf && isShowNickNameForOthers))
|
||||
if ((isSelf && isShowNickNameForSelf) || (!isSelf && isShowNickNameForOthers))
|
||||
widget.topRowBuilder != null
|
||||
? widget.topRowBuilder!(context, message)
|
||||
: Container(
|
||||
// margin: const EdgeInsets.only(bottom: 4),
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context)
|
||||
.size
|
||||
.width /
|
||||
1.7),
|
||||
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width / 1.7),
|
||||
child: Text(
|
||||
MessageUtils.getDisplayName(message),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: widget.themeData
|
||||
?.nickNameTextStyle ??
|
||||
TextStyle(
|
||||
fontSize: 12,
|
||||
color: theme.weakTextColor),
|
||||
style: widget.themeData?.nickNameTextStyle ?? TextStyle(fontSize: 12, color: theme.weakTextColor),
|
||||
),
|
||||
)),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
if (isSelf)
|
||||
renderHoverTipAndReadStatus(
|
||||
model,
|
||||
isSelf,
|
||||
message,
|
||||
isPeerRead,
|
||||
theme,
|
||||
isDownloadWaiting),
|
||||
if (isSelf) renderHoverTipAndReadStatus(model, isSelf, message, isPeerRead, theme, isDownloadWaiting),
|
||||
Container(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: constraints.maxWidth * 0.77,
|
||||
),
|
||||
child: Builder(builder: (context) {
|
||||
return GestureDetector(
|
||||
child: IgnorePointer(
|
||||
ignoring: model.isMultiSelect,
|
||||
child: _getMessageItemBuilder(
|
||||
message,
|
||||
message.status,
|
||||
model)),
|
||||
child: IgnorePointer(ignoring: model.isMultiSelect, child: _getMessageItemBuilder(message, message.status, model)),
|
||||
onSecondaryTapDown: (details) {
|
||||
if (widget.onLongPress != null) {
|
||||
widget.onLongPress!(
|
||||
context, message);
|
||||
widget.onLongPress!(context, message);
|
||||
return;
|
||||
}
|
||||
if (!PlatformUtils().isMobile) {
|
||||
if (widget.allowLongPress) {
|
||||
_onOpenToolTip(
|
||||
context,
|
||||
message,
|
||||
model,
|
||||
theme,
|
||||
details,
|
||||
false,
|
||||
false);
|
||||
_onOpenToolTip(context, message, model, theme, details, false, false);
|
||||
}
|
||||
}
|
||||
},
|
||||
onLongPress: () {
|
||||
if (widget.onLongPress != null) {
|
||||
widget.onLongPress!(
|
||||
context, message);
|
||||
widget.onLongPress!(context, message);
|
||||
return;
|
||||
}
|
||||
if (widget.allowLongPress &&
|
||||
!isDesktopScreen) {
|
||||
_onOpenToolTip(
|
||||
context,
|
||||
message,
|
||||
model,
|
||||
theme,
|
||||
null,
|
||||
false,
|
||||
false);
|
||||
if (widget.allowLongPress && !isDesktopScreen) {
|
||||
_onOpenToolTip(context, message, model, theme, null, false, false);
|
||||
}
|
||||
},
|
||||
onTapDown: (details) {
|
||||
|
|
@ -1536,45 +1332,23 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
);
|
||||
}),
|
||||
),
|
||||
if (!isSelf &&
|
||||
message.elemType ==
|
||||
MessageElemType
|
||||
.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),
|
||||
if (!isSelf && message.elemType == MessageElemType.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(
|
||||
message: message,
|
||||
customEmojiStickerList:
|
||||
widget.customEmojiStickerList,
|
||||
customEmojiStickerList: widget.customEmojiStickerList,
|
||||
isFromSelf: message.isSelf ?? true,
|
||||
isShowJump: false,
|
||||
clearJump: () {},
|
||||
chatModel: model),
|
||||
if (widget.bottomRowBuilder != null)
|
||||
widget.bottomRowBuilder!(context, message)
|
||||
if (widget.bottomRowBuilder != null) widget.bottomRowBuilder!(context, message)
|
||||
],
|
||||
),
|
||||
),
|
||||
if (!isSelf &&
|
||||
widget.message.elemType == 6 &&
|
||||
isDownloadWaiting)
|
||||
if (!isSelf && widget.message.elemType == 6 && isDownloadWaiting)
|
||||
Container(
|
||||
margin: const EdgeInsets.only(top: 46, left: 10),
|
||||
child: LoadingAnimationWidget.threeArchedCircle(
|
||||
|
|
@ -1590,17 +1364,11 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
height: 40,
|
||||
child: InkWell(
|
||||
onTapDown: (details) {
|
||||
if (widget.onTapForOthersPortrait !=
|
||||
null &&
|
||||
widget.allowAvatarTap) {
|
||||
widget.onTapForOthersPortrait!(
|
||||
message.sender ?? "", details);
|
||||
if (widget.onTapForOthersPortrait != null && widget.allowAvatarTap) {
|
||||
widget.onTapForOthersPortrait!(message.sender ?? "", details);
|
||||
}
|
||||
},
|
||||
child: Avatar(
|
||||
faceUrl: message.faceUrl ?? "",
|
||||
showName: MessageUtils.getDisplayName(
|
||||
message)),
|
||||
child: Avatar(faceUrl: message.faceUrl ?? "", showName: MessageUtils.getDisplayName(message)),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -7,13 +7,18 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/services.dart';
|
||||
import 'package:open_file/open_file.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/data_services/services_locatar.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/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_state.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: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 {
|
||||
/// tool tips panel configuration, long press message will show tool tips panel
|
||||
final ToolTipsConfig? toolTipsConfig;
|
||||
|
|
@ -195,15 +204,13 @@ class TIMUIKitMessageTooltipState
|
|||
bool showTranslation = true;
|
||||
if (widget.message.localCustomData != null) {
|
||||
final LocalCustomDataModel localCustomData = LocalCustomDataModel.fromMap(
|
||||
json.decode(
|
||||
TencentUtils.checkString(widget.message.localCustomData) ??
|
||||
"{}"));
|
||||
if (localCustomData.translatedText != null &&
|
||||
localCustomData.translatedText != "") {
|
||||
json.decode(TencentUtils.checkString(widget.message.localCustomData) ?? "{}"));
|
||||
if (localCustomData.translatedText != null && localCustomData.translatedText != "") {
|
||||
showTranslation = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final dynamicQuote =
|
||||
model.chatConfig.isAtWhenReplyDynamic?.call(widget.message);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,11 @@ import 'package:flutter/foundation.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.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_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/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';
|
||||
|
|
@ -130,8 +133,7 @@ class _TIMUIKitHistoryMessageListContainerState
|
|||
direction: direction,
|
||||
count: count ?? (kIsWeb ? 15 : HistoryMessageDartConstant.getCount),
|
||||
lastMsgID: lastMsgID,
|
||||
lastMsgSeq: lastSeq ?? -1,
|
||||
);
|
||||
lastMsgSeq: lastSeq ?? -1,);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -202,8 +204,7 @@ class _TIMUIKitHistoryMessageListContainerState
|
|||
tongueItemBuilder: widget.tongueItemBuilder,
|
||||
initFindingMsg: widget.initFindingMsg,
|
||||
messageList: messageList,
|
||||
onLoadMore: (String? a, LoadDirection direction,
|
||||
[int? b, int? lastSeq]) async {
|
||||
onLoadMore: (String? a, LoadDirection direction, [int? b, int? lastSeq]) async {
|
||||
return await requestForData(a, direction, model, b, lastSeq);
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
import 'package:flutter/material.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/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/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/widgets/message_read_receipt.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';
|
||||
|
||||
class TIMUIKitMessageReadReceipt extends TIMUIKitStatelessWidget {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
static String? getMessageIDWithinIndex(
|
||||
|
|
|
|||
|
|
@ -2,17 +2,22 @@
|
|||
|
||||
import 'package:flutter/material.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/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/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/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/views/TIMUIKitChat/TIMUIKitAppBar/tim_uikit_appbar_title.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/theme/color.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
class TIMUIKitAppBar extends StatefulWidget implements PreferredSizeWidget {
|
||||
/// Appbar config
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:flutter/material.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/tencent_cloud_chat_uikit.dart';
|
||||
|
||||
class TIMUIKitAppBarTitle extends StatelessWidget {
|
||||
final Widget? title;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
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_state.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/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 {
|
||||
/// the index of the current emoji sticker
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
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_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/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/message_reaction_emoji.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_emoji_panel.dart'
|
||||
as emoji;
|
||||
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/theme/color.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
enum SelectEmojiPanelPosition { up, down }
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,11 @@
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/material.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/base_widgets/tim_ui_kit_base.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/data_services/message/message_services.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/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/theme/color.dart';
|
||||
|
||||
class TIMUIKitMessageReactionShowItem extends TIMUIKitStatelessWidget {
|
||||
/// the unicode of the emoji
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
import 'package:flutter/material.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_statelesswidget.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
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/business_logic/view_models/tui_self_info_view_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart';
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ import 'dart:async';
|
|||
import 'dart:convert';
|
||||
|
||||
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_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_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
// ignore_for_file: unrelated_type_equality_checks
|
||||
|
||||
|
||||
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_statelesswidget.dart';
|
||||
|
||||
|
||||
class TIMUIKitCustomElem extends TIMUIKitStatelessWidget {
|
||||
final V2TimCustomElem? customElem;
|
||||
final bool isFromSelf;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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_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_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
|
||||
|
|
|
|||
|
|
@ -8,12 +8,21 @@ import 'package:flutter/material.dart';
|
|||
import 'package:http/http.dart' as http;
|
||||
import 'package:loading_animation_widget/loading_animation_widget.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_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/view_models/tui_chat_global_model.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/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/platform.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_wrapper.dart';
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
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_im_base/tencent_im_base.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/theme/color.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
class TIMUIKitGroupTipsElem extends StatefulWidget {
|
||||
final V2TimGroupTipsElem groupTipsElem;
|
||||
|
|
@ -39,7 +42,8 @@ class _TIMUIKitGroupTipsElemState extends TIMUIKitState<TIMUIKitGroupTipsElem> {
|
|||
return MessageUtils.wrapMessageTips(
|
||||
Text(
|
||||
groupTipsAbstractText,
|
||||
softWrap: true,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ import 'package:loading_animation_widget/loading_animation_widget.dart';
|
|||
import 'package:open_file/open_file.dart';
|
||||
import 'package:path_provider/path_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_state.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/services_locatar.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/utils/logger.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) {
|
||||
String savePath;
|
||||
if (widget.message.imageElem!.path != null &&
|
||||
widget.message.imageElem!.path != '' &&
|
||||
File(widget.message.imageElem!.path!).existsSync()) {
|
||||
widget.message.imageElem!.path != '' && File(widget.message.imageElem!.path!).existsSync()) {
|
||||
savePath = widget.message.imageElem!.path!;
|
||||
} else {
|
||||
savePath = model.getFileMessageLocation(widget.message.msgID);
|
||||
|
|
@ -594,6 +598,7 @@ class _TIMUIKitImageElem extends TIMUIKitState<TIMUIKitImageElem> {
|
|||
|
||||
Widget? _renderImage(dynamic heroTag, TUITheme theme,
|
||||
{V2TimImage? originalImg, V2TimImage? smallImg}) {
|
||||
|
||||
double positionRadio = 1.0;
|
||||
if (smallImg?.width != null &&
|
||||
smallImg?.height != null &&
|
||||
|
|
|
|||
|
|
@ -3,18 +3,23 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
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/ui/utils/common_utils.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/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.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_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/view_models/tui_chat_global_model.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/main.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() {
|
||||
try {
|
||||
final CloudCustomData messageCloudCustomData = CloudCustomData.fromJson(
|
||||
json.decode(
|
||||
TencentUtils.checkString(widget.message.cloudCustomData) != null
|
||||
? widget.message.cloudCustomData!
|
||||
: "{}"));
|
||||
final CloudCustomData messageCloudCustomData = CloudCustomData.fromJson(json.decode(
|
||||
TencentUtils.checkString(widget.message.cloudCustomData) != null ? widget.message.cloudCustomData! : "{}"));
|
||||
if (messageCloudCustomData.messageReply != null) {
|
||||
final MessageRepliedData repliedMessage =
|
||||
MessageRepliedData.fromJson(messageCloudCustomData.messageReply!);
|
||||
final MessageRepliedData repliedMessage = MessageRepliedData.fromJson(messageCloudCustomData.messageReply!);
|
||||
return repliedMessage;
|
||||
}
|
||||
return null;
|
||||
|
|
@ -99,8 +100,7 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
|
|||
if (message == null) {
|
||||
try {
|
||||
final RepliedMessageAbstract repliedMessageAbstract =
|
||||
RepliedMessageAbstract.fromJson(
|
||||
jsonDecode(cloudCustomData.messageAbstract));
|
||||
RepliedMessageAbstract.fromJson(jsonDecode(cloudCustomData.messageAbstract));
|
||||
if (repliedMessageAbstract.isNotEmpty) {
|
||||
message = V2TimMessage(
|
||||
elemType: 0,
|
||||
|
|
@ -127,25 +127,19 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
|
|||
return Text(text,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: theme?.weakTextColor,
|
||||
fontWeight: FontWeight.w400));
|
||||
style: TextStyle(fontSize: 12, color: theme?.weakTextColor, fontWeight: FontWeight.w400));
|
||||
}
|
||||
|
||||
_renderMessageSummary(TUITheme? theme) {
|
||||
try {
|
||||
final RepliedMessageAbstract repliedMessageAbstract =
|
||||
RepliedMessageAbstract.fromJson(
|
||||
jsonDecode(repliedMessage?.messageAbstract ?? ""));
|
||||
RepliedMessageAbstract.fromJson(jsonDecode(repliedMessage?.messageAbstract ?? ""));
|
||||
if (TencentUtils.checkString(repliedMessageAbstract.summary) != null) {
|
||||
return _defaultRawMessageText(repliedMessageAbstract.summary!, theme);
|
||||
}
|
||||
return _defaultRawMessageText(
|
||||
repliedMessage?.messageAbstract ?? TIM_t("[未知消息]"), theme);
|
||||
return _defaultRawMessageText(repliedMessage?.messageAbstract ?? TIM_t("[未知消息]"), theme);
|
||||
} catch (e) {
|
||||
return _defaultRawMessageText(
|
||||
repliedMessage?.messageAbstract ?? TIM_t("[未知消息]"), theme);
|
||||
return _defaultRawMessageText(repliedMessage?.messageAbstract ?? TIM_t("[未知消息]"), theme);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -180,16 +174,13 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
|
|||
final isAdminRevoke = revokeStatus.$2;
|
||||
|
||||
if (isRevokedMsg) {
|
||||
return _defaultRawMessageText(
|
||||
isAdminRevoke ? TIM_t("[消息被管理员撤回]") : TIM_t("[消息被撤回]"), theme);
|
||||
return _defaultRawMessageText(isAdminRevoke ? TIM_t("[消息被管理员撤回]") : TIM_t("[消息被撤回]"), theme);
|
||||
}
|
||||
|
||||
final messageType = message.elemType;
|
||||
final isSelf = message.isSelf ?? true;
|
||||
final customAbstractMessage =
|
||||
widget.chatModel.abstractMessageBuilder != null
|
||||
? widget.chatModel.abstractMessageBuilder!(message)
|
||||
: null;
|
||||
widget.chatModel.abstractMessageBuilder != null ? widget.chatModel.abstractMessageBuilder!(message) : null;
|
||||
if (customAbstractMessage != null) {
|
||||
return _defaultRawMessageText(
|
||||
customAbstractMessage,
|
||||
|
|
@ -222,15 +213,9 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
|
|||
isShowJump: false);
|
||||
case MessageElemType.V2TIM_ELEM_TYPE_IMAGE:
|
||||
return TIMUIKitImageElem(
|
||||
chatModel: widget.chatModel,
|
||||
message: message,
|
||||
isFrom: "reply",
|
||||
isShowMessageReaction: false);
|
||||
chatModel: widget.chatModel, message: message, isFrom: "reply", isShowMessageReaction: false);
|
||||
case MessageElemType.V2TIM_ELEM_TYPE_VIDEO:
|
||||
return TIMUIKitVideoElem(message,
|
||||
chatModel: widget.chatModel,
|
||||
isFrom: "reply",
|
||||
isShowMessageReaction: false);
|
||||
return TIMUIKitVideoElem(message, chatModel: widget.chatModel, isFrom: "reply", isShowMessageReaction: false);
|
||||
case MessageElemType.V2TIM_ELEM_TYPE_LOCATION:
|
||||
return _defaultRawMessageText(TIM_t("[位置]"), theme);
|
||||
case MessageElemType.V2TIM_ELEM_TYPE_MERGER:
|
||||
|
|
@ -262,8 +247,7 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
|
|||
}
|
||||
|
||||
_showJumpColor() {
|
||||
if ((widget.chatModel.jumpMsgID != widget.message.msgID) &&
|
||||
(widget.message.msgID?.isNotEmpty ?? true)) {
|
||||
if ((widget.chatModel.jumpMsgID != widget.message.msgID) && (widget.message.msgID?.isNotEmpty ?? true)) {
|
||||
return;
|
||||
}
|
||||
isShining = true;
|
||||
|
|
@ -287,26 +271,21 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
|
|||
}
|
||||
|
||||
void _jumpToRawMsg() {
|
||||
if (rawMessage?.status != MessageStatus.V2TIM_MSG_STATUS_LOCAL_REVOKED &&
|
||||
rawMessage?.timestamp != null) {
|
||||
if (rawMessage?.status != MessageStatus.V2TIM_MSG_STATUS_LOCAL_REVOKED && rawMessage?.timestamp != null) {
|
||||
widget.scrollToIndex(rawMessage);
|
||||
} else {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO, infoRecommendText: TIM_t("无法定位到原消息")));
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("无法定位到原消息")));
|
||||
}
|
||||
}
|
||||
|
||||
Widget? _renderPreviewWidget() {
|
||||
// If the link preview info from [localCustomData] is available, use it to render the preview card.
|
||||
// Otherwise, it will returns null.
|
||||
if (widget.message.localCustomData != null &&
|
||||
widget.message.localCustomData!.isNotEmpty) {
|
||||
if (widget.message.localCustomData != null && widget.message.localCustomData!.isNotEmpty) {
|
||||
try {
|
||||
final String localJSON = widget.message.localCustomData!;
|
||||
final LocalCustomDataModel? localPreviewInfo =
|
||||
LocalCustomDataModel.fromMap(json.decode(localJSON));
|
||||
if (localPreviewInfo != null &&
|
||||
!localPreviewInfo.isLinkPreviewEmpty()) {
|
||||
final LocalCustomDataModel? localPreviewInfo = LocalCustomDataModel.fromMap(json.decode(localJSON));
|
||||
if (localPreviewInfo != null && !localPreviewInfo.isLinkPreviewEmpty()) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(top: 8),
|
||||
child:
|
||||
|
|
@ -327,16 +306,14 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
|
|||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final theme = value.theme;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
if (widget.isShowJump) {
|
||||
if (!isShining) {
|
||||
Future.delayed(Duration.zero, () {
|
||||
_showJumpColor();
|
||||
});
|
||||
} else {
|
||||
if ((widget.chatModel.jumpMsgID == widget.message.msgID) &&
|
||||
(widget.message.msgID?.isNotEmpty ?? false)) {
|
||||
if ((widget.chatModel.jumpMsgID == widget.message.msgID) && (widget.message.msgID?.isNotEmpty ?? false)) {
|
||||
widget.clearJump();
|
||||
}
|
||||
}
|
||||
|
|
@ -345,13 +322,11 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
|
|||
final isFromSelf = widget.message.isSelf ?? true;
|
||||
|
||||
final defaultStyle = isFromSelf
|
||||
? (theme.chatMessageItemFromSelfBgColor ??
|
||||
theme.lightPrimaryMaterialColor.shade50)
|
||||
? (theme.chatMessageItemFromSelfBgColor ?? theme.lightPrimaryMaterialColor.shade50)
|
||||
: (theme.chatMessageItemFromOthersBgColor);
|
||||
|
||||
final backgroundColor = isShowJumpState
|
||||
? const Color.fromRGBO(245, 166, 35, 1)
|
||||
: (defaultStyle ?? widget.backgroundColor);
|
||||
final backgroundColor =
|
||||
isShowJumpState ? const Color.fromRGBO(245, 166, 35, 1) : (defaultStyle ?? widget.backgroundColor);
|
||||
|
||||
final borderRadius = isFromSelf
|
||||
? const BorderRadius.only(
|
||||
|
|
@ -365,29 +340,22 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
|
|||
bottomLeft: Radius.circular(10),
|
||||
bottomRight: Radius.circular(10));
|
||||
final textWithLink = LinkPreviewEntry.getHyperlinksText(
|
||||
widget.message.textElem?.text ?? "",
|
||||
widget.chatModel.chatConfig.isSupportMarkdownForTextMessage,
|
||||
widget.message.textElem?.text ?? "", widget.chatModel.chatConfig.isSupportMarkdownForTextMessage,
|
||||
onLinkTap: widget.chatModel.chatConfig.onTapLink,
|
||||
isUseQQPackage: widget
|
||||
.chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ??
|
||||
true,
|
||||
isUseTencentCloudChatPackage: widget.chatModel.chatConfig
|
||||
.stickerPanelConfig?.useTencentCloudChatStickerPackage ??
|
||||
true,
|
||||
isUseTencentCloudChatPackageOldKeys: widget.chatModel.chatConfig
|
||||
.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ??
|
||||
false,
|
||||
isUseQQPackage: widget.chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? true,
|
||||
isUseTencentCloudChatPackage:
|
||||
widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true,
|
||||
isUseTencentCloudChatPackageOldKeys:
|
||||
widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ?? false,
|
||||
customEmojiStickerList: widget.customEmojiStickerList,
|
||||
isEnableTextSelection:
|
||||
widget.chatModel.chatConfig.isEnableTextSelection ?? false);
|
||||
isEnableTextSelection: widget.chatModel.chatConfig.isEnableTextSelection ?? false);
|
||||
return Container(
|
||||
padding: widget.textPadding ?? EdgeInsets.all(isDesktopScreen ? 12 : 10),
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor,
|
||||
borderRadius: widget.borderRadius ?? borderRadius,
|
||||
),
|
||||
constraints:
|
||||
BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.6),
|
||||
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.6),
|
||||
child: GestureDetector(
|
||||
onTap: _jumpToRawMsg,
|
||||
child: Column(
|
||||
|
|
@ -399,20 +367,13 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
|
|||
constraints: const BoxConstraints(minWidth: 120),
|
||||
decoration: const BoxDecoration(
|
||||
color: Color.fromRGBO(68, 68, 68, 0.05),
|
||||
border: Border(
|
||||
left: BorderSide(
|
||||
color: Color.fromRGBO(68, 68, 68, 0.1), width: 2))),
|
||||
border: Border(left: BorderSide(color: Color.fromRGBO(68, 68, 68, 0.1), width: 2))),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
repliedMessage != null
|
||||
? "${repliedMessage!.messageSender}:"
|
||||
: "",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: theme.weakTextColor,
|
||||
fontWeight: FontWeight.w500),
|
||||
repliedMessage != null ? "${repliedMessage!.messageSender}:" : "",
|
||||
style: TextStyle(fontSize: 12, color: theme.weakTextColor, fontWeight: FontWeight.w500),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 4,
|
||||
|
|
@ -436,35 +397,22 @@ class _TIMUIKitReplyElemState extends TIMUIKitState<TIMUIKitReplyElem> {
|
|||
: ExtendedText(widget.message.textElem?.text ?? "",
|
||||
softWrap: true,
|
||||
style: widget.fontStyle ??
|
||||
TextStyle(
|
||||
fontSize: isDesktopScreen ? 14 : 16,
|
||||
height: widget.chatModel.chatConfig.textHeight),
|
||||
TextStyle(fontSize: isDesktopScreen ? 14 : 16, height: widget.chatModel.chatConfig.textHeight),
|
||||
specialTextSpanBuilder: DefaultSpecialTextSpanBuilder(
|
||||
isUseQQPackage: widget.chatModel.chatConfig
|
||||
.stickerPanelConfig?.useQQStickerPackage ??
|
||||
true,
|
||||
isUseTencentCloudChatPackage: widget
|
||||
.chatModel
|
||||
.chatConfig
|
||||
.stickerPanelConfig
|
||||
?.useTencentCloudChatStickerPackage ??
|
||||
true,
|
||||
isUseTencentCloudChatPackageOldKeys: widget
|
||||
.chatModel
|
||||
.chatConfig
|
||||
.stickerPanelConfig
|
||||
?.useTencentCloudChatStickerPackageOldKeys ??
|
||||
isUseQQPackage: widget.chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? true,
|
||||
isUseTencentCloudChatPackage:
|
||||
widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true,
|
||||
isUseTencentCloudChatPackageOldKeys:
|
||||
widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ??
|
||||
false,
|
||||
customEmojiStickerList: widget.customEmojiStickerList,
|
||||
showAtBackground: true,
|
||||
)),
|
||||
// If the link preview info is available, render the preview card.
|
||||
if (_renderPreviewWidget() != null &&
|
||||
widget.chatModel.chatConfig.urlPreviewType ==
|
||||
UrlPreviewType.previewCardAndHyperlink)
|
||||
widget.chatModel.chatConfig.urlPreviewType == UrlPreviewType.previewCardAndHyperlink)
|
||||
_renderPreviewWidget()!,
|
||||
if (widget.isShowMessageReaction ?? true)
|
||||
TIMUIKitMessageReactionShowPanel(message: widget.message)
|
||||
if (widget.isShowMessageReaction ?? true) TIMUIKitMessageReactionShowPanel(message: widget.message)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import 'dart:math';
|
|||
|
||||
import 'package:flutter/material.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_state.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/utils/platform.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';
|
||||
|
||||
class TIMUIKitSoundElem extends StatefulWidget {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:async';
|
||||
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:extended_text/extended_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
|
@ -65,8 +66,7 @@ class _TIMUIKitTextElemState extends TIMUIKitState<TIMUIKitTextElem> {
|
|||
}
|
||||
|
||||
_showJumpColor() {
|
||||
if ((widget.chatModel.jumpMsgID != widget.message.msgID) &&
|
||||
(widget.message.msgID?.isNotEmpty ?? true)) {
|
||||
if ((widget.chatModel.jumpMsgID != widget.message.msgID) && (widget.message.msgID?.isNotEmpty ?? true)) {
|
||||
return;
|
||||
}
|
||||
isShining = true;
|
||||
|
|
@ -93,16 +93,13 @@ class _TIMUIKitTextElemState extends TIMUIKitState<TIMUIKitTextElem> {
|
|||
|
||||
// get the link preview info
|
||||
_getLinkPreview() {
|
||||
if (widget.chatModel.chatConfig.urlPreviewType !=
|
||||
UrlPreviewType.previewCardAndHyperlink) {
|
||||
if (widget.chatModel.chatConfig.urlPreviewType != UrlPreviewType.previewCardAndHyperlink) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (widget.message.localCustomData != null &&
|
||||
widget.message.localCustomData!.isNotEmpty) {
|
||||
if (widget.message.localCustomData != null && widget.message.localCustomData!.isNotEmpty) {
|
||||
final String localJSON = widget.message.localCustomData!;
|
||||
final LocalCustomDataModel? localPreviewInfo =
|
||||
LocalCustomDataModel.fromMap(json.decode(localJSON));
|
||||
final LocalCustomDataModel? localPreviewInfo = LocalCustomDataModel.fromMap(json.decode(localJSON));
|
||||
// If [localCustomData] is not empty, check if the link preview info exists
|
||||
if (localPreviewInfo == null || localPreviewInfo.isLinkPreviewEmpty()) {
|
||||
// If not exists, get it
|
||||
|
|
@ -123,22 +120,18 @@ class _TIMUIKitTextElemState extends TIMUIKitState<TIMUIKitTextElem> {
|
|||
LinkPreviewEntry.getFirstLinkPreviewContent(
|
||||
message: widget.message,
|
||||
onUpdateMessage: (message) {
|
||||
widget.chatModel.updateMessageFromController(
|
||||
msgID: widget.message.msgID!, message: message);
|
||||
widget.chatModel.updateMessageFromController(msgID: widget.message.msgID!, message: message);
|
||||
});
|
||||
}
|
||||
|
||||
Widget? _renderPreviewWidget() {
|
||||
// If the link preview info from [localCustomData] is available, use it to render the preview card.
|
||||
// Otherwise, it will returns null.
|
||||
if (widget.message.localCustomData != null &&
|
||||
widget.message.localCustomData!.isNotEmpty) {
|
||||
if (widget.message.localCustomData != null && widget.message.localCustomData!.isNotEmpty) {
|
||||
try {
|
||||
final String localJSON = widget.message.localCustomData!;
|
||||
final LocalCustomDataModel? localPreviewInfo =
|
||||
LocalCustomDataModel.fromMap(json.decode(localJSON));
|
||||
if (localPreviewInfo != null &&
|
||||
!localPreviewInfo.isLinkPreviewEmpty()) {
|
||||
final LocalCustomDataModel? localPreviewInfo = LocalCustomDataModel.fromMap(json.decode(localJSON));
|
||||
if (localPreviewInfo != null && !localPreviewInfo.isLinkPreviewEmpty()) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(top: 8),
|
||||
child:
|
||||
|
|
@ -159,24 +152,17 @@ class _TIMUIKitTextElemState extends TIMUIKitState<TIMUIKitTextElem> {
|
|||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final theme = value.theme;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final textWithLink = LinkPreviewEntry.getHyperlinksText(
|
||||
widget.message.textElem?.text ?? "",
|
||||
widget.chatModel.chatConfig.isSupportMarkdownForTextMessage,
|
||||
widget.message.textElem?.text ?? "", widget.chatModel.chatConfig.isSupportMarkdownForTextMessage,
|
||||
onLinkTap: widget.chatModel.chatConfig.onTapLink,
|
||||
isUseQQPackage: widget
|
||||
.chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ??
|
||||
true,
|
||||
isUseTencentCloudChatPackage: widget.chatModel.chatConfig
|
||||
.stickerPanelConfig?.useTencentCloudChatStickerPackage ??
|
||||
true,
|
||||
isUseTencentCloudChatPackageOldKeys: widget.chatModel.chatConfig
|
||||
.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ??
|
||||
false,
|
||||
isUseQQPackage: widget.chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? true,
|
||||
isUseTencentCloudChatPackage:
|
||||
widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true,
|
||||
isUseTencentCloudChatPackageOldKeys:
|
||||
widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ?? false,
|
||||
customEmojiStickerList: widget.customEmojiStickerList,
|
||||
isEnableTextSelection:
|
||||
widget.chatModel.chatConfig.isEnableTextSelection ?? false);
|
||||
isEnableTextSelection: widget.chatModel.chatConfig.isEnableTextSelection ?? false);
|
||||
final borderRadius = widget.isFromSelf
|
||||
? const BorderRadius.only(
|
||||
topLeft: Radius.circular(10),
|
||||
|
|
@ -195,21 +181,18 @@ class _TIMUIKitTextElemState extends TIMUIKitState<TIMUIKitTextElem> {
|
|||
_showJumpColor();
|
||||
});
|
||||
} else {
|
||||
if ((widget.chatModel.jumpMsgID == widget.message.msgID) &&
|
||||
(widget.message.msgID?.isNotEmpty ?? false)) {
|
||||
if ((widget.chatModel.jumpMsgID == widget.message.msgID) && (widget.message.msgID?.isNotEmpty ?? false)) {
|
||||
widget.clearJump();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final defaultStyle = widget.isFromSelf
|
||||
? (theme.chatMessageItemFromSelfBgColor ??
|
||||
theme.lightPrimaryMaterialColor.shade50)
|
||||
? (theme.chatMessageItemFromSelfBgColor ?? theme.lightPrimaryMaterialColor.shade50)
|
||||
: (theme.chatMessageItemFromOthersBgColor);
|
||||
|
||||
final backgroundColor = isShowJumpState
|
||||
? const Color.fromRGBO(245, 166, 35, 1)
|
||||
: (defaultStyle ?? widget.backgroundColor);
|
||||
final backgroundColor =
|
||||
isShowJumpState ? const Color.fromRGBO(245, 166, 35, 1) : (defaultStyle ?? widget.backgroundColor);
|
||||
|
||||
return Container(
|
||||
padding: widget.textPadding ?? EdgeInsets.all(isDesktopScreen ? 12 : 10),
|
||||
|
|
@ -217,8 +200,7 @@ class _TIMUIKitTextElemState extends TIMUIKitState<TIMUIKitTextElem> {
|
|||
color: backgroundColor,
|
||||
borderRadius: widget.borderRadius ?? borderRadius,
|
||||
),
|
||||
constraints:
|
||||
BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.6),
|
||||
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.6),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
|
@ -234,24 +216,13 @@ class _TIMUIKitTextElemState extends TIMUIKitState<TIMUIKitTextElem> {
|
|||
: ExtendedText(widget.message.textElem?.text ?? "",
|
||||
softWrap: true,
|
||||
style: widget.fontStyle ??
|
||||
TextStyle(
|
||||
fontSize: isDesktopScreen ? 14 : 16,
|
||||
height: widget.chatModel.chatConfig.textHeight),
|
||||
TextStyle(fontSize: isDesktopScreen ? 14 : 16, height: widget.chatModel.chatConfig.textHeight),
|
||||
specialTextSpanBuilder: DefaultSpecialTextSpanBuilder(
|
||||
isUseQQPackage: widget.chatModel.chatConfig
|
||||
.stickerPanelConfig?.useQQStickerPackage ??
|
||||
true,
|
||||
isUseTencentCloudChatPackage: widget
|
||||
.chatModel
|
||||
.chatConfig
|
||||
.stickerPanelConfig
|
||||
?.useTencentCloudChatStickerPackage ??
|
||||
true,
|
||||
isUseTencentCloudChatPackageOldKeys: widget
|
||||
.chatModel
|
||||
.chatConfig
|
||||
.stickerPanelConfig
|
||||
?.useTencentCloudChatStickerPackageOldKeys ??
|
||||
isUseQQPackage: widget.chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? true,
|
||||
isUseTencentCloudChatPackage:
|
||||
widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true,
|
||||
isUseTencentCloudChatPackageOldKeys:
|
||||
widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ??
|
||||
false,
|
||||
customEmojiStickerList: widget.customEmojiStickerList,
|
||||
showAtBackground: true,
|
||||
|
|
@ -259,11 +230,9 @@ class _TIMUIKitTextElemState extends TIMUIKitState<TIMUIKitTextElem> {
|
|||
)),
|
||||
// If the link preview info is available, render the preview card.
|
||||
if (_renderPreviewWidget() != null &&
|
||||
widget.chatModel.chatConfig.urlPreviewType ==
|
||||
UrlPreviewType.previewCardAndHyperlink)
|
||||
widget.chatModel.chatConfig.urlPreviewType == UrlPreviewType.previewCardAndHyperlink)
|
||||
_renderPreviewWidget()!,
|
||||
if (widget.isShowMessageReaction ?? true)
|
||||
TIMUIKitMessageReactionShowPanel(message: widget.message)
|
||||
if (widget.isShowMessageReaction ?? true) TIMUIKitMessageReactionShowPanel(message: widget.message)
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import 'dart:async';
|
||||
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:extended_text/extended_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
|
@ -43,14 +45,12 @@ class TIMUIKitTextTranslationElem extends StatefulWidget {
|
|||
State<StatefulWidget> createState() => _TIMUIKitTextTranslationElemState();
|
||||
}
|
||||
|
||||
class _TIMUIKitTextTranslationElemState
|
||||
extends TIMUIKitState<TIMUIKitTextTranslationElem> {
|
||||
class _TIMUIKitTextTranslationElemState extends TIMUIKitState<TIMUIKitTextTranslationElem> {
|
||||
bool isShowJumpState = false;
|
||||
bool isShining = false;
|
||||
|
||||
_showJumpColor() {
|
||||
if ((widget.chatModel.jumpMsgID != widget.message.msgID) &&
|
||||
(widget.message.msgID?.isNotEmpty ?? true)) {
|
||||
if ((widget.chatModel.jumpMsgID != widget.message.msgID) && (widget.message.msgID?.isNotEmpty ?? true)) {
|
||||
return;
|
||||
}
|
||||
isShining = true;
|
||||
|
|
@ -78,8 +78,7 @@ class _TIMUIKitTextTranslationElemState
|
|||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final theme = value.theme;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final borderRadius = widget.isFromSelf
|
||||
? const BorderRadius.only(
|
||||
topLeft: Radius.circular(10),
|
||||
|
|
@ -98,61 +97,49 @@ class _TIMUIKitTextTranslationElemState
|
|||
_showJumpColor();
|
||||
});
|
||||
} else {
|
||||
if ((widget.chatModel.jumpMsgID == widget.message.msgID) &&
|
||||
(widget.message.msgID?.isNotEmpty ?? false)) {
|
||||
if ((widget.chatModel.jumpMsgID == widget.message.msgID) && (widget.message.msgID?.isNotEmpty ?? false)) {
|
||||
widget.clearJump();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final defaultStyle = widget.isFromSelf
|
||||
? (theme.chatMessageItemFromSelfBgColor ??
|
||||
theme.lightPrimaryMaterialColor.shade50)
|
||||
? (theme.chatMessageItemFromSelfBgColor ?? theme.lightPrimaryMaterialColor.shade50)
|
||||
: (theme.chatMessageItemFromOthersBgColor);
|
||||
|
||||
final backgroundColor = isShowJumpState
|
||||
? const Color.fromRGBO(245, 166, 35, 1)
|
||||
: (defaultStyle ?? widget.backgroundColor);
|
||||
final backgroundColor =
|
||||
isShowJumpState ? const Color.fromRGBO(245, 166, 35, 1) : (defaultStyle ?? widget.backgroundColor);
|
||||
|
||||
final LocalCustomDataModel localCustomData = LocalCustomDataModel.fromMap(
|
||||
json.decode(
|
||||
TencentUtils.checkString(widget.message.localCustomData) ?? "{}"));
|
||||
final LocalCustomDataModel localCustomData =
|
||||
LocalCustomDataModel.fromMap(json.decode(TencentUtils.checkString(widget.message.localCustomData) ?? "{}"));
|
||||
final String? translateText = localCustomData.translatedText;
|
||||
|
||||
final textWithLink = LinkPreviewEntry.getHyperlinksText(translateText ?? "",
|
||||
widget.chatModel.chatConfig.isSupportMarkdownForTextMessage,
|
||||
final textWithLink = LinkPreviewEntry.getHyperlinksText(
|
||||
translateText ?? "", widget.chatModel.chatConfig.isSupportMarkdownForTextMessage,
|
||||
onLinkTap: widget.chatModel.chatConfig.onTapLink,
|
||||
isUseQQPackage: widget
|
||||
.chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ??
|
||||
true,
|
||||
isUseTencentCloudChatPackage: widget.chatModel.chatConfig
|
||||
.stickerPanelConfig?.useTencentCloudChatStickerPackage ??
|
||||
true,
|
||||
isUseTencentCloudChatPackageOldKeys: widget.chatModel.chatConfig
|
||||
.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ??
|
||||
false,
|
||||
isUseQQPackage: widget.chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? true,
|
||||
isUseTencentCloudChatPackage:
|
||||
widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true,
|
||||
isUseTencentCloudChatPackageOldKeys:
|
||||
widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ?? false,
|
||||
customEmojiStickerList: widget.customEmojiStickerList,
|
||||
isEnableTextSelection:
|
||||
widget.chatModel.chatConfig.isEnableTextSelection ?? false);
|
||||
isEnableTextSelection: widget.chatModel.chatConfig.isEnableTextSelection ?? false);
|
||||
|
||||
return TencentUtils.checkString(translateText) != null
|
||||
? Container(
|
||||
margin: const EdgeInsets.only(top: 6),
|
||||
padding:
|
||||
widget.textPadding ?? EdgeInsets.all(isDesktopScreen ? 12 : 10),
|
||||
padding: widget.textPadding ?? EdgeInsets.all(isDesktopScreen ? 12 : 10),
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor,
|
||||
borderRadius: widget.borderRadius ?? borderRadius,
|
||||
),
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context).size.width * 0.6),
|
||||
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.6),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// If the [elemType] is text message, it will not be null here.
|
||||
// You can render the widget from extension directly, with a [TextStyle] optionally.
|
||||
widget.chatModel.chatConfig.urlPreviewType !=
|
||||
UrlPreviewType.none
|
||||
widget.chatModel.chatConfig.urlPreviewType != UrlPreviewType.none
|
||||
? textWithLink!(
|
||||
style: widget.fontStyle ??
|
||||
TextStyle(
|
||||
|
|
@ -163,23 +150,13 @@ class _TIMUIKitTextTranslationElemState
|
|||
softWrap: true,
|
||||
style: widget.fontStyle ??
|
||||
TextStyle(
|
||||
fontSize: isDesktopScreen ? 14 : 16,
|
||||
height: widget.chatModel.chatConfig.textHeight),
|
||||
fontSize: isDesktopScreen ? 14 : 16, height: widget.chatModel.chatConfig.textHeight),
|
||||
specialTextSpanBuilder: DefaultSpecialTextSpanBuilder(
|
||||
isUseQQPackage: widget.chatModel.chatConfig
|
||||
.stickerPanelConfig?.useQQStickerPackage ??
|
||||
true,
|
||||
isUseTencentCloudChatPackage: widget
|
||||
.chatModel
|
||||
.chatConfig
|
||||
.stickerPanelConfig
|
||||
?.useTencentCloudChatStickerPackage ??
|
||||
true,
|
||||
isUseQQPackage: widget.chatModel.chatConfig.stickerPanelConfig?.useQQStickerPackage ?? true,
|
||||
isUseTencentCloudChatPackage:
|
||||
widget.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true,
|
||||
isUseTencentCloudChatPackageOldKeys: widget
|
||||
.chatModel
|
||||
.chatConfig
|
||||
.stickerPanelConfig
|
||||
?.useTencentCloudChatStickerPackageOldKeys ??
|
||||
.chatModel.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackageOldKeys ??
|
||||
false,
|
||||
customEmojiStickerList: widget.customEmojiStickerList,
|
||||
showAtBackground: true,
|
||||
|
|
@ -200,8 +177,7 @@ class _TIMUIKitTextTranslationElemState
|
|||
),
|
||||
Text(
|
||||
TIM_t("翻译完成"),
|
||||
style: const TextStyle(
|
||||
color: Color(0x72282c34), fontSize: 10),
|
||||
style: const TextStyle(color: Color(0x72282c34), fontSize: 10),
|
||||
)
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -4,12 +4,18 @@ import 'dart:math';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:loading_animation_widget/loading_animation_widget.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_state.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/data_services/message/message_services.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/platform.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_wrapper.dart';
|
||||
|
|
|
|||
|
|
@ -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!,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,20 @@
|
|||
import 'dart:async';
|
||||
|
||||
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/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/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/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/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';
|
||||
|
||||
class TIMUIKitMergerElem extends StatefulWidget {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.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_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -32,9 +32,7 @@ class DefaultSpecialTextSpanBuilder extends SpecialTextSpanBuilder {
|
|||
|
||||
@override
|
||||
SpecialText? createSpecialText(String flag,
|
||||
{TextStyle? textStyle,
|
||||
SpecialTextGestureTapCallback? onTap,
|
||||
int? index}) {
|
||||
{TextStyle? textStyle, SpecialTextGestureTapCallback? onTap, int? index}) {
|
||||
if (flag == '') {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -43,14 +41,12 @@ class DefaultSpecialTextSpanBuilder extends SpecialTextSpanBuilder {
|
|||
if (isStart(flag, EmojiText.flag)) {
|
||||
return EmojiText(textStyle,
|
||||
isUseTencentCloudChatPackage: isUseTencentCloudChatPackage,
|
||||
isUseTencentCloudChatPackageOldKeys:
|
||||
isUseTencentCloudChatPackageOldKeys,
|
||||
isUseTencentCloudChatPackageOldKeys: isUseTencentCloudChatPackageOldKeys,
|
||||
isUseQQPackage: isUseQQPackage,
|
||||
start: index! - (EmojiText.flag.length - 1),
|
||||
customEmojiStickerList: customEmojiStickerList);
|
||||
} else if (isStart(flag, HttpText.flag) && checkHttpLink) {
|
||||
return HttpText(textStyle, onTap,
|
||||
start: index! - (HttpText.flag.length - 1));
|
||||
return HttpText(textStyle, onTap, start: index! - (HttpText.flag.length - 1));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ class EmojiUtil {
|
|||
String emojiName = emoji.split('.png')[0];
|
||||
String compatibleEmojiName = emojiName;
|
||||
if (isUseTencentCloudChatPackageOldKeys) {
|
||||
// 兼容旧版本的 key 值
|
||||
// use old emoji keys in 3.x version
|
||||
compatibleEmojiName = getCompatibleEmojiName(emojiName);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,21 @@
|
|||
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/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/services_locatar.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_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/widgets/group_member_list.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 {
|
||||
final String? groupID;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
import 'package:flutter/material.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/data_services/group/group_services.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/base_widgets/tim_ui_kit_base.dart';
|
||||
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
class SelectCallInviter extends StatefulWidget {
|
||||
final String? groupID;
|
||||
const SelectCallInviter({
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
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_im_base/tencent_im_base.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/ui/utils/logger.dart';
|
||||
|
||||
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
|
||||
|
||||
class EmojiPanel extends TIMUIKitStatelessWidget {
|
||||
final void Function(int unicode) onTapEmoji;
|
||||
final void Function() onSubmitted;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// ignore_for_file: unused_field, avoid_print, unused_import
|
||||
|
||||
import 'dart:io';
|
||||
import 'package:better_player_plus/better_player_plus.dart';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:fc_native_video_thumbnail/fc_native_video_thumbnail.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:path_provider/path_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/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/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';
|
||||
|
|
@ -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/permission.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: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: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 {
|
||||
static final int FILE_MAX_SIZE = 100 * 1024 * 1024;
|
||||
static final int VIDEO_MAX_SIZE = 100 * 1024 * 1024;
|
||||
|
|
@ -65,8 +71,7 @@ class MorePanelItem {
|
|||
final Widget icon;
|
||||
final Function(BuildContext context)? onTap;
|
||||
|
||||
MorePanelItem(
|
||||
{this.onTap, required this.icon, required this.id, required this.title});
|
||||
MorePanelItem({this.onTap, required this.icon, required this.id, required this.title});
|
||||
}
|
||||
|
||||
class MorePanel extends StatefulWidget {
|
||||
|
|
@ -78,11 +83,7 @@ class MorePanel extends StatefulWidget {
|
|||
|
||||
final MorePanelConfig? morePanelConfig;
|
||||
|
||||
const MorePanel(
|
||||
{required this.conversationID,
|
||||
required this.conversationType,
|
||||
Key? key,
|
||||
this.morePanelConfig})
|
||||
const MorePanel({required this.conversationID, required this.conversationType, Key? key, this.morePanelConfig})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
|
|
@ -91,8 +92,7 @@ class MorePanel extends StatefulWidget {
|
|||
|
||||
class _MorePanelState extends TIMUIKitState<MorePanel> {
|
||||
final ImagePicker _picker = ImagePicker();
|
||||
final TUISelfInfoViewModel _selfInfoViewModel =
|
||||
serviceLocator<TUISelfInfoViewModel>();
|
||||
final TUISelfInfoViewModel _selfInfoViewModel = serviceLocator<TUISelfInfoViewModel>();
|
||||
Uint8List? fileContent;
|
||||
String? fileName;
|
||||
File? tempFile;
|
||||
|
|
@ -102,6 +102,8 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
final ScrollController _scrollController = ScrollController();
|
||||
final DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
|
||||
|
||||
late BetterPlayerController _betterPlayerController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
|
@ -111,33 +113,13 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
isInstallCallkit = value;
|
||||
});
|
||||
});
|
||||
_betterPlayerController = BetterPlayerController(const BetterPlayerConfiguration());
|
||||
}
|
||||
}
|
||||
|
||||
List<MorePanelItem> itemList(TUIChatSeparateViewModel model, TUITheme theme) {
|
||||
final config = widget.morePanelConfig ?? MorePanelConfig();
|
||||
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)
|
||||
MorePanelItem(
|
||||
id: "photo",
|
||||
|
|
@ -154,9 +136,7 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
height: 64,
|
||||
width: 64,
|
||||
margin: const EdgeInsets.only(bottom: 4),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(5))),
|
||||
decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
|
||||
child: SvgPicture.asset(
|
||||
"images/photo.svg",
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
|
|
@ -164,6 +144,44 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
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)
|
||||
MorePanelItem(
|
||||
id: "image",
|
||||
|
|
@ -180,9 +198,7 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
height: 64,
|
||||
width: 64,
|
||||
margin: const EdgeInsets.only(bottom: 4),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(5))),
|
||||
decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
|
||||
child: SvgPicture.asset(
|
||||
"images/photo.svg",
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
|
|
@ -206,11 +222,8 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
height: 64,
|
||||
width: 64,
|
||||
margin: const EdgeInsets.only(bottom: 4),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(5))),
|
||||
child:
|
||||
Icon(Icons.video_file, color: hexToColor("5c6168"), size: 26),
|
||||
decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
|
||||
child: Icon(Icons.video_file, color: hexToColor("5c6168"), size: 26),
|
||||
)),
|
||||
MorePanelItem(
|
||||
id: "file",
|
||||
|
|
@ -227,9 +240,7 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
height: 64,
|
||||
width: 64,
|
||||
margin: const EdgeInsets.only(bottom: 4),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(5))),
|
||||
decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
|
||||
child: SvgPicture.asset(
|
||||
"images/file.svg",
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
|
|
@ -253,9 +264,7 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
height: 64,
|
||||
width: 64,
|
||||
margin: const EdgeInsets.only(bottom: 4),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(5))),
|
||||
decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
|
||||
child: SvgPicture.asset(
|
||||
"images/video-call.svg",
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
|
|
@ -279,9 +288,7 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
height: 64,
|
||||
width: 64,
|
||||
margin: const EdgeInsets.only(bottom: 4),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(5))),
|
||||
decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
|
||||
child: SvgPicture.asset(
|
||||
"images/voice-call.svg",
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
|
|
@ -320,28 +327,21 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
}).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) {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("文件大小超出了限制")));
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("文件大小超出了限制")));
|
||||
return;
|
||||
}
|
||||
|
||||
final plugin = FcNativeVideoThumbnail();
|
||||
final originFile = await asset.originFile;
|
||||
|
||||
final duration = asset.videoDuration.inSeconds;
|
||||
final filePath = originFile!.path;
|
||||
final convID = widget.conversationID;
|
||||
final convType = widget.conversationType;
|
||||
|
||||
String tempPath = (await getTemporaryDirectory()).path +
|
||||
p.basename(originFile.path) +
|
||||
".jpeg";
|
||||
String tempPath = (await getTemporaryDirectory()).path + p.basename(originFilePath) + ".jpeg";
|
||||
|
||||
await plugin.getVideoThumbnail(
|
||||
srcFile: originFile.path,
|
||||
srcFile: originFilePath,
|
||||
destFile: tempPath,
|
||||
format: 'jpeg',
|
||||
width: 1280,
|
||||
|
|
@ -350,11 +350,7 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
);
|
||||
MessageUtils.handleMessageError(
|
||||
model.sendVideoMessage(
|
||||
videoPath: filePath,
|
||||
duration: duration,
|
||||
snapshotPath: tempPath,
|
||||
convID: convID,
|
||||
convType: convType),
|
||||
videoPath: originFilePath, duration: duration, snapshotPath: tempPath, convID: convID, convType: convType),
|
||||
context);
|
||||
}
|
||||
|
||||
|
|
@ -414,46 +410,34 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
if (filePath != null) {
|
||||
if (type == AssetType.image) {
|
||||
if (size >= MorePanelConfig.IMAGE_MAX_SIZE) {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("文件大小超出了限制")));
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("文件大小超出了限制")));
|
||||
return;
|
||||
}
|
||||
|
||||
MessageUtils.handleMessageError(
|
||||
model.sendImageMessage(
|
||||
imagePath: filePath,
|
||||
convID: convID,
|
||||
convType: convType),
|
||||
context);
|
||||
model.sendImageMessage(imagePath: filePath, convID: convID, convType: convType), context);
|
||||
}
|
||||
|
||||
if (type == AssetType.video) {
|
||||
_sendVideoMessage(asset, size, model);
|
||||
_sendVideoMessage(originFile!.path, asset.videoDuration.inSeconds, size, model);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FilePickerResult? result =
|
||||
await FilePicker.platform.pickFiles(type: FileType.media);
|
||||
FilePickerResult? result = await FilePicker.platform.pickFiles(type: FileType.media);
|
||||
if (result != null && result.files.isNotEmpty) {
|
||||
File file = File(result.files.single.path!);
|
||||
final String savePath = file.path;
|
||||
final String type = TencentUtils.getFileType(
|
||||
savePath.split(".")[savePath.split(".").length - 1])
|
||||
.split("/")[0];
|
||||
final String type =
|
||||
TencentUtils.getFileType(savePath.split(".")[savePath.split(".").length - 1]).split("/")[0];
|
||||
|
||||
if (type == "image") {
|
||||
MessageUtils.handleMessageError(
|
||||
model.sendImageMessage(
|
||||
imagePath: savePath, convID: convID, convType: convType),
|
||||
context);
|
||||
model.sendImageMessage(imagePath: savePath, convID: convID, convType: convType), context);
|
||||
} else if (type == "video") {
|
||||
MessageUtils.handleMessageError(
|
||||
model.sendVideoMessage(
|
||||
videoPath: savePath, convID: convID, convType: convType),
|
||||
context);
|
||||
model.sendVideoMessage(videoPath: savePath, convID: convID, convType: convType), context);
|
||||
}
|
||||
} else {
|
||||
throw TypeError();
|
||||
|
|
@ -464,10 +448,7 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
}
|
||||
}
|
||||
|
||||
_sendImageFromCamera(
|
||||
TUIChatSeparateViewModel model,
|
||||
TUITheme theme,
|
||||
) async {
|
||||
_sendImageFromCamera(TUIChatSeparateViewModel model, TUITheme theme, {required isVideo}) async {
|
||||
try {
|
||||
if (!await Permissions.checkPermission(
|
||||
context,
|
||||
|
|
@ -484,34 +465,41 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
|
||||
final convID = widget.conversationID;
|
||||
final convType = widget.conversationType;
|
||||
final pickedFile = await CameraPicker.pickFromCamera(context,
|
||||
pickerConfig: CameraPickerConfig(
|
||||
enableRecording: true,
|
||||
textDelegate: IntlCameraPickerTextDelegate()));
|
||||
final originFile = await pickedFile?.originFile;
|
||||
if (originFile != null) {
|
||||
final type = pickedFile!.type;
|
||||
final ImagePicker picker = ImagePicker();
|
||||
XFile? originFile;
|
||||
if (isVideo) {
|
||||
originFile = await picker.pickVideo(source: ImageSource.camera);
|
||||
} else {
|
||||
originFile = await picker.pickImage(source: ImageSource.camera);
|
||||
}
|
||||
final size = await originFile!.length();
|
||||
if (type == AssetType.image) {
|
||||
if (!isVideo) {
|
||||
if (size >= MorePanelConfig.IMAGE_MAX_SIZE) {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("文件大小超出了限制")));
|
||||
onTIMCallback(
|
||||
TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("文件大小超出了限制")));
|
||||
return;
|
||||
}
|
||||
|
||||
MessageUtils.handleMessageError(
|
||||
model.sendImageMessage(
|
||||
imagePath: originFile.path,
|
||||
convID: convID,
|
||||
convType: convType),
|
||||
model.sendImageMessage(imagePath: originFile.path, convID: convID, convType: convType),
|
||||
context);
|
||||
}
|
||||
if (type == AssetType.video) {
|
||||
_sendVideoMessage(pickedFile, size, model);
|
||||
}
|
||||
} 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) {
|
||||
outputLogger.i("err: $error");
|
||||
|
|
@ -527,17 +515,12 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
fileContent = imageContent;
|
||||
|
||||
html.Node? inputElem;
|
||||
inputElem = html.document
|
||||
.getElementById("__image_picker_web-file-input")
|
||||
?.querySelector("input");
|
||||
inputElem = html.document.getElementById("__image_picker_web-file-input")?.querySelector("input");
|
||||
final convID = widget.conversationID;
|
||||
final convType = widget.conversationType;
|
||||
MessageUtils.handleMessageError(
|
||||
model.sendImageMessage(
|
||||
inputElement: inputElem,
|
||||
imagePath: tempFile?.path,
|
||||
convID: convID,
|
||||
convType: convType),
|
||||
inputElement: inputElem, imagePath: tempFile?.path, convID: convID, convType: convType),
|
||||
context);
|
||||
} catch (e) {
|
||||
outputLogger.i("_sendFileErr: ${e.toString()}");
|
||||
|
|
@ -553,25 +536,18 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
fileContent = videoContent;
|
||||
|
||||
if (fileName!.split(".")[fileName!.split(".").length - 1] != "mp4") {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("视频消息仅限 mp4 格式"),
|
||||
infoCode: 6660412));
|
||||
onTIMCallback(
|
||||
TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频消息仅限 mp4 格式"), infoCode: 6660412));
|
||||
return;
|
||||
}
|
||||
|
||||
html.Node? inputElem;
|
||||
inputElem = html.document
|
||||
.getElementById("__image_picker_web-file-input")
|
||||
?.querySelector("input");
|
||||
inputElem = html.document.getElementById("__image_picker_web-file-input")?.querySelector("input");
|
||||
final convID = widget.conversationID;
|
||||
final convType = widget.conversationType;
|
||||
MessageUtils.handleMessageError(
|
||||
model.sendVideoMessage(
|
||||
inputElement: inputElem,
|
||||
videoPath: tempFile?.path,
|
||||
convID: convID,
|
||||
convType: convType),
|
||||
inputElement: inputElem, videoPath: tempFile?.path, convID: convID, convType: convType),
|
||||
context);
|
||||
} catch (e) {
|
||||
outputLogger.i("_sendFileErr: ${e.toString()}");
|
||||
|
|
@ -589,43 +565,29 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
if (result != null && result.files.isNotEmpty) {
|
||||
if (PlatformUtils().isWeb) {
|
||||
html.Node? inputElem;
|
||||
inputElem = html.document
|
||||
.getElementById("__file_picker_web-file-input")
|
||||
?.querySelector("input");
|
||||
inputElem = html.document.getElementById("__file_picker_web-file-input")?.querySelector("input");
|
||||
fileName = result.files.single.name;
|
||||
|
||||
MessageUtils.handleMessageError(
|
||||
model.sendFileMessage(
|
||||
inputElement: inputElem,
|
||||
fileName: fileName,
|
||||
convID: convID,
|
||||
convType: convType),
|
||||
model.sendFileMessage(inputElement: inputElem, fileName: fileName, convID: convID, convType: convType),
|
||||
context);
|
||||
return;
|
||||
}
|
||||
|
||||
String? option2 = result.files.single.path ?? "";
|
||||
outputLogger
|
||||
.i(TIM_t_para("选择成功{{option2}}", "选择成功$option2")(option2: option2));
|
||||
outputLogger.i(TIM_t_para("选择成功{{option2}}", "选择成功$option2")(option2: option2));
|
||||
|
||||
File file = File(result.files.single.path!);
|
||||
final int size = file.lengthSync();
|
||||
if (size >= MorePanelConfig.FILE_MAX_SIZE) {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("文件大小超出了限制")));
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("文件大小超出了限制")));
|
||||
return;
|
||||
}
|
||||
|
||||
final String savePath = file.path;
|
||||
|
||||
MessageUtils.handleMessageError(
|
||||
model.sendFileMessage(
|
||||
filePath: savePath,
|
||||
size: size,
|
||||
convID: convID,
|
||||
convType: convType),
|
||||
context);
|
||||
model.sendFileMessage(filePath: savePath, size: size, convID: convID, convType: convType), context);
|
||||
} else {
|
||||
throw TypeError();
|
||||
}
|
||||
|
|
@ -644,8 +606,11 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
case "photo":
|
||||
_sendImageMessage(model, theme);
|
||||
break;
|
||||
case "screen":
|
||||
_sendImageFromCamera(model, theme);
|
||||
case "take_photo":
|
||||
_sendImageFromCamera(model, theme, isVideo: false);
|
||||
break;
|
||||
case "take_video":
|
||||
_sendImageFromCamera(model, theme, isVideo: true);
|
||||
break;
|
||||
case "file":
|
||||
_sendFile(model, theme);
|
||||
|
|
@ -673,14 +638,12 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
bool hasMicrophonePermission = false;
|
||||
if (type == TYPE_VIDEO) {
|
||||
hasCameraPermission = await Permissions.checkPermission(context, Permission.camera.value);
|
||||
hasMicrophonePermission = await Permissions.checkPermission(
|
||||
context, Permission.microphone.value);
|
||||
hasMicrophonePermission = await Permissions.checkPermission(context, Permission.microphone.value);
|
||||
if (!hasCameraPermission || !hasMicrophonePermission) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
hasMicrophonePermission = await Permissions.checkPermission(
|
||||
context, Permission.microphone.value);
|
||||
hasMicrophonePermission = await Permissions.checkPermission(context, Permission.microphone.value);
|
||||
if (!hasMicrophonePermission) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -702,9 +665,7 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
_tUICore.callService(TUICALLKIT_SERVICE_NAME, METHOD_NAME_CALL, {
|
||||
PARAM_NAME_TYPE: type,
|
||||
PARAM_NAME_USERIDS: inviteMember,
|
||||
PARAM_NAME_GROUPID: widget.conversationType == ConvType.group
|
||||
? widget.conversationID
|
||||
: ""
|
||||
PARAM_NAME_GROUPID: widget.conversationType == ConvType.group ? widget.conversationID : ""
|
||||
});
|
||||
}
|
||||
} else {
|
||||
|
|
@ -716,11 +677,16 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_betterPlayerController?.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
final TUIChatSeparateViewModel model =
|
||||
Provider.of<TUIChatSeparateViewModel>(context);
|
||||
final TUIChatSeparateViewModel model = Provider.of<TUIChatSeparateViewModel>(context);
|
||||
final screenWidth = MediaQuery.of(context).size.width;
|
||||
return Container(
|
||||
height: 248,
|
||||
|
|
@ -757,15 +723,12 @@ class _MorePanelState extends TIMUIKitState<MorePanel> {
|
|||
height: 64,
|
||||
width: 64,
|
||||
margin: const EdgeInsets.only(bottom: 4),
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(5))),
|
||||
decoration: const BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5))),
|
||||
child: item.icon,
|
||||
),
|
||||
Text(
|
||||
item.title,
|
||||
style: TextStyle(
|
||||
fontSize: 12, color: theme.darkTextColor),
|
||||
style: TextStyle(fontSize: 12, color: theme.darkTextColor),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ import 'dart:io';
|
|||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:tencent_im_base/tencent_im_base.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/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';
|
||||
|
|
@ -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/base_widgets/tim_ui_kit_base.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 {
|
||||
/// conversation ID
|
||||
|
|
|
|||
|
|
@ -7,6 +7,11 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/services.dart';
|
||||
import 'package:provider/provider.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_state.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;
|
||||
Map<String, V2TimGroupMemberFullInfo> mentionedMembersMap = {};
|
||||
late TextEditingController textEditingController;
|
||||
final TUIConversationViewModel conversationModel =
|
||||
serviceLocator<TUIConversationViewModel>();
|
||||
final TUIConversationViewModel conversationModel = serviceLocator<TUIConversationViewModel>();
|
||||
final TUISelfInfoViewModel selfModel = serviceLocator<TUISelfInfoViewModel>();
|
||||
MuteStatus muteStatus = MuteStatus.none;
|
||||
bool _isComposingText = false;
|
||||
|
|
@ -155,28 +159,42 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
// Keep using original scheme.
|
||||
return;
|
||||
}
|
||||
final stickerConfig =
|
||||
widget.model.chatConfig.stickerPanelConfig ?? StickerPanelConfig();
|
||||
final stickerConfig = widget.model.chatConfig.stickerPanelConfig ?? StickerPanelConfig();
|
||||
if (stickerConfig.useTencentCloudChatStickerPackage) {
|
||||
final tccEmojiSet = TUIKitStickerConstData.emojiList
|
||||
.firstWhere((element) => element.name == "tcc1");
|
||||
final tccEmojiSet = TUIKitStickerConstData.emojiList.firstWhere((element) => element.name == "tcc1");
|
||||
stickerPackageList.add(CustomStickerPackage(
|
||||
name: tccEmojiSet.name,
|
||||
baseUrl: "assets/custom_face_resource/${tccEmojiSet.name}",
|
||||
isEmoji: tccEmojiSet.isEmoji,
|
||||
isDefaultEmoji: true,
|
||||
stickerList: tccEmojiSet.list
|
||||
.asMap()
|
||||
.keys
|
||||
.map((idx) =>
|
||||
CustomSticker(index: idx, name: tccEmojiSet.list[idx]))
|
||||
.toList(),
|
||||
stickerList: tccEmojiSet.list.asMap().keys.map((idx) => CustomSticker(index: idx, name: tccEmojiSet.list[idx])).toList(),
|
||||
menuItem: CustomSticker(
|
||||
index: 0,
|
||||
name: tccEmojiSet.icon,
|
||||
)));
|
||||
}
|
||||
|
||||
if (stickerConfig.useQQStickerPackage) {
|
||||
final qqEmojiSet = TUIKitStickerConstData.emojiList.firstWhere((element) => element.name == "4349");
|
||||
stickerPackageList.add(CustomStickerPackage(
|
||||
name: qqEmojiSet.name,
|
||||
baseUrl: "assets/custom_face_resource/${qqEmojiSet.name}",
|
||||
isEmoji: qqEmojiSet.isEmoji,
|
||||
isDefaultEmoji: true,
|
||||
stickerList: qqEmojiSet.list.asMap().keys.map((idx) => CustomSticker(index: idx, name: qqEmojiSet.list[idx])).toList(),
|
||||
menuItem: CustomSticker(
|
||||
index: 0,
|
||||
name: qqEmojiSet.icon,
|
||||
)));
|
||||
}
|
||||
|
||||
if (stickerConfig.unicodeEmojiList.isNotEmpty) {
|
||||
final defEmojiList = TUIKitStickerConstData.defaultUnicodeEmojiList.map((emojiItem) {
|
||||
return CustomSticker(index: 0, name: emojiItem.toString(), unicode: emojiItem);
|
||||
}).toList();
|
||||
stickerPackageList.add(CustomStickerPackage(name: "defaultEmoji", stickerList: defEmojiList, menuItem: defEmojiList[0]));
|
||||
}
|
||||
|
||||
stickerPackageList.addAll(stickerConfig.customStickerPackages);
|
||||
return stickerPackageList;
|
||||
}
|
||||
|
|
@ -204,8 +222,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
if (cursorPosition > 0) {
|
||||
final EmojiUtil emojiUtil = EmojiUtil();
|
||||
int removeLength = 1;
|
||||
int openBracketIndex =
|
||||
originalText.lastIndexOf('[', cursorPosition - 1);
|
||||
int openBracketIndex = originalText.lastIndexOf('[', cursorPosition - 1);
|
||||
|
||||
if (openBracketIndex != -1 && originalText[cursorPosition - 1] == ']') {
|
||||
// Small png emoji
|
||||
|
|
@ -214,23 +231,18 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
if (emojiUtil.emojiMap.containsKey(key)) {
|
||||
removeLength = cursorPosition - openBracketIndex;
|
||||
}
|
||||
} else if (cursorPosition > 1 &&
|
||||
isEmoji(
|
||||
originalText.substring(cursorPosition - 2, cursorPosition))) {
|
||||
} else if (cursorPosition > 1 && isEmoji(originalText.substring(cursorPosition - 2, cursorPosition))) {
|
||||
removeLength = 2;
|
||||
}
|
||||
|
||||
text = originalText.substring(0, cursorPosition - removeLength) +
|
||||
originalText.substring(cursorPosition);
|
||||
text = originalText.substring(0, cursorPosition - removeLength) + originalText.substring(cursorPosition);
|
||||
currentCursor = (currentCursor ?? removeLength) - removeLength;
|
||||
}
|
||||
|
||||
textEditingController.text = text;
|
||||
|
||||
if (TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop) {
|
||||
textEditingController.selection = TextSelection.fromPosition(
|
||||
TextPosition(
|
||||
offset: currentCursor ?? textEditingController.text.length));
|
||||
textEditingController.selection = TextSelection.fromPosition(TextPosition(offset: currentCursor ?? textEditingController.text.length));
|
||||
focusNode.requestFocus();
|
||||
}
|
||||
}
|
||||
|
|
@ -250,9 +262,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
|
||||
void _addStickerToText(String sticker) {
|
||||
final currentText = textEditingController.text;
|
||||
if (currentCursor != null &&
|
||||
currentCursor! > -1 &&
|
||||
currentCursor! < currentText.length + 1) {
|
||||
if (currentCursor != null && currentCursor! > -1 && currentCursor! < currentText.length + 1) {
|
||||
final firstString = currentText.substring(0, currentCursor);
|
||||
final secondString = currentText.substring(currentCursor!);
|
||||
currentCursor = currentCursor! + sticker.length;
|
||||
|
|
@ -263,8 +273,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
}
|
||||
|
||||
if (TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop) {
|
||||
textEditingController.selection = TextSelection.fromPosition(TextPosition(
|
||||
offset: currentCursor ?? textEditingController.text.length));
|
||||
textEditingController.selection = TextSelection.fromPosition(TextPosition(offset: currentCursor ?? textEditingController.text.length));
|
||||
focusNode.requestFocus();
|
||||
}
|
||||
}
|
||||
|
|
@ -273,23 +282,13 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
return text.replaceAll(RegExp(r'\ufeff'), "");
|
||||
}
|
||||
|
||||
Future handleSetDraftText(
|
||||
{String? id, ConvType? convType, String? groupID}) async {
|
||||
Future handleSetDraftText({String? id, ConvType? convType, String? groupID}) async {
|
||||
String text = textEditingController.text;
|
||||
String convID = id ?? widget.conversationID;
|
||||
final isTopic = convID.contains("@TOPIC#");
|
||||
String conversationID = isTopic
|
||||
? convID
|
||||
: ((convType ?? widget.conversationType) == ConvType.c2c
|
||||
? "${TUIConversationViewModel.conversationC2CPrefix}$convID"
|
||||
: "${TUIConversationViewModel.conversationGroupPrefix}$convID");
|
||||
String conversationID = isTopic ? convID : ((convType ?? widget.conversationType) == ConvType.c2c ? "${TUIConversationViewModel.conversationC2CPrefix}$convID" : "${TUIConversationViewModel.conversationGroupPrefix}$convID");
|
||||
String draftText = _filterU200b(text);
|
||||
return await conversationModel.setConversationDraft(
|
||||
groupID: groupID ?? widget.groupID,
|
||||
isTopic: isTopic,
|
||||
isAllowWeb: widget.model.chatConfig.isUseDraftOnWeb,
|
||||
conversationID: conversationID,
|
||||
draftText: draftText);
|
||||
return await conversationModel.setConversationDraft(groupID: groupID ?? widget.groupID, isTopic: isTopic, isAllowWeb: widget.model.chatConfig.isUseDraftOnWeb, conversationID: conversationID, draftText: draftText);
|
||||
}
|
||||
|
||||
// 和onSubmitted一样,只是保持焦点的不同
|
||||
|
|
@ -330,28 +329,26 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
// 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
|
||||
// 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)');
|
||||
if (regex.hasMatch(data)) {
|
||||
index += 1;
|
||||
data = (data.split("/")[3]).split("@")[0];
|
||||
}
|
||||
|
||||
if (widget.model.repliedMessage != null) {
|
||||
MessageUtils.handleMessageError(
|
||||
widget.model.sendFaceMessage(
|
||||
index: index,
|
||||
data: data,
|
||||
convID: widget.conversationID,
|
||||
convType: convType),
|
||||
context);
|
||||
MessageUtils.handleMessageError(widget.model.sendFaceMessage(index: groupID, data: data, convID: widget.conversationID, convType: convType), context);
|
||||
} else {
|
||||
MessageUtils.handleMessageError(
|
||||
widget.model.sendFaceMessage(
|
||||
index: index,
|
||||
data: data,
|
||||
convID: widget.conversationID,
|
||||
convType: convType),
|
||||
context);
|
||||
MessageUtils.handleMessageError(widget.model.sendFaceMessage(index: groupID, data: data, convID: widget.conversationID, convType: convType), context);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -371,24 +368,11 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
final convType = widget.conversationType;
|
||||
if (text.isNotEmpty && text != zeroWidthSpace) {
|
||||
if (widget.model.repliedMessage != null) {
|
||||
MessageUtils.handleMessageError(
|
||||
widget.model.sendReplyMessage(
|
||||
text: text,
|
||||
convID: widget.conversationID,
|
||||
convType: convType,
|
||||
atUserIDList: getUserIdFromMemberInfoMap()),
|
||||
context);
|
||||
MessageUtils.handleMessageError(widget.model.sendReplyMessage(text: text, convID: widget.conversationID, convType: convType, atUserIDList: getUserIdFromMemberInfoMap()), context);
|
||||
} else if (mentionedMembersMap.isNotEmpty) {
|
||||
widget.model.sendTextAtMessage(
|
||||
text: text,
|
||||
convType: widget.conversationType,
|
||||
convID: widget.conversationID,
|
||||
atUserList: getUserIdFromMemberInfoMap());
|
||||
widget.model.sendTextAtMessage(text: text, convType: widget.conversationType, convID: widget.conversationID, atUserList: getUserIdFromMemberInfoMap());
|
||||
} else {
|
||||
MessageUtils.handleMessageError(
|
||||
widget.model.sendTextMessage(
|
||||
text: text, convID: widget.conversationID, convType: convType),
|
||||
context);
|
||||
MessageUtils.handleMessageError(widget.model.sendTextMessage(text: text, convID: widget.conversationID, convType: convType), context);
|
||||
}
|
||||
textEditingController.clear();
|
||||
currentCursor = null;
|
||||
|
|
@ -401,8 +385,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
}
|
||||
|
||||
void goDownBottom() {
|
||||
if (globalModel.getMessageListPosition(widget.conversationID) ==
|
||||
HistoryMessagePosition.notShowLatest) {
|
||||
if (globalModel.getMessageListPosition(widget.conversationID) == HistoryMessagePosition.notShowLatest) {
|
||||
return;
|
||||
}
|
||||
Future.delayed(const Duration(milliseconds: 50), () {
|
||||
|
|
@ -431,18 +414,14 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
}
|
||||
|
||||
String _getShowName(V2TimGroupMemberFullInfo? item) {
|
||||
return TencentUtils.checkStringWithoutSpace(item?.nameCard) ??
|
||||
TencentUtils.checkStringWithoutSpace(item?.nickName) ??
|
||||
TencentUtils.checkStringWithoutSpace(item?.userID) ??
|
||||
"";
|
||||
return TencentUtils.checkStringWithoutSpace(item?.nameCard) ?? TencentUtils.checkStringWithoutSpace(item?.nickName) ?? TencentUtils.checkStringWithoutSpace(item?.userID) ?? "";
|
||||
}
|
||||
|
||||
mentionMemberInMessage(String? userID, String? nickName) {
|
||||
if (TencentUtils.checkString(userID) == null) {
|
||||
focusNode.requestFocus();
|
||||
} else {
|
||||
final memberInfo = widget.model.groupMemberList
|
||||
?.firstWhereOrNull((element) => element?.userID == userID) ??
|
||||
final memberInfo = widget.model.groupMemberList?.firstWhereOrNull((element) => element?.userID == userID) ??
|
||||
V2TimGroupMemberFullInfo(
|
||||
userID: userID ?? "",
|
||||
nickName: nickName,
|
||||
|
|
@ -453,8 +432,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
//please do not delete space
|
||||
focusNode.requestFocus();
|
||||
textEditingController.text = text;
|
||||
textEditingController.selection =
|
||||
TextSelection.fromPosition(TextPosition(offset: text.length));
|
||||
textEditingController.selection = TextSelection.fromPosition(TextPosition(offset: text.length));
|
||||
lastText = text;
|
||||
_isComposingText = false;
|
||||
narrowTextFieldKey.currentState?.showKeyboard = true;
|
||||
|
|
@ -482,16 +460,10 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
maxLines: null,
|
||||
);
|
||||
textPainter.layout(maxWidth: inputWidth);
|
||||
final TextPosition lastLineOffset = textPainter
|
||||
.getPositionForOffset(Offset(textPainter.width, textPainter.height));
|
||||
final Offset caretPosition =
|
||||
textPainter.getOffsetForCaret(lastLineOffset, Rect.zero);
|
||||
final TextPosition lastLineOffset = textPainter.getPositionForOffset(Offset(textPainter.width, textPainter.height));
|
||||
final Offset caretPosition = textPainter.getOffsetForCaret(lastLineOffset, Rect.zero);
|
||||
final dx = min(inputWidth - 180, caretPosition.dx + 16);
|
||||
final dy = max(
|
||||
24,
|
||||
21 * widget.model.chatConfig.desktopMessageInputFieldLines -
|
||||
caretPosition.dy)
|
||||
.toDouble();
|
||||
final dy = max(24, 21 * widget.model.chatConfig.desktopMessageInputFieldLines - caretPosition.dy).toDouble();
|
||||
|
||||
return Offset(dx, dy);
|
||||
}
|
||||
|
|
@ -528,19 +500,13 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
mentionedMembersMap = map;
|
||||
}
|
||||
|
||||
(int, String, bool)? findChangedCharacter(
|
||||
String originalString, String newString) {
|
||||
(int, String, bool)? findChangedCharacter(String originalString, String newString) {
|
||||
if (newString.length < originalString.length) {
|
||||
final originalStringLength = originalString.length;
|
||||
final newStringLength = newString.length;
|
||||
for (int i = 0; i < newString.length; ++i) {
|
||||
if (originalString[originalStringLength - i - 1] !=
|
||||
newString[newStringLength - i - 1]) {
|
||||
return (
|
||||
newStringLength - i,
|
||||
originalString[originalStringLength - i - 1],
|
||||
false
|
||||
);
|
||||
if (originalString[originalStringLength - i - 1] != newString[newStringLength - i - 1]) {
|
||||
return (newStringLength - i, originalString[originalStringLength - i - 1], false);
|
||||
}
|
||||
}
|
||||
return (newString.length, originalString[newString.length], false);
|
||||
|
|
@ -559,11 +525,8 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
_handleAtText(String text, TUIChatSeparateViewModel model) async {
|
||||
final text = textEditingController.text;
|
||||
final String originalText = lastText;
|
||||
String? groupID = widget.conversationType == ConvType.group
|
||||
? widget.conversationID
|
||||
: null;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
String? groupID = widget.conversationType == ConvType.group ? widget.conversationID : null;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
|
||||
if (groupID == null) {
|
||||
lastText = text;
|
||||
|
|
@ -583,11 +546,9 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
String atTag = originalText.substring(atIndex, spaceIndex);
|
||||
String deletedChar = originalText[diffIndex];
|
||||
if (shouldRemoveAtTag(atTag, deletedChar)) {
|
||||
final newText = originalText.substring(0, atIndex) +
|
||||
originalText.substring(spaceIndex + 1);
|
||||
final newText = originalText.substring(0, atIndex) + originalText.substring(spaceIndex + 1);
|
||||
textEditingController.text = newText;
|
||||
textEditingController.selection =
|
||||
TextSelection.collapsed(offset: atIndex);
|
||||
textEditingController.selection = TextSelection.collapsed(offset: atIndex);
|
||||
lastText = newText;
|
||||
updateMentionedMap();
|
||||
return;
|
||||
|
|
@ -597,14 +558,13 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
}
|
||||
|
||||
final int selfRole = widget.model.selfMemberInfo?.role ?? 0;
|
||||
final bool canAtAll = widget.model.chatConfig.isMemberCanAtAll
|
||||
? true
|
||||
: (selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN ||
|
||||
selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER);
|
||||
final bool canAtAll = widget.model.chatConfig.isMemberCanAtAll ? true : (selfRole == GroupMemberRoleType
|
||||
.V2TIM_GROUP_MEMBER_ROLE_ADMIN || selfRole
|
||||
==
|
||||
GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER);
|
||||
|
||||
if (isDesktopScreen) {
|
||||
(int, String, bool)? changedCharacterRecord =
|
||||
findChangedCharacter(originalText, text);
|
||||
(int, String, bool)? changedCharacterRecord = findChangedCharacter(originalText, text);
|
||||
int? changedTextPosition = changedCharacterRecord?.$1;
|
||||
String? changedCharacter = changedCharacterRecord?.$2;
|
||||
bool isAdded = changedCharacterRecord?.$3 ?? false;
|
||||
|
|
@ -613,13 +573,10 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
int? atPlace;
|
||||
|
||||
if (changedTextPosition != null) {
|
||||
subText = isAdded == true
|
||||
? text.substring(0, changedTextPosition + 1)
|
||||
: text.substring(0, changedTextPosition);
|
||||
subText = isAdded == true ? text.substring(0, changedTextPosition + 1) : text.substring(0, changedTextPosition);
|
||||
atPlace = subText.lastIndexOf('@');
|
||||
if (atPlace != -1) {
|
||||
keyword = text.substring(
|
||||
atPlace + 1, changedTextPosition + (isAdded ? 1 : 0));
|
||||
keyword = text.substring(atPlace + 1, changedTextPosition + (isAdded ? 1 : 0));
|
||||
}
|
||||
} else {
|
||||
atPlace = -1;
|
||||
|
|
@ -632,28 +589,21 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
model.atPositionY = atPosition.dy;
|
||||
isAddingAtSearchWords = true;
|
||||
}
|
||||
List<V2TimGroupMemberFullInfo> showAtMemberList = (model
|
||||
.groupMemberList ??
|
||||
[])
|
||||
List<V2TimGroupMemberFullInfo> showAtMemberList = (model.groupMemberList ?? [])
|
||||
.where((element) {
|
||||
final showName = (TencentUtils.checkStringWithoutSpace(
|
||||
element?.friendRemark) ??
|
||||
final showName = (TencentUtils.checkStringWithoutSpace(element?.friendRemark) ??
|
||||
TencentUtils.checkStringWithoutSpace(element?.nameCard) ??
|
||||
TencentUtils.checkStringWithoutSpace(element?.nickName) ??
|
||||
TencentUtils.checkStringWithoutSpace(element?.userID) ??
|
||||
"")
|
||||
.toLowerCase();
|
||||
keyword ??= "";
|
||||
return element != null &&
|
||||
showName.contains(keyword!.toLowerCase()) &&
|
||||
TencentUtils.checkString(showName) != null &&
|
||||
element.userID != widget.model.selfMemberInfo?.userID;
|
||||
return element != null && showName.contains(keyword!.toLowerCase()) && TencentUtils.checkString(showName) != null && element.userID != widget.model.selfMemberInfo?.userID;
|
||||
})
|
||||
.whereType<V2TimGroupMemberFullInfo>()
|
||||
.toList();
|
||||
|
||||
showAtMemberList.sort(
|
||||
(V2TimGroupMemberFullInfo userA, V2TimGroupMemberFullInfo userB) {
|
||||
showAtMemberList.sort((V2TimGroupMemberFullInfo userA, V2TimGroupMemberFullInfo userB) {
|
||||
final isUserAIsGroupAdmin = userA.role == 300;
|
||||
final isUserAIsGroupOwner = userA.role == 400;
|
||||
|
||||
|
|
@ -676,11 +626,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
|
||||
keyword ??= "";
|
||||
if (canAtAll && showAtMemberList.isNotEmpty && keyword!.isEmpty) {
|
||||
showAtMemberList = [
|
||||
V2TimGroupMemberFullInfo(
|
||||
userID: "__kImSDK_MesssageAtALL__", nickName: TIM_t("所有人")),
|
||||
...showAtMemberList
|
||||
];
|
||||
showAtMemberList = [V2TimGroupMemberFullInfo(userID: "__kImSDK_MesssageAtALL__", nickName: TIM_t("所有人")), ...showAtMemberList];
|
||||
}
|
||||
|
||||
model.activeAtIndex = 0;
|
||||
|
|
@ -692,19 +638,11 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
model.showAtMemberList = [];
|
||||
isAddingAtSearchWords = false;
|
||||
}
|
||||
} else if (textLength > 0 &&
|
||||
text[textLength - 1] == "@" &&
|
||||
lastText.length < textLength) {
|
||||
List<V2TimGroupMemberFullInfo> selectedAtMemberList =
|
||||
await Navigator.push(
|
||||
} else if (textLength > 0 && text[textLength - 1] == "@" && lastText.length < textLength) {
|
||||
List<V2TimGroupMemberFullInfo> selectedAtMemberList = await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => AtText(
|
||||
groupMemberList: model.groupMemberList,
|
||||
groupInfo: model.groupInfo,
|
||||
groupID: groupID,
|
||||
canAtAll: canAtAll,
|
||||
groupType: widget.groupType),
|
||||
builder: (context) => AtText(groupMemberList: model.groupMemberList, groupInfo: model.groupInfo, groupID: groupID, canAtAll: canAtAll, groupType: widget.groupType),
|
||||
),
|
||||
);
|
||||
|
||||
|
|
@ -714,8 +652,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
if (memberInfo != null) {
|
||||
mentionedMembersMap["@$showName"] = memberInfo;
|
||||
String addAtCharacter = i == 0 ? "" : "@";
|
||||
textEditingController.text =
|
||||
"${textEditingController.text}$addAtCharacter$showName ";
|
||||
textEditingController.text = "${textEditingController.text}$addAtCharacter$showName ";
|
||||
lastText = "${textEditingController.text}$addAtCharacter$showName ";
|
||||
}
|
||||
}
|
||||
|
|
@ -726,22 +663,17 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
|
||||
void replaceAtTag(String selectedMember) {
|
||||
int cursorPosition = textEditingController.selection.baseOffset;
|
||||
int atIndex =
|
||||
textEditingController.text.lastIndexOf('@', cursorPosition - 1);
|
||||
int atIndex = textEditingController.text.lastIndexOf('@', cursorPosition - 1);
|
||||
if (atIndex >= 0) {
|
||||
String beforeAt = textEditingController.text.substring(0, atIndex);
|
||||
String afterAt = textEditingController.text.substring(cursorPosition);
|
||||
textEditingController.text =
|
||||
beforeAt + '@' + selectedMember + ' ' + afterAt;
|
||||
textEditingController.selection =
|
||||
TextSelection.collapsed(offset: atIndex + selectedMember.length + 2);
|
||||
textEditingController.text = beforeAt + '@' + selectedMember + ' ' + afterAt;
|
||||
textEditingController.selection = TextSelection.collapsed(offset: atIndex + selectedMember.length + 2);
|
||||
lastText = beforeAt + '@' + selectedMember + ' ' + afterAt;
|
||||
}
|
||||
}
|
||||
|
||||
void handleAtMember(
|
||||
{V2TimGroupMemberFullInfo? memberInfo,
|
||||
bool? isAddToCursorPosition = false}) {
|
||||
void handleAtMember({V2TimGroupMemberFullInfo? memberInfo, bool? isAddToCursorPosition = false}) {
|
||||
if (memberInfo != null) {
|
||||
final String showName = _getShowName(memberInfo);
|
||||
mentionedMembersMap["@$showName"] = memberInfo;
|
||||
|
|
@ -755,24 +687,17 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
KeyEventResult handleDesktopKeyEvent(FocusNode node, RawKeyEvent event) {
|
||||
final activeIndex = widget.model.activeAtIndex;
|
||||
final showMemberList = widget.model.showAtMemberList;
|
||||
final isPressEnter = (event.physicalKey == PhysicalKeyboardKey.enter) ||
|
||||
(event.physicalKey == PhysicalKeyboardKey.numpadEnter);
|
||||
final isPressEnter = (event.physicalKey == PhysicalKeyboardKey.enter) || (event.physicalKey == PhysicalKeyboardKey.numpadEnter);
|
||||
if (event.runtimeType == RawKeyDownEvent) {
|
||||
if (event.physicalKey == PhysicalKeyboardKey.backspace) {
|
||||
if (textEditingController.text.isEmpty && lastText.isEmpty) {
|
||||
widget.model.repliedMessage = null;
|
||||
return KeyEventResult.handled;
|
||||
}
|
||||
} else if ((event.isShiftPressed ||
|
||||
event.isAltPressed ||
|
||||
event.isControlPressed ||
|
||||
event.isMetaPressed) &&
|
||||
isPressEnter) {
|
||||
} else if ((event.isShiftPressed || event.isAltPressed || event.isControlPressed || event.isMetaPressed) && isPressEnter) {
|
||||
final offset = textEditingController.selection.baseOffset;
|
||||
textEditingController.text =
|
||||
'${lastText.substring(0, offset)}\n${lastText.substring(offset)}';
|
||||
textEditingController.selection =
|
||||
TextSelection.fromPosition(TextPosition(offset: offset + 1));
|
||||
textEditingController.text = '${lastText.substring(0, offset)}\n${lastText.substring(offset)}';
|
||||
textEditingController.selection = TextSelection.fromPosition(TextPosition(offset: offset + 1));
|
||||
lastText = textEditingController.text;
|
||||
|
||||
return KeyEventResult.handled;
|
||||
|
|
@ -782,34 +707,26 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
onSubmitted();
|
||||
} else {
|
||||
isAddingAtSearchWords = false;
|
||||
final V2TimGroupMemberFullInfo? memberInfo =
|
||||
showMemberList[activeIndex];
|
||||
final V2TimGroupMemberFullInfo? memberInfo = showMemberList[activeIndex];
|
||||
if (memberInfo != null) {
|
||||
handleAtMember(
|
||||
memberInfo: memberInfo, isAddToCursorPosition: true);
|
||||
handleAtMember(memberInfo: memberInfo, isAddToCursorPosition: true);
|
||||
}
|
||||
}
|
||||
return KeyEventResult.handled;
|
||||
}
|
||||
}
|
||||
|
||||
if (event.isKeyPressed(LogicalKeyboardKey.arrowUp) &&
|
||||
isAddingAtSearchWords &&
|
||||
showMemberList.isNotEmpty) {
|
||||
if (event.isKeyPressed(LogicalKeyboardKey.arrowUp) && isAddingAtSearchWords && showMemberList.isNotEmpty) {
|
||||
final newIndex = max(activeIndex - 1, 0);
|
||||
widget.model.activeAtIndex = newIndex;
|
||||
widget.atMemberPanelScroll?.scrollToIndex(newIndex,
|
||||
preferPosition: AutoScrollPosition.middle);
|
||||
widget.atMemberPanelScroll?.scrollToIndex(newIndex, preferPosition: AutoScrollPosition.middle);
|
||||
return KeyEventResult.handled;
|
||||
}
|
||||
|
||||
if (event.isKeyPressed(LogicalKeyboardKey.arrowDown) &&
|
||||
isAddingAtSearchWords &&
|
||||
showMemberList.isNotEmpty) {
|
||||
if (event.isKeyPressed(LogicalKeyboardKey.arrowDown) && isAddingAtSearchWords && showMemberList.isNotEmpty) {
|
||||
final newIndex = min(activeIndex + 1, showMemberList.length - 1);
|
||||
widget.model.activeAtIndex = newIndex;
|
||||
widget.atMemberPanelScroll?.scrollToIndex(newIndex,
|
||||
preferPosition: AutoScrollPosition.middle);
|
||||
widget.atMemberPanelScroll?.scrollToIndex(newIndex, preferPosition: AutoScrollPosition.middle);
|
||||
return KeyEventResult.handled;
|
||||
}
|
||||
}
|
||||
|
|
@ -827,8 +744,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
} else {
|
||||
focusNode = FocusNode();
|
||||
}
|
||||
textEditingController =
|
||||
widget.controller?.textEditingController ?? TextEditingController();
|
||||
textEditingController = widget.controller?.textEditingController ?? TextEditingController();
|
||||
if (widget.initText != null) {
|
||||
textEditingController.text = widget.initText!;
|
||||
}
|
||||
|
|
@ -836,10 +752,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
widget.controller?.addListener(controllerHandler);
|
||||
}
|
||||
final AppLocale appLocale = I18nUtils.findDeviceLocale(null);
|
||||
languageType =
|
||||
(appLocale == AppLocale.zhHans || appLocale == AppLocale.zhHant)
|
||||
? 'zh'
|
||||
: 'en';
|
||||
languageType = (appLocale == AppLocale.zhHans || appLocale == AppLocale.zhHant) ? 'zh' : 'en';
|
||||
textEditingController.addListener(() {
|
||||
_isComposingText = textEditingController.value.composing.start != -1;
|
||||
});
|
||||
|
|
@ -849,13 +762,11 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
controllerHandler() {
|
||||
final actionType = widget.controller?.actionType;
|
||||
if (actionType == ActionType.longPressToAt) {
|
||||
mentionMemberInMessage(
|
||||
widget.controller?.atUserID, widget.controller?.atUserName);
|
||||
mentionMemberInMessage(widget.controller?.atUserID, widget.controller?.atUserName);
|
||||
} else if (actionType == ActionType.setTextField) {
|
||||
final newText = widget.controller?.inputText ?? "";
|
||||
textEditingController.text = newText;
|
||||
textEditingController.selection = TextSelection.fromPosition(
|
||||
TextPosition(offset: textEditingController.text.length));
|
||||
textEditingController.selection = TextSelection.fromPosition(TextPosition(offset: textEditingController.text.length));
|
||||
lastText = textEditingController.text;
|
||||
focusNode.requestFocus();
|
||||
return;
|
||||
|
|
@ -873,18 +784,14 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
super.didUpdateWidget(oldWidget);
|
||||
if (widget.conversationID != oldWidget.conversationID) {
|
||||
mentionedMembersMap.clear();
|
||||
handleSetDraftText(
|
||||
id: oldWidget.conversationID,
|
||||
convType: oldWidget.conversationType,
|
||||
groupID: oldWidget.groupID);
|
||||
handleSetDraftText(id: oldWidget.conversationID, convType: oldWidget.conversationType, groupID: oldWidget.groupID);
|
||||
if (oldWidget.initText != widget.initText) {
|
||||
textEditingController.text = widget.initText ?? "";
|
||||
} else {
|
||||
textEditingController.clear();
|
||||
}
|
||||
}
|
||||
if (widget.initText != oldWidget.initText &&
|
||||
TencentUtils.checkString(widget.initText) != null) {
|
||||
if (widget.initText != oldWidget.initText && TencentUtils.checkString(widget.initText) != null) {
|
||||
textEditingController.text = widget.initText!;
|
||||
focusNode.requestFocus();
|
||||
}
|
||||
|
|
@ -902,12 +809,8 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
|
||||
Future<bool> getMemberMuteStatus(String userID) async {
|
||||
// Get the mute state of the members recursively
|
||||
if (widget.model.groupMemberList?.any((item) => (item?.userID == userID)) ??
|
||||
false) {
|
||||
final int muteUntil = widget.model.groupMemberList
|
||||
?.firstWhere((item) => (item?.userID == userID))
|
||||
?.muteUntil ??
|
||||
0;
|
||||
if (widget.model.groupMemberList?.any((item) => (item?.userID == userID)) ?? false) {
|
||||
final int muteUntil = widget.model.groupMemberList?.firstWhere((item) => (item?.userID == userID))?.muteUntil ?? 0;
|
||||
return muteUntil * 1000 > DateTime.now().millisecondsSinceEpoch;
|
||||
} else {
|
||||
return false;
|
||||
|
|
@ -920,30 +823,22 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
}
|
||||
|
||||
final int selfRole = widget.model.selfMemberInfo?.role ?? 0;
|
||||
final bool willNotBeenMuted =
|
||||
(selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN ||
|
||||
selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER);
|
||||
final bool willNotBeenMuted = (selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN || selfRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER);
|
||||
|
||||
if (widget.conversationType == ConvType.group && !willNotBeenMuted) {
|
||||
if ((model.groupInfo?.isAllMuted ?? false) &&
|
||||
muteStatus != MuteStatus.all) {
|
||||
if ((model.groupInfo?.isAllMuted ?? false) && muteStatus != MuteStatus.all) {
|
||||
Future.delayed(const Duration(seconds: 0), () {
|
||||
setState(() {
|
||||
muteStatus = MuteStatus.all;
|
||||
});
|
||||
});
|
||||
} else if (selfModel.loginInfo?.userID != null &&
|
||||
await getMemberMuteStatus(selfModel.loginInfo!.userID!) &&
|
||||
muteStatus != MuteStatus.me) {
|
||||
} else if (selfModel.loginInfo?.userID != null && await getMemberMuteStatus(selfModel.loginInfo!.userID!) && muteStatus != MuteStatus.me) {
|
||||
Future.delayed(const Duration(seconds: 0), () {
|
||||
setState(() {
|
||||
muteStatus = MuteStatus.me;
|
||||
});
|
||||
});
|
||||
} else if (!(model.groupInfo?.isAllMuted ?? false) &&
|
||||
!(selfModel.loginInfo?.userID != null &&
|
||||
await getMemberMuteStatus(selfModel.loginInfo!.userID!)) &&
|
||||
muteStatus != MuteStatus.none) {
|
||||
} else if (!(model.groupInfo?.isAllMuted ?? false) && !(selfModel.loginInfo?.userID != null && await getMemberMuteStatus(selfModel.loginInfo!.userID!)) && muteStatus != MuteStatus.none) {
|
||||
Future.delayed(const Duration(seconds: 0), () {
|
||||
setState(() {
|
||||
muteStatus = MuteStatus.none;
|
||||
|
|
@ -972,8 +867,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final theme = value.theme;
|
||||
final TUIChatSeparateViewModel model =
|
||||
Provider.of<TUIChatSeparateViewModel>(context);
|
||||
final TUIChatSeparateViewModel model = Provider.of<TUIChatSeparateViewModel>(context);
|
||||
|
||||
_getMuteType(model);
|
||||
|
||||
|
|
@ -993,8 +887,7 @@ class _InputTextFieldState extends TIMUIKitState<TIMUIKitInputTextField> {
|
|||
}
|
||||
|
||||
final forbiddenText = getForbiddenText();
|
||||
return LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
return LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
|
||||
inputWidth = constraints.maxWidth;
|
||||
return TUIKitScreenUtils.getDeviceWidget(
|
||||
context: context,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
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 {
|
||||
hideAllPanel,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import 'package:extended_text_field/extended_text_field.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.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_state.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/data_services/services_locatar.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/optimize_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/permission.dart';
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ import 'package:package_info_plus/package_info_plus.dart';
|
|||
import 'package:pasteboard/pasteboard.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
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_state.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:uuid/uuid.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 {
|
||||
final String item;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue