opt: filter data

Closes #283

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-02-19 15:19:50 +08:00
parent cfb6c674ea
commit f22cad42d7
9 changed files with 53 additions and 65 deletions

View File

@@ -4,6 +4,7 @@ import 'package:PiliPlus/grpc/grpc_repo.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/video/reply/item.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/storage.dart';
import 'package:dio/dio.dart';
import '../models/video/reply/data.dart';
@@ -14,6 +15,9 @@ import 'init.dart';
class ReplyHttp {
static Options get _options => Options(extra: {'clearCookie': true});
static RegExp replyRegExp =
RegExp(GStorage.banWordForReply, caseSensitive: false);
static Future<LoadingState> replyList({
required bool isLogin,
required int oid,
@@ -21,8 +25,8 @@ class ReplyHttp {
required int type,
required int page,
int sort = 1,
required String banWordForReply,
required bool antiGoodsReply,
bool? enableFilter,
}) async {
var res = !isLogin
? await Request().get(
@@ -49,18 +53,16 @@ class ReplyHttp {
);
if (res.data['code'] == 0) {
ReplyData replyData = ReplyData.fromJson(res.data['data']);
if (banWordForReply.isNotEmpty) {
if (enableFilter != false && replyRegExp.pattern.isNotEmpty) {
// topReplies
if (replyData.topReplies?.isNotEmpty == true) {
replyData.topReplies!.removeWhere((item) {
bool hasMatch = RegExp(banWordForReply, caseSensitive: false)
.hasMatch(item.content?.message ?? '');
bool hasMatch = replyRegExp.hasMatch(item.content?.message ?? '');
// remove subreplies
if (hasMatch.not) {
if (item.replies?.isNotEmpty == true) {
item.replies!.removeWhere((item) =>
RegExp(banWordForReply, caseSensitive: false)
.hasMatch(item.content?.message ?? ''));
replyRegExp.hasMatch(item.content?.message ?? ''));
}
}
return hasMatch;
@@ -70,14 +72,12 @@ class ReplyHttp {
// replies
if (replyData.replies?.isNotEmpty == true) {
replyData.replies!.removeWhere((item) {
bool hasMatch = RegExp(banWordForReply, caseSensitive: false)
.hasMatch(item.content?.message ?? '');
bool hasMatch = replyRegExp.hasMatch(item.content?.message ?? '');
// remove subreplies
if (hasMatch.not) {
if (item.replies?.isNotEmpty == true) {
item.replies!.removeWhere((item) =>
RegExp(banWordForReply, caseSensitive: false)
.hasMatch(item.content?.message ?? ''));
replyRegExp.hasMatch(item.content?.message ?? ''));
}
}
return hasMatch;
@@ -125,32 +125,28 @@ class ReplyHttp {
int type = 1,
required int oid,
required CursorReq cursor,
required String banWordForReply,
required bool antiGoodsReply,
}) async {
dynamic res = await GrpcRepo.mainList(type: type, oid: oid, cursor: cursor);
if (res['status']) {
MainListReply mainListReply = res['data'];
// keyword filter
if (banWordForReply.isNotEmpty) {
if (replyRegExp.pattern.isNotEmpty) {
// upTop
if (mainListReply.hasUpTop() &&
RegExp(banWordForReply, caseSensitive: false)
.hasMatch(mainListReply.upTop.content.message)) {
replyRegExp.hasMatch(mainListReply.upTop.content.message)) {
mainListReply.clearUpTop();
}
// replies
if (mainListReply.replies.isNotEmpty) {
mainListReply.replies.removeWhere((item) {
bool hasMatch = RegExp(banWordForReply, caseSensitive: false)
.hasMatch(item.content.message);
bool hasMatch = replyRegExp.hasMatch(item.content.message);
// remove subreplies
if (hasMatch.not) {
if (item.replies.isNotEmpty) {
item.replies.removeWhere((item) =>
RegExp(banWordForReply, caseSensitive: false)
.hasMatch(item.content.message));
item.replies.removeWhere(
(item) => replyRegExp.hasMatch(item.content.message));
}
}
return hasMatch;
@@ -222,9 +218,9 @@ class ReplyHttp {
required int root,
required int pageNum,
required int type,
required String banWordForReply,
required bool antiGoodsReply,
bool? isCheck,
bool? filterBanWord,
}) async {
var res = await Request().get(
Api.replyReplyList,
@@ -240,11 +236,10 @@ class ReplyHttp {
);
if (res.data['code'] == 0) {
ReplyReplyData replyData = ReplyReplyData.fromJson(res.data['data']);
if (banWordForReply.isNotEmpty) {
if (filterBanWord != false && replyRegExp.pattern.isNotEmpty) {
if (replyData.replies?.isNotEmpty == true) {
replyData.replies!.removeWhere((item) =>
RegExp(banWordForReply, caseSensitive: false)
.hasMatch(item.content?.message ?? ''));
replyData.replies!.removeWhere(
(item) => replyRegExp.hasMatch(item.content?.message ?? ''));
}
}
if (antiGoodsReply) {
@@ -268,7 +263,6 @@ class ReplyHttp {
required int root,
required int rpid,
required CursorReq cursor,
required String banWordForReply,
required bool antiGoodsReply,
}) async {
dynamic res = await GrpcRepo.detailList(
@@ -280,11 +274,10 @@ class ReplyHttp {
);
if (res['status']) {
DetailListReply detailListReply = res['data'];
if (banWordForReply.isNotEmpty) {
if (replyRegExp.pattern.isNotEmpty) {
if (detailListReply.root.replies.isNotEmpty) {
detailListReply.root.replies.removeWhere((item) =>
RegExp(banWordForReply, caseSensitive: false)
.hasMatch(item.content.message));
detailListReply.root.replies.removeWhere(
(item) => replyRegExp.hasMatch(item.content.message));
}
}
if (antiGoodsReply) {
@@ -304,7 +297,6 @@ class ReplyHttp {
required int root,
required int rpid,
required CursorReq cursor,
required String banWordForReply,
required bool antiGoodsReply,
}) async {
dynamic res = await GrpcRepo.dialogList(
@@ -316,11 +308,10 @@ class ReplyHttp {
);
if (res['status']) {
DialogListReply dialogListReply = res['data'];
if (banWordForReply.isNotEmpty) {
if (replyRegExp.pattern.isNotEmpty) {
if (dialogListReply.replies.isNotEmpty) {
dialogListReply.replies.removeWhere((item) =>
RegExp(banWordForReply, caseSensitive: false)
.hasMatch(item.content.message));
dialogListReply.replies.removeWhere(
(item) => replyRegExp.hasMatch(item.content.message));
}
}
if (antiGoodsReply) {

View File

@@ -32,6 +32,8 @@ import 'login.dart';
class VideoHttp {
static bool enableRcmdDynamic =
GStorage.setting.get(SettingBoxKey.enableRcmdDynamic, defaultValue: true);
static RegExp zoneRegExp =
RegExp(GStorage.banWordForZone, caseSensitive: false);
// 首页推荐视频
static Future<LoadingState> rcmdVideoList(
@@ -145,10 +147,8 @@ class VideoHttp {
(!enableRcmdDynamic ? i['card_goto'] != 'picture' : true) &&
(i['args'] != null &&
!blackMidsList.contains(i['args']['up_id']))) {
String banWordForZone = GStorage.banWordForZone;
if (banWordForZone.isNotEmpty &&
RegExp(banWordForZone, caseSensitive: false)
.hasMatch(i['args']['rname'])) {
if (zoneRegExp.pattern.isNotEmpty &&
zoneRegExp.hasMatch(i['args']['rname'])) {
continue;
}
RecVideoItemAppModel videoItem = RecVideoItemAppModel.fromJson(i);
@@ -178,10 +178,8 @@ class VideoHttp {
!RecommendFilter.filterTitle(i['title']) &&
!RecommendFilter.filterLikeRatio(
i['stat']['like'], i['stat']['view'])) {
String banWordForZone = GStorage.banWordForZone;
if (banWordForZone.isNotEmpty &&
RegExp(banWordForZone, caseSensitive: false)
.hasMatch(i['tname'])) {
if (zoneRegExp.pattern.isNotEmpty &&
zoneRegExp.hasMatch(i['tname'])) {
continue;
}
list.add(HotVideoItemModel.fromJson(i));
@@ -1096,10 +1094,8 @@ class VideoHttp {
!RecommendFilter.filterTitle(i['title']) &&
!RecommendFilter.filterLikeRatio(
i['stat']['like'], i['stat']['view'])) {
String banWordForZone = GStorage.banWordForZone;
if (banWordForZone.isNotEmpty &&
RegExp(banWordForZone, caseSensitive: false)
.hasMatch(i['tname'])) {
if (zoneRegExp.pattern.isNotEmpty &&
zoneRegExp.hasMatch(i['tname'])) {
continue;
}
list.add(HotVideoItemModel.fromJson(i));

View File

@@ -37,7 +37,6 @@ abstract class ReplyController extends CommonController {
late Rx<Mode> mode = Mode.MAIN_LIST_HOT.obs;
late bool hasUpTop = false;
late final banWordForReply = GStorage.banWordForReply;
late final antiGoodsReply = GStorage.antiGoodsReply;
// comment antifraud
@@ -384,7 +383,7 @@ abstract class ReplyController extends CommonController {
type: replyType,
sort: ReplySortType.time.index,
page: 1,
banWordForReply: '',
enableFilter: false,
antiGoodsReply: false,
);
if (context.mounted.not) return;
@@ -412,7 +411,7 @@ abstract class ReplyController extends CommonController {
root: rpid ?? replyId,
pageNum: 1,
type: replyType,
banWordForReply: '',
filterBanWord: false,
antiGoodsReply: false,
);
if (context.mounted.not) return;
@@ -433,7 +432,7 @@ abstract class ReplyController extends CommonController {
root: rpid ?? replyId,
pageNum: 1,
type: replyType,
banWordForReply: '',
filterBanWord: false,
isCheck: true,
antiGoodsReply: false,
);
@@ -470,7 +469,7 @@ https://api.bilibili.com/x/v2/reply/reply?oid=$oid&pn=1&ps=20&root=${rpid ?? rep
root: rpid ?? replyId,
pageNum: i,
type: replyType,
banWordForReply: '',
filterBanWord: false,
isCheck: true,
antiGoodsReply: false,
);
@@ -505,7 +504,7 @@ https://api.bilibili.com/x/v2/reply/reply?oid=$oid&pn=1&ps=20&root=${rpid ?? rep
root: rpid ?? replyId,
pageNum: i,
type: replyType,
banWordForReply: '',
filterBanWord: false,
isCheck: true,
antiGoodsReply: false,
);

View File

@@ -54,7 +54,6 @@ class DynamicDetailController extends ReplyController {
next: cursor?.next ?? $fixnum.Int64(0),
mode: mode.value,
),
banWordForReply: banWordForReply,
antiGoodsReply: antiGoodsReply,
)
: ReplyHttp.replyList(
@@ -64,7 +63,6 @@ class DynamicDetailController extends ReplyController {
type: type,
sort: sortType.value.index,
page: currentPage,
banWordForReply: banWordForReply,
antiGoodsReply: antiGoodsReply,
);
}

View File

@@ -85,7 +85,6 @@ class HtmlRenderController extends ReplyController {
next: cursor?.next ?? $fixnum.Int64(0),
mode: mode.value,
),
banWordForReply: banWordForReply,
antiGoodsReply: antiGoodsReply,
)
: ReplyHttp.replyList(
@@ -95,7 +94,6 @@ class HtmlRenderController extends ReplyController {
type: type,
sort: sortType.value.index,
page: currentPage,
banWordForReply: banWordForReply,
antiGoodsReply: antiGoodsReply,
);
}

View File

@@ -4,6 +4,8 @@ import 'dart:math';
import 'package:PiliPlus/common/widgets/refresh_indicator.dart'
show kDragContainerExtentPercentage, displacement;
import 'package:PiliPlus/http/interceptor.dart';
import 'package:PiliPlus/http/reply.dart';
import 'package:PiliPlus/http/video.dart';
import 'package:PiliPlus/models/common/audio_normalization.dart';
import 'package:PiliPlus/models/common/dynamic_badge_mode.dart';
import 'package:PiliPlus/models/common/dynamics_type.dart';
@@ -2320,6 +2322,16 @@ SettingsModel getBanwordModel({
await GStorage.setting.put(key, banWord);
setState();
SmartDialog.showToast('已保存');
if (key == SettingBoxKey.banWordForReply) {
ReplyHttp.replyRegExp =
RegExp(banWord, caseSensitive: false);
} else if (key == SettingBoxKey.banWordForRecommend) {
RecommendFilter.rcmdRegExp =
RegExp(banWord, caseSensitive: false);
} else if (key == SettingBoxKey.banWordForZone) {
VideoHttp.zoneRegExp =
RegExp(banWord, caseSensitive: false);
}
},
),
],

View File

@@ -23,7 +23,6 @@ class VideoReplyController extends ReplyController {
next: cursor?.next ?? $fixnum.Int64(0),
mode: mode.value,
),
banWordForReply: banWordForReply,
antiGoodsReply: antiGoodsReply,
)
: ReplyHttp.replyList(
@@ -33,7 +32,6 @@ class VideoReplyController extends ReplyController {
type: ReplyType.video.index,
sort: sortType.value.index,
page: currentPage,
banWordForReply: banWordForReply,
antiGoodsReply: antiGoodsReply,
);
}

View File

@@ -169,7 +169,6 @@ class VideoReplyReplyController extends ReplyController
next: cursor?.next,
mode: mode.value,
),
banWordForReply: banWordForReply,
antiGoodsReply: antiGoodsReply,
)
: GlobalData().grpcReply
@@ -182,7 +181,6 @@ class VideoReplyReplyController extends ReplyController
next: cursor?.next,
mode: mode.value,
),
banWordForReply: banWordForReply,
antiGoodsReply: antiGoodsReply,
)
: ReplyHttp.replyReplyList(
@@ -191,7 +189,6 @@ class VideoReplyReplyController extends ReplyController
root: rpid,
pageNum: currentPage,
type: replyType.index,
banWordForReply: banWordForReply,
antiGoodsReply: antiGoodsReply,
);

View File

@@ -8,7 +8,8 @@ class RecommendFilter {
static late int minLikeRatioForRecommend;
static late bool exemptFilterForFollowed;
static late bool applyFilterToRelatedVideos;
static late String banWords;
static RegExp rcmdRegExp =
RegExp(GStorage.banWordForRecommend, caseSensitive: false);
RecommendFilter() {
update();
@@ -23,7 +24,6 @@ class RecommendFilter {
setting.get(SettingBoxKey.minDurationForRcmd, defaultValue: 0);
minLikeRatioForRecommend =
setting.get(SettingBoxKey.minLikeRatioForRecommend, defaultValue: 0);
banWords = setting.get(SettingBoxKey.banWordForRecommend, defaultValue: '');
exemptFilterForFollowed =
setting.get(SettingBoxKey.exemptFilterForFollowed, defaultValue: true);
applyFilterToRelatedVideos = setting
@@ -67,8 +67,7 @@ class RecommendFilter {
if (exemptFilterForFollowed && isFollowed == true) {
return false;
}
if (banWords.isNotEmpty &&
RegExp(banWords, caseSensitive: false).hasMatch(title)) {
if (rcmdRegExp.pattern.isNotEmpty && rcmdRegExp.hasMatch(title)) {
return true;
}
return false;