mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-19 00:40:08 +08:00
opt ui
fix report im msg Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -10,8 +10,9 @@ Future<void> autoWrapReportDialog(
|
||||
BuildContext context,
|
||||
Map<String, Map<int, String>> options,
|
||||
Future<LoadingState> Function(int reasonType, String? reasonDesc, bool banUid)
|
||||
onSuccess,
|
||||
) {
|
||||
onSuccess, {
|
||||
bool ban = true,
|
||||
}) {
|
||||
int? reasonType;
|
||||
String? reasonDesc;
|
||||
bool banUid = false;
|
||||
@@ -69,6 +70,8 @@ Future<void> autoWrapReportDialog(
|
||||
labelText: '为帮助审核人员更快处理,请补充问题类型和出现位置等详细信息',
|
||||
border: OutlineInputBorder(),
|
||||
contentPadding: .all(10),
|
||||
labelStyle: TextStyle(fontSize: 14),
|
||||
floatingLabelStyle: TextStyle(fontSize: 14),
|
||||
),
|
||||
onChanged: (value) => reasonDesc = value,
|
||||
validator: (value) =>
|
||||
@@ -81,7 +84,7 @@ Future<void> autoWrapReportDialog(
|
||||
),
|
||||
),
|
||||
),
|
||||
if (options != ReportOptions.liveDanmakuReport)
|
||||
if (ban)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 14, top: 6),
|
||||
child: CheckBoxText(
|
||||
@@ -251,4 +254,16 @@ abstract final class ReportOptions {
|
||||
7: '其他', // avoid show form
|
||||
},
|
||||
};
|
||||
|
||||
static Map<String, Map<int, String>> get imMsgReport => const {
|
||||
'': {
|
||||
1: '色情低俗',
|
||||
2: '政治敏感',
|
||||
3: '违法有害',
|
||||
4: '广告骚扰',
|
||||
5: '人身攻击',
|
||||
6: '诈骗',
|
||||
0: '其他问题',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -337,6 +337,7 @@ class ListTile extends StatelessWidget {
|
||||
this.onTap,
|
||||
this.onLongPress,
|
||||
this.onSecondaryTap,
|
||||
this.onSecondaryTapUp,
|
||||
this.onFocusChange,
|
||||
this.mouseCursor,
|
||||
this.selected = false,
|
||||
@@ -569,6 +570,8 @@ class ListTile extends StatelessWidget {
|
||||
|
||||
final GestureTapCallback? onSecondaryTap;
|
||||
|
||||
final GestureTapUpCallback? onSecondaryTapUp;
|
||||
|
||||
/// {@macro flutter.material.inkwell.onFocusChange}
|
||||
final ValueChanged<bool>? onFocusChange;
|
||||
|
||||
@@ -983,6 +986,7 @@ class ListTile extends StatelessWidget {
|
||||
onTap: enabled ? onTap : null,
|
||||
onLongPress: enabled ? onLongPress : null,
|
||||
onSecondaryTap: enabled ? onSecondaryTap : null,
|
||||
onSecondaryTapUp: enabled ? onSecondaryTapUp : null,
|
||||
onFocusChange: onFocusChange,
|
||||
mouseCursor: effectiveMouseCursor,
|
||||
canRequestFocus: enabled,
|
||||
|
||||
@@ -984,4 +984,6 @@ abstract final class Api {
|
||||
|
||||
static const String superChatReport =
|
||||
'${HttpString.liveBaseUrl}/av/v1/SuperChat/report';
|
||||
|
||||
static const String imMsgReport = '${HttpString.tUrl}/x/bplus/im/report/add';
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:PiliPlus/http/api.dart';
|
||||
import 'package:PiliPlus/http/constants.dart';
|
||||
import 'package:PiliPlus/http/init.dart';
|
||||
@@ -609,4 +611,33 @@ abstract final class MsgHttp {
|
||||
return Error(res.data['message']);
|
||||
}
|
||||
}
|
||||
|
||||
static Future<LoadingState<Null>> imMsgReport({
|
||||
required Object accusedUid,
|
||||
required int reasonType,
|
||||
required String reasonDesc,
|
||||
required Map comment,
|
||||
required Map extra,
|
||||
}) async {
|
||||
final res = await Request().post(
|
||||
Api.imMsgReport,
|
||||
data: {
|
||||
'biz_code': 4,
|
||||
'accused_uid': accusedUid,
|
||||
'object_id': accusedUid,
|
||||
'reason_type': reasonType,
|
||||
'reason_desc': reasonDesc,
|
||||
'module': 604,
|
||||
'comment': jsonEncode(comment),
|
||||
'extra': jsonEncode(extra),
|
||||
'csrf': Accounts.main.csrf,
|
||||
},
|
||||
options: Options(contentType: Headers.formUrlEncodedContentType),
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return const Success(null);
|
||||
} else {
|
||||
return Error(res.data['message']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,9 +248,9 @@ class ModuleDispute {
|
||||
String? jumpUrl;
|
||||
|
||||
ModuleDispute.fromJson(Map<String, dynamic> json) {
|
||||
title=json['title'];
|
||||
desc=json['desc'];
|
||||
jumpUrl=json['jump_url'];
|
||||
title = json['title'];
|
||||
desc = json['desc'];
|
||||
jumpUrl = json['jump_url'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -607,6 +607,7 @@ class LiveRoomController extends GetxController {
|
||||
}
|
||||
autoWrapReportDialog(
|
||||
Get.context!,
|
||||
ban: false,
|
||||
ReportOptions.liveDanmakuReport,
|
||||
(reasonType, reasonDesc, banUid) {
|
||||
return LiveHttp.superChatReport(
|
||||
|
||||
@@ -84,7 +84,7 @@ class LiveRoomChatPanel extends StatelessWidget {
|
||||
recognizer: item.uid == 0
|
||||
? null
|
||||
: (TapGestureRecognizer()
|
||||
..onTapDown = (e) => _showMsgMenu(
|
||||
..onTapUp = (e) => _showMsgMenu(
|
||||
context,
|
||||
itemContext,
|
||||
e,
|
||||
@@ -290,7 +290,7 @@ class LiveRoomChatPanel extends StatelessWidget {
|
||||
void _showMsgMenu(
|
||||
BuildContext context,
|
||||
BuildContext itemContext,
|
||||
TapDownDetails details,
|
||||
TapUpDetails details,
|
||||
DanmakuMsg item,
|
||||
) {
|
||||
final dx = details.globalPosition.dx;
|
||||
|
||||
@@ -855,6 +855,7 @@ class VideoDetailController extends GetxController
|
||||
}
|
||||
|
||||
void initSkip() {
|
||||
if (isClosed) return;
|
||||
if (segmentList.isNotEmpty) {
|
||||
positionSubscription?.cancel();
|
||||
positionSubscription = plPlayerController
|
||||
@@ -1174,6 +1175,8 @@ class VideoDetailController extends GetxController
|
||||
mediaType: isFileSource ? entry.mediaType : null,
|
||||
);
|
||||
|
||||
if (isClosed) return;
|
||||
|
||||
if (!isFileSource) {
|
||||
if (plPlayerController.enableBlock) {
|
||||
initSkip();
|
||||
@@ -1482,7 +1485,7 @@ class VideoDetailController extends GetxController
|
||||
final result = await VideoHttp.vttSubtitles(
|
||||
subtitles[index - 1].subtitleUrl!,
|
||||
);
|
||||
if (result != null) {
|
||||
if (!isClosed && result != null) {
|
||||
vttSubtitles[index - 1] = result;
|
||||
await setSub(result);
|
||||
}
|
||||
|
||||
@@ -282,6 +282,7 @@ class HeaderControl extends StatefulWidget {
|
||||
if (Accounts.main.isLogin) {
|
||||
return autoWrapReportDialog(
|
||||
context,
|
||||
ban: false,
|
||||
ReportOptions.liveDanmakuReport,
|
||||
(reasonType, reasonDesc, banUid) {
|
||||
// if (banUid) {
|
||||
|
||||
@@ -46,55 +46,6 @@ class WhisperSessionItem extends StatelessWidget {
|
||||
: null;
|
||||
final ThemeData theme = Theme.of(context);
|
||||
|
||||
void onLongPress() => showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 12),
|
||||
content: DefaultTextStyle(
|
||||
style: const TextStyle(fontSize: 14),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ListTile(
|
||||
dense: true,
|
||||
onTap: () {
|
||||
Get.back();
|
||||
onSetTop(item.isPinned, item.id);
|
||||
},
|
||||
title: Text(item.isPinned ? '移除置顶' : '置顶'),
|
||||
),
|
||||
if (item.id.privateId.hasTalkerUid())
|
||||
ListTile(
|
||||
dense: true,
|
||||
onTap: () {
|
||||
Get.back();
|
||||
onSetMute(item.isMuted, item.id.privateId.talkerUid);
|
||||
},
|
||||
title: Text('${item.isMuted ? '关闭' : '开启'}免打扰'),
|
||||
),
|
||||
if (item.id.privateId.hasTalkerUid())
|
||||
ListTile(
|
||||
dense: true,
|
||||
onTap: () {
|
||||
Get.back();
|
||||
showConfirmDialog(
|
||||
context: context,
|
||||
title: '确定删除该对话?',
|
||||
onConfirm: () =>
|
||||
onRemove(item.id.privateId.talkerUid.toInt()),
|
||||
);
|
||||
},
|
||||
title: const Text('删除'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
return ListTile(
|
||||
safeArea: true,
|
||||
tileColor: item.isPinned
|
||||
@@ -102,8 +53,88 @@ class WhisperSessionItem extends StatelessWidget {
|
||||
alpha: theme.brightness.isDark ? 0.4 : 0.8,
|
||||
)
|
||||
: null,
|
||||
onLongPress: onLongPress,
|
||||
onSecondaryTap: PlatformUtils.isMobile ? null : onLongPress,
|
||||
onLongPress: () => showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 12),
|
||||
content: DefaultTextStyle(
|
||||
style: const TextStyle(fontSize: 14),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ListTile(
|
||||
dense: true,
|
||||
onTap: () {
|
||||
Get.back();
|
||||
onSetTop(item.isPinned, item.id);
|
||||
},
|
||||
title: Text(item.isPinned ? '移除置顶' : '置顶'),
|
||||
),
|
||||
if (item.id.privateId.hasTalkerUid())
|
||||
ListTile(
|
||||
dense: true,
|
||||
onTap: () {
|
||||
Get.back();
|
||||
onSetMute(item.isMuted, item.id.privateId.talkerUid);
|
||||
},
|
||||
title: Text('${item.isMuted ? '关闭' : '开启'}免打扰'),
|
||||
),
|
||||
if (item.id.privateId.hasTalkerUid())
|
||||
ListTile(
|
||||
dense: true,
|
||||
onTap: () {
|
||||
Get.back();
|
||||
showConfirmDialog(
|
||||
context: context,
|
||||
title: '确定删除该对话?',
|
||||
onConfirm: () =>
|
||||
onRemove(item.id.privateId.talkerUid.toInt()),
|
||||
);
|
||||
},
|
||||
title: const Text('删除'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
onSecondaryTapUp: PlatformUtils.isDesktop
|
||||
? (details) {
|
||||
final offset = details.globalPosition;
|
||||
showMenu(
|
||||
context: context,
|
||||
position: .fromLTRB(offset.dx, offset.dy, offset.dx, 0),
|
||||
items: [
|
||||
PopupMenuItem(
|
||||
height: 42,
|
||||
onTap: () => onSetTop(item.isPinned, item.id),
|
||||
child: Text(item.isPinned ? '移除置顶' : '置顶'),
|
||||
),
|
||||
if (item.id.privateId.hasTalkerUid())
|
||||
PopupMenuItem(
|
||||
height: 42,
|
||||
onTap: () =>
|
||||
onSetMute(item.isMuted, item.id.privateId.talkerUid),
|
||||
child: Text('${item.isMuted ? '关闭' : '开启'}免打扰'),
|
||||
),
|
||||
if (item.id.privateId.hasTalkerUid())
|
||||
PopupMenuItem(
|
||||
height: 42,
|
||||
onTap: () => showConfirmDialog(
|
||||
context: context,
|
||||
title: '确定删除该对话?',
|
||||
onConfirm: () =>
|
||||
onRemove(item.id.privateId.talkerUid.toInt()),
|
||||
),
|
||||
child: const Text('删除'),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
: null,
|
||||
onTap: () {
|
||||
if (item.hasUnread()) {
|
||||
item.clearUnread();
|
||||
|
||||
@@ -131,4 +131,14 @@ class WhisperDetailController extends CommonListController<RspSessionMsg, Msg> {
|
||||
beginSeqno: msgSeqno != null ? Int64.ZERO : null,
|
||||
endSeqno: msgSeqno,
|
||||
);
|
||||
|
||||
Future<LoadingState> onReport(Msg item, int reasonType, String reasonDesc) {
|
||||
return MsgHttp.imMsgReport(
|
||||
accusedUid: item.senderUid,
|
||||
reasonType: reasonType,
|
||||
reasonDesc: reasonDesc,
|
||||
comment: {'group_id': 0, 'msg_key': item.msgKey},
|
||||
extra: {"msg_keys": []},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io' show File;
|
||||
|
||||
import 'package:PiliPlus/common/widgets/dialog/report.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/text_field/text_field.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
|
||||
@@ -168,14 +169,18 @@ class _WhisperDetailPageState
|
||||
_whisperDetailController.onLoadMore();
|
||||
}
|
||||
final item = response[index];
|
||||
final isOwner =
|
||||
item.senderUid.toInt() ==
|
||||
_whisperDetailController.account.mid;
|
||||
return ChatItem(
|
||||
item: item,
|
||||
eInfos: _whisperDetailController.eInfos,
|
||||
onLongPress:
|
||||
item.senderUid.toInt() ==
|
||||
_whisperDetailController.account.mid
|
||||
? () => onLongPress(index, item)
|
||||
onLongPress: () => onLongPress(index, item, isOwner),
|
||||
onSecondaryTapUp: PlatformUtils.isDesktop
|
||||
? (e) =>
|
||||
_showMenu(e.globalPosition, index, item, isOwner)
|
||||
: null,
|
||||
isOwner: isOwner,
|
||||
);
|
||||
},
|
||||
separatorBuilder: (context, index) =>
|
||||
@@ -189,34 +194,86 @@ class _WhisperDetailPageState
|
||||
};
|
||||
}
|
||||
|
||||
void onLongPress(int index, Msg item) {
|
||||
void _showMenu(Offset offset, int index, Msg item, bool isOwner) {
|
||||
showMenu(
|
||||
context: context,
|
||||
position: .fromLTRB(offset.dx, offset.dy, offset.dx, 0),
|
||||
items: [
|
||||
if (isOwner)
|
||||
PopupMenuItem(
|
||||
height: 42,
|
||||
onTap: () => _whisperDetailController.sendMsg(
|
||||
message: '${item.msgKey}',
|
||||
onClearText: editController.clear,
|
||||
msgType: 5,
|
||||
index: index,
|
||||
),
|
||||
child: const Text('撤回', style: TextStyle(fontSize: 14)),
|
||||
)
|
||||
else
|
||||
PopupMenuItem(
|
||||
height: 42,
|
||||
onTap: () => autoWrapReportDialog(
|
||||
context,
|
||||
ban: false,
|
||||
ReportOptions.imMsgReport,
|
||||
(reasonType, reasonDesc, banUid) =>
|
||||
_whisperDetailController.onReport(
|
||||
item,
|
||||
reasonType,
|
||||
reasonType == 0
|
||||
? reasonDesc!
|
||||
: ReportOptions.imMsgReport['']![reasonType]!,
|
||||
),
|
||||
),
|
||||
child: const Text('举报', style: TextStyle(fontSize: 14)),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
void onLongPress(int index, Msg item, bool isOwner) {
|
||||
Feedback.forLongPress(context);
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 12),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
_whisperDetailController.sendMsg(
|
||||
message: '${item.msgKey}',
|
||||
onClearText: editController.clear,
|
||||
msgType: 5,
|
||||
index: index,
|
||||
);
|
||||
},
|
||||
dense: true,
|
||||
title: const Text(
|
||||
'撤回',
|
||||
style: TextStyle(fontSize: 14),
|
||||
content: isOwner
|
||||
? ListTile(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
_whisperDetailController.sendMsg(
|
||||
message: '${item.msgKey}',
|
||||
onClearText: editController.clear,
|
||||
msgType: 5,
|
||||
index: index,
|
||||
);
|
||||
},
|
||||
dense: true,
|
||||
title: const Text('撤回', style: TextStyle(fontSize: 14)),
|
||||
)
|
||||
: ListTile(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
autoWrapReportDialog(
|
||||
context,
|
||||
ban: false,
|
||||
ReportOptions.imMsgReport,
|
||||
(reasonType, reasonDesc, banUid) =>
|
||||
_whisperDetailController.onReport(
|
||||
item,
|
||||
reasonType,
|
||||
reasonType == 0
|
||||
? reasonDesc!
|
||||
: ReportOptions.imMsgReport['']![reasonType]!,
|
||||
),
|
||||
);
|
||||
},
|
||||
dense: true,
|
||||
title: const Text('举报', style: TextStyle(fontSize: 14)),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -18,7 +18,6 @@ import 'package:PiliPlus/utils/extension/num_ext.dart';
|
||||
import 'package:PiliPlus/utils/id_utils.dart';
|
||||
import 'package:PiliPlus/utils/image_utils.dart';
|
||||
import 'package:PiliPlus/utils/page_utils.dart';
|
||||
import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -33,13 +32,16 @@ class ChatItem extends StatelessWidget {
|
||||
const ChatItem({
|
||||
super.key,
|
||||
required this.item,
|
||||
this.eInfos,
|
||||
this.onLongPress,
|
||||
}) : isOwner = onLongPress != null;
|
||||
required this.eInfos,
|
||||
required this.onLongPress,
|
||||
required this.onSecondaryTapUp,
|
||||
required this.isOwner,
|
||||
});
|
||||
|
||||
final Msg item;
|
||||
final List<EmotionInfo>? eInfos;
|
||||
final VoidCallback? onLongPress;
|
||||
final VoidCallback onLongPress;
|
||||
final GestureTapUpCallback? onSecondaryTapUp;
|
||||
final bool isOwner;
|
||||
|
||||
// 消息来源
|
||||
@@ -51,14 +53,11 @@ class ChatItem extends StatelessWidget {
|
||||
// };
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
bool isPic = item.msgType == MsgType.EN_MSG_TYPE_PIC.value; // 图片
|
||||
bool isRevoke = item.msgType == MsgType.EN_MSG_TYPE_DRAW_BACK.value; // 撤回消息
|
||||
bool isSystem =
|
||||
item.msgType == MsgType.EN_MSG_TYPE_VIDEO_CARD.value ||
|
||||
item.msgType == MsgType.EN_MSG_TYPE_TIP_MESSAGE.value ||
|
||||
item.msgType == MsgType.EN_MSG_TYPE_NOTIFY_MSG.value ||
|
||||
item.msgType == MsgType.EN_MSG_TYPE_PICTURE_CARD.value ||
|
||||
item.msgType == 16;
|
||||
final msgType = item.msgType;
|
||||
final isRevoke = msgType == MsgType.EN_MSG_TYPE_DRAW_BACK.value; // 撤回消息
|
||||
if (isRevoke) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
late final ThemeData theme = Theme.of(context);
|
||||
late final Color textColor = isOwner
|
||||
@@ -66,108 +65,98 @@ class ChatItem extends StatelessWidget {
|
||||
: theme.colorScheme.onSurfaceVariant;
|
||||
late final dynamic content = jsonDecode(item.content);
|
||||
|
||||
return isRevoke
|
||||
? const SizedBox.shrink()
|
||||
: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 6, bottom: 18),
|
||||
child: Text(
|
||||
DateFormatUtils.chatFormat(item.timestamp.toInt()),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(color: theme.colorScheme.outline),
|
||||
),
|
||||
),
|
||||
isSystem
|
||||
? messageContent(
|
||||
context: context,
|
||||
theme: theme,
|
||||
content: content,
|
||||
textColor: textColor,
|
||||
Widget child = messageContent(
|
||||
context: context,
|
||||
theme: theme,
|
||||
content: content,
|
||||
textColor: textColor,
|
||||
);
|
||||
|
||||
final isSystem =
|
||||
msgType == MsgType.EN_MSG_TYPE_VIDEO_CARD.value ||
|
||||
msgType == MsgType.EN_MSG_TYPE_TIP_MESSAGE.value ||
|
||||
msgType == MsgType.EN_MSG_TYPE_NOTIFY_MSG.value ||
|
||||
msgType == MsgType.EN_MSG_TYPE_PICTURE_CARD.value ||
|
||||
msgType == 16;
|
||||
|
||||
if (!isSystem) {
|
||||
final isPic = msgType == MsgType.EN_MSG_TYPE_PIC.value; // 图片
|
||||
child = Row(
|
||||
mainAxisAlignment: isOwner ? .end : .start,
|
||||
children: [
|
||||
Container(
|
||||
constraints: const BoxConstraints(maxWidth: 300.0),
|
||||
decoration: BoxDecoration(
|
||||
color: isOwner
|
||||
? theme.colorScheme.secondaryContainer
|
||||
: theme.colorScheme.onInverseSurface,
|
||||
borderRadius: isOwner
|
||||
? const .only(
|
||||
topLeft: .circular(16),
|
||||
topRight: .circular(16),
|
||||
bottomLeft: .circular(16),
|
||||
bottomRight: .circular(6),
|
||||
)
|
||||
: GestureDetector(
|
||||
onLongPress: () {
|
||||
Feedback.forLongPress(context);
|
||||
onLongPress!();
|
||||
},
|
||||
onSecondaryTap: PlatformUtils.isMobile
|
||||
? null
|
||||
: onLongPress,
|
||||
child: Row(
|
||||
mainAxisAlignment: isOwner
|
||||
? MainAxisAlignment.end
|
||||
: MainAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
constraints: const BoxConstraints(maxWidth: 300.0),
|
||||
decoration: BoxDecoration(
|
||||
color: isOwner
|
||||
? theme.colorScheme.secondaryContainer
|
||||
: theme.colorScheme.onInverseSurface,
|
||||
borderRadius: isOwner
|
||||
? const BorderRadius.only(
|
||||
topLeft: Radius.circular(16),
|
||||
topRight: Radius.circular(16),
|
||||
bottomLeft: Radius.circular(16),
|
||||
bottomRight: Radius.circular(6),
|
||||
)
|
||||
: const BorderRadius.only(
|
||||
topLeft: Radius.circular(16),
|
||||
topRight: Radius.circular(16),
|
||||
bottomLeft: Radius.circular(6),
|
||||
bottomRight: Radius.circular(16),
|
||||
),
|
||||
),
|
||||
padding: EdgeInsets.only(
|
||||
top: 8,
|
||||
bottom: 6,
|
||||
left: isPic ? 8 : 12,
|
||||
right: isPic ? 8 : 12,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: isOwner
|
||||
? CrossAxisAlignment.end
|
||||
: CrossAxisAlignment.start,
|
||||
children: [
|
||||
messageContent(
|
||||
context: context,
|
||||
theme: theme,
|
||||
content: content,
|
||||
textColor: textColor,
|
||||
),
|
||||
SizedBox(height: isPic ? 7 : 2),
|
||||
if (item.msgStatus == 1)
|
||||
Text(
|
||||
' 已撤回',
|
||||
style: theme.textTheme.labelSmall!.copyWith(
|
||||
color: theme.colorScheme.onErrorContainer,
|
||||
),
|
||||
),
|
||||
if (item.msgSource >= 8 &&
|
||||
item.msgSource <= 11) ...[
|
||||
Divider(
|
||||
height: 10,
|
||||
thickness: 1,
|
||||
color: theme.colorScheme.outline.withValues(
|
||||
alpha: 0.2,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'此条消息为自动回复',
|
||||
style: theme.textTheme.labelMedium!
|
||||
.copyWith(
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
: const .only(
|
||||
topLeft: .circular(16),
|
||||
topRight: .circular(16),
|
||||
bottomLeft: .circular(6),
|
||||
bottomRight: .circular(16),
|
||||
),
|
||||
],
|
||||
);
|
||||
),
|
||||
padding: isPic
|
||||
? const .only(top: 8, bottom: 6, left: 8, right: 8)
|
||||
: const .only(top: 8, bottom: 6, left: 12, right: 12),
|
||||
child: Column(
|
||||
crossAxisAlignment: isOwner ? .end : .start,
|
||||
children: [
|
||||
child,
|
||||
isPic ? const SizedBox(height: 7) : const SizedBox(height: 2),
|
||||
if (item.msgStatus == 1)
|
||||
Text(
|
||||
' 已撤回',
|
||||
style: theme.textTheme.labelSmall!.copyWith(
|
||||
color: theme.colorScheme.onErrorContainer,
|
||||
),
|
||||
),
|
||||
if (item.msgSource >= 8 && item.msgSource <= 11) ...[
|
||||
Divider(
|
||||
height: 10,
|
||||
thickness: 1,
|
||||
color: theme.colorScheme.outline.withValues(alpha: 0.2),
|
||||
),
|
||||
Text(
|
||||
'此条消息为自动回复',
|
||||
style: theme.textTheme.labelMedium!.copyWith(
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 6, bottom: 18),
|
||||
child: Text(
|
||||
DateFormatUtils.chatFormat(item.timestamp.toInt()),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(color: theme.colorScheme.outline),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
behavior: .opaque,
|
||||
onLongPress: onLongPress,
|
||||
onSecondaryTapUp: onSecondaryTapUp,
|
||||
child: child,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget messageContent({
|
||||
|
||||
@@ -793,7 +793,7 @@ packages:
|
||||
description:
|
||||
path: "."
|
||||
ref: "version_4.7.2"
|
||||
resolved-ref: "4f5c47f38bde5df0abd6481702b2d8ec199a0e49"
|
||||
resolved-ref: "9addd004c11e1c388bff5988ac9564e7ee5ff395"
|
||||
url: "https://github.com/bggRGjQaUbCoE/getx.git"
|
||||
source: git
|
||||
version: "4.7.2"
|
||||
|
||||
Reference in New Issue
Block a user