mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
feat: whisper: revoke msg
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -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']}",
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user