tencent_cloud_chat_uikit/lib/ui/widgets/merger_message_screen.dart

333 lines
12 KiB
Dart

import 'dart:convert';
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/models/v2_tim_message.dart'
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart';
import 'package:tencent_cloud_chat_uikit/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/ui/views/TIMUIKitChat/TIMUIKitMessageItem/main.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_face_elem.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/tim_uikit_cloud_custom_data.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';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme_view_model.dart';
class MergerMessageScreen extends StatefulWidget {
final TUIChatSeparateViewModel model;
final String msgID;
final MessageItemBuilder? messageItemBuilder;
const MergerMessageScreen({Key? key, required this.model, required this.msgID, this.messageItemBuilder})
: super(key: key);
@override
State<StatefulWidget> createState() => MergerMessageScreenState();
}
class MergerMessageScreenState extends TIMUIKitState<MergerMessageScreen> {
final MessageService _messageService = serviceLocator<MessageService>();
List<V2TimMessage> messageList = [];
@override
initState() {
super.initState();
initMessageList();
}
void initMessageList() async {
final mergerMessageList = await _messageService.downloadMergerMessage(msgID: widget.msgID);
setState(() {
messageList = mergerMessageList ?? [];
});
}
bool isReplyMessage(V2TimMessage message) {
final hasCustomData = message.cloudCustomData != null && message.cloudCustomData != "";
if (hasCustomData) {
try {
final CloudCustomData messageCloudCustomData = CloudCustomData.fromJson(
json.decode(TencentUtils.checkString(message.cloudCustomData) != null ? message.cloudCustomData! : "{}"));
if (messageCloudCustomData.messageReply != null) {
MessageRepliedData.fromJson(messageCloudCustomData.messageReply!);
return true;
}
return false;
} catch (error) {
return false;
}
}
return false;
}
Widget _getMsgItem(V2TimMessage message) {
final type = message.elemType;
final isFromSelf = message.isSelf ?? true;
switch (type) {
case MessageElemType.V2TIM_ELEM_TYPE_CUSTOM:
if (widget.messageItemBuilder?.customMessageItemBuilder != null) {
return widget.messageItemBuilder!.customMessageItemBuilder!(
message,
false,
() {},
)!;
}
return Text(TIM_t("[自定义]"));
case MessageElemType.V2TIM_ELEM_TYPE_SOUND:
if (widget.messageItemBuilder?.soundMessageItemBuilder != null) {
return widget.messageItemBuilder!.soundMessageItemBuilder!(
message,
false,
() {},
)!;
}
return TIMUIKitSoundElem(
chatModel: widget.model,
isShowMessageReaction: false,
message: message,
soundElem: message.soundElem!,
msgID: message.msgID ?? "",
isFromSelf: isFromSelf,
localCustomInt: message.localCustomInt);
case MessageElemType.V2TIM_ELEM_TYPE_TEXT:
if (isReplyMessage(message)) {
if (widget.messageItemBuilder?.textReplyMessageItemBuilder != null) {
return widget.messageItemBuilder!.textReplyMessageItemBuilder!(
message,
false,
() {},
)!;
}
return TIMUIKitReplyElem(
isShowMessageReaction: false,
chatModel: widget.model,
message: message,
scrollToIndex: () {},
clearJump: () {});
}
if (widget.messageItemBuilder?.textMessageItemBuilder != null) {
return widget.messageItemBuilder!.textMessageItemBuilder!(
message,
false,
() {},
)!;
}
return TIMUIKitTextElem(
chatModel: widget.model,
message: message,
isFromSelf: message.isSelf ?? true,
clearJump: () {},
isShowJump: false,
isShowMessageReaction: false,
);
case MessageElemType.V2TIM_ELEM_TYPE_FACE:
if (widget.messageItemBuilder?.faceMessageItemBuilder != null) {
return widget.messageItemBuilder!.faceMessageItemBuilder!(
message,
false,
() {},
)!;
}
return TIMUIKitFaceElem(
model: widget.model,
isShowJump: false,
isShowMessageReaction: false,
path: message.faceElem?.data ?? "",
message: message);
case MessageElemType.V2TIM_ELEM_TYPE_FILE:
if (widget.messageItemBuilder?.fileMessageItemBuilder != null) {
return widget.messageItemBuilder!.fileMessageItemBuilder!(
message,
false,
() {},
)!;
}
return TIMUIKitFileElem(
chatModel: widget.model,
isShowMessageReaction: false,
message: message,
messageID: message.msgID,
fileElem: message.fileElem,
isSelf: isFromSelf,
isShowJump: false);
case MessageElemType.V2TIM_ELEM_TYPE_IMAGE:
if (widget.messageItemBuilder?.imageMessageItemBuilder != null) {
return widget.messageItemBuilder!.imageMessageItemBuilder!(
message,
false,
() {},
)!;
}
return TIMUIKitImageElem(
chatModel: widget.model,
isShowMessageReaction: false,
message: message,
isFrom: "merger",
key: Key("${message.seq}_${message.timestamp}"),
);
case MessageElemType.V2TIM_ELEM_TYPE_VIDEO:
if (widget.messageItemBuilder?.videoMessageItemBuilder != null) {
return widget.messageItemBuilder!.videoMessageItemBuilder!(
message,
false,
() {},
)!;
}
return TIMUIKitVideoElem(message, chatModel: widget.model, isFrom: "merger", isShowMessageReaction: false);
case MessageElemType.V2TIM_ELEM_TYPE_LOCATION:
if (widget.messageItemBuilder?.locationMessageItemBuilder != null) {
return widget.messageItemBuilder!.locationMessageItemBuilder!(
message,
false,
() {},
)!;
}
return Text(TIM_t("[位置]"));
case MessageElemType.V2TIM_ELEM_TYPE_MERGER:
if (widget.messageItemBuilder?.mergerMessageItemBuilder != null) {
return widget.messageItemBuilder!.mergerMessageItemBuilder!(
message,
false,
() {},
)!;
}
return TIMUIKitMergerElem(
model: widget.model,
isShowJump: false,
isShowMessageReaction: false,
message: message,
mergerElem: message.mergerElem!,
isSelf: isFromSelf,
messageID: message.msgID!);
default:
return Text(TIM_t("未知消息"));
}
}
double getMaxWidth(BuildContext context) {
final size = MediaQuery.of(context).size;
final width = size.width;
return width - 150;
}
Widget _itemBuilder(V2TimMessage message, BuildContext context) {
final faceUrl = message.faceUrl ?? "";
final showName = message.nickName ?? message.userID ?? "";
final theme = Provider.of<TUIThemeViewModel>(context).theme;
final isSelf = message.isSelf ?? false;
return Container(
margin: const EdgeInsets.only(top: 20),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: isSelf ? MainAxisAlignment.end : MainAxisAlignment.start,
children: [
if (!isSelf)
SizedBox(
width: 40,
height: 40,
child: Avatar(faceUrl: faceUrl, showName: showName),
),
if (!isSelf)
const SizedBox(
width: 12,
),
Column(
crossAxisAlignment: isSelf ? CrossAxisAlignment.end : CrossAxisAlignment.start,
children: [
Text(showName, style: TextStyle(fontSize: 12, color: theme.weakTextColor)),
const SizedBox(
height: 4,
),
ConstrainedBox(
constraints: BoxConstraints(maxWidth: getMaxWidth(context)),
child: _getMsgItem(message),
)
],
),
if (isSelf)
const SizedBox(
width: 12,
),
if (isSelf)
SizedBox(
width: 40,
height: 40,
child: Avatar(faceUrl: faceUrl, showName: showName),
),
],
),
);
}
@override
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
final TUITheme theme = value.theme;
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
Widget messageListPage() {
return messageList.isEmpty
? Row(
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
LoadingAnimationWidget.staggeredDotsWave(
color: theme.weakTextColor ?? Colors.grey,
size: 48,
),
const SizedBox(height: 20),
Text(TIM_t("消息列表加载中"))
],
))
],
)
: Container(
padding: isDesktopScreen ? null : const EdgeInsets.all(16),
child: ListView.builder(
shrinkWrap: true,
itemCount: messageList.length,
itemBuilder: (context, index) {
final message = messageList[index];
return _itemBuilder(message, context);
},
),
);
}
return TUIKitScreenUtils.getDeviceWidget(
context: context,
desktopWidget: Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: messageListPage(),
),
defaultWidget: Scaffold(
appBar: AppBar(
title: Text(
TIM_t("聊天记录"),
style: TextStyle(color: theme.appbarTextColor, fontSize: 17),
),
shadowColor: theme.weakDividerColor,
backgroundColor: theme.appbarBgColor ?? theme.primaryColor,
iconTheme: IconThemeData(
color: theme.appbarTextColor,
)),
body: messageListPage(),
));
}
}