mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-18 16:16:14 +08:00
refa: whisper detail
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:PiliPlus/build_config.dart';
|
||||||
import 'package:PiliPlus/common/constants.dart';
|
import 'package:PiliPlus/common/constants.dart';
|
||||||
import 'package:PiliPlus/grpc/bilibili/metadata.pb.dart';
|
import 'package:PiliPlus/grpc/bilibili/metadata.pb.dart';
|
||||||
import 'package:PiliPlus/grpc/bilibili/metadata/device.pb.dart';
|
import 'package:PiliPlus/grpc/bilibili/metadata/device.pb.dart';
|
||||||
@@ -60,6 +61,7 @@ class GrpcUrl {
|
|||||||
static const keywordBlockingList = '$im2/KeywordBlockingList';
|
static const keywordBlockingList = '$im2/KeywordBlockingList';
|
||||||
static const keywordBlockingAdd = '$im2/KeywordBlockingAdd';
|
static const keywordBlockingAdd = '$im2/KeywordBlockingAdd';
|
||||||
static const keywordBlockingDelete = '$im2/KeywordBlockingDelete';
|
static const keywordBlockingDelete = '$im2/KeywordBlockingDelete';
|
||||||
|
static const syncFetchSessionMsgs = '$im/SyncFetchSessionMsgs';
|
||||||
}
|
}
|
||||||
|
|
||||||
class GrpcRepo {
|
class GrpcRepo {
|
||||||
@@ -205,8 +207,11 @@ class GrpcRepo {
|
|||||||
try {
|
try {
|
||||||
final grpcMsg = Status.fromBuffer(msgBytes);
|
final grpcMsg = Status.fromBuffer(msgBytes);
|
||||||
// UNKNOWN : -400 : msg
|
// UNKNOWN : -400 : msg
|
||||||
msg =
|
final errMsg =
|
||||||
'${grpcMsg.code} : ${grpcMsg.message} : ${grpcMsg.details.firstOrNull?.status.message}';
|
grpcMsg.details.map((e) => e.status.message).join('\n');
|
||||||
|
msg = BuildConfig.isDebug
|
||||||
|
? 'CODE: ${grpcMsg.code}(${grpcMsg.message})\nMSG: $errMsg'
|
||||||
|
: errMsg;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
msg = utf8
|
msg = utf8
|
||||||
.decode(msgBytes, allowMalformed: true)
|
.decode(msgBytes, allowMalformed: true)
|
||||||
|
|||||||
@@ -41,8 +41,28 @@ class ImGrpc {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<LoadingState<SessionMainReply>> sessionMain(
|
static Future<LoadingState<RspSessionMsg>> syncFetchSessionMsgs({
|
||||||
{PbMap<int, Offset>? offset}) {
|
required int talkerId,
|
||||||
|
Int64? endSeqno,
|
||||||
|
Int64? beginSeqno,
|
||||||
|
}) {
|
||||||
|
return GrpcRepo.request(
|
||||||
|
GrpcUrl.syncFetchSessionMsgs,
|
||||||
|
ReqSessionMsg(
|
||||||
|
talkerId: Int64(talkerId),
|
||||||
|
sessionType: 1,
|
||||||
|
endSeqno: endSeqno,
|
||||||
|
beginSeqno: beginSeqno,
|
||||||
|
size: 20,
|
||||||
|
devId: '1',
|
||||||
|
),
|
||||||
|
RspSessionMsg.fromBuffer,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<LoadingState<SessionMainReply>> sessionMain({
|
||||||
|
PbMap<int, Offset>? offset,
|
||||||
|
}) {
|
||||||
return GrpcRepo.request(
|
return GrpcRepo.request(
|
||||||
GrpcUrl.sessionMain,
|
GrpcUrl.sessionMain,
|
||||||
SessionMainReq(
|
SessionMainReq(
|
||||||
|
|||||||
@@ -46,9 +46,9 @@ class _ZanButtonGrpcState extends State<ZanButtonGrpc> {
|
|||||||
widget.replyItem.like =
|
widget.replyItem.like =
|
||||||
$fixnum.Int64(widget.replyItem.like.toInt() - 1);
|
$fixnum.Int64(widget.replyItem.like.toInt() - 1);
|
||||||
}
|
}
|
||||||
widget.replyItem.replyControl.action = $fixnum.Int64(2);
|
widget.replyItem.replyControl.action = $fixnum.Int64.TWO;
|
||||||
} else {
|
} else {
|
||||||
widget.replyItem.replyControl.action = $fixnum.Int64(0);
|
widget.replyItem.replyControl.action = $fixnum.Int64.ZERO;
|
||||||
}
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
} else {
|
} else {
|
||||||
@@ -76,11 +76,11 @@ class _ZanButtonGrpcState extends State<ZanButtonGrpc> {
|
|||||||
if (action == 1) {
|
if (action == 1) {
|
||||||
widget.replyItem.like =
|
widget.replyItem.like =
|
||||||
$fixnum.Int64(widget.replyItem.like.toInt() + 1);
|
$fixnum.Int64(widget.replyItem.like.toInt() + 1);
|
||||||
widget.replyItem.replyControl.action = $fixnum.Int64(1);
|
widget.replyItem.replyControl.action = $fixnum.Int64.ONE;
|
||||||
} else {
|
} else {
|
||||||
widget.replyItem.like =
|
widget.replyItem.like =
|
||||||
$fixnum.Int64(widget.replyItem.like.toInt() - 1);
|
$fixnum.Int64(widget.replyItem.like.toInt() - 1);
|
||||||
widget.replyItem.replyControl.action = $fixnum.Int64(0);
|
widget.replyItem.replyControl.action = $fixnum.Int64.ZERO;
|
||||||
}
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,67 +1,70 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
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/loading_state.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_list_controller.dart';
|
import 'package:PiliPlus/pages/common/common_list_controller.dart';
|
||||||
import 'package:PiliPlus/utils/extension.dart';
|
import 'package:PiliPlus/utils/extension.dart';
|
||||||
import 'package:PiliPlus/utils/feed_back.dart';
|
import 'package:PiliPlus/utils/feed_back.dart';
|
||||||
import 'package:PiliPlus/utils/storage.dart';
|
import 'package:PiliPlus/utils/storage.dart';
|
||||||
|
import 'package:fixnum/fixnum.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
class WhisperDetailController
|
class WhisperDetailController extends CommonListController<RspSessionMsg, Msg> {
|
||||||
extends CommonListController<SessionMsgDataModel, MessageItem> {
|
|
||||||
late final ownerMid = Accounts.main.mid;
|
late final ownerMid = Accounts.main.mid;
|
||||||
|
|
||||||
late int talkerId;
|
late int talkerId;
|
||||||
late String name;
|
late String name;
|
||||||
late String face;
|
late String face;
|
||||||
String? mid;
|
int? mid;
|
||||||
|
|
||||||
int? msgSeqno;
|
Int64? msgSeqno;
|
||||||
|
|
||||||
//表情转换图片规则
|
//表情转换图片规则
|
||||||
List<dynamic>? eInfos;
|
List<EmotionInfo>? eInfos;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
|
|
||||||
talkerId = int.parse(Get.parameters['talkerId']!);
|
talkerId = int.parse(Get.parameters['talkerId']!);
|
||||||
name = Get.parameters['name']!;
|
name = Get.parameters['name']!;
|
||||||
face = Get.parameters['face']!;
|
face = Get.parameters['face']!;
|
||||||
mid = Get.parameters['mid'];
|
mid = Get.parameters['mid'] != null
|
||||||
|
? int.parse(Get.parameters['mid']!)
|
||||||
|
: null;
|
||||||
|
|
||||||
queryData();
|
queryData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool customHandleResponse(
|
bool customHandleResponse(bool isRefresh, Success<RspSessionMsg> response) {
|
||||||
bool isRefresh, Success<SessionMsgDataModel> response) {
|
List<Msg> msgs = response.response.messages;
|
||||||
List<MessageItem>? messageList = response.response.messages;
|
if (msgs.isNotEmpty) {
|
||||||
if (messageList?.isNotEmpty == true) {
|
msgSeqno = msgs.last.msgSeqno;
|
||||||
msgSeqno = messageList!.last.msgSeqno;
|
if (msgs.length == 1 &&
|
||||||
if (messageList.length == 1 &&
|
msgs.last.msgType == 18 &&
|
||||||
messageList.last.msgType == 18 &&
|
msgs.last.msgSource == 18) {
|
||||||
messageList.last.msgSource == 18) {
|
|
||||||
// debugPrint(messageList.last);
|
// debugPrint(messageList.last);
|
||||||
// debugPrint(messageList.last.content);
|
// debugPrint(messageList.last.content);
|
||||||
//{content: [{"text":"对方主动回复或关注你前,最多发送1条消息","color_day":"#9499A0","color_nig":"#9499A0"}]}
|
//{content: [{"text":"对方主动回复或关注你前,最多发送1条消息","color_day":"#9499A0","color_nig":"#9499A0"}]}
|
||||||
} else {
|
} else {
|
||||||
ackSessionMsg(messageList.last.msgSeqno);
|
ackSessionMsg(msgs.last.msgSeqno.toInt());
|
||||||
}
|
|
||||||
if (response.response.eInfos != null) {
|
|
||||||
eInfos ??= [];
|
|
||||||
eInfos!.addAll(response.response.eInfos!);
|
|
||||||
}
|
}
|
||||||
|
eInfos ??= <EmotionInfo>[];
|
||||||
|
eInfos!.addAll(response.response.eInfos);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 消息标记已读
|
// 消息标记已读
|
||||||
Future<void> ackSessionMsg(int? msgSeqno) async {
|
Future<void> ackSessionMsg(int msgSeqno) async {
|
||||||
var res = await MsgHttp.ackSessionMsg(
|
var res = await MsgHttp.ackSessionMsg(
|
||||||
talkerId: talkerId,
|
talkerId: talkerId,
|
||||||
ackSeqno: msgSeqno,
|
ackSeqno: msgSeqno,
|
||||||
@@ -79,37 +82,24 @@ class WhisperDetailController
|
|||||||
int? index,
|
int? index,
|
||||||
}) async {
|
}) async {
|
||||||
feedBack();
|
feedBack();
|
||||||
|
SmartDialog.dismiss();
|
||||||
if (ownerMid == 0) {
|
if (ownerMid == 0) {
|
||||||
SmartDialog.dismiss();
|
|
||||||
SmartDialog.showToast('请先登录');
|
SmartDialog.showToast('请先登录');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mid == null) {
|
var result = await ImGrpc.sendMsg(
|
||||||
SmartDialog.dismiss();
|
|
||||||
SmartDialog.showToast('这里不能发');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (picMsg == null && message == '') {
|
|
||||||
SmartDialog.dismiss();
|
|
||||||
SmartDialog.showToast('请输入内容');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var result = await MsgHttp.sendMsg(
|
|
||||||
senderUid: ownerMid,
|
senderUid: ownerMid,
|
||||||
receiverId: int.parse(mid!),
|
receiverId: mid!,
|
||||||
content: msgType == 5
|
content:
|
||||||
? message
|
msgType == 5 ? message : jsonEncode(picMsg ?? {"content": message}),
|
||||||
: jsonEncode(
|
msgType: MsgType.values[msgType ?? (picMsg != null ? 2 : 1)],
|
||||||
picMsg ?? {"content": message},
|
|
||||||
),
|
|
||||||
msgType: msgType ?? (picMsg != null ? 2 : 1),
|
|
||||||
);
|
);
|
||||||
SmartDialog.dismiss();
|
SmartDialog.dismiss();
|
||||||
if (result['status']) {
|
if (result.isSuccess) {
|
||||||
if (msgType == 5) {
|
if (msgType == 5) {
|
||||||
List<MessageItem> list = (loadingState.value as Success).response;
|
loadingState
|
||||||
list[index!].msgStatus = 1;
|
..value.data![index!].msgStatus = 1
|
||||||
loadingState.refresh();
|
..refresh();
|
||||||
SmartDialog.showToast('撤回成功');
|
SmartDialog.showToast('撤回成功');
|
||||||
} else {
|
} else {
|
||||||
onRefresh();
|
onRefresh();
|
||||||
@@ -117,12 +107,12 @@ class WhisperDetailController
|
|||||||
SmartDialog.showToast('发送成功');
|
SmartDialog.showToast('发送成功');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SmartDialog.showToast(result['msg']);
|
result.toast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<MessageItem>? getDataList(SessionMsgDataModel response) {
|
List<Msg>? getDataList(RspSessionMsg response) {
|
||||||
if (response.hasMore == 0) {
|
if (response.hasMore == 0) {
|
||||||
isEnd = true;
|
isEnd = true;
|
||||||
}
|
}
|
||||||
@@ -138,10 +128,10 @@ class WhisperDetailController
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<LoadingState<SessionMsgDataModel>> customGetData() =>
|
Future<LoadingState<RspSessionMsg>> customGetData() =>
|
||||||
MsgHttp.sessionMsg(
|
ImGrpc.syncFetchSessionMsgs(
|
||||||
talkerId: talkerId,
|
talkerId: talkerId,
|
||||||
beginSeqno: msgSeqno != null ? 0 : null,
|
beginSeqno: msgSeqno != null ? Int64.ZERO : null,
|
||||||
endSeqno: msgSeqno,
|
endSeqno: msgSeqno,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ import 'dart:async';
|
|||||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||||
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
|
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
|
||||||
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
||||||
|
import 'package:PiliPlus/grpc/bilibili/im/type.pb.dart' show Msg;
|
||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/http/msg.dart';
|
import 'package:PiliPlus/http/msg.dart';
|
||||||
import 'package:PiliPlus/models/common/publish_panel_type.dart';
|
import 'package:PiliPlus/models/common/publish_panel_type.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/pages/whisper_detail/controller.dart';
|
import 'package:PiliPlus/pages/whisper_detail/controller.dart';
|
||||||
@@ -110,15 +110,17 @@ class _WhisperDetailPageState
|
|||||||
_buildBody(_whisperDetailController.loadingState.value)),
|
_buildBody(_whisperDetailController.loadingState.value)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
_buildInputView(theme),
|
if (_whisperDetailController.mid != null) ...[
|
||||||
buildPanelContainer(theme.colorScheme.onInverseSurface),
|
_buildInputView(theme),
|
||||||
|
buildPanelContainer(theme.colorScheme.onInverseSurface),
|
||||||
|
],
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody(LoadingState<List<MessageItem>?> loadingState) {
|
Widget _buildBody(LoadingState<List<Msg>?> loadingState) {
|
||||||
return switch (loadingState) {
|
return switch (loadingState) {
|
||||||
Loading() => loadingWidget,
|
Loading() => loadingWidget,
|
||||||
Success() => loadingState.response?.isNotEmpty == true
|
Success() => loadingState.response?.isNotEmpty == true
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user