mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-18 16:16:14 +08:00
opt: reply type (#850)
This commit is contained in:
committed by
GitHub
parent
0b57cd3555
commit
c899ea95e1
@@ -138,7 +138,7 @@ class ReplyHttp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated('Use replyReplyListGrpc instead')
|
@Deprecated('Use replyReplyListGrpc instead')
|
||||||
static Future<LoadingState> replyReplyList({
|
static Future<LoadingState<ReplyReplyData>> replyReplyList({
|
||||||
required bool isLogin,
|
required bool isLogin,
|
||||||
required int oid,
|
required int oid,
|
||||||
required int root,
|
required int root,
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ abstract class ReplyController<R> extends CommonListController<R, ReplyInfo> {
|
|||||||
|
|
||||||
late final bool isLogin = Accounts.main.isLogin;
|
late final bool isLogin = Accounts.main.isLogin;
|
||||||
|
|
||||||
dynamic upMid;
|
Int64? upMid;
|
||||||
Int64? cursorNext;
|
Int64? cursorNext;
|
||||||
FeedPaginationReply? paginationReply;
|
FeedPaginationReply? paginationReply;
|
||||||
late Rx<Mode> mode = Mode.MAIN_LIST_HOT.obs;
|
late Rx<Mode> mode = Mode.MAIN_LIST_HOT.obs;
|
||||||
@@ -256,8 +256,8 @@ abstract class ReplyController<R> extends CommonListController<R, ReplyInfo> {
|
|||||||
// ref https://github.com/freedom-introvert/biliSendCommAntifraud
|
// ref https://github.com/freedom-introvert/biliSendCommAntifraud
|
||||||
Future<void> checkReply({
|
Future<void> checkReply({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
required dynamic oid,
|
required int oid,
|
||||||
required dynamic rpid,
|
required int? rpid,
|
||||||
required int replyType,
|
required int replyType,
|
||||||
required int replyId,
|
required int replyId,
|
||||||
required String message,
|
required String message,
|
||||||
@@ -346,7 +346,7 @@ abstract class ReplyController<R> extends CommonListController<R, ReplyInfo> {
|
|||||||
// not found
|
// not found
|
||||||
if (context.mounted.not) return;
|
if (context.mounted.not) return;
|
||||||
// cookie check
|
// cookie check
|
||||||
dynamic res1 = await ReplyHttp.replyReplyList(
|
final res1 = await ReplyHttp.replyReplyList(
|
||||||
isLogin: isLogin,
|
isLogin: isLogin,
|
||||||
oid: oid,
|
oid: oid,
|
||||||
root: rpid ?? replyId,
|
root: rpid ?? replyId,
|
||||||
@@ -363,11 +363,11 @@ abstract class ReplyController<R> extends CommonListController<R, ReplyInfo> {
|
|||||||
'无法找到你的评论。\n\n你的评论:$message',
|
'无法找到你的评论。\n\n你的评论:$message',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if (res1 is Success) {
|
} else {
|
||||||
// found
|
// found
|
||||||
if (context.mounted.not) return;
|
if (context.mounted.not) return;
|
||||||
// no cookie check
|
// no cookie check
|
||||||
dynamic res2 = await ReplyHttp.replyReplyList(
|
final res2 = await ReplyHttp.replyReplyList(
|
||||||
isLogin: false,
|
isLogin: false,
|
||||||
oid: oid,
|
oid: oid,
|
||||||
root: rpid ?? replyId,
|
root: rpid ?? replyId,
|
||||||
@@ -387,7 +387,7 @@ abstract class ReplyController<R> extends CommonListController<R, ReplyInfo> {
|
|||||||
: '评论不可见(${res2.errMsg}): $message',
|
: '评论不可见(${res2.errMsg}): $message',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if (res2 is Success) {
|
} else {
|
||||||
// found
|
// found
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
showReplyCheckResult(isManual
|
showReplyCheckResult(isManual
|
||||||
@@ -404,12 +404,12 @@ https://api.bilibili.com/x/v2/reply/reply?oid=$oid&pn=1&ps=20&root=${rpid ?? rep
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 1; true; i++) {
|
for (int i = 1;; i++) {
|
||||||
if (context.mounted.not) return;
|
if (context.mounted.not) return;
|
||||||
dynamic res3 = await ReplyHttp.replyReplyList(
|
final res3 = await ReplyHttp.replyReplyList(
|
||||||
isLogin: false,
|
isLogin: false,
|
||||||
oid: oid,
|
oid: oid,
|
||||||
root: rpid ?? replyId,
|
root: rpid,
|
||||||
pageNum: i,
|
pageNum: i,
|
||||||
type: replyType,
|
type: replyType,
|
||||||
filterBanWord: false,
|
filterBanWord: false,
|
||||||
@@ -418,8 +418,8 @@ https://api.bilibili.com/x/v2/reply/reply?oid=$oid&pn=1&ps=20&root=${rpid ?? rep
|
|||||||
);
|
);
|
||||||
if (res3 is Error) {
|
if (res3 is Error) {
|
||||||
break;
|
break;
|
||||||
} else if (res3 is Success) {
|
} else {
|
||||||
ReplyReplyData data = res3.response;
|
final data = res3.data;
|
||||||
if (data.replies.isNullOrEmpty) {
|
if (data.replies.isNullOrEmpty) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -439,12 +439,12 @@ https://api.bilibili.com/x/v2/reply/reply?oid=$oid&pn=1&ps=20&root=${rpid ?? rep
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 1; true; i++) {
|
for (int i = 1;; i++) {
|
||||||
if (context.mounted.not) return;
|
if (context.mounted.not) return;
|
||||||
dynamic res4 = await ReplyHttp.replyReplyList(
|
final res4 = await ReplyHttp.replyReplyList(
|
||||||
isLogin: true,
|
isLogin: true,
|
||||||
oid: oid,
|
oid: oid,
|
||||||
root: rpid ?? replyId,
|
root: rpid,
|
||||||
pageNum: i,
|
pageNum: i,
|
||||||
type: replyType,
|
type: replyType,
|
||||||
filterBanWord: false,
|
filterBanWord: false,
|
||||||
@@ -453,8 +453,8 @@ https://api.bilibili.com/x/v2/reply/reply?oid=$oid&pn=1&ps=20&root=${rpid ?? rep
|
|||||||
);
|
);
|
||||||
if (res4 is Error) {
|
if (res4 is Error) {
|
||||||
break;
|
break;
|
||||||
} else if (res4 is Success) {
|
} else {
|
||||||
ReplyReplyData data = res4.response;
|
final data = res4.data;
|
||||||
if (data.replies.isNullOrEmpty) {
|
if (data.replies.isNullOrEmpty) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import 'package:PiliPlus/utils/url_utils.dart';
|
|||||||
import 'package:PiliPlus/utils/utils.dart';
|
import 'package:PiliPlus/utils/utils.dart';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:fixnum/fixnum.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.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';
|
||||||
@@ -54,7 +55,7 @@ class ReplyItemGrpc extends StatelessWidget {
|
|||||||
final bool needDivider;
|
final bool needDivider;
|
||||||
final VoidCallback? onReply;
|
final VoidCallback? onReply;
|
||||||
final ValueChanged<int?>? onDelete;
|
final ValueChanged<int?>? onDelete;
|
||||||
final dynamic upMid;
|
final Int64? upMid;
|
||||||
final VoidCallback? showDialogue;
|
final VoidCallback? showDialogue;
|
||||||
final Function? getTag;
|
final Function? getTag;
|
||||||
final VoidCallback? onViewImage;
|
final VoidCallback? onViewImage;
|
||||||
@@ -667,7 +668,7 @@ class ReplyItemGrpc extends StatelessWidget {
|
|||||||
content.atNameToMid.containsKey(matchStr.substring(1))) {
|
content.atNameToMid.containsKey(matchStr.substring(1))) {
|
||||||
// 处理@用户
|
// 处理@用户
|
||||||
final String userName = matchStr.substring(1);
|
final String userName = matchStr.substring(1);
|
||||||
final int userId = content.atNameToMid[userName]!.toInt();
|
final userId = content.atNameToMid[userName]!.toString();
|
||||||
spanChildren.add(
|
spanChildren.add(
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: matchStr,
|
text: matchStr,
|
||||||
@@ -966,8 +967,8 @@ class ReplyItemGrpc extends StatelessWidget {
|
|||||||
required onDelete,
|
required onDelete,
|
||||||
required bool isSubReply,
|
required bool isSubReply,
|
||||||
}) {
|
}) {
|
||||||
int ownerMid = Accounts.main.mid;
|
final ownerMid = Int64(Accounts.main.mid);
|
||||||
Future<dynamic> menuActionHandler(String type) async {
|
Future<void> menuActionHandler(String type) async {
|
||||||
late String message = item.content.message;
|
late String message = item.content.message;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'report':
|
case 'report':
|
||||||
@@ -1100,7 +1101,7 @@ class ReplyItemGrpc extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
Color errorColor = theme.colorScheme.error;
|
final errorColor = theme.colorScheme.error;
|
||||||
final style = theme.textTheme.titleSmall;
|
final style = theme.textTheme.titleSmall;
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
@@ -1129,21 +1130,21 @@ class ReplyItemGrpc extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (ownerMid == upMid.toInt() || ownerMid == item.member.mid.toInt())
|
if (ownerMid == upMid || ownerMid == item.member.mid)
|
||||||
ListTile(
|
ListTile(
|
||||||
onTap: () => menuActionHandler('delete'),
|
onTap: () => menuActionHandler('delete'),
|
||||||
minLeadingWidth: 0,
|
minLeadingWidth: 0,
|
||||||
leading: Icon(Icons.delete_outlined, color: errorColor, size: 19),
|
leading: Icon(Icons.delete_outlined, color: errorColor, size: 19),
|
||||||
title: Text('删除', style: style!.copyWith(color: errorColor)),
|
title: Text('删除', style: style!.copyWith(color: errorColor)),
|
||||||
),
|
),
|
||||||
if (ownerMid != 0)
|
if (ownerMid != Int64.ZERO)
|
||||||
ListTile(
|
ListTile(
|
||||||
onTap: () => menuActionHandler('report'),
|
onTap: () => menuActionHandler('report'),
|
||||||
minLeadingWidth: 0,
|
minLeadingWidth: 0,
|
||||||
leading: Icon(Icons.error_outline, color: errorColor, size: 19),
|
leading: Icon(Icons.error_outline, color: errorColor, size: 19),
|
||||||
title: Text('举报', style: style!.copyWith(color: errorColor)),
|
title: Text('举报', style: style!.copyWith(color: errorColor)),
|
||||||
),
|
),
|
||||||
if (replyLevel == '1' && isSubReply.not && ownerMid == upMid.toInt())
|
if (replyLevel == '1' && isSubReply.not && ownerMid == upMid)
|
||||||
ListTile(
|
ListTile(
|
||||||
onTap: () => menuActionHandler('top'),
|
onTap: () => menuActionHandler('top'),
|
||||||
minLeadingWidth: 0,
|
minLeadingWidth: 0,
|
||||||
@@ -1171,7 +1172,7 @@ class ReplyItemGrpc extends StatelessWidget {
|
|||||||
leading: const Icon(Icons.save_alt, size: 19),
|
leading: const Icon(Icons.save_alt, size: 19),
|
||||||
title: Text('保存评论', style: style),
|
title: Text('保存评论', style: style),
|
||||||
),
|
),
|
||||||
if (item.mid.toInt() == ownerMid)
|
if (item.mid == ownerMid)
|
||||||
ListTile(
|
ListTile(
|
||||||
onTap: () => menuActionHandler('checkReply'),
|
onTap: () => menuActionHandler('checkReply'),
|
||||||
minLeadingWidth: 0,
|
minLeadingWidth: 0,
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class VideoReplyReplyController extends ReplyController
|
|||||||
int rpid;
|
int rpid;
|
||||||
ReplyType replyType; // = ReplyType.video;
|
ReplyType replyType; // = ReplyType.video;
|
||||||
|
|
||||||
dynamic firstFloor;
|
ReplyInfo? firstFloor;
|
||||||
|
|
||||||
int? index;
|
int? index;
|
||||||
AnimationController? controller;
|
AnimationController? controller;
|
||||||
@@ -65,9 +65,9 @@ class VideoReplyReplyController extends ReplyController
|
|||||||
bool customHandleResponse(bool isRefresh, Success response) {
|
bool customHandleResponse(bool isRefresh, Success response) {
|
||||||
final data = response.response;
|
final data = response.response;
|
||||||
|
|
||||||
upMid ??= data.subjectControl.upMid.toInt();
|
upMid ??= data.subjectControl.upMid;
|
||||||
paginationReply = data.paginationReply;
|
paginationReply = data.paginationReply;
|
||||||
isEnd = data.cursor?.isEnd ?? false;
|
isEnd = data.cursor.isEnd;
|
||||||
|
|
||||||
// reply2Reply // isDialogue.not
|
// reply2Reply // isDialogue.not
|
||||||
if (data is DetailListReply) {
|
if (data is DetailListReply) {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class VideoReplyReplyPanel extends CommonSlidePage {
|
|||||||
final int oid;
|
final int oid;
|
||||||
final int rpid;
|
final int rpid;
|
||||||
final int? dialog;
|
final int? dialog;
|
||||||
final dynamic firstFloor;
|
final ReplyInfo? firstFloor;
|
||||||
final String? source;
|
final String? source;
|
||||||
final ReplyType replyType;
|
final ReplyType replyType;
|
||||||
final bool isDialogue;
|
final bool isDialogue;
|
||||||
@@ -53,14 +53,14 @@ class _VideoReplyReplyPanelState
|
|||||||
extends CommonSlidePageState<VideoReplyReplyPanel>
|
extends CommonSlidePageState<VideoReplyReplyPanel>
|
||||||
with TickerProviderStateMixin {
|
with TickerProviderStateMixin {
|
||||||
late VideoReplyReplyController _videoReplyReplyController;
|
late VideoReplyReplyController _videoReplyReplyController;
|
||||||
late final _savedReplies = {};
|
late final _savedReplies = <int, String>{};
|
||||||
late final itemPositionsListener = ItemPositionsListener.create();
|
late final itemPositionsListener = ItemPositionsListener.create();
|
||||||
late final _key = GlobalKey<ScaffoldState>();
|
late final _key = GlobalKey<ScaffoldState>();
|
||||||
late final _listKey = GlobalKey();
|
late final _listKey = GlobalKey();
|
||||||
late final _tag =
|
late final _tag =
|
||||||
Utils.makeHeroTag('${widget.rpid}${widget.dialog}${widget.isDialogue}');
|
Utils.makeHeroTag('${widget.rpid}${widget.dialog}${widget.isDialogue}');
|
||||||
|
|
||||||
dynamic get firstFloor =>
|
ReplyInfo? get firstFloor =>
|
||||||
widget.firstFloor ?? _videoReplyReplyController.firstFloor;
|
widget.firstFloor ?? _videoReplyReplyController.firstFloor;
|
||||||
|
|
||||||
bool get _horizontalPreview =>
|
bool get _horizontalPreview =>
|
||||||
@@ -179,11 +179,11 @@ class _VideoReplyReplyPanelState
|
|||||||
} else if (firstFloor != null) {
|
} else if (firstFloor != null) {
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
return ReplyItemGrpc(
|
return ReplyItemGrpc(
|
||||||
replyItem: firstFloor,
|
replyItem: firstFloor!,
|
||||||
replyLevel: '2',
|
replyLevel: '2',
|
||||||
needDivider: false,
|
needDivider: false,
|
||||||
onReply: () {
|
onReply: () {
|
||||||
_onReply(firstFloor, -1);
|
_onReply(firstFloor!, -1);
|
||||||
},
|
},
|
||||||
upMid: _videoReplyReplyController.upMid,
|
upMid: _videoReplyReplyController.upMid,
|
||||||
onViewImage: widget.onViewImage,
|
onViewImage: widget.onViewImage,
|
||||||
@@ -287,41 +287,40 @@ class _VideoReplyReplyPanelState
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
Function(dynamic imgList, dynamic index)? get _getImageCallback =>
|
Function(List<String>, int)? get _getImageCallback => _horizontalPreview
|
||||||
_horizontalPreview
|
? (imgList, index) {
|
||||||
? (imgList, index) {
|
final ctr = AnimationController(
|
||||||
final ctr = AnimationController(
|
vsync: this,
|
||||||
vsync: this,
|
duration: const Duration(milliseconds: 200),
|
||||||
duration: const Duration(milliseconds: 200),
|
)..forward();
|
||||||
)..forward();
|
PageUtils.onHorizontalPreview(
|
||||||
PageUtils.onHorizontalPreview(
|
_key,
|
||||||
_key,
|
AnimationController(
|
||||||
AnimationController(
|
vsync: this,
|
||||||
vsync: this,
|
duration: Duration.zero,
|
||||||
duration: Duration.zero,
|
),
|
||||||
),
|
ctr,
|
||||||
ctr,
|
imgList,
|
||||||
imgList,
|
index,
|
||||||
index,
|
(value) async {
|
||||||
(value) async {
|
if (value == false) {
|
||||||
if (value == false) {
|
await ctr.reverse();
|
||||||
await ctr.reverse();
|
}
|
||||||
}
|
try {
|
||||||
try {
|
ctr.dispose();
|
||||||
ctr.dispose();
|
} catch (_) {}
|
||||||
} catch (_) {}
|
if (value == false) {
|
||||||
if (value == false) {
|
Get.back();
|
||||||
Get.back();
|
}
|
||||||
}
|
},
|
||||||
},
|
);
|
||||||
);
|
}
|
||||||
}
|
: null;
|
||||||
: null;
|
|
||||||
|
|
||||||
void _onReply(dynamic item, int index) {
|
void _onReply(ReplyInfo item, int index) {
|
||||||
dynamic oid = item?.oid.toInt();
|
final oid = item.oid.toInt();
|
||||||
dynamic root = item?.id.toInt();
|
final root = item.id.toInt();
|
||||||
dynamic key = oid + root;
|
final key = oid + root;
|
||||||
|
|
||||||
Navigator.of(context)
|
Navigator.of(context)
|
||||||
.push(
|
.push(
|
||||||
@@ -357,7 +356,7 @@ class _VideoReplyReplyPanelState
|
|||||||
)
|
)
|
||||||
.then((res) {
|
.then((res) {
|
||||||
if (res != null) {
|
if (res != null) {
|
||||||
_savedReplies[key] = null;
|
_savedReplies.remove(key);
|
||||||
ReplyInfo replyInfo = RequestUtils.replyCast(res);
|
ReplyInfo replyInfo = RequestUtils.replyCast(res);
|
||||||
_videoReplyReplyController.loadingState.value.dataOrNull
|
_videoReplyReplyController.loadingState.value.dataOrNull
|
||||||
?.insert(index + 1, replyInfo);
|
?.insert(index + 1, replyInfo);
|
||||||
@@ -385,7 +384,8 @@ class _VideoReplyReplyPanelState
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody(ThemeData theme, LoadingState loadingState, int index) {
|
Widget _buildBody(
|
||||||
|
ThemeData theme, LoadingState<List<ReplyInfo>?> loadingState, int index) {
|
||||||
return switch (loadingState) {
|
return switch (loadingState) {
|
||||||
Loading() => IgnorePointer(
|
Loading() => IgnorePointer(
|
||||||
child: CustomScrollView(
|
child: CustomScrollView(
|
||||||
@@ -402,7 +402,7 @@ class _VideoReplyReplyPanelState
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Success(:var response) => () {
|
Success(:var response) => () {
|
||||||
if (index == response.length) {
|
if (index == response!.length) {
|
||||||
_videoReplyReplyController.onLoadMore();
|
_videoReplyReplyController.onLoadMore();
|
||||||
return Container(
|
return Container(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
@@ -445,7 +445,7 @@ class _VideoReplyReplyPanelState
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _replyItem(replyItem, index) {
|
Widget _replyItem(ReplyInfo replyItem, int index) {
|
||||||
return ReplyItemGrpc(
|
return ReplyItemGrpc(
|
||||||
replyItem: replyItem,
|
replyItem: replyItem,
|
||||||
replyLevel: widget.isDialogue ? '3' : '2',
|
replyLevel: widget.isDialogue ? '3' : '2',
|
||||||
@@ -484,18 +484,14 @@ class _VideoReplyReplyPanelState
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _itemCount(LoadingState loadingState) {
|
int _itemCount(LoadingState<List<ReplyInfo>?> loadingState) {
|
||||||
if (widget.isDialogue) {
|
if (widget.isDialogue) {
|
||||||
return (loadingState is Success ? loadingState.response.length : 0) + 1;
|
return (loadingState.dataOrNull?.length ?? 0) + 1;
|
||||||
}
|
}
|
||||||
int itemCount = 0;
|
int itemCount = 0;
|
||||||
if (firstFloor != null) {
|
if (firstFloor != null) {
|
||||||
itemCount = 2;
|
itemCount = 2;
|
||||||
}
|
}
|
||||||
if (loadingState is Success) {
|
return (loadingState.dataOrNull?.length ?? 0) + itemCount + 2;
|
||||||
return loadingState.response.length + itemCount + 2;
|
|
||||||
} else {
|
|
||||||
return itemCount + 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user