diff options
| author | Hazel Koehler <acomputerdog@gmail.com> | 2024-05-02 20:31:34 -0400 |
|---|---|---|
| committer | Hazel Koehler <acomputerdog@gmail.com> | 2024-05-02 20:31:34 -0400 |
| commit | 26f89194324da565aafd5943284d83fed9dcde5f (patch) | |
| tree | 9b80e922cbd3c38f65d5735f380e192311710dd2 /packages/frontend/src/scripts | |
| parent | merge: handle non-ASCII emoji names (!464) (diff) | |
| download | sharkey-26f89194324da565aafd5943284d83fed9dcde5f.tar.gz sharkey-26f89194324da565aafd5943284d83fed9dcde5f.tar.bz2 sharkey-26f89194324da565aafd5943284d83fed9dcde5f.zip | |
feat: check polls and media for muted keywords
Diffstat (limited to 'packages/frontend/src/scripts')
| -rw-r--r-- | packages/frontend/src/scripts/check-word-mute.ts | 73 |
1 files changed, 48 insertions, 25 deletions
diff --git a/packages/frontend/src/scripts/check-word-mute.ts b/packages/frontend/src/scripts/check-word-mute.ts index 67e896b4b9..6f3c6c40de 100644 --- a/packages/frontend/src/scripts/check-word-mute.ts +++ b/packages/frontend/src/scripts/check-word-mute.ts @@ -3,40 +3,63 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -export function checkWordMute(note: Record<string, any>, me: Record<string, any> | null | undefined, mutedWords: Array<string | string[]>): boolean { +import type { Note, MeDetailed } from "misskey-js/entities.js"; + +// TODO: this implementation is horribly inefficient. +// Each regex is validated (using a regex, ironically), transformed, and then parsed - for each note being checked. +// These regex objects should be cached somewhere. + +export function checkWordMute(note: Note, me: MeDetailed | null | undefined, mutedWords: Array<string | string[]>): boolean { // 自分自身 if (me && (note.userId === me.id)) return false; - if (mutedWords.length > 0) { - const text = ((note.cw ?? '') + '\n' + (note.text ?? '')).trim(); + if (mutedWords.length < 1) return false; - if (text === '') return false; + const text = getNoteText(note); + if (text === '') return false; - const matched = mutedWords.some(filter => { - if (Array.isArray(filter)) { - // Clean up - const filteredFilter = filter.filter(keyword => keyword !== ''); - if (filteredFilter.length === 0) return false; + return mutedWords.some(filter => { + if (Array.isArray(filter)) { + // Clean up + const filteredFilter = filter.filter(keyword => keyword !== ''); + if (filteredFilter.length === 0) return false; - return filteredFilter.every(keyword => text.includes(keyword)); - } else { - // represents RegExp - const regexp = filter.match(/^\/(.+)\/(.*)$/); + return filteredFilter.every(keyword => text.includes(keyword)); + } else { + // represents RegExp + const regexp = filter.match(/^\/(.+)\/(.*)$/); - // This should never happen due to input sanitisation. - if (!regexp) return false; + // This should never happen due to input sanitisation. + if (!regexp) return false; - try { - return new RegExp(regexp[1], regexp[2]).test(text); - } catch (err) { - // This should never happen due to input sanitisation. - return false; - } + try { + return new RegExp(regexp[1], regexp[2]).test(text); + } catch (err) { + // This should never happen due to input sanitisation. + return false; } - }); + } + }); +} + +function getNoteText(note: Note): string { + const textParts: string[] = []; + + if (note.cw) + textParts.push(note.cw); + + if (note.text) + textParts.push(note.text); + + if (note.files) + for (const file of note.files) + if (file.comment) + textParts.push(file.comment); - if (matched) return true; - } + if (note.poll) + for (const choice of note.poll.choices) + if (choice.text) + textParts.push(choice.text); - return false; + return textParts.join('\n').trim(); } |