From 589d77fba621392da79542cb45fdd1338db87942 Mon Sep 17 00:00:00 2001 From: festoney8 Date: Thu, 31 Oct 2024 00:29:20 +0800 Subject: [PATCH] feat: add dynamic content filter (#166) --- CHANGELOG.md | 4 ++ src/components/items/EditorComp.vue | 3 +- .../filters/variety/dynamic/pages/dynamic.ts | 63 ++++++++++++++++++- .../variety/dynamic/subFilters/black.ts | 2 + vite.config.ts | 2 +- 5 files changed, 70 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0eab59c4..c0011d04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## 4.0.5 + +- 新增:动态内容关键词过滤 + ## 4.0.4 - 移除:稍后再看列表页 双列模式 适配页面变化 diff --git a/src/components/items/EditorComp.vue b/src/components/items/EditorComp.vue index 8c09f492..894452d3 100644 --- a/src/components/items/EditorComp.vue +++ b/src/components/items/EditorComp.vue @@ -79,7 +79,8 @@ const saveSuccess = ref(false) const editorData = ref('') const updateData = () => { - editorData.value = BiliCleanerStorage.get(item.id, []).join('\n') + '\n' // 末尾空行 + const val = BiliCleanerStorage.get(item.id, []).join('\n') + editorData.value = val ? val + '\n' : val // 末尾空行 } const saveData = () => { diff --git a/src/modules/filters/variety/dynamic/pages/dynamic.ts b/src/modules/filters/variety/dynamic/pages/dynamic.ts index 8fb4ec9e..a53cd07d 100644 --- a/src/modules/filters/variety/dynamic/pages/dynamic.ts +++ b/src/modules/filters/variety/dynamic/pages/dynamic.ts @@ -12,7 +12,7 @@ import { isPageDynamic } from '../../../../../utils/pageType' import { BiliCleanerStorage } from '../../../../../utils/storage' import { convertTimeToSec, orderedUniq, showEle, waitForEle } from '../../../../../utils/tool' import { coreCheck } from '../../../core/core' -import { DynDurationFilter, DynUploaderFilter, DynVideoTitleFilter } from '../subFilters/black' +import { DynContentFilter, DynDurationFilter, DynUploaderFilter, DynVideoTitleFilter } from '../subFilters/black' const GM_KEYS = { black: { @@ -28,6 +28,10 @@ const GM_KEYS = { statusKey: 'dyn-title-keyword-filter-status', valueKey: 'global-title-keyword-filter-value', }, + content: { + statusKey: 'dyn-content-keyword-filter-status', + valueKey: 'global-content-keyword-filter-value', + }, }, } @@ -47,6 +51,16 @@ const selectorFns = { title: (dyn: HTMLElement): SelectorResult => { return dyn.querySelector('.bili-dyn-card-video__title')?.textContent?.trim() }, + content: (dyn: HTMLElement): SelectorResult => { + return Array.from( + dyn.querySelectorAll( + '.bili-dyn-content :is(.dyn-card-opus__title, .bili-rich-text__content > span:not(.bili-rich-text-module.at))', + ), + ) + .map((v) => v?.textContent?.trim()) + .filter((v) => v?.trim()) + .join(' ') + }, } class DynamicFilterDynamic implements IMainFilter { @@ -56,12 +70,14 @@ class DynamicFilterDynamic implements IMainFilter { dynUploaderFilter = new DynUploaderFilter() dynDurationFilter = new DynDurationFilter() dynVideoTitleFilter = new DynVideoTitleFilter() + dynContentFilter = new DynContentFilter() init() { // 黑名单 this.dynUploaderFilter.setParam(BiliCleanerStorage.get(GM_KEYS.black.uploader.valueKey, [])) this.dynDurationFilter.setParam(BiliCleanerStorage.get(GM_KEYS.black.duration.valueKey, 0)) this.dynVideoTitleFilter.setParam(BiliCleanerStorage.get(GM_KEYS.black.title.valueKey, [])) + this.dynContentFilter.setParam(BiliCleanerStorage.get(GM_KEYS.black.content.valueKey, [])) } async check(mode?: 'full' | 'incr') { @@ -70,7 +86,12 @@ class DynamicFilterDynamic implements IMainFilter { } let revertAll = false if ( - !(this.dynUploaderFilter.isEnable || this.dynDurationFilter.isEnable || this.dynVideoTitleFilter.isEnable) + !( + this.dynUploaderFilter.isEnable || + this.dynDurationFilter.isEnable || + this.dynVideoTitleFilter.isEnable || + this.dynContentFilter.isEnable + ) ) { revertAll = true } @@ -101,6 +122,7 @@ class DynamicFilterDynamic implements IMainFilter { `uploader: ${selectorFns.uploader(v)}`, `title: ${selectorFns.title(v)}`, `duration: ${selectorFns.duration(v)}`, + `content: ${selectorFns.content(v)}`, ].join('\n'), ) }) @@ -111,6 +133,7 @@ class DynamicFilterDynamic implements IMainFilter { this.dynUploaderFilter.isEnable && blackPairs.push([this.dynUploaderFilter, selectorFns.uploader]) this.dynDurationFilter.isEnable && blackPairs.push([this.dynDurationFilter, selectorFns.duration]) this.dynVideoTitleFilter.isEnable && blackPairs.push([this.dynVideoTitleFilter, selectorFns.title]) + this.dynContentFilter.isEnable && blackPairs.push([this.dynContentFilter, selectorFns.content]) // 检测 const blackCnt = await coreCheck(dyns, true, blackPairs, []) @@ -267,6 +290,42 @@ export const dynamicFilterDynamicGroups: Group[] = [ }, ], }, + { + name: '动态内容过滤', + items: [ + { + type: 'switch', + id: GM_KEYS.black.content.statusKey, + name: '启用 动态内容关键词过滤', + description: ['包含被转发动态内容', '不含动态内视频信息'], + defaultEnable: false, + noStyle: true, + enableFn: () => { + mainFilter.dynContentFilter.enable() + mainFilter.checkFull() + }, + disableFn: () => { + mainFilter.dynContentFilter.disable() + mainFilter.checkFull() + }, + }, + { + type: 'editor', + id: GM_KEYS.black.content.valueKey, + name: '编辑 动态内容关键词黑名单', + editorTitle: '动态内容关键词 黑名单', + editorDescription: [ + '每行一个关键词或正则,不区分大小写', + '请勿使用过于激进的关键词或正则', + '正则默认 iu 模式,无需 flag,语法:/abc|\\d+/', + ], + saveFn: async () => { + mainFilter.dynContentFilter.setParam(BiliCleanerStorage.get(GM_KEYS.black.content.valueKey, [])) + mainFilter.checkFull() + }, + }, + ], + }, ] // 右键菜单handler diff --git a/src/modules/filters/variety/dynamic/subFilters/black.ts b/src/modules/filters/variety/dynamic/subFilters/black.ts index fbf00e71..f2c3ab4f 100644 --- a/src/modules/filters/variety/dynamic/subFilters/black.ts +++ b/src/modules/filters/variety/dynamic/subFilters/black.ts @@ -7,3 +7,5 @@ export class DynUploaderFilter extends StringFilter {} export class DynDurationFilter extends NumberMinFilter {} export class DynVideoTitleFilter extends KeywordFilter {} + +export class DynContentFilter extends KeywordFilter {} diff --git a/vite.config.ts b/vite.config.ts index bc78e16c..ead12f17 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -19,7 +19,7 @@ export default defineConfig({ userscript: { name: 'bilibili 页面净化大师', namespace: 'http://tampermonkey.net/', - version: '4.0.4', + version: '4.0.5', description: '净化 B站/哔哩哔哩 页面,支持「精简功能、播放器净化、过滤视频、过滤评论、全站黑白名单」,提供 300+ 功能,定制自己的 B 站', author: 'festoney8',