Bilibili-Evolved/registry/lib/components/style/clear-home/index.ts

268 lines
5.8 KiB
TypeScript

import type { OptionsOfMetadata } from '@/components/define'
import { defineComponentMetadata, defineOptionsMetadata } from '@/components/define'
import type { ComponentEntry } from '@/components/types'
import { addComponentListener } from '@/core/settings'
type Options = OptionsOfMetadata<typeof options>
const removeBadgeList: string[] = []
let removeLive = false
let removeAds = true
const options = defineOptionsMetadata({
广: {
displayName: '广告',
defaultValue: true,
},
: {
displayName: '番剧',
defaultValue: true,
},
: {
displayName: '电影',
defaultValue: true,
},
: {
displayName: '国创',
defaultValue: true,
},
: {
displayName: '电视剧',
defaultValue: true,
},
: {
displayName: '综艺',
defaultValue: true,
},
: {
displayName: '纪录片',
defaultValue: true,
},
: {
displayName: '动画',
defaultValue: true,
},
: {
displayName: '游戏',
defaultValue: true,
},
: {
displayName: '鬼畜',
defaultValue: true,
},
: {
displayName: '音乐',
defaultValue: true,
},
: {
displayName: '舞蹈',
defaultValue: true,
},
: {
displayName: '影视',
defaultValue: true,
},
: {
displayName: '娱乐',
defaultValue: true,
},
: {
displayName: '知识',
defaultValue: true,
},
: {
displayName: '科技',
defaultValue: true,
},
: {
displayName: '资讯',
defaultValue: true,
},
: {
displayName: '美食',
defaultValue: true,
},
: {
displayName: '生活',
defaultValue: true,
},
: {
displayName: '汽车',
defaultValue: true,
},
: {
displayName: '时尚',
defaultValue: true,
},
: {
displayName: '运动',
defaultValue: true,
},
: {
displayName: '动物圈',
defaultValue: true,
},
VLOG: {
displayName: 'VLOG',
defaultValue: true,
},
: {
displayName: '搞笑',
defaultValue: true,
},
: {
displayName: '单机游戏',
defaultValue: true,
},
UP主: {
displayName: '虚拟UP主',
defaultValue: true,
},
: {
displayName: '公益',
defaultValue: true,
},
: {
displayName: '公开课',
defaultValue: true,
},
: {
displayName: '专栏',
defaultValue: true,
},
: {
displayName: '直播',
defaultValue: true,
},
: {
displayName: '赛事',
defaultValue: true,
},
: {
displayName: '活动',
defaultValue: true,
},
: {
displayName: '课堂',
defaultValue: true,
},
: {
displayName: '社区中心',
defaultValue: true,
},
: {
displayName: '新歌热榜',
defaultValue: true,
},
: {
displayName: '漫画',
defaultValue: true,
},
})
function cardClear(mutationsList: HTMLElement[]) {
for (const mutation of mutationsList) {
if (!mutation.classList) {
continue
}
if (mutation.classList.contains('floor-single-card')) {
const badge = mutation.querySelector('.badge').textContent
if (badge && removeBadgeList.includes(badge)) {
mutation.remove()
}
} else if (mutation.classList.contains('bili-live-card')) {
if (removeLive) {
mutation.remove()
}
} else if (
mutation.classList.contains('bili-video-card') ||
mutation.classList.contains('feed-card')
) {
if (
removeAds &&
(mutation.querySelector('.bili-video-card__info--ad') ||
mutation.querySelector('.bili-video-card__info--creative-ad'))
) {
mutation.remove()
}
}
}
}
function cardFilter(mutationsList: MutationRecord[]) {
const filteredList: HTMLElement[] = []
for (const mutation of mutationsList) {
const mutationTarget = mutation.target as HTMLElement
if (
(mutationTarget.classList && mutationTarget.classList.contains('carousel-transform')) ||
mutationTarget.tagName === 'SPAN'
) {
continue
}
if (mutation.addedNodes.length > 0) {
for (const node of mutation.addedNodes) {
const nodeTarget = node as HTMLElement
if (
nodeTarget.nodeName === '#text' ||
(nodeTarget.classList && nodeTarget.classList.contains('bili-watch-later'))
) {
continue
}
filteredList.push(nodeTarget)
}
} else {
continue
}
}
if (filteredList.length > 0) {
cardClear(filteredList)
}
}
const clearHome: ComponentEntry<Options> = async ({ metadata, settings }) => {
const container = document.querySelector(
'main > .feed2 > .recommended-container_floor-aside > .container',
)
if (!container) {
return
}
const config = { childList: true }
const observer = new MutationObserver(cardFilter)
observer.observe(container, config)
Object.keys(settings.options).forEach(disableType => {
addComponentListener(
`${metadata.name}.${disableType}`,
(value: boolean) => {
if (value) {
if (disableType === '广告') {
removeAds = true
return
}
removeBadgeList.push(disableType)
if (disableType === '直播') {
removeLive = true
}
}
},
true,
)
})
const containerList = container.children as unknown as HTMLElement[]
cardClear(containerList)
}
export const component = defineComponentMetadata({
name: 'clear-home',
author: {
name: 'RieN7',
link: 'https://github.com/rien7',
},
tags: [componentsTags.style],
displayName: '首页净化',
description: '删除首页特定类型的卡片',
entry: clearHome,
options,
})