Deal with withPackedNote(onNote) types in stream channels

This commit is contained in:
Michcio 2022-09-25 18:42:35 +02:00
parent 56f577ddb8
commit b1d133c3d5
8 changed files with 29 additions and 15 deletions

View file

@ -62,7 +62,7 @@ export default abstract class Channel {
}); });
} }
protected withPackedNote(callback: (note: Packed<'Note'>) => void): (Note) => void { protected withPackedNote(callback: (note: Packed<'Note'>) => Promise<void>): (note: Note) => Promise<void> {
return async (note: Note) => { return async (note: Note) => {
try { try {
// because `note` was previously JSON.stringify'ed, the fields that // because `note` was previously JSON.stringify'ed, the fields that

View file

@ -2,6 +2,7 @@ import { Users } from '@/models/index.js';
import { isUserRelated } from '@/misc/is-user-related.js'; import { isUserRelated } from '@/misc/is-user-related.js';
import { User } from '@/models/entities/user.js'; import { User } from '@/models/entities/user.js';
import { Packed } from '@/misc/schema.js'; import { Packed } from '@/misc/schema.js';
import { Note } from '@/models/entities/note.js';
import { StreamMessages } from '../types.js'; import { StreamMessages } from '../types.js';
import Channel from '../channel.js'; import Channel from '../channel.js';
@ -12,10 +13,11 @@ export default class extends Channel {
private channelId: string; private channelId: string;
private typers: Record<User['id'], Date> = {}; private typers: Record<User['id'], Date> = {};
private emitTypersIntervalId: ReturnType<typeof setInterval>; private emitTypersIntervalId: ReturnType<typeof setInterval>;
private onNote: (note: Note) => Promise<void>;
constructor(id: string, connection: Channel['connection']) { constructor(id: string, connection: Channel['connection']) {
super(id, connection); super(id, connection);
this.onNote = this.withPackedNote(this.onNote.bind(this)); this.onNote = this.withPackedNote(this.onPackedNote.bind(this));
} }
public async init(params: any) { public async init(params: any) {
@ -27,7 +29,7 @@ export default class extends Channel {
this.emitTypersIntervalId = setInterval(this.emitTypers, 5000); this.emitTypersIntervalId = setInterval(this.emitTypers, 5000);
} }
private async onNote(note: Packed<'Note'>) { private async onPackedNote(note: Packed<'Note'>): Promise<void> {
if (note.channelId !== this.channelId) return; if (note.channelId !== this.channelId) return;
// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する // 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する

View file

@ -3,16 +3,18 @@ import { checkWordMute } from '@/misc/check-word-mute.js';
import { isInstanceMuted } from '@/misc/is-instance-muted.js'; import { isInstanceMuted } from '@/misc/is-instance-muted.js';
import { isUserRelated } from '@/misc/is-user-related.js'; import { isUserRelated } from '@/misc/is-user-related.js';
import { Packed } from '@/misc/schema.js'; import { Packed } from '@/misc/schema.js';
import { Note } from '@/models/entities/note.js';
import Channel from '../channel.js'; import Channel from '../channel.js';
export default class extends Channel { export default class extends Channel {
public readonly chName = 'globalTimeline'; public readonly chName = 'globalTimeline';
public static shouldShare = true; public static shouldShare = true;
public static requireCredential = false; public static requireCredential = false;
private onNote: (note: Note) => Promise<void>;
constructor(id: string, connection: Channel['connection']) { constructor(id: string, connection: Channel['connection']) {
super(id, connection); super(id, connection);
this.onNote = this.withPackedNote(this.onNote.bind(this)); this.onNote = this.withPackedNote(this.onPackedNote.bind(this));
} }
public async init(params: any) { public async init(params: any) {
@ -25,7 +27,7 @@ export default class extends Channel {
this.subscriber.on('notesStream', this.onNote); this.subscriber.on('notesStream', this.onNote);
} }
private async onNote(note: Packed<'Note'>) { private async onPackedNote(note: Packed<'Note'>): Promise<void> {
if (note.visibility !== 'public') return; if (note.visibility !== 'public') return;
if (note.channelId != null) return; if (note.channelId != null) return;

View file

@ -1,6 +1,7 @@
import { normalizeForSearch } from '@/misc/normalize-for-search.js'; import { normalizeForSearch } from '@/misc/normalize-for-search.js';
import { isUserRelated } from '@/misc/is-user-related.js'; import { isUserRelated } from '@/misc/is-user-related.js';
import { Packed } from '@/misc/schema.js'; import { Packed } from '@/misc/schema.js';
import { Note } from '@/models/entities/note.js';
import Channel from '../channel.js'; import Channel from '../channel.js';
export default class extends Channel { export default class extends Channel {
@ -8,10 +9,11 @@ export default class extends Channel {
public static shouldShare = false; public static shouldShare = false;
public static requireCredential = false; public static requireCredential = false;
private q: string[][]; private q: string[][];
private onNote: (note: Note) => Promise<void>;
constructor(id: string, connection: Channel['connection']) { constructor(id: string, connection: Channel['connection']) {
super(id, connection); super(id, connection);
this.onNote = this.withPackedNote(this.onNote.bind(this)); this.onNote = this.withPackedNote(this.onPackedNote.bind(this));
} }
public async init(params: any) { public async init(params: any) {
@ -23,7 +25,7 @@ export default class extends Channel {
this.subscriber.on('notesStream', this.onNote); this.subscriber.on('notesStream', this.onNote);
} }
private async onNote(note: Packed<'Note'>) { private async onPackedNote(note: Packed<'Note'>): Promise<void> {
const noteTags = note.tags ? note.tags.map((t: string) => t.toLowerCase()) : []; const noteTags = note.tags ? note.tags.map((t: string) => t.toLowerCase()) : [];
const matched = this.q.some(tags => tags.every(tag => noteTags.includes(normalizeForSearch(tag)))); const matched = this.q.some(tags => tags.every(tag => noteTags.includes(normalizeForSearch(tag))));
if (!matched) return; if (!matched) return;

View file

@ -2,16 +2,18 @@ import { checkWordMute } from '@/misc/check-word-mute.js';
import { isUserRelated } from '@/misc/is-user-related.js'; import { isUserRelated } from '@/misc/is-user-related.js';
import { isInstanceMuted } from '@/misc/is-instance-muted.js'; import { isInstanceMuted } from '@/misc/is-instance-muted.js';
import { Packed } from '@/misc/schema.js'; import { Packed } from '@/misc/schema.js';
import { Note } from '@/models/entities/note.js';
import Channel from '../channel.js'; import Channel from '../channel.js';
export default class extends Channel { export default class extends Channel {
public readonly chName = 'homeTimeline'; public readonly chName = 'homeTimeline';
public static shouldShare = true; public static shouldShare = true;
public static requireCredential = true; public static requireCredential = true;
private onNote: (note: Note) => Promise<void>;
constructor(id: string, connection: Channel['connection']) { constructor(id: string, connection: Channel['connection']) {
super(id, connection); super(id, connection);
this.onNote = this.withPackedNote(this.onNote.bind(this)); this.onNote = this.withPackedNote(this.onPackedNote.bind(this));
} }
public async init(params: any) { public async init(params: any) {
@ -19,7 +21,7 @@ export default class extends Channel {
this.subscriber.on('notesStream', this.onNote); this.subscriber.on('notesStream', this.onNote);
} }
private async onNote(note: Packed<'Note'>) { private async onPackedNote(note: Packed<'Note'>): Promise<void> {
if (note.channelId) { if (note.channelId) {
if (!this.followingChannels.has(note.channelId)) return; if (!this.followingChannels.has(note.channelId)) return;
} else { } else {

View file

@ -3,16 +3,18 @@ import { checkWordMute } from '@/misc/check-word-mute.js';
import { isUserRelated } from '@/misc/is-user-related.js'; import { isUserRelated } from '@/misc/is-user-related.js';
import { isInstanceMuted } from '@/misc/is-instance-muted.js'; import { isInstanceMuted } from '@/misc/is-instance-muted.js';
import { Packed } from '@/misc/schema.js'; import { Packed } from '@/misc/schema.js';
import { Note } from '@/models/entities/note.js';
import Channel from '../channel.js'; import Channel from '../channel.js';
export default class extends Channel { export default class extends Channel {
public readonly chName = 'hybridTimeline'; public readonly chName = 'hybridTimeline';
public static shouldShare = true; public static shouldShare = true;
public static requireCredential = true; public static requireCredential = true;
private onNote: (note: Note) => Promise<void>;
constructor(id: string, connection: Channel['connection']) { constructor(id: string, connection: Channel['connection']) {
super(id, connection); super(id, connection);
this.onNote = this.withPackedNote(this.onNote.bind(this)); this.onNote = this.withPackedNote(this.onPackedNote.bind(this));
} }
public async init(params: any) { public async init(params: any) {
@ -23,7 +25,7 @@ export default class extends Channel {
this.subscriber.on('notesStream', this.onNote); this.subscriber.on('notesStream', this.onNote);
} }
private async onNote(note: Packed<'Note'>) { private async onPackedNote(note: Packed<'Note'>): Promise<void> {
// チャンネルの投稿ではなく、自分自身の投稿 または // チャンネルの投稿ではなく、自分自身の投稿 または
// チャンネルの投稿ではなく、その投稿のユーザーをフォローしている または // チャンネルの投稿ではなく、その投稿のユーザーをフォローしている または
// チャンネルの投稿ではなく、全体公開のローカルの投稿 または // チャンネルの投稿ではなく、全体公開のローカルの投稿 または

View file

@ -2,16 +2,18 @@ import { fetchMeta } from '@/misc/fetch-meta.js';
import { checkWordMute } from '@/misc/check-word-mute.js'; import { checkWordMute } from '@/misc/check-word-mute.js';
import { isUserRelated } from '@/misc/is-user-related.js'; import { isUserRelated } from '@/misc/is-user-related.js';
import { Packed } from '@/misc/schema.js'; import { Packed } from '@/misc/schema.js';
import { Note } from '@/models/entities/note.js';
import Channel from '../channel.js'; import Channel from '../channel.js';
export default class extends Channel { export default class extends Channel {
public readonly chName = 'localTimeline'; public readonly chName = 'localTimeline';
public static shouldShare = true; public static shouldShare = true;
public static requireCredential = false; public static requireCredential = false;
onNote: (note: Note) => Promise<void>;
constructor(id: string, connection: Channel['connection']) { constructor(id: string, connection: Channel['connection']) {
super(id, connection); super(id, connection);
this.onNote = this.withPackedNote(this.onNote.bind(this)); this.onNote = this.withPackedNote(this.onPackedNote.bind(this));
} }
public async init(params: any) { public async init(params: any) {
@ -24,7 +26,7 @@ export default class extends Channel {
this.subscriber.on('notesStream', this.onNote); this.subscriber.on('notesStream', this.onNote);
} }
private async onNote(note: Packed<'Note'>) { private async onPackedNote(note: Packed<'Note'>): Promise<void> {
if (note.user.host !== null) return; if (note.user.host !== null) return;
if (note.visibility !== 'public') return; if (note.visibility !== 'public') return;
if (note.channelId != null && !this.followingChannels.has(note.channelId)) return; if (note.channelId != null && !this.followingChannels.has(note.channelId)) return;

View file

@ -2,6 +2,7 @@ import { UserListJoinings, UserLists } from '@/models/index.js';
import { User } from '@/models/entities/user.js'; import { User } from '@/models/entities/user.js';
import { isUserRelated } from '@/misc/is-user-related.js'; import { isUserRelated } from '@/misc/is-user-related.js';
import { Packed } from '@/misc/schema.js'; import { Packed } from '@/misc/schema.js';
import { Note } from '@/models/entities/note.js';
import Channel from '../channel.js'; import Channel from '../channel.js';
export default class extends Channel { export default class extends Channel {
@ -11,11 +12,12 @@ export default class extends Channel {
private listId: string; private listId: string;
public listUsers: User['id'][] = []; public listUsers: User['id'][] = [];
private listUsersClock: NodeJS.Timer; private listUsersClock: NodeJS.Timer;
private onNote: (note: Note) => Promise<void>;
constructor(id: string, connection: Channel['connection']) { constructor(id: string, connection: Channel['connection']) {
super(id, connection); super(id, connection);
this.updateListUsers = this.updateListUsers.bind(this); this.updateListUsers = this.updateListUsers.bind(this);
this.onNote = this.withPackedNote(this.onNote.bind(this)); this.onNote = this.withPackedNote(this.onPackedNote.bind(this));
} }
public async init(params: any) { public async init(params: any) {
@ -48,7 +50,7 @@ export default class extends Channel {
this.listUsers = users.map(x => x.userId); this.listUsers = users.map(x => x.userId);
} }
private async onNote(note: Packed<'Note'>) { private async onPackedNote(note: Packed<'Note'>): Promise<void> {
if (!this.listUsers.includes(note.userId)) return; if (!this.listUsers.includes(note.userId)) return;
// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する // 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する