forked from mirrors/iceshrimp
Laura Hausmann
ef3463e8dc
It's been shown that the current approach doesn't scale. This implementation should scale perfectly fine.
78 lines
2.9 KiB
TypeScript
78 lines
2.9 KiB
TypeScript
import Channel from "../channel.js";
|
|
import { fetchMeta } from "@/misc/fetch-meta.js";
|
|
import { isUserRelated } from "@/misc/is-user-related.js";
|
|
import type { Packed } from "@/misc/schema.js";
|
|
import { isFiltered } from "@/misc/is-filtered.js";
|
|
import { Note } from "@/models/entities/note.js";
|
|
|
|
export default class extends Channel {
|
|
public readonly chName = "localTimeline";
|
|
public static shouldShare = true;
|
|
public static requireCredential = false;
|
|
private withReplies: boolean;
|
|
|
|
constructor(id: string, connection: Channel["connection"]) {
|
|
super(id, connection);
|
|
this.onNote = this.withPackedNote(this.onNote.bind(this));
|
|
}
|
|
|
|
public async init(params: any) {
|
|
const meta = await fetchMeta();
|
|
if (meta.disableLocalTimeline) {
|
|
if (this.user == null || !(this.user.isAdmin || this.user.isModerator))
|
|
return;
|
|
}
|
|
|
|
this.withReplies = params.withReplies as boolean;
|
|
|
|
// Subscribe events
|
|
this.subscriber.on("notesStream", this.onNote);
|
|
}
|
|
|
|
private async onNote(note: Packed<"Note">) {
|
|
if (note.user.host !== null) return;
|
|
if (note.visibility !== "public") return;
|
|
if (note.channelId != null && !this.followingChannels.has(note.channelId))
|
|
return;
|
|
|
|
// 関係ない返信は除外
|
|
if (note.reply && !this.withReplies) {
|
|
const reply = note.reply;
|
|
// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
|
|
if (
|
|
reply.userId !== this.user!.id &&
|
|
note.userId !== this.user!.id &&
|
|
reply.userId !== note.userId
|
|
)
|
|
return;
|
|
}
|
|
|
|
// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
|
|
if (isUserRelated(note, this.muting)) return;
|
|
// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
|
|
if (isUserRelated(note, this.blocking)) return;
|
|
|
|
if (note.renote && !note.text && this.renoteMuting.has(note.userId)) return;
|
|
|
|
// 流れてきたNoteがミュートすべきNoteだったら無視する
|
|
// TODO: 将来的には、単にMutedNoteテーブルにレコードがあるかどうかで判定したい(以下の理由により難しそうではある)
|
|
// 現状では、ワードミュートにおけるMutedNoteレコードの追加処理はストリーミングに流す処理と並列で行われるため、
|
|
// レコードが追加されるNoteでも追加されるより先にここのストリーミングの処理に到達することが起こる。
|
|
// そのためレコードが存在するかのチェックでは不十分なので、改めてgetWordHardMuteを呼んでいる
|
|
if (
|
|
this.userProfile &&
|
|
(await isFiltered(note as unknown as Note, this.user, this.userProfile))
|
|
)
|
|
return;
|
|
|
|
this.connection.cacheNote(note);
|
|
|
|
this.send("note", note);
|
|
}
|
|
|
|
public dispose() {
|
|
// Unsubscribe events
|
|
this.subscriber.off("notesStream", this.onNote);
|
|
}
|
|
}
|