mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
Filter feeds using user patterns (#584)
This commit is contained in:
parent
679b89d88a
commit
d7a6257c98
2
min/custom-navbar-activities.min.js
vendored
2
min/custom-navbar-activities.min.js
vendored
File diff suppressed because one or more lines are too long
2
min/feeds-apis.min.js
vendored
2
min/feeds-apis.min.js
vendored
File diff suppressed because one or more lines are too long
2
min/feeds-filter-card.vue.min.js
vendored
2
min/feeds-filter-card.vue.min.js
vendored
File diff suppressed because one or more lines are too long
@ -387,6 +387,34 @@ class FeedsCardsManager extends EventTarget {
|
|||||||
}
|
}
|
||||||
export const feedsCardsManager = new FeedsCardsManager()
|
export const feedsCardsManager = new FeedsCardsManager()
|
||||||
|
|
||||||
|
export const isCardBlocked = (card: Pick<FeedsCard, 'text' | 'username'>) => {
|
||||||
|
if (!settings.feedsFilter) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const testPattern = (pattern: Pattern, text: string) => {
|
||||||
|
if (pattern.startsWith('/') && pattern.endsWith('/')) {
|
||||||
|
return new RegExp(pattern.slice(1, pattern.length - 1)).test(text)
|
||||||
|
}
|
||||||
|
return text.includes(pattern)
|
||||||
|
}
|
||||||
|
return settings.feedsFilterPatterns.some(pattern => {
|
||||||
|
const upNameMatch = pattern.match(/(.+) up:([^ ]+)/)
|
||||||
|
if (upNameMatch) {
|
||||||
|
return (
|
||||||
|
testPattern(upNameMatch[1], card.text) &&
|
||||||
|
testPattern(upNameMatch[2], card.username)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return testPattern(pattern, card.text)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export const isVideoCardBlocked = (card: Pick<VideoCardInfo, 'title' | 'dynamic' | 'upName'>) => {
|
||||||
|
return isCardBlocked({
|
||||||
|
text: card.title + (card.dynamic ?? ''),
|
||||||
|
username: card.upName,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export const getVideoFeeds = async (type: 'video' | 'bangumi' = 'video'): Promise<VideoCardInfo[]> => {
|
export const getVideoFeeds = async (type: 'video' | 'bangumi' = 'video'): Promise<VideoCardInfo[]> => {
|
||||||
if (!getUID()) {
|
if (!getUID()) {
|
||||||
return []
|
return []
|
||||||
@ -397,69 +425,72 @@ export const getVideoFeeds = async (type: 'video' | 'bangumi' = 'video'): Promis
|
|||||||
if (json.code !== 0) {
|
if (json.code !== 0) {
|
||||||
throw new Error(json.message)
|
throw new Error(json.message)
|
||||||
}
|
}
|
||||||
if (type === 'video') {
|
const cards = (() => {
|
||||||
return _.uniqBy(json.data.cards.map(
|
const jsonCards = json.data.cards as any[]
|
||||||
(c: any): VideoCardInfo => {
|
if (type === 'video') {
|
||||||
const card = JSON.parse(c.card)
|
return _.uniqBy(jsonCards.map(
|
||||||
const topics = _.get(c, 'display.topic_info.topic_details', []).map(
|
(c: any): VideoCardInfo => {
|
||||||
(it: any) => {
|
const card = JSON.parse(c.card)
|
||||||
return {
|
const topics = _.get(c, 'display.topic_info.topic_details', []).map(
|
||||||
id: it.topic_id,
|
(it: any) => {
|
||||||
name: it.topic_name
|
return {
|
||||||
|
id: it.topic_id,
|
||||||
|
name: it.topic_name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
)
|
return {
|
||||||
return {
|
id: c.desc.dynamic_id_str,
|
||||||
id: c.desc.dynamic_id_str,
|
aid: card.aid,
|
||||||
aid: card.aid,
|
bvid: c.desc.bvid || card.bvid,
|
||||||
bvid: c.desc.bvid || card.bvid,
|
title: card.title,
|
||||||
title: card.title,
|
upID: c.desc.user_profile.info.uid,
|
||||||
upID: c.desc.user_profile.info.uid,
|
upName: c.desc.user_profile.info.uname,
|
||||||
upName: c.desc.user_profile.info.uname,
|
upFaceUrl: c.desc.user_profile.info.face,
|
||||||
upFaceUrl: c.desc.user_profile.info.face,
|
coverUrl: card.pic,
|
||||||
coverUrl: card.pic,
|
description: card.desc,
|
||||||
description: card.desc,
|
timestamp: c.timestamp,
|
||||||
timestamp: c.timestamp,
|
time: new Date(c.timestamp * 1000),
|
||||||
time: new Date(c.timestamp * 1000),
|
topics,
|
||||||
topics,
|
dynamic: card.dynamic,
|
||||||
dynamic: card.dynamic,
|
like: formatCount(c.desc.like),
|
||||||
like: formatCount(c.desc.like),
|
duration: card.duration,
|
||||||
duration: card.duration,
|
durationText: formatDuration(card.duration, 0),
|
||||||
durationText: formatDuration(card.duration, 0),
|
playCount: formatCount(card.stat.view),
|
||||||
playCount: formatCount(card.stat.view),
|
danmakuCount: formatCount(card.stat.danmaku),
|
||||||
danmakuCount: formatCount(card.stat.danmaku),
|
watchlater: store.state.watchlaterList.includes(card.aid)
|
||||||
watchlater: store.state.watchlaterList.includes(card.aid)
|
} as VideoCardInfo
|
||||||
}
|
}
|
||||||
}
|
), it => it.aid)
|
||||||
), it => it.aid)
|
} else if (type === 'bangumi') {
|
||||||
} else if (type === 'bangumi') {
|
return jsonCards.map(
|
||||||
return json.data.cards.map(
|
(c: any): VideoCardInfo => {
|
||||||
(c: any): VideoCardInfo => {
|
const card = JSON.parse(c.card)
|
||||||
const card = JSON.parse(c.card)
|
return {
|
||||||
return {
|
id: c.desc.dynamic_id_str,
|
||||||
id: c.desc.dynamic_id_str,
|
aid: card.aid,
|
||||||
aid: card.aid,
|
bvid: c.desc.bvid || card.bvid,
|
||||||
bvid: c.desc.bvid || card.bvid,
|
epID: card.episode_id,
|
||||||
epID: card.episode_id,
|
title: card.new_desc,
|
||||||
title: card.new_desc,
|
upName: card.apiSeasonInfo.title,
|
||||||
upName: card.apiSeasonInfo.title,
|
upFaceUrl: card.apiSeasonInfo.cover,
|
||||||
upFaceUrl: card.apiSeasonInfo.cover,
|
coverUrl: card.cover,
|
||||||
coverUrl: card.cover,
|
description: '',
|
||||||
description: '',
|
timestamp: c.timestamp,
|
||||||
timestamp: c.timestamp,
|
time: new Date(c.timestamp * 1000),
|
||||||
time: new Date(c.timestamp * 1000),
|
like: formatCount(c.desc.like),
|
||||||
like: formatCount(c.desc.like),
|
durationText: '',
|
||||||
durationText: '',
|
playCount: formatCount(card.play_count),
|
||||||
playCount: formatCount(card.play_count),
|
danmakuCount: formatCount(card.bullet_count),
|
||||||
danmakuCount: formatCount(card.bullet_count),
|
watchlater: false,
|
||||||
watchlater: false,
|
} as VideoCardInfo
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
)
|
} else {
|
||||||
|
return []
|
||||||
} else {
|
}
|
||||||
return []
|
})()
|
||||||
}
|
return cards.filter(c => !isVideoCardBlocked(c))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const forEachFeedsCard = (callback: FeedsCardCallback) => {
|
export const forEachFeedsCard = (callback: FeedsCardCallback) => {
|
||||||
@ -524,5 +555,7 @@ export default {
|
|||||||
getVideoFeeds,
|
getVideoFeeds,
|
||||||
forEachFeedsCard,
|
forEachFeedsCard,
|
||||||
addMenuItem,
|
addMenuItem,
|
||||||
|
isCardBlocked,
|
||||||
|
isVideoCardBlocked,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -110,26 +110,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateCard(card: FeedsCard) {
|
async updateCard(card: FeedsCard) {
|
||||||
const testPattern = (pattern: Pattern, text: string) => {
|
const { isCardBlocked } = await import('../feeds-apis')
|
||||||
if (pattern.startsWith('/') && pattern.endsWith('/')) {
|
if (isCardBlocked(card)) {
|
||||||
return new RegExp(pattern.slice(1, pattern.length - 1)).test(text)
|
|
||||||
}
|
|
||||||
return text.includes(pattern)
|
|
||||||
}
|
|
||||||
const block: boolean = (() => {
|
|
||||||
return settings.feedsFilterPatterns.some(pattern => {
|
|
||||||
const upNameMatch = pattern.match(/(.+) up:([^ ]+)/)
|
|
||||||
if (upNameMatch) {
|
|
||||||
return (
|
|
||||||
testPattern(upNameMatch[1], card.text) &&
|
|
||||||
testPattern(upNameMatch[2], card.username)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return testPattern(pattern, card.text)
|
|
||||||
})
|
|
||||||
})()
|
|
||||||
if (block) {
|
|
||||||
card.element.classList.add('pattern-block')
|
card.element.classList.add('pattern-block')
|
||||||
} else {
|
} else {
|
||||||
card.element.classList.remove('pattern-block')
|
card.element.classList.remove('pattern-block')
|
||||||
|
|||||||
@ -163,6 +163,7 @@ export class Activities extends NavbarComponent {
|
|||||||
this.setNotifyCount(json.data.update_num)
|
this.setNotifyCount(json.data.update_num)
|
||||||
}
|
}
|
||||||
async init() {
|
async init() {
|
||||||
|
const { isVideoCardBlocked, isCardBlocked } = await import('../../../activity/feeds-apis')
|
||||||
Vue.component('activity-loading', {
|
Vue.component('activity-loading', {
|
||||||
template: /*html*/`
|
template: /*html*/`
|
||||||
<div v-if="loading" class="loading">
|
<div v-if="loading" class="loading">
|
||||||
@ -321,6 +322,7 @@ export class Activities extends NavbarComponent {
|
|||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
return b.id > a.id ? 1 : -1
|
return b.id > a.id ? 1 : -1
|
||||||
})
|
})
|
||||||
|
.filter(c => !isVideoCardBlocked(c))
|
||||||
if (cards.length === 0) {
|
if (cards.length === 0) {
|
||||||
this.hasMoreContent = false
|
this.hasMoreContent = false
|
||||||
}
|
}
|
||||||
@ -417,7 +419,7 @@ export class Activities extends NavbarComponent {
|
|||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
handleJson: async function (json) {
|
handleJson: async function (json) {
|
||||||
const cards = _.get(json, 'data.cards', []).map((card: any) => {
|
const cards = _.get<any[]>(json, 'data.cards', []).map((card: any) => {
|
||||||
const cardJson = JSON.parse(card.card)
|
const cardJson = JSON.parse(card.card)
|
||||||
return {
|
return {
|
||||||
title: cardJson.apiSeasonInfo.title,
|
title: cardJson.apiSeasonInfo.title,
|
||||||
@ -428,11 +430,12 @@ export class Activities extends NavbarComponent {
|
|||||||
id: card.desc.dynamic_id_str,
|
id: card.desc.dynamic_id_str,
|
||||||
get new() { return Activities.isNewID(this.id) },
|
get new() { return Activities.isNewID(this.id) },
|
||||||
}
|
}
|
||||||
}) as { id: string }[]
|
})
|
||||||
this.cards = _.uniqBy(cards.concat(this.cards), it => it.id)
|
this.cards = _.uniqBy(cards.concat(this.cards), it => it.id)
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
return b.id > a.id ? 1 : -1
|
return b.id > a.id ? 1 : -1
|
||||||
})
|
})
|
||||||
|
.filter(c => !isCardBlocked({ text: c.epTitle, username: c.title }))
|
||||||
if (cards.length === 0) {
|
if (cards.length === 0) {
|
||||||
this.hasMoreContent = false
|
this.hasMoreContent = false
|
||||||
}
|
}
|
||||||
@ -479,7 +482,7 @@ export class Activities extends NavbarComponent {
|
|||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
handleJson: async function (json) {
|
handleJson: async function (json) {
|
||||||
const cards = _.get(json, 'data.cards', []).map((card: any) => {
|
const cards = _.get<any[]>(json, 'data.cards', []).map((card: any) => {
|
||||||
const cardJson = JSON.parse(card.card)
|
const cardJson = JSON.parse(card.card)
|
||||||
return {
|
return {
|
||||||
covers: cardJson.image_urls,
|
covers: cardJson.image_urls,
|
||||||
@ -493,11 +496,12 @@ export class Activities extends NavbarComponent {
|
|||||||
id: card.desc.dynamic_id_str,
|
id: card.desc.dynamic_id_str,
|
||||||
get new() { return Activities.isNewID(this.id) },
|
get new() { return Activities.isNewID(this.id) },
|
||||||
}
|
}
|
||||||
}) as { id: string }[]
|
})
|
||||||
this.cards = _.uniqBy(cards.concat(this.cards), it => it.id)
|
this.cards = _.uniqBy(cards.concat(this.cards), it => it.id)
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
return b.id > a.id ? 1 : -1
|
return b.id > a.id ? 1 : -1
|
||||||
})
|
})
|
||||||
|
.filter(c => !isVideoCardBlocked(c))
|
||||||
if (cards.length === 0) {
|
if (cards.length === 0) {
|
||||||
this.hasMoreContent = false
|
this.hasMoreContent = false
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user