Files
PiliPlus/lib/pages/whisper_detail/controller.dart
dom d63116542b tweaks
Signed-off-by: dom <githubaccount56556@proton.me>
2026-05-09 13:41:09 +08:00

176 lines
5.0 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:async';
import 'dart:convert';
import 'package:PiliPlus/grpc/bilibili/im/interfaces/v1.pb.dart'
show EmotionInfo, RspSessionMsg;
import 'package:PiliPlus/grpc/bilibili/im/type.pb.dart' show Msg, MsgType;
import 'package:PiliPlus/grpc/im.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/http/msg.dart';
import 'package:PiliPlus/pages/common/common_list_controller.dart';
import 'package:PiliPlus/utils/accounts.dart';
import 'package:PiliPlus/utils/extension/scroll_controller_ext.dart';
import 'package:PiliPlus/utils/feed_back.dart';
import 'package:fixnum/fixnum.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
class WhisperDetailController extends CommonListController<RspSessionMsg, Msg> {
late final account = Accounts.main;
late final int talkerId;
late final String name;
late final String face;
late final int? mid;
late final bool isLive;
Int64? msgSeqno;
//表情转换图片规则
List<EmotionInfo>? eInfos;
@override
void onInit() {
super.onInit();
final args = Get.arguments;
talkerId = args['talkerId'];
name = args['name'];
face = args['face'];
mid = args['mid'];
isLive = args['isLive'] ?? false;
queryData();
}
@override
bool customHandleResponse(bool isRefresh, Success<RspSessionMsg> response) {
List<Msg> msgs = response.response.messages;
if (msgs.isNotEmpty) {
msgSeqno = msgs.last.msgSeqno;
if (msgs.length == 1 &&
msgs.last.msgType == 18 &&
msgs.last.msgSource == 18) {
//{content: [{"text":"对方主动回复或关注你前最多发送1条消息","color_day":"#9499A0","color_nig":"#9499A0"}]}
} else {
ackSessionMsg(msgs.last.msgSeqno.toInt());
}
msgs.removeWhere((e) => e.msgType == MsgType.EN_MSG_TYPE_DRAW_BACK.value);
eInfos ??= <EmotionInfo>[];
eInfos!.addAll(response.response.eInfos);
}
return false;
}
// 消息标记已读
Future<void> ackSessionMsg(int msgSeqno) async {
final res = await MsgHttp.ackSessionMsg(
talkerId: talkerId,
ackSeqno: msgSeqno,
);
if (!res.isSuccess) {
res.toast();
}
}
late bool _isSending = false;
Future<void> sendMsg({
String? message,
Map? picMsg,
required VoidCallback onClearText,
int? msgType,
int? index,
}) async {
// debug
// if (loadingState.value case Success(:final response)) {
// final list = List.of(response ?? <Msg>[])
// ..insert(
// 0,
// Msg.create()..mergeFromProto3Json({
// "senderUid": "${account.mid}",
// "receiverType": 1,
// "receiverId": "$mid",
// "msgType": msgType,
// "content": jsonEncode({"content": message}),
// "msgSeqno": "1",
// "timestamp": "${DateTime.now().millisecondsSinceEpoch ~/ 1000}",
// "atUids": ["0"],
// "msgKey": "2",
// "msgSource": msgType,
// }),
// );
// loadingState.value = Success(list);
// }
// onClearText();
// scrollController.jumpToTop();
// SmartDialog.showToast('发送成功');
// return;
assert((message != null) ^ (picMsg != null));
if (_isSending) return;
_isSending = true;
feedBack();
SmartDialog.dismiss();
if (!account.isLogin) {
SmartDialog.showToast('请先登录');
return;
}
final res = await ImGrpc.sendMsg(
senderUid: account.mid,
receiverId: mid!,
content: msgType == 5
? message!
: jsonEncode(picMsg ?? {"content": message!}),
msgType: MsgType.values[msgType ?? (picMsg != null ? 2 : 1)],
);
SmartDialog.dismiss();
if (res.isSuccess) {
if (msgType == 5) {
loadingState
..value.data![index!].msgStatus = 1
..refresh();
SmartDialog.showToast('撤回成功');
} else {
onRefresh();
onClearText();
SmartDialog.showToast('发送成功');
}
} else {
res.toast();
}
_isSending = false;
}
@override
List<Msg>? getDataList(RspSessionMsg response) {
if (response.hasMore == 0) {
isEnd = true;
}
return response.messages;
}
@override
Future<void> onRefresh() {
msgSeqno = null;
eInfos = null;
scrollController.jumpToTop();
return super.onRefresh();
}
@override
Future<LoadingState<RspSessionMsg>> customGetData() =>
ImGrpc.syncFetchSessionMsgs(
talkerId: talkerId,
beginSeqno: msgSeqno != null ? Int64.ZERO : null,
endSeqno: msgSeqno,
);
Future<LoadingState> onReport(Msg item, int reasonType, String reasonDesc) {
return MsgHttp.imMsgReport(
accusedUid: item.senderUid.toInt(),
reasonType: reasonType,
reasonDesc: reasonDesc,
comment: {'group_id': 0, 'msg_key': item.msgKey.toString()},
extra: {"msg_keys": []},
);
}
}