summaryrefslogtreecommitdiff
path: root/packages/frontend/src/scripts
diff options
context:
space:
mode:
authorHazel Koehler <acomputerdog@gmail.com>2024-05-02 20:31:34 -0400
committerHazel Koehler <acomputerdog@gmail.com>2024-05-02 20:31:34 -0400
commit26f89194324da565aafd5943284d83fed9dcde5f (patch)
tree9b80e922cbd3c38f65d5735f380e192311710dd2 /packages/frontend/src/scripts
parentmerge: handle non-ASCII emoji names (!464) (diff)
downloadsharkey-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.ts73
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();
}