なんかもうめっちゃ変えた
This commit is contained in:
62
packages/backend/src/server/api/stream/ChannelsService.ts
Normal file
62
packages/backend/src/server/api/stream/ChannelsService.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { HybridTimelineChannelService } from './channels/hybrid-timeline.js';
|
||||
import { LocalTimelineChannelService } from './channels/local-timeline.js';
|
||||
import { HomeTimelineChannelService } from './channels/home-timeline.js';
|
||||
import { GlobalTimelineChannelService } from './channels/global-timeline.js';
|
||||
import { MainChannelService } from './channels/main.js';
|
||||
import { ChannelChannelService } from './channels/channel.js';
|
||||
import { AdminChannelService } from './channels/admin.js';
|
||||
import { ServerStatsChannelService } from './channels/server-stats.js';
|
||||
import { QueueStatsChannelService } from './channels/queue-stats.js';
|
||||
import { UserListChannelService } from './channels/user-list.js';
|
||||
import { AntennaChannelService } from './channels/antenna.js';
|
||||
import { MessagingChannelService } from './channels/messaging.js';
|
||||
import { MessagingIndexChannelService } from './channels/messaging-index.js';
|
||||
import { DriveChannelService } from './channels/drive.js';
|
||||
import { HashtagChannelService } from './channels/hashtag.js';
|
||||
|
||||
@Injectable()
|
||||
export class ChannelsService {
|
||||
constructor(
|
||||
private mainChannelService: MainChannelService,
|
||||
private homeTimelineChannelService: HomeTimelineChannelService,
|
||||
private localTimelineChannelService: LocalTimelineChannelService,
|
||||
private hybridTimelineChannelService: HybridTimelineChannelService,
|
||||
private globalTimelineChannelService: GlobalTimelineChannelService,
|
||||
private userListChannelService: UserListChannelService,
|
||||
private hashtagChannelService: HashtagChannelService,
|
||||
private antennaChannelService: AntennaChannelService,
|
||||
private channelChannelService: ChannelChannelService,
|
||||
private messagingChannelService: MessagingChannelService,
|
||||
private messagingIndexChannelService: MessagingIndexChannelService,
|
||||
private driveChannelService: DriveChannelService,
|
||||
private serverStatsChannelService: ServerStatsChannelService,
|
||||
private queueStatsChannelService: QueueStatsChannelService,
|
||||
private adminChannelService: AdminChannelService,
|
||||
) {
|
||||
}
|
||||
|
||||
public getChannelService(name: string) {
|
||||
switch (name) {
|
||||
case 'main': return this.mainChannelService;
|
||||
case 'homeTimeline': return this.homeTimelineChannelService;
|
||||
case 'localTimeline': return this.localTimelineChannelService;
|
||||
case 'hybridTimeline': return this.hybridTimelineChannelService;
|
||||
case 'globalTimeline': return this.globalTimelineChannelService;
|
||||
case 'userList': return this.userListChannelService;
|
||||
case 'hashtag': return this.hashtagChannelService;
|
||||
case 'antenna': return this.antennaChannelService;
|
||||
case 'channel': return this.channelChannelService;
|
||||
case 'messaging': return this.messagingChannelService;
|
||||
case 'messagingIndex': return this.messagingIndexChannelService;
|
||||
case 'drive': return this.driveChannelService;
|
||||
case 'serverStats': return this.serverStatsChannelService;
|
||||
case 'queueStats': return this.queueStatsChannelService;
|
||||
case 'admin': return this.adminChannelService;
|
||||
|
||||
default:
|
||||
throw new Error(`no such channel: ${name}`);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
import Connection from '.';
|
||||
import type Connection from '.';
|
||||
|
||||
/**
|
||||
* Stream channel
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import Channel from '../channel.js';
|
||||
|
||||
export default class extends Channel {
|
||||
class AdminChannel extends Channel {
|
||||
public readonly chName = 'admin';
|
||||
public static shouldShare = true;
|
||||
public static requireCredential = true;
|
||||
@@ -12,3 +13,20 @@ export default class extends Channel {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class AdminChannelService {
|
||||
public readonly shouldShare = AdminChannel.shouldShare;
|
||||
public readonly requireCredential = AdminChannel.requireCredential;
|
||||
|
||||
constructor(
|
||||
) {
|
||||
}
|
||||
|
||||
public create(id: string, connection: Channel['connection']): AdminChannel {
|
||||
return new AdminChannel(
|
||||
id,
|
||||
connection,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,15 +1,22 @@
|
||||
import Channel from '../channel.js';
|
||||
import { Notes } from '@/models/index.js';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { NotesRepository } from '@/models/index.js';
|
||||
import { isUserRelated } from '@/misc/is-user-related.js';
|
||||
import { StreamMessages } from '../types.js';
|
||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
import Channel from '../channel.js';
|
||||
import type { StreamMessages } from '../types.js';
|
||||
|
||||
export default class extends Channel {
|
||||
class AntennaChannel extends Channel {
|
||||
public readonly chName = 'antenna';
|
||||
public static shouldShare = false;
|
||||
public static requireCredential = false;
|
||||
private antennaId: string;
|
||||
|
||||
constructor(id: string, connection: Channel['connection']) {
|
||||
constructor(
|
||||
private noteEntityService: NoteEntityService,
|
||||
|
||||
id: string,
|
||||
connection: Channel['connection'],
|
||||
) {
|
||||
super(id, connection);
|
||||
this.onEvent = this.onEvent.bind(this);
|
||||
}
|
||||
@@ -23,7 +30,7 @@ export default class extends Channel {
|
||||
|
||||
private async onEvent(data: StreamMessages['antenna']['payload']) {
|
||||
if (data.type === 'note') {
|
||||
const note = await Notes.pack(data.body.id, this.user, { detail: true });
|
||||
const note = await this.noteEntityService.pack(data.body.id, this.user, { detail: true });
|
||||
|
||||
// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
|
||||
if (isUserRelated(note, this.muting)) return;
|
||||
@@ -43,3 +50,22 @@ export default class extends Channel {
|
||||
this.subscriber.off(`antennaStream:${this.antennaId}`, this.onEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class AntennaChannelService {
|
||||
public readonly shouldShare = AntennaChannel.shouldShare;
|
||||
public readonly requireCredential = AntennaChannel.requireCredential;
|
||||
|
||||
constructor(
|
||||
private noteEntityService: NoteEntityService,
|
||||
) {
|
||||
}
|
||||
|
||||
public create(id: string, connection: Channel['connection']): AntennaChannel {
|
||||
return new AntennaChannel(
|
||||
this.noteEntityService,
|
||||
id,
|
||||
connection,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,14 @@
|
||||
import Channel from '../channel.js';
|
||||
import { Notes, Users } from '@/models/index.js';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { NotesRepository, UsersRepository } from '@/models/index.js';
|
||||
import { isUserRelated } from '@/misc/is-user-related.js';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
import { StreamMessages } from '../types.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import type { Packed } from '@/misc/schema.js';
|
||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import Channel from '../channel.js';
|
||||
import type { StreamMessages } from '../types.js';
|
||||
|
||||
export default class extends Channel {
|
||||
class ChannelChannel extends Channel {
|
||||
public readonly chName = 'channel';
|
||||
public static shouldShare = false;
|
||||
public static requireCredential = false;
|
||||
@@ -13,7 +16,13 @@ export default class extends Channel {
|
||||
private typers: Record<User['id'], Date> = {};
|
||||
private emitTypersIntervalId: ReturnType<typeof setInterval>;
|
||||
|
||||
constructor(id: string, connection: Channel['connection']) {
|
||||
constructor(
|
||||
private noteEntityService: NoteEntityService,
|
||||
private userEntityService: UserEntityService,
|
||||
|
||||
id: string,
|
||||
connection: Channel['connection'],
|
||||
) {
|
||||
super(id, connection);
|
||||
this.onNote = this.onNote.bind(this);
|
||||
this.emitTypers = this.emitTypers.bind(this);
|
||||
@@ -33,13 +42,13 @@ export default class extends Channel {
|
||||
|
||||
// リプライなら再pack
|
||||
if (note.replyId != null) {
|
||||
note.reply = await Notes.pack(note.replyId, this.user, {
|
||||
note.reply = await this.noteEntityService.pack(note.replyId, this.user, {
|
||||
detail: true,
|
||||
});
|
||||
}
|
||||
// Renoteなら再pack
|
||||
if (note.renoteId != null) {
|
||||
note.renote = await Notes.pack(note.renoteId, this.user, {
|
||||
note.renote = await this.noteEntityService.pack(note.renoteId, this.user, {
|
||||
detail: true,
|
||||
});
|
||||
}
|
||||
@@ -73,7 +82,7 @@ export default class extends Channel {
|
||||
if (now.getTime() - date.getTime() > 5000) delete this.typers[userId];
|
||||
}
|
||||
|
||||
const users = await Users.packMany(Object.keys(this.typers), null, { detail: false });
|
||||
const users = await this.userEntityService.packMany(Object.keys(this.typers), null, { detail: false });
|
||||
|
||||
this.send({
|
||||
type: 'typers',
|
||||
@@ -89,3 +98,24 @@ export default class extends Channel {
|
||||
clearInterval(this.emitTypersIntervalId);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class ChannelChannelService {
|
||||
public readonly shouldShare = ChannelChannel.shouldShare;
|
||||
public readonly requireCredential = ChannelChannel.requireCredential;
|
||||
|
||||
constructor(
|
||||
private noteEntityService: NoteEntityService,
|
||||
private userEntityService: UserEntityService,
|
||||
) {
|
||||
}
|
||||
|
||||
public create(id: string, connection: Channel['connection']): ChannelChannel {
|
||||
return new ChannelChannel(
|
||||
this.noteEntityService,
|
||||
this.userEntityService,
|
||||
id,
|
||||
connection,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import Channel from '../channel.js';
|
||||
|
||||
export default class extends Channel {
|
||||
class DriveChannel extends Channel {
|
||||
public readonly chName = 'drive';
|
||||
public static shouldShare = true;
|
||||
public static requireCredential = true;
|
||||
@@ -12,3 +13,20 @@ export default class extends Channel {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class DriveChannelService {
|
||||
public readonly shouldShare = DriveChannel.shouldShare;
|
||||
public readonly requireCredential = DriveChannel.requireCredential;
|
||||
|
||||
constructor(
|
||||
) {
|
||||
}
|
||||
|
||||
public create(id: string, connection: Channel['connection']): DriveChannel {
|
||||
return new DriveChannel(
|
||||
id,
|
||||
connection,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,23 +1,31 @@
|
||||
import Channel from '../channel.js';
|
||||
import { fetchMeta } from '@/misc/fetch-meta.js';
|
||||
import { Notes } from '@/models/index.js';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { NotesRepository } from '@/models/index.js';
|
||||
import { checkWordMute } from '@/misc/check-word-mute.js';
|
||||
import { isInstanceMuted } from '@/misc/is-instance-muted.js';
|
||||
import { isUserRelated } from '@/misc/is-user-related.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import type { Packed } from '@/misc/schema.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
import Channel from '../channel.js';
|
||||
|
||||
export default class extends Channel {
|
||||
class GlobalTimelineChannel extends Channel {
|
||||
public readonly chName = 'globalTimeline';
|
||||
public static shouldShare = true;
|
||||
public static requireCredential = false;
|
||||
|
||||
constructor(id: string, connection: Channel['connection']) {
|
||||
constructor(
|
||||
private metaService: MetaService,
|
||||
private noteEntityService: NoteEntityService,
|
||||
|
||||
id: string,
|
||||
connection: Channel['connection'],
|
||||
) {
|
||||
super(id, connection);
|
||||
this.onNote = this.onNote.bind(this);
|
||||
}
|
||||
|
||||
public async init(params: any) {
|
||||
const meta = await fetchMeta();
|
||||
const meta = await this.metaService.fetch();
|
||||
if (meta.disableGlobalTimeline) {
|
||||
if (this.user == null || (!this.user.isAdmin && !this.user.isModerator)) return;
|
||||
}
|
||||
@@ -32,13 +40,13 @@ export default class extends Channel {
|
||||
|
||||
// リプライなら再pack
|
||||
if (note.replyId != null) {
|
||||
note.reply = await Notes.pack(note.replyId, this.user, {
|
||||
note.reply = await this.noteEntityService.pack(note.replyId, this.user, {
|
||||
detail: true,
|
||||
});
|
||||
}
|
||||
// Renoteなら再pack
|
||||
if (note.renoteId != null) {
|
||||
note.renote = await Notes.pack(note.renoteId, this.user, {
|
||||
note.renote = await this.noteEntityService.pack(note.renoteId, this.user, {
|
||||
detail: true,
|
||||
});
|
||||
}
|
||||
@@ -75,3 +83,24 @@ export default class extends Channel {
|
||||
this.subscriber.off('notesStream', this.onNote);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class GlobalTimelineChannelService {
|
||||
public readonly shouldShare = GlobalTimelineChannel.shouldShare;
|
||||
public readonly requireCredential = GlobalTimelineChannel.requireCredential;
|
||||
|
||||
constructor(
|
||||
private metaService: MetaService,
|
||||
private noteEntityService: NoteEntityService,
|
||||
) {
|
||||
}
|
||||
|
||||
public create(id: string, connection: Channel['connection']): GlobalTimelineChannel {
|
||||
return new GlobalTimelineChannel(
|
||||
this.metaService,
|
||||
this.noteEntityService,
|
||||
id,
|
||||
connection,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,16 +1,23 @@
|
||||
import Channel from '../channel.js';
|
||||
import { Notes } from '@/models/index.js';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { NotesRepository } from '@/models/index.js';
|
||||
import { normalizeForSearch } from '@/misc/normalize-for-search.js';
|
||||
import { isUserRelated } from '@/misc/is-user-related.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import type { Packed } from '@/misc/schema.js';
|
||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
import Channel from '../channel.js';
|
||||
|
||||
export default class extends Channel {
|
||||
class HashtagChannel extends Channel {
|
||||
public readonly chName = 'hashtag';
|
||||
public static shouldShare = false;
|
||||
public static requireCredential = false;
|
||||
private q: string[][];
|
||||
|
||||
constructor(id: string, connection: Channel['connection']) {
|
||||
constructor(
|
||||
private noteEntityService: NoteEntityService,
|
||||
|
||||
id: string,
|
||||
connection: Channel['connection'],
|
||||
) {
|
||||
super(id, connection);
|
||||
this.onNote = this.onNote.bind(this);
|
||||
}
|
||||
@@ -31,7 +38,7 @@ export default class extends Channel {
|
||||
|
||||
// Renoteなら再pack
|
||||
if (note.renoteId != null) {
|
||||
note.renote = await Notes.pack(note.renoteId, this.user, {
|
||||
note.renote = await this.noteEntityService.pack(note.renoteId, this.user, {
|
||||
detail: true,
|
||||
});
|
||||
}
|
||||
@@ -51,3 +58,22 @@ export default class extends Channel {
|
||||
this.subscriber.off('notesStream', this.onNote);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class HashtagChannelService {
|
||||
public readonly shouldShare = HashtagChannel.shouldShare;
|
||||
public readonly requireCredential = HashtagChannel.requireCredential;
|
||||
|
||||
constructor(
|
||||
private noteEntityService: NoteEntityService,
|
||||
) {
|
||||
}
|
||||
|
||||
public create(id: string, connection: Channel['connection']): HashtagChannel {
|
||||
return new HashtagChannel(
|
||||
this.noteEntityService,
|
||||
id,
|
||||
connection,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,16 +1,23 @@
|
||||
import Channel from '../channel.js';
|
||||
import { Notes } from '@/models/index.js';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { NotesRepository } from '@/models/index.js';
|
||||
import { checkWordMute } from '@/misc/check-word-mute.js';
|
||||
import { isUserRelated } from '@/misc/is-user-related.js';
|
||||
import { isInstanceMuted } from '@/misc/is-instance-muted.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import type { Packed } from '@/misc/schema.js';
|
||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
import Channel from '../channel.js';
|
||||
|
||||
export default class extends Channel {
|
||||
class HomeTimelineChannel extends Channel {
|
||||
public readonly chName = 'homeTimeline';
|
||||
public static shouldShare = true;
|
||||
public static requireCredential = true;
|
||||
|
||||
constructor(id: string, connection: Channel['connection']) {
|
||||
constructor(
|
||||
private noteEntityService: NoteEntityService,
|
||||
|
||||
id: string,
|
||||
connection: Channel['connection'],
|
||||
) {
|
||||
super(id, connection);
|
||||
this.onNote = this.onNote.bind(this);
|
||||
}
|
||||
@@ -32,7 +39,7 @@ export default class extends Channel {
|
||||
if (isInstanceMuted(note, new Set<string>(this.userProfile?.mutedInstances ?? []))) return;
|
||||
|
||||
if (['followers', 'specified'].includes(note.visibility)) {
|
||||
note = await Notes.pack(note.id, this.user!, {
|
||||
note = await this.noteEntityService.pack(note.id, this.user!, {
|
||||
detail: true,
|
||||
});
|
||||
|
||||
@@ -42,13 +49,13 @@ export default class extends Channel {
|
||||
} else {
|
||||
// リプライなら再pack
|
||||
if (note.replyId != null) {
|
||||
note.reply = await Notes.pack(note.replyId, this.user!, {
|
||||
note.reply = await this.noteEntityService.pack(note.replyId, this.user!, {
|
||||
detail: true,
|
||||
});
|
||||
}
|
||||
// Renoteなら再pack
|
||||
if (note.renoteId != null) {
|
||||
note.renote = await Notes.pack(note.renoteId, this.user!, {
|
||||
note.renote = await this.noteEntityService.pack(note.renoteId, this.user!, {
|
||||
detail: true,
|
||||
});
|
||||
}
|
||||
@@ -83,3 +90,22 @@ export default class extends Channel {
|
||||
this.subscriber.off('notesStream', this.onNote);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class HomeTimelineChannelService {
|
||||
public readonly shouldShare = HomeTimelineChannel.shouldShare;
|
||||
public readonly requireCredential = HomeTimelineChannel.requireCredential;
|
||||
|
||||
constructor(
|
||||
private noteEntityService: NoteEntityService,
|
||||
) {
|
||||
}
|
||||
|
||||
public create(id: string, connection: Channel['connection']): HomeTimelineChannel {
|
||||
return new HomeTimelineChannel(
|
||||
this.noteEntityService,
|
||||
id,
|
||||
connection,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,23 +1,32 @@
|
||||
import Channel from '../channel.js';
|
||||
import { fetchMeta } from '@/misc/fetch-meta.js';
|
||||
import { Notes } from '@/models/index.js';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { NotesRepository } from '@/models/index.js';
|
||||
import { checkWordMute } from '@/misc/check-word-mute.js';
|
||||
import { isUserRelated } from '@/misc/is-user-related.js';
|
||||
import { isInstanceMuted } from '@/misc/is-instance-muted.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import type { Packed } from '@/misc/schema.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
import Channel from '../channel.js';
|
||||
|
||||
export default class extends Channel {
|
||||
class HybridTimelineChannel extends Channel {
|
||||
public readonly chName = 'hybridTimeline';
|
||||
public static shouldShare = true;
|
||||
public static requireCredential = true;
|
||||
|
||||
constructor(id: string, connection: Channel['connection']) {
|
||||
constructor(
|
||||
private metaService: MetaService,
|
||||
private noteEntityService: NoteEntityService,
|
||||
|
||||
id: string,
|
||||
connection: Channel['connection'],
|
||||
) {
|
||||
super(id, connection);
|
||||
this.onNote = this.onNote.bind(this);
|
||||
}
|
||||
|
||||
public async init(params: any) {
|
||||
const meta = await fetchMeta();
|
||||
public async init(params: any): Promise<void> {
|
||||
const meta = await this.metaService.fetch();
|
||||
if (meta.disableLocalTimeline && !this.user!.isAdmin && !this.user!.isModerator) return;
|
||||
|
||||
// Subscribe events
|
||||
@@ -37,7 +46,7 @@ export default class extends Channel {
|
||||
)) return;
|
||||
|
||||
if (['followers', 'specified'].includes(note.visibility)) {
|
||||
note = await Notes.pack(note.id, this.user!, {
|
||||
note = await this.noteEntityService.pack(note.id, this.user!, {
|
||||
detail: true,
|
||||
});
|
||||
|
||||
@@ -47,13 +56,13 @@ export default class extends Channel {
|
||||
} else {
|
||||
// リプライなら再pack
|
||||
if (note.replyId != null) {
|
||||
note.reply = await Notes.pack(note.replyId, this.user!, {
|
||||
note.reply = await this.noteEntityService.pack(note.replyId, this.user!, {
|
||||
detail: true,
|
||||
});
|
||||
}
|
||||
// Renoteなら再pack
|
||||
if (note.renoteId != null) {
|
||||
note.renote = await Notes.pack(note.renoteId, this.user!, {
|
||||
note.renote = await this.noteEntityService.pack(note.renoteId, this.user!, {
|
||||
detail: true,
|
||||
});
|
||||
}
|
||||
@@ -86,8 +95,29 @@ export default class extends Channel {
|
||||
this.send('note', note);
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
public dispose(): void {
|
||||
// Unsubscribe events
|
||||
this.subscriber.off('notesStream', this.onNote);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class HybridTimelineChannelService {
|
||||
public readonly shouldShare = HybridTimelineChannel.shouldShare;
|
||||
public readonly requireCredential = HybridTimelineChannel.requireCredential;
|
||||
|
||||
constructor(
|
||||
private metaService: MetaService,
|
||||
private noteEntityService: NoteEntityService,
|
||||
) {
|
||||
}
|
||||
|
||||
public create(id: string, connection: Channel['connection']): HybridTimelineChannel {
|
||||
return new HybridTimelineChannel(
|
||||
this.metaService,
|
||||
this.noteEntityService,
|
||||
id,
|
||||
connection,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,33 +0,0 @@
|
||||
import main from './main.js';
|
||||
import homeTimeline from './home-timeline.js';
|
||||
import localTimeline from './local-timeline.js';
|
||||
import hybridTimeline from './hybrid-timeline.js';
|
||||
import globalTimeline from './global-timeline.js';
|
||||
import serverStats from './server-stats.js';
|
||||
import queueStats from './queue-stats.js';
|
||||
import userList from './user-list.js';
|
||||
import antenna from './antenna.js';
|
||||
import messaging from './messaging.js';
|
||||
import messagingIndex from './messaging-index.js';
|
||||
import drive from './drive.js';
|
||||
import hashtag from './hashtag.js';
|
||||
import channel from './channel.js';
|
||||
import admin from './admin.js';
|
||||
|
||||
export default {
|
||||
main,
|
||||
homeTimeline,
|
||||
localTimeline,
|
||||
hybridTimeline,
|
||||
globalTimeline,
|
||||
serverStats,
|
||||
queueStats,
|
||||
userList,
|
||||
antenna,
|
||||
messaging,
|
||||
messagingIndex,
|
||||
drive,
|
||||
hashtag,
|
||||
channel,
|
||||
admin,
|
||||
};
|
@@ -1,22 +1,30 @@
|
||||
import Channel from '../channel.js';
|
||||
import { fetchMeta } from '@/misc/fetch-meta.js';
|
||||
import { Notes } from '@/models/index.js';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { NotesRepository } from '@/models/index.js';
|
||||
import { checkWordMute } from '@/misc/check-word-mute.js';
|
||||
import { isUserRelated } from '@/misc/is-user-related.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import type { Packed } from '@/misc/schema.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
import Channel from '../channel.js';
|
||||
|
||||
export default class extends Channel {
|
||||
class LocalTimelineChannel extends Channel {
|
||||
public readonly chName = 'localTimeline';
|
||||
public static shouldShare = true;
|
||||
public static requireCredential = false;
|
||||
|
||||
constructor(id: string, connection: Channel['connection']) {
|
||||
constructor(
|
||||
private metaService: MetaService,
|
||||
private noteEntityService: NoteEntityService,
|
||||
|
||||
id: string,
|
||||
connection: Channel['connection'],
|
||||
) {
|
||||
super(id, connection);
|
||||
this.onNote = this.onNote.bind(this);
|
||||
}
|
||||
|
||||
public async init(params: any) {
|
||||
const meta = await fetchMeta();
|
||||
const meta = await this.metaService.fetch();
|
||||
if (meta.disableLocalTimeline) {
|
||||
if (this.user == null || (!this.user.isAdmin && !this.user.isModerator)) return;
|
||||
}
|
||||
@@ -32,13 +40,13 @@ export default class extends Channel {
|
||||
|
||||
// リプライなら再pack
|
||||
if (note.replyId != null) {
|
||||
note.reply = await Notes.pack(note.replyId, this.user, {
|
||||
note.reply = await this.noteEntityService.pack(note.replyId, this.user, {
|
||||
detail: true,
|
||||
});
|
||||
}
|
||||
// Renoteなら再pack
|
||||
if (note.renoteId != null) {
|
||||
note.renote = await Notes.pack(note.renoteId, this.user, {
|
||||
note.renote = await this.noteEntityService.pack(note.renoteId, this.user, {
|
||||
detail: true,
|
||||
});
|
||||
}
|
||||
@@ -72,3 +80,24 @@ export default class extends Channel {
|
||||
this.subscriber.off('notesStream', this.onNote);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class LocalTimelineChannelService {
|
||||
public readonly shouldShare = LocalTimelineChannel.shouldShare;
|
||||
public readonly requireCredential = LocalTimelineChannel.requireCredential;
|
||||
|
||||
constructor(
|
||||
private metaService: MetaService,
|
||||
private noteEntityService: NoteEntityService,
|
||||
) {
|
||||
}
|
||||
|
||||
public create(id: string, connection: Channel['connection']): LocalTimelineChannel {
|
||||
return new LocalTimelineChannel(
|
||||
this.metaService,
|
||||
this.noteEntityService,
|
||||
id,
|
||||
connection,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,12 +1,23 @@
|
||||
import Channel from '../channel.js';
|
||||
import { Notes } from '@/models/index.js';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { NotesRepository } from '@/models/index.js';
|
||||
import { isInstanceMuted, isUserFromMutedInstance } from '@/misc/is-instance-muted.js';
|
||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
import Channel from '../channel.js';
|
||||
|
||||
export default class extends Channel {
|
||||
class MainChannel extends Channel {
|
||||
public readonly chName = 'main';
|
||||
public static shouldShare = true;
|
||||
public static requireCredential = true;
|
||||
|
||||
constructor(
|
||||
private noteEntityService: NoteEntityService,
|
||||
|
||||
id: string,
|
||||
connection: Channel['connection'],
|
||||
) {
|
||||
super(id, connection);
|
||||
}
|
||||
|
||||
public async init(params: any) {
|
||||
// Subscribe main stream channel
|
||||
this.subscriber.on(`mainStream:${this.user!.id}`, async data => {
|
||||
@@ -17,7 +28,7 @@ export default class extends Channel {
|
||||
if (data.body.userId && this.muting.has(data.body.userId)) return;
|
||||
|
||||
if (data.body.note && data.body.note.isHidden) {
|
||||
const note = await Notes.pack(data.body.note.id, this.user, {
|
||||
const note = await this.noteEntityService.pack(data.body.note.id, this.user, {
|
||||
detail: true,
|
||||
});
|
||||
this.connection.cacheNote(note);
|
||||
@@ -30,7 +41,7 @@ export default class extends Channel {
|
||||
|
||||
if (this.muting.has(data.body.userId)) return;
|
||||
if (data.body.isHidden) {
|
||||
const note = await Notes.pack(data.body.id, this.user, {
|
||||
const note = await this.noteEntityService.pack(data.body.id, this.user, {
|
||||
detail: true,
|
||||
});
|
||||
this.connection.cacheNote(note);
|
||||
@@ -44,3 +55,22 @@ export default class extends Channel {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class MainChannelService {
|
||||
public readonly shouldShare = MainChannel.shouldShare;
|
||||
public readonly requireCredential = MainChannel.requireCredential;
|
||||
|
||||
constructor(
|
||||
private noteEntityService: NoteEntityService,
|
||||
) {
|
||||
}
|
||||
|
||||
public create(id: string, connection: Channel['connection']): MainChannel {
|
||||
return new MainChannel(
|
||||
this.noteEntityService,
|
||||
id,
|
||||
connection,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import Channel from '../channel.js';
|
||||
|
||||
export default class extends Channel {
|
||||
class MessagingIndexChannel extends Channel {
|
||||
public readonly chName = 'messagingIndex';
|
||||
public static shouldShare = true;
|
||||
public static requireCredential = true;
|
||||
@@ -12,3 +13,20 @@ export default class extends Channel {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class MessagingIndexChannelService {
|
||||
public readonly shouldShare = MessagingIndexChannel.shouldShare;
|
||||
public readonly requireCredential = MessagingIndexChannel.requireCredential;
|
||||
|
||||
constructor(
|
||||
) {
|
||||
}
|
||||
|
||||
public create(id: string, connection: Channel['connection']): MessagingIndexChannel {
|
||||
return new MessagingIndexChannel(
|
||||
id,
|
||||
connection,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,14 @@
|
||||
import { readUserMessagingMessage, readGroupMessagingMessage, deliverReadActivity } from '../../common/read-messaging-message.js';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { UserGroupJoiningsRepository, UsersRepository, MessagingMessagesRepository } from '@/models/index.js';
|
||||
import type { User, ILocalUser, IRemoteUser } from '@/models/entities/User.js';
|
||||
import type { UserGroup } from '@/models/entities/UserGroup.js';
|
||||
import { MessagingService } from '@/core/MessagingService.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import Channel from '../channel.js';
|
||||
import { UserGroupJoinings, Users, MessagingMessages } from '@/models/index.js';
|
||||
import { User, ILocalUser, IRemoteUser } from '@/models/entities/user.js';
|
||||
import { UserGroup } from '@/models/entities/user-group.js';
|
||||
import { StreamMessages } from '../types.js';
|
||||
import type { StreamMessages } from '../types.js';
|
||||
|
||||
export default class extends Channel {
|
||||
class MessagingChannel extends Channel {
|
||||
public readonly chName = 'messaging';
|
||||
public static shouldShare = false;
|
||||
public static requireCredential = true;
|
||||
@@ -17,7 +20,16 @@ export default class extends Channel {
|
||||
private typers: Record<User['id'], Date> = {};
|
||||
private emitTypersIntervalId: ReturnType<typeof setInterval>;
|
||||
|
||||
constructor(id: string, connection: Channel['connection']) {
|
||||
constructor(
|
||||
private usersRepository: UsersRepository,
|
||||
private userGroupJoiningsRepository: UserGroupJoiningsRepository,
|
||||
private messagingMessagesRepository: MessagingMessagesRepository,
|
||||
private userEntityService: UserEntityService,
|
||||
private messagingService: MessagingService,
|
||||
|
||||
id: string,
|
||||
connection: Channel['connection'],
|
||||
) {
|
||||
super(id, connection);
|
||||
this.onEvent = this.onEvent.bind(this);
|
||||
this.onMessage = this.onMessage.bind(this);
|
||||
@@ -26,12 +38,12 @@ export default class extends Channel {
|
||||
|
||||
public async init(params: any) {
|
||||
this.otherpartyId = params.otherparty;
|
||||
this.otherparty = this.otherpartyId ? await Users.findOneByOrFail({ id: this.otherpartyId }) : null;
|
||||
this.otherparty = this.otherpartyId ? await this.usersRepository.findOneByOrFail({ id: this.otherpartyId }) : null;
|
||||
this.groupId = params.group;
|
||||
|
||||
// Check joining
|
||||
if (this.groupId) {
|
||||
const joining = await UserGroupJoinings.findOneBy({
|
||||
const joining = await this.userGroupJoiningsRepository.findOneBy({
|
||||
userId: this.user!.id,
|
||||
userGroupId: this.groupId,
|
||||
});
|
||||
@@ -68,16 +80,16 @@ export default class extends Channel {
|
||||
switch (type) {
|
||||
case 'read':
|
||||
if (this.otherpartyId) {
|
||||
readUserMessagingMessage(this.user!.id, this.otherpartyId, [body.id]);
|
||||
this.messagingService.readUserMessagingMessage(this.user!.id, this.otherpartyId, [body.id]);
|
||||
|
||||
// リモートユーザーからのメッセージだったら既読配信
|
||||
if (Users.isLocalUser(this.user!) && Users.isRemoteUser(this.otherparty!)) {
|
||||
MessagingMessages.findOneBy({ id: body.id }).then(message => {
|
||||
if (message) deliverReadActivity(this.user as ILocalUser, this.otherparty as IRemoteUser, message);
|
||||
if (this.userEntityService.isLocalUser(this.user!) && this.userEntityService.isRemoteUser(this.otherparty!)) {
|
||||
this.messagingMessagesRepository.findOneBy({ id: body.id }).then(message => {
|
||||
if (message) this.messagingService.deliverReadActivity(this.user as ILocalUser, this.otherparty as IRemoteUser, message);
|
||||
});
|
||||
}
|
||||
} else if (this.groupId) {
|
||||
readGroupMessagingMessage(this.user!.id, this.groupId, [body.id]);
|
||||
this.messagingService.readGroupMessagingMessage(this.user!.id, this.groupId, [body.id]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -91,7 +103,7 @@ export default class extends Channel {
|
||||
if (now.getTime() - date.getTime() > 5000) delete this.typers[userId];
|
||||
}
|
||||
|
||||
const users = await Users.packMany(Object.keys(this.typers), null, { detail: false });
|
||||
const users = await this.userEntityService.packMany(Object.keys(this.typers), null, { detail: false });
|
||||
|
||||
this.send({
|
||||
type: 'typers',
|
||||
@@ -105,3 +117,36 @@ export default class extends Channel {
|
||||
clearInterval(this.emitTypersIntervalId);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class MessagingChannelService {
|
||||
public readonly shouldShare = MessagingChannel.shouldShare;
|
||||
public readonly requireCredential = MessagingChannel.requireCredential;
|
||||
|
||||
constructor(
|
||||
@Inject(DI.usersRepository)
|
||||
private usersRepository: UsersRepository,
|
||||
|
||||
@Inject(DI.userGroupJoiningsRepository)
|
||||
private userGroupJoiningsRepository: UserGroupJoiningsRepository,
|
||||
|
||||
@Inject(DI.messagingMessagesRepository)
|
||||
private messagingMessagesRepository: MessagingMessagesRepository,
|
||||
|
||||
private userEntityService: UserEntityService,
|
||||
private messagingService: MessagingService,
|
||||
) {
|
||||
}
|
||||
|
||||
public create(id: string, connection: Channel['connection']): MessagingChannel {
|
||||
return new MessagingChannel(
|
||||
this.usersRepository,
|
||||
this.userGroupJoiningsRepository,
|
||||
this.messagingMessagesRepository,
|
||||
this.userEntityService,
|
||||
this.messagingService,
|
||||
id,
|
||||
connection,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,10 @@
|
||||
import Xev from 'xev';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import Channel from '../channel.js';
|
||||
|
||||
const ev = new Xev();
|
||||
|
||||
export default class extends Channel {
|
||||
class QueueStatsChannel extends Channel {
|
||||
public readonly chName = 'queueStats';
|
||||
public static shouldShare = true;
|
||||
public static requireCredential = false;
|
||||
@@ -40,3 +41,20 @@ export default class extends Channel {
|
||||
ev.removeListener('queueStats', this.onStats);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class QueueStatsChannelService {
|
||||
public readonly shouldShare = QueueStatsChannel.shouldShare;
|
||||
public readonly requireCredential = QueueStatsChannel.requireCredential;
|
||||
|
||||
constructor(
|
||||
) {
|
||||
}
|
||||
|
||||
public create(id: string, connection: Channel['connection']): QueueStatsChannel {
|
||||
return new QueueStatsChannel(
|
||||
id,
|
||||
connection,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,10 @@
|
||||
import Xev from 'xev';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import Channel from '../channel.js';
|
||||
|
||||
const ev = new Xev();
|
||||
|
||||
export default class extends Channel {
|
||||
class ServerStatsChannel extends Channel {
|
||||
public readonly chName = 'serverStats';
|
||||
public static shouldShare = true;
|
||||
public static requireCredential = false;
|
||||
@@ -40,3 +41,20 @@ export default class extends Channel {
|
||||
ev.removeListener('serverStats', this.onStats);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class ServerStatsChannelService {
|
||||
public readonly shouldShare = ServerStatsChannel.shouldShare;
|
||||
public readonly requireCredential = ServerStatsChannel.requireCredential;
|
||||
|
||||
constructor(
|
||||
) {
|
||||
}
|
||||
|
||||
public create(id: string, connection: Channel['connection']): ServerStatsChannel {
|
||||
return new ServerStatsChannel(
|
||||
id,
|
||||
connection,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,10 +1,14 @@
|
||||
import Channel from '../channel.js';
|
||||
import { Notes, UserListJoinings, UserLists } from '@/models/index.js';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { UserListJoiningsRepository, UserListsRepository } from '@/models/index.js';
|
||||
import type { NotesRepository } from '@/models/index.js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import { isUserRelated } from '@/misc/is-user-related.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import type { Packed } from '@/misc/schema.js';
|
||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import Channel from '../channel.js';
|
||||
|
||||
export default class extends Channel {
|
||||
class UserListChannel extends Channel {
|
||||
public readonly chName = 'userList';
|
||||
public static shouldShare = false;
|
||||
public static requireCredential = false;
|
||||
@@ -12,7 +16,14 @@ export default class extends Channel {
|
||||
public listUsers: User['id'][] = [];
|
||||
private listUsersClock: NodeJS.Timer;
|
||||
|
||||
constructor(id: string, connection: Channel['connection']) {
|
||||
constructor(
|
||||
private userListsRepository: UserListsRepository,
|
||||
private userListJoiningsRepository: UserListJoiningsRepository,
|
||||
private noteEntityService: NoteEntityService,
|
||||
|
||||
id: string,
|
||||
connection: Channel['connection'],
|
||||
) {
|
||||
super(id, connection);
|
||||
this.updateListUsers = this.updateListUsers.bind(this);
|
||||
this.onNote = this.onNote.bind(this);
|
||||
@@ -22,7 +33,7 @@ export default class extends Channel {
|
||||
this.listId = params.listId as string;
|
||||
|
||||
// Check existence and owner
|
||||
const list = await UserLists.findOneBy({
|
||||
const list = await this.userListsRepository.findOneBy({
|
||||
id: this.listId,
|
||||
userId: this.user!.id,
|
||||
});
|
||||
@@ -38,7 +49,7 @@ export default class extends Channel {
|
||||
}
|
||||
|
||||
private async updateListUsers() {
|
||||
const users = await UserListJoinings.find({
|
||||
const users = await this.userListJoiningsRepository.find({
|
||||
where: {
|
||||
userListId: this.listId,
|
||||
},
|
||||
@@ -52,7 +63,7 @@ export default class extends Channel {
|
||||
if (!this.listUsers.includes(note.userId)) return;
|
||||
|
||||
if (['followers', 'specified'].includes(note.visibility)) {
|
||||
note = await Notes.pack(note.id, this.user, {
|
||||
note = await this.noteEntityService.pack(note.id, this.user, {
|
||||
detail: true,
|
||||
});
|
||||
|
||||
@@ -62,13 +73,13 @@ export default class extends Channel {
|
||||
} else {
|
||||
// リプライなら再pack
|
||||
if (note.replyId != null) {
|
||||
note.reply = await Notes.pack(note.replyId, this.user, {
|
||||
note.reply = await this.noteEntityService.pack(note.replyId, this.user, {
|
||||
detail: true,
|
||||
});
|
||||
}
|
||||
// Renoteなら再pack
|
||||
if (note.renoteId != null) {
|
||||
note.renote = await Notes.pack(note.renoteId, this.user, {
|
||||
note.renote = await this.noteEntityService.pack(note.renoteId, this.user, {
|
||||
detail: true,
|
||||
});
|
||||
}
|
||||
@@ -90,3 +101,30 @@ export default class extends Channel {
|
||||
clearInterval(this.listUsersClock);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class UserListChannelService {
|
||||
public readonly shouldShare = UserListChannel.shouldShare;
|
||||
public readonly requireCredential = UserListChannel.requireCredential;
|
||||
|
||||
constructor(
|
||||
@Inject(DI.userListsRepository)
|
||||
private userListsRepository: UserListsRepository,
|
||||
|
||||
@Inject(DI.userListJoiningsRepository)
|
||||
private userListJoiningsRepository: UserListJoiningsRepository,
|
||||
|
||||
private noteEntityService: NoteEntityService,
|
||||
) {
|
||||
}
|
||||
|
||||
public create(id: string, connection: Channel['connection']): UserListChannel {
|
||||
return new UserListChannel(
|
||||
this.userListsRepository,
|
||||
this.userListJoiningsRepository,
|
||||
this.noteEntityService,
|
||||
id,
|
||||
connection,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,18 +1,18 @@
|
||||
import { EventEmitter } from 'events';
|
||||
import * as websocket from 'websocket';
|
||||
import readNote from '@/services/note/read.js';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
import { Channel as ChannelModel } from '@/models/entities/channel.js';
|
||||
import { Users, Followings, Mutings, UserProfiles, ChannelFollowings, Blockings } from '@/models/index.js';
|
||||
import { AccessToken } from '@/models/entities/access-token.js';
|
||||
import { UserProfile } from '@/models/entities/user-profile.js';
|
||||
import { publishChannelStream, publishGroupMessagingStream, publishMessagingStream } from '@/services/stream.js';
|
||||
import { UserGroup } from '@/models/entities/user-group.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import { readNotification } from '../common/read-notification.js';
|
||||
import channels from './channels/index.js';
|
||||
import Channel from './channel.js';
|
||||
import { StreamEventEmitter, StreamMessages } from './types.js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import type { Channel as ChannelModel } from '@/models/entities/Channel.js';
|
||||
import type { FollowingsRepository, MutingsRepository, UserProfilesRepository, ChannelFollowingsRepository, BlockingsRepository } from '@/models/index.js';
|
||||
import type { AccessToken } from '@/models/entities/AccessToken.js';
|
||||
import type { UserProfile } from '@/models/entities/UserProfile.js';
|
||||
import type { UserGroup } from '@/models/entities/UserGroup.js';
|
||||
import type { Packed } from '@/misc/schema.js';
|
||||
import type { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import type { NoteReadService } from '@/core/NoteReadService.js';
|
||||
import type { NotificationService } from '@/core/NotificationService.js';
|
||||
import type { ChannelsService } from './ChannelsService.js';
|
||||
import type * as websocket from 'websocket';
|
||||
import type { EventEmitter } from 'events';
|
||||
import type Channel from './channel.js';
|
||||
import type { StreamEventEmitter, StreamMessages } from './types.js';
|
||||
|
||||
/**
|
||||
* Main stream connection
|
||||
@@ -32,6 +32,16 @@ export default class Connection {
|
||||
private cachedNotes: Packed<'Note'>[] = [];
|
||||
|
||||
constructor(
|
||||
private followingsRepository: FollowingsRepository,
|
||||
private mutingsRepository: MutingsRepository,
|
||||
private blockingsRepository: BlockingsRepository,
|
||||
private channelFollowingsRepository: ChannelFollowingsRepository,
|
||||
private userProfilesRepository: UserProfilesRepository,
|
||||
private channelsService: ChannelsService,
|
||||
private globalEventService: GlobalEventService,
|
||||
private noteReadService: NoteReadService,
|
||||
private notificationService: NotificationService,
|
||||
|
||||
wsConnection: websocket.connection,
|
||||
subscriber: EventEmitter,
|
||||
user: User | null | undefined,
|
||||
@@ -173,7 +183,7 @@ export default class Connection {
|
||||
if (note == null) return;
|
||||
|
||||
if (this.user && (note.userId !== this.user.id)) {
|
||||
readNote(this.user.id, [note], {
|
||||
this.noteReadService.read(this.user.id, [note], {
|
||||
following: this.following,
|
||||
followingChannels: this.followingChannels,
|
||||
});
|
||||
@@ -182,7 +192,7 @@ export default class Connection {
|
||||
|
||||
private onReadNotification(payload: any) {
|
||||
if (!payload.id) return;
|
||||
readNotification(this.user!.id, [payload.id]);
|
||||
this.notificationService.readNotification(this.user!.id, [payload.id]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -253,16 +263,18 @@ export default class Connection {
|
||||
* チャンネルに接続
|
||||
*/
|
||||
public connectChannel(id: string, params: any, channel: string, pong = false) {
|
||||
if ((channels as any)[channel].requireCredential && this.user == null) {
|
||||
const channelService = this.channelsService.getChannelService(channel);
|
||||
|
||||
if (channelService.requireCredential && this.user == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 共有可能チャンネルに接続しようとしていて、かつそのチャンネルに既に接続していたら無意味なので無視
|
||||
if ((channels as any)[channel].shouldShare && this.channels.some(c => c.chName === channel)) {
|
||||
if (channelService.shouldShare && this.channels.some(c => c.chName === channel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ch: Channel = new (channels as any)[channel](id, this);
|
||||
const ch: Channel = channelService.create(id, this);
|
||||
this.channels.push(ch);
|
||||
ch.init(params);
|
||||
|
||||
@@ -299,22 +311,22 @@ export default class Connection {
|
||||
|
||||
private typingOnChannel(channel: ChannelModel['id']) {
|
||||
if (this.user) {
|
||||
publishChannelStream(channel, 'typing', this.user.id);
|
||||
this.globalEventService.publishChannelStream(channel, 'typing', this.user.id);
|
||||
}
|
||||
}
|
||||
|
||||
private typingOnMessaging(param: { partner?: User['id']; group?: UserGroup['id']; }) {
|
||||
if (this.user) {
|
||||
if (param.partner) {
|
||||
publishMessagingStream(param.partner, this.user.id, 'typing', this.user.id);
|
||||
this.globalEventService.publishMessagingStream(param.partner, this.user.id, 'typing', this.user.id);
|
||||
} else if (param.group) {
|
||||
publishGroupMessagingStream(param.group, 'typing', this.user.id);
|
||||
this.globalEventService.publishGroupMessagingStream(param.group, 'typing', this.user.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async updateFollowing() {
|
||||
const followings = await Followings.find({
|
||||
const followings = await this.followingsRepository.find({
|
||||
where: {
|
||||
followerId: this.user!.id,
|
||||
},
|
||||
@@ -325,7 +337,7 @@ export default class Connection {
|
||||
}
|
||||
|
||||
private async updateMuting() {
|
||||
const mutings = await Mutings.find({
|
||||
const mutings = await this.mutingsRepository.find({
|
||||
where: {
|
||||
muterId: this.user!.id,
|
||||
},
|
||||
@@ -336,7 +348,7 @@ export default class Connection {
|
||||
}
|
||||
|
||||
private async updateBlocking() { // ここでいうBlockingは被Blockingの意
|
||||
const blockings = await Blockings.find({
|
||||
const blockings = await this.blockingsRepository.find({
|
||||
where: {
|
||||
blockeeId: this.user!.id,
|
||||
},
|
||||
@@ -347,7 +359,7 @@ export default class Connection {
|
||||
}
|
||||
|
||||
private async updateFollowingChannels() {
|
||||
const followings = await ChannelFollowings.find({
|
||||
const followings = await this.channelFollowingsRepository.find({
|
||||
where: {
|
||||
followerId: this.user!.id,
|
||||
},
|
||||
@@ -358,7 +370,7 @@ export default class Connection {
|
||||
}
|
||||
|
||||
private async updateUserProfile() {
|
||||
this.userProfile = await UserProfiles.findOneBy({
|
||||
this.userProfile = await this.userProfilesRepository.findOneBy({
|
||||
userId: this.user!.id,
|
||||
});
|
||||
}
|
||||
|
@@ -1,21 +1,20 @@
|
||||
import { EventEmitter } from 'events';
|
||||
import Emitter from 'strict-event-emitter-types';
|
||||
import { Channel } from '@/models/entities/channel.js';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
import { UserProfile } from '@/models/entities/user-profile.js';
|
||||
import { Note } from '@/models/entities/note.js';
|
||||
import { Antenna } from '@/models/entities/antenna.js';
|
||||
import { DriveFile } from '@/models/entities/drive-file.js';
|
||||
import { DriveFolder } from '@/models/entities/drive-folder.js';
|
||||
import { Emoji } from '@/models/entities/emoji.js';
|
||||
import { UserList } from '@/models/entities/user-list.js';
|
||||
import { MessagingMessage } from '@/models/entities/messaging-message.js';
|
||||
import { UserGroup } from '@/models/entities/user-group.js';
|
||||
import { AbuseUserReport } from '@/models/entities/abuse-user-report.js';
|
||||
import { Signin } from '@/models/entities/signin.js';
|
||||
import { Page } from '@/models/entities/page.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import { Webhook } from '@/models/entities/webhook';
|
||||
import type { Channel } from '@/models/entities/Channel.js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import type { UserProfile } from '@/models/entities/UserProfile.js';
|
||||
import type { Note } from '@/models/entities/Note.js';
|
||||
import type { Antenna } from '@/models/entities/Antenna.js';
|
||||
import type { DriveFile } from '@/models/entities/DriveFile.js';
|
||||
import type { DriveFolder } from '@/models/entities/DriveFolder.js';
|
||||
import type { UserList } from '@/models/entities/UserList.js';
|
||||
import type { MessagingMessage } from '@/models/entities/MessagingMessage.js';
|
||||
import type { UserGroup } from '@/models/entities/UserGroup.js';
|
||||
import type { AbuseUserReport } from '@/models/entities/AbuseUserReport.js';
|
||||
import type { Signin } from '@/models/entities/Signin.js';
|
||||
import type { Page } from '@/models/entities/Page.js';
|
||||
import type { Packed } from '@/misc/schema.js';
|
||||
import type { Webhook } from '@/models/entities/Webhook.js';
|
||||
import type Emitter from 'strict-event-emitter-types';
|
||||
import type { EventEmitter } from 'events';
|
||||
|
||||
//#region Stream type-body definitions
|
||||
export interface InternalStreamTypes {
|
||||
|
Reference in New Issue
Block a user