Filter feeds using user patterns (#584)

This commit is contained in:
the1812 2021-03-29 17:57:56 +08:00
parent 679b89d88a
commit d7a6257c98
6 changed files with 107 additions and 87 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -387,6 +387,34 @@ class FeedsCardsManager extends EventTarget {
}
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[]> => {
if (!getUID()) {
return []
@ -397,8 +425,10 @@ export const getVideoFeeds = async (type: 'video' | 'bangumi' = 'video'): Promis
if (json.code !== 0) {
throw new Error(json.message)
}
const cards = (() => {
const jsonCards = json.data.cards as any[]
if (type === 'video') {
return _.uniqBy(json.data.cards.map(
return _.uniqBy(jsonCards.map(
(c: any): VideoCardInfo => {
const card = JSON.parse(c.card)
const topics = _.get(c, 'display.topic_info.topic_details', []).map(
@ -429,11 +459,11 @@ export const getVideoFeeds = async (type: 'video' | 'bangumi' = 'video'): Promis
playCount: formatCount(card.stat.view),
danmakuCount: formatCount(card.stat.danmaku),
watchlater: store.state.watchlaterList.includes(card.aid)
}
} as VideoCardInfo
}
), it => it.aid)
} else if (type === 'bangumi') {
return json.data.cards.map(
return jsonCards.map(
(c: any): VideoCardInfo => {
const card = JSON.parse(c.card)
return {
@ -453,13 +483,14 @@ export const getVideoFeeds = async (type: 'video' | 'bangumi' = 'video'): Promis
playCount: formatCount(card.play_count),
danmakuCount: formatCount(card.bullet_count),
watchlater: false,
}
} as VideoCardInfo
}
)
} else {
return []
}
})()
return cards.filter(c => !isVideoCardBlocked(c))
}
export const forEachFeedsCard = (callback: FeedsCardCallback) => {
@ -524,5 +555,7 @@ export default {
getVideoFeeds,
forEachFeedsCard,
addMenuItem,
isCardBlocked,
isVideoCardBlocked,
},
}

View File

@ -110,26 +110,9 @@ export default {
}
},
methods: {
updateCard(card: FeedsCard) {
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)
}
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) {
async updateCard(card: FeedsCard) {
const { isCardBlocked } = await import('../feeds-apis')
if (isCardBlocked(card)) {
card.element.classList.add('pattern-block')
} else {
card.element.classList.remove('pattern-block')

View File

@ -163,6 +163,7 @@ export class Activities extends NavbarComponent {
this.setNotifyCount(json.data.update_num)
}
async init() {
const { isVideoCardBlocked, isCardBlocked } = await import('../../../activity/feeds-apis')
Vue.component('activity-loading', {
template: /*html*/`
<div v-if="loading" class="loading">
@ -321,6 +322,7 @@ export class Activities extends NavbarComponent {
.sort((a, b) => {
return b.id > a.id ? 1 : -1
})
.filter(c => !isVideoCardBlocked(c))
if (cards.length === 0) {
this.hasMoreContent = false
}
@ -417,7 +419,7 @@ export class Activities extends NavbarComponent {
</div>
`,
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)
return {
title: cardJson.apiSeasonInfo.title,
@ -428,11 +430,12 @@ export class Activities extends NavbarComponent {
id: card.desc.dynamic_id_str,
get new() { return Activities.isNewID(this.id) },
}
}) as { id: string }[]
})
this.cards = _.uniqBy(cards.concat(this.cards), it => it.id)
.sort((a, b) => {
return b.id > a.id ? 1 : -1
})
.filter(c => !isCardBlocked({ text: c.epTitle, username: c.title }))
if (cards.length === 0) {
this.hasMoreContent = false
}
@ -479,7 +482,7 @@ export class Activities extends NavbarComponent {
</div>
`,
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)
return {
covers: cardJson.image_urls,
@ -493,11 +496,12 @@ export class Activities extends NavbarComponent {
id: card.desc.dynamic_id_str,
get new() { return Activities.isNewID(this.id) },
}
}) as { id: string }[]
})
this.cards = _.uniqBy(cards.concat(this.cards), it => it.id)
.sort((a, b) => {
return b.id > a.id ? 1 : -1
})
.filter(c => !isVideoCardBlocked(c))
if (cards.length === 0) {
this.hasMoreContent = false
}