From dae71d427c8f98c1081b6e33061e86cb7c6680fa Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Fri, 14 Feb 2025 23:28:48 +0800 Subject: [PATCH] feat: whisper: revoke msg Signed-off-by: bggRGjQaUbCoE --- lib/http/msg.dart | 4 +- lib/pages/whisper_detail/controller.dart | 32 +++- lib/pages/whisper_detail/view.dart | 49 ++++- .../whisper_detail/widget/chat_item.dart | 177 ++++++++++-------- 4 files changed, 164 insertions(+), 98 deletions(-) diff --git a/lib/http/msg.dart b/lib/http/msg.dart index 43989239..1cca0dfc 100644 --- a/lib/http/msg.dart +++ b/lib/http/msg.dart @@ -560,9 +560,7 @@ class MsgHttp { return { 'status': false, 'date': [], - 'msg': "message: ${res.data['message']}," - " msg: ${res.data['msg']}," - " code: ${res.data['code']}", + 'msg': res.data['message'] ?? res.data['msg'], }; } } diff --git a/lib/pages/whisper_detail/controller.dart b/lib/pages/whisper_detail/controller.dart index 17c03a18..74afc708 100644 --- a/lib/pages/whisper_detail/controller.dart +++ b/lib/pages/whisper_detail/controller.dart @@ -65,14 +65,17 @@ class WhisperDetailController extends GetxController { } } + late final ownerMid = GStorage.userInfo.get('userInfoCache')?.mid; + Future sendMsg({ required String message, dynamic picMsg, required VoidCallback onClearText, + int? msgType, + int? index, }) async { feedBack(); - final userInfo = GStorage.userInfo.get('userInfoCache'); - if (userInfo == null) { + if (ownerMid == null) { SmartDialog.dismiss(); SmartDialog.showToast('请先登录'); return; @@ -88,19 +91,28 @@ class WhisperDetailController extends GetxController { return; } var result = await MsgHttp.sendMsg( - senderUid: userInfo.mid, + senderUid: ownerMid, receiverId: int.parse(mid!), - content: picMsg != null ? jsonEncode(picMsg) : '{"content":"$message"}', - msgType: picMsg != null ? 2 : 1, + content: msgType == 5 + ? message + : picMsg != null + ? jsonEncode(picMsg) + : '{"content":"$message"}', + msgType: msgType ?? (picMsg != null ? 2 : 1), ); + SmartDialog.dismiss(); if (result['status']) { // debugPrint(result['data']); - querySessionMsg(); - onClearText(); - SmartDialog.dismiss(); - SmartDialog.showToast('发送成功'); + if (msgType == 5) { + messageList[index!].msgStatus = 1; + messageList.refresh(); + SmartDialog.showToast('撤回成功'); + } else { + querySessionMsg(); + onClearText(); + SmartDialog.showToast('发送成功'); + } } else { - SmartDialog.dismiss(); SmartDialog.showToast(result['msg']); } } diff --git a/lib/pages/whisper_detail/view.dart b/lib/pages/whisper_detail/view.dart index d9f5683d..bc944132 100644 --- a/lib/pages/whisper_detail/view.dart +++ b/lib/pages/whisper_detail/view.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:io'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/http/msg.dart'; +import 'package:PiliPlus/models/msg/session.dart'; import 'package:PiliPlus/pages/common/common_publish_page.dart'; import 'package:PiliPlus/pages/emote/view.dart'; import 'package:PiliPlus/utils/extension.dart'; @@ -108,7 +109,7 @@ class _WhisperDetailPageState Widget _buildList() { Widget resultWidget = Obx( () { - List messageList = _whisperDetailController.messageList; + List messageList = _whisperDetailController.messageList; if (messageList.isEmpty) { return const Center( child: CircularProgressIndicator(), @@ -120,10 +121,52 @@ class _WhisperDetailPageState shrinkWrap: true, reverse: true, itemCount: messageList.length, - itemBuilder: (context, int i) { + itemBuilder: (context, int index) { return ChatItem( - item: messageList[i], + item: messageList[index], eInfos: _whisperDetailController.eInfos, + onLongPress: messageList[index].senderUid == + _whisperDetailController.ownerMid + ? () { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + clipBehavior: Clip.hardEdge, + contentPadding: + const EdgeInsets.fromLTRB(0, 12, 0, 12), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ListTile( + onTap: () { + Get.back(); + _whisperDetailController.sendMsg( + message: '${messageList[index].msgKey}', + onClearText: editController.clear, + msgType: 5, + index: index, + ); + }, + dense: true, + title: const Text('撤回', + style: TextStyle(fontSize: 14)), + ), + // ListTile( + // onTap: () { + // Get.back(); + // }, + // dense: true, + // title: const Text('删除', + // style: TextStyle(fontSize: 14)), + // ), + ], + ), + ); + }, + ); + } + : null, ); }, padding: const EdgeInsets.only(bottom: 20), diff --git a/lib/pages/whisper_detail/widget/chat_item.dart b/lib/pages/whisper_detail/widget/chat_item.dart index 3c345f0f..1ef3fa10 100644 --- a/lib/pages/whisper_detail/widget/chat_item.dart +++ b/lib/pages/whisper_detail/widget/chat_item.dart @@ -42,11 +42,13 @@ enum MsgType { class ChatItem extends StatelessWidget { final dynamic item; final List? eInfos; + final VoidCallback? onLongPress; const ChatItem({ super.key, this.item, this.eInfos, + this.onLongPress, }); @override @@ -65,10 +67,10 @@ class ChatItem extends StatelessWidget { item.msgType == MsgType.pic_card.value || item.msgType == MsgType.auto_reply_push.value; dynamic content = item.content ?? ''; - Color textColor(BuildContext context) { + Color textColor() { return isOwner - ? Theme.of(context).colorScheme.onPrimary - : Theme.of(context).colorScheme.onSecondaryContainer; + ? Theme.of(context).colorScheme.onSecondaryContainer + : Theme.of(context).colorScheme.onSurfaceVariant; } Widget richTextMessage(BuildContext context) { @@ -95,7 +97,7 @@ class ChatItem extends StatelessWidget { children.add(TextSpan( text: emojiKey, style: TextStyle( - color: textColor(context), + color: textColor(), letterSpacing: 0.6, height: 1.5, ), @@ -104,13 +106,16 @@ class ChatItem extends StatelessWidget { return ''; }, onNonMatch: (String text) { - children.add(TextSpan( + children.add( + TextSpan( text: text, style: TextStyle( - color: textColor(context), + color: textColor(), letterSpacing: 0.6, height: 1.5, - ))); + ), + ), + ); return ''; }, ); @@ -124,7 +129,7 @@ class ChatItem extends StatelessWidget { text, style: TextStyle( letterSpacing: 0.6, - color: textColor(context), + color: textColor(), height: 1.5, ), ); @@ -200,7 +205,7 @@ class ChatItem extends StatelessWidget { style: TextStyle( letterSpacing: 0.6, height: 1.5, - color: textColor(context), + color: textColor(), fontWeight: FontWeight.bold, ), ), @@ -210,7 +215,7 @@ class ChatItem extends StatelessWidget { style: TextStyle( letterSpacing: 0.6, height: 1.5, - color: textColor(context).withOpacity(0.6), + color: textColor().withOpacity(0.6), fontSize: 12, ), ), @@ -252,7 +257,7 @@ class ChatItem extends StatelessWidget { style: TextStyle( letterSpacing: 0.6, height: 1.5, - color: textColor(context), + color: textColor(), fontWeight: FontWeight.bold, ), ), @@ -262,7 +267,7 @@ class ChatItem extends StatelessWidget { style: TextStyle( letterSpacing: 0.6, height: 1.5, - color: textColor(context).withOpacity(0.6), + color: textColor().withOpacity(0.6), fontSize: 12, ), ), @@ -295,7 +300,7 @@ class ChatItem extends StatelessWidget { style: TextStyle( letterSpacing: 0.6, height: 1.5, - color: textColor(context), + color: textColor(), fontWeight: FontWeight.bold, ), ), @@ -348,7 +353,7 @@ class ChatItem extends StatelessWidget { style: TextStyle( letterSpacing: 0.6, height: 1.5, - color: textColor(context), + color: textColor(), fontWeight: FontWeight.bold, ), ), @@ -357,7 +362,7 @@ class ChatItem extends StatelessWidget { style: TextStyle( letterSpacing: 0.6, height: 1.5, - color: textColor(context).withOpacity(0.6), + color: textColor().withOpacity(0.6), fontSize: 12, ), ), @@ -366,7 +371,7 @@ class ChatItem extends StatelessWidget { style: TextStyle( letterSpacing: 0.6, height: 1.5, - color: textColor(context).withOpacity(0.6), + color: textColor().withOpacity(0.6), fontSize: 12, ), ), @@ -385,7 +390,7 @@ class ChatItem extends StatelessWidget { style: TextStyle( letterSpacing: 0.6, height: 1.5, - color: textColor(context), + color: textColor(), fontWeight: FontWeight.bold, ), ); @@ -396,73 +401,81 @@ class ChatItem extends StatelessWidget { ? messageContent(context) : isRevoke ? const SizedBox() - : Row( - children: [ - if (!isOwner) const SizedBox(width: 12), - if (isOwner) const Spacer(), - Container( - constraints: const BoxConstraints( - maxWidth: 300.0, // 设置最大宽度为200.0 - ), - decoration: BoxDecoration( - color: isOwner - ? Theme.of(context).colorScheme.primary - : Theme.of(context).colorScheme.secondaryContainer, - borderRadius: BorderRadius.only( - topLeft: const Radius.circular(16), - topRight: const Radius.circular(16), - bottomLeft: Radius.circular(isOwner ? 16 : 6), - bottomRight: Radius.circular(isOwner ? 6 : 16), + : GestureDetector( + onLongPress: onLongPress, + child: Row( + children: [ + if (!isOwner) const SizedBox(width: 12), + if (isOwner) const Spacer(), + Container( + constraints: const BoxConstraints( + maxWidth: 300.0, // 设置最大宽度为200.0 + ), + decoration: BoxDecoration( + color: isOwner + ? Theme.of(context).colorScheme.secondaryContainer + : Theme.of(context).colorScheme.onInverseSurface, + borderRadius: BorderRadius.only( + topLeft: const Radius.circular(16), + topRight: const Radius.circular(16), + bottomLeft: Radius.circular(isOwner ? 16 : 6), + bottomRight: Radius.circular(isOwner ? 6 : 16), + ), + ), + margin: const EdgeInsets.only(top: 12), + 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), + SizedBox(height: isPic ? 7 : 2), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + Utils.dateFormat(item.timestamp), + style: Theme.of(context) + .textTheme + .labelSmall! + .copyWith( + color: isOwner + ? Theme.of(context) + .colorScheme + .onSecondaryContainer + .withOpacity(0.8) + : Theme.of(context) + .colorScheme + .onSurfaceVariant + .withOpacity(0.8)), + ), + if (item.msgStatus == 1) + Text( + ' 已撤回', + style: Theme.of(context) + .textTheme + .labelSmall! + .copyWith( + color: Theme.of(context) + .colorScheme + .onErrorContainer, + ), + ), + ], + ) + ], ), ), - margin: const EdgeInsets.only(top: 12), - 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), - SizedBox(height: isPic ? 7 : 2), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - Utils.dateFormat(item.timestamp), - style: Theme.of(context) - .textTheme - .labelSmall! - .copyWith( - color: isOwner - ? Theme.of(context) - .colorScheme - .onPrimary - .withOpacity(0.8) - : Theme.of(context) - .colorScheme - .onSecondaryContainer - .withOpacity(0.8)), - ), - item.msgStatus == 1 - ? Text( - ' 已撤回', - style: - Theme.of(context).textTheme.labelSmall!, - ) - : const SizedBox() - ], - ) - ], - ), - ), - if (!isOwner) const Spacer(), - if (isOwner) const SizedBox(width: 12), - ], + if (!isOwner) const Spacer(), + if (isOwner) const SizedBox(width: 12), + ], + ), ); } }