diff --git a/lib/http/reply.dart b/lib/http/reply.dart index 61356147a..989bdf59a 100644 --- a/lib/http/reply.dart +++ b/lib/http/reply.dart @@ -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 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) { diff --git a/lib/http/video.dart b/lib/http/video.dart index 12115fc85..130b57f30 100644 --- a/lib/http/video.dart +++ b/lib/http/video.dart @@ -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 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)); diff --git a/lib/pages/common/reply_controller.dart b/lib/pages/common/reply_controller.dart index 88011702c..01c42e904 100644 --- a/lib/pages/common/reply_controller.dart +++ b/lib/pages/common/reply_controller.dart @@ -37,7 +37,6 @@ abstract class ReplyController extends CommonController { late Rx 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, ); diff --git a/lib/pages/dynamics/detail/controller.dart b/lib/pages/dynamics/detail/controller.dart index fa8994c8a..6636943b9 100644 --- a/lib/pages/dynamics/detail/controller.dart +++ b/lib/pages/dynamics/detail/controller.dart @@ -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, ); } diff --git a/lib/pages/html/controller.dart b/lib/pages/html/controller.dart index 16a802ff7..702f352ee 100644 --- a/lib/pages/html/controller.dart +++ b/lib/pages/html/controller.dart @@ -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, ); } diff --git a/lib/pages/setting/widgets/model.dart b/lib/pages/setting/widgets/model.dart index 1f0aa628f..6bb493469 100644 --- a/lib/pages/setting/widgets/model.dart +++ b/lib/pages/setting/widgets/model.dart @@ -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); + } }, ), ], diff --git a/lib/pages/video/detail/reply/controller.dart b/lib/pages/video/detail/reply/controller.dart index 189874ffa..593b466d6 100644 --- a/lib/pages/video/detail/reply/controller.dart +++ b/lib/pages/video/detail/reply/controller.dart @@ -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, ); } diff --git a/lib/pages/video/detail/reply_reply/controller.dart b/lib/pages/video/detail/reply_reply/controller.dart index 3f8ac7b44..4a474bf02 100644 --- a/lib/pages/video/detail/reply_reply/controller.dart +++ b/lib/pages/video/detail/reply_reply/controller.dart @@ -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, ); diff --git a/lib/utils/recommend_filter.dart b/lib/utils/recommend_filter.dart index 2ce2e5b54..109f632aa 100644 --- a/lib/utils/recommend_filter.dart +++ b/lib/utils/recommend_filter.dart @@ -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;