feat: whisper: revoke msg

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-02-14 23:28:48 +08:00
parent 46bc2ceb78
commit dae71d427c
4 changed files with 164 additions and 98 deletions

View File

@@ -560,9 +560,7 @@ class MsgHttp {
return { return {
'status': false, 'status': false,
'date': [], 'date': [],
'msg': "message: ${res.data['message']}," 'msg': res.data['message'] ?? res.data['msg'],
" msg: ${res.data['msg']},"
" code: ${res.data['code']}",
}; };
} }
} }

View File

@@ -65,14 +65,17 @@ class WhisperDetailController extends GetxController {
} }
} }
late final ownerMid = GStorage.userInfo.get('userInfoCache')?.mid;
Future sendMsg({ Future sendMsg({
required String message, required String message,
dynamic picMsg, dynamic picMsg,
required VoidCallback onClearText, required VoidCallback onClearText,
int? msgType,
int? index,
}) async { }) async {
feedBack(); feedBack();
final userInfo = GStorage.userInfo.get('userInfoCache'); if (ownerMid == null) {
if (userInfo == null) {
SmartDialog.dismiss(); SmartDialog.dismiss();
SmartDialog.showToast('请先登录'); SmartDialog.showToast('请先登录');
return; return;
@@ -88,19 +91,28 @@ class WhisperDetailController extends GetxController {
return; return;
} }
var result = await MsgHttp.sendMsg( var result = await MsgHttp.sendMsg(
senderUid: userInfo.mid, senderUid: ownerMid,
receiverId: int.parse(mid!), receiverId: int.parse(mid!),
content: picMsg != null ? jsonEncode(picMsg) : '{"content":"$message"}', content: msgType == 5
msgType: picMsg != null ? 2 : 1, ? message
: picMsg != null
? jsonEncode(picMsg)
: '{"content":"$message"}',
msgType: msgType ?? (picMsg != null ? 2 : 1),
); );
SmartDialog.dismiss();
if (result['status']) { if (result['status']) {
// debugPrint(result['data']); // debugPrint(result['data']);
querySessionMsg(); if (msgType == 5) {
onClearText(); messageList[index!].msgStatus = 1;
SmartDialog.dismiss(); messageList.refresh();
SmartDialog.showToast('发送成功'); SmartDialog.showToast('撤回成功');
} else {
querySessionMsg();
onClearText();
SmartDialog.showToast('发送成功');
}
} else { } else {
SmartDialog.dismiss();
SmartDialog.showToast(result['msg']); SmartDialog.showToast(result['msg']);
} }
} }

View File

@@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
import 'package:PiliPlus/http/msg.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/common/common_publish_page.dart';
import 'package:PiliPlus/pages/emote/view.dart'; import 'package:PiliPlus/pages/emote/view.dart';
import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/extension.dart';
@@ -108,7 +109,7 @@ class _WhisperDetailPageState
Widget _buildList() { Widget _buildList() {
Widget resultWidget = Obx( Widget resultWidget = Obx(
() { () {
List messageList = _whisperDetailController.messageList; List<MessageItem> messageList = _whisperDetailController.messageList;
if (messageList.isEmpty) { if (messageList.isEmpty) {
return const Center( return const Center(
child: CircularProgressIndicator(), child: CircularProgressIndicator(),
@@ -120,10 +121,52 @@ class _WhisperDetailPageState
shrinkWrap: true, shrinkWrap: true,
reverse: true, reverse: true,
itemCount: messageList.length, itemCount: messageList.length,
itemBuilder: (context, int i) { itemBuilder: (context, int index) {
return ChatItem( return ChatItem(
item: messageList[i], item: messageList[index],
eInfos: _whisperDetailController.eInfos, 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), padding: const EdgeInsets.only(bottom: 20),

View File

@@ -42,11 +42,13 @@ enum MsgType {
class ChatItem extends StatelessWidget { class ChatItem extends StatelessWidget {
final dynamic item; final dynamic item;
final List? eInfos; final List? eInfos;
final VoidCallback? onLongPress;
const ChatItem({ const ChatItem({
super.key, super.key,
this.item, this.item,
this.eInfos, this.eInfos,
this.onLongPress,
}); });
@override @override
@@ -65,10 +67,10 @@ class ChatItem extends StatelessWidget {
item.msgType == MsgType.pic_card.value || item.msgType == MsgType.pic_card.value ||
item.msgType == MsgType.auto_reply_push.value; item.msgType == MsgType.auto_reply_push.value;
dynamic content = item.content ?? ''; dynamic content = item.content ?? '';
Color textColor(BuildContext context) { Color textColor() {
return isOwner 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) { Widget richTextMessage(BuildContext context) {
@@ -95,7 +97,7 @@ class ChatItem extends StatelessWidget {
children.add(TextSpan( children.add(TextSpan(
text: emojiKey, text: emojiKey,
style: TextStyle( style: TextStyle(
color: textColor(context), color: textColor(),
letterSpacing: 0.6, letterSpacing: 0.6,
height: 1.5, height: 1.5,
), ),
@@ -104,13 +106,16 @@ class ChatItem extends StatelessWidget {
return ''; return '';
}, },
onNonMatch: (String text) { onNonMatch: (String text) {
children.add(TextSpan( children.add(
TextSpan(
text: text, text: text,
style: TextStyle( style: TextStyle(
color: textColor(context), color: textColor(),
letterSpacing: 0.6, letterSpacing: 0.6,
height: 1.5, height: 1.5,
))); ),
),
);
return ''; return '';
}, },
); );
@@ -124,7 +129,7 @@ class ChatItem extends StatelessWidget {
text, text,
style: TextStyle( style: TextStyle(
letterSpacing: 0.6, letterSpacing: 0.6,
color: textColor(context), color: textColor(),
height: 1.5, height: 1.5,
), ),
); );
@@ -200,7 +205,7 @@ class ChatItem extends StatelessWidget {
style: TextStyle( style: TextStyle(
letterSpacing: 0.6, letterSpacing: 0.6,
height: 1.5, height: 1.5,
color: textColor(context), color: textColor(),
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
@@ -210,7 +215,7 @@ class ChatItem extends StatelessWidget {
style: TextStyle( style: TextStyle(
letterSpacing: 0.6, letterSpacing: 0.6,
height: 1.5, height: 1.5,
color: textColor(context).withOpacity(0.6), color: textColor().withOpacity(0.6),
fontSize: 12, fontSize: 12,
), ),
), ),
@@ -252,7 +257,7 @@ class ChatItem extends StatelessWidget {
style: TextStyle( style: TextStyle(
letterSpacing: 0.6, letterSpacing: 0.6,
height: 1.5, height: 1.5,
color: textColor(context), color: textColor(),
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
@@ -262,7 +267,7 @@ class ChatItem extends StatelessWidget {
style: TextStyle( style: TextStyle(
letterSpacing: 0.6, letterSpacing: 0.6,
height: 1.5, height: 1.5,
color: textColor(context).withOpacity(0.6), color: textColor().withOpacity(0.6),
fontSize: 12, fontSize: 12,
), ),
), ),
@@ -295,7 +300,7 @@ class ChatItem extends StatelessWidget {
style: TextStyle( style: TextStyle(
letterSpacing: 0.6, letterSpacing: 0.6,
height: 1.5, height: 1.5,
color: textColor(context), color: textColor(),
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
@@ -348,7 +353,7 @@ class ChatItem extends StatelessWidget {
style: TextStyle( style: TextStyle(
letterSpacing: 0.6, letterSpacing: 0.6,
height: 1.5, height: 1.5,
color: textColor(context), color: textColor(),
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
@@ -357,7 +362,7 @@ class ChatItem extends StatelessWidget {
style: TextStyle( style: TextStyle(
letterSpacing: 0.6, letterSpacing: 0.6,
height: 1.5, height: 1.5,
color: textColor(context).withOpacity(0.6), color: textColor().withOpacity(0.6),
fontSize: 12, fontSize: 12,
), ),
), ),
@@ -366,7 +371,7 @@ class ChatItem extends StatelessWidget {
style: TextStyle( style: TextStyle(
letterSpacing: 0.6, letterSpacing: 0.6,
height: 1.5, height: 1.5,
color: textColor(context).withOpacity(0.6), color: textColor().withOpacity(0.6),
fontSize: 12, fontSize: 12,
), ),
), ),
@@ -385,7 +390,7 @@ class ChatItem extends StatelessWidget {
style: TextStyle( style: TextStyle(
letterSpacing: 0.6, letterSpacing: 0.6,
height: 1.5, height: 1.5,
color: textColor(context), color: textColor(),
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
); );
@@ -396,73 +401,81 @@ class ChatItem extends StatelessWidget {
? messageContent(context) ? messageContent(context)
: isRevoke : isRevoke
? const SizedBox() ? const SizedBox()
: Row( : GestureDetector(
children: [ onLongPress: onLongPress,
if (!isOwner) const SizedBox(width: 12), child: Row(
if (isOwner) const Spacer(), children: [
Container( if (!isOwner) const SizedBox(width: 12),
constraints: const BoxConstraints( if (isOwner) const Spacer(),
maxWidth: 300.0, // 设置最大宽度为200.0 Container(
), constraints: const BoxConstraints(
decoration: BoxDecoration( maxWidth: 300.0, // 设置最大宽度为200.0
color: isOwner ),
? Theme.of(context).colorScheme.primary decoration: BoxDecoration(
: Theme.of(context).colorScheme.secondaryContainer, color: isOwner
borderRadius: BorderRadius.only( ? Theme.of(context).colorScheme.secondaryContainer
topLeft: const Radius.circular(16), : Theme.of(context).colorScheme.onInverseSurface,
topRight: const Radius.circular(16), borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(isOwner ? 16 : 6), topLeft: const Radius.circular(16),
bottomRight: Radius.circular(isOwner ? 6 : 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), if (!isOwner) const Spacer(),
padding: EdgeInsets.only( if (isOwner) const SizedBox(width: 12),
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),
],
); );
} }
} }