FoundKey/src/server/api/stream/channels/channel.ts
tamaina 69b56f6658
refactor: publishHogeStreamとStreamのEventEmitterに型定義する (#7769)
* wip

* wip

* wip

* ✌️

* add main stream

* packedNotificationSchemaを更新

* read:gallery, write:gallery, read:gallery-likes, write:gallery-likesに翻訳を追加

* fix

* ok

* add header, choice, invitation

* add header, choice, invitation

* test

* fix

* fix

* yatta

* remove no longer needed "as PackedUser/PackedNote"

* clean up

* add simple-schema

* fix lint

* fix lint

* wip

* wip!

* wip

* fix

* wip

* wip

* ✌️

* 送信側に型エラーがないことを3回確認した

* ✌️

* wip

* update typescript

* define items in full Schema

* edit comment

* edit comment

* edit comment

* Update src/prelude/types.ts

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>

* https://github.com/misskey-dev/misskey/pull/7769#discussion_r703058458

* user packとnote packの型不整合を修正

* revert https://github.com/misskey-dev/misskey/pull/7772#discussion_r706627736

* revert https://github.com/misskey-dev/misskey/pull/7772#discussion_r706627736

* user packとnote packの型不整合を修正

* add prelude/types.ts

* emoji

* signin

* game

* matching

* clean up

* ev => data

* refactor

* clean up

* add type

* antenna

* channel

* fix

* add Packed type

* add PackedRef

* fix lint

* add emoji schema

* add reversiGame

* add reversiMatching

* remove signin schema (use Signin entity)

* add schemas refs, fix Packed type

* wip PackedHoge => Packed<'Hoge'>

* add Packed type

* note-reaction

* user

* user-group

* user-list

* note

* app, messaging-message

* notification

* drive-file

* drive-folder

* following

* muting

* blocking

* hashtag

* page

* app (with modifying schema)

* import user?

* channel

* antenna

* clip

* gallery-post

* emoji

* Packed

* reversi-matching

* update stream.ts

* https://github.com/misskey-dev/misskey/pull/7769#issuecomment-917542339

* fix lint

* clean up?

* add changelog

* add changelog

* add changelog

* fix: アンテナが既読にならないのを修正

* revert fix

* https://github.com/misskey-dev/misskey/pull/7769#discussion_r711474875

* spec => payload

* edit commetn

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
2021-10-21 01:04:10 +09:00

93 lines
2.6 KiB
TypeScript

import autobind from 'autobind-decorator';
import Channel from '../channel';
import { Notes, Users } from '@/models/index';
import { isMutedUserRelated } from '@/misc/is-muted-user-related';
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
import { User } from '@/models/entities/user';
import { StreamMessages } from '../types';
import { Packed } from '@/misc/schema';
export default class extends Channel {
public readonly chName = 'channel';
public static shouldShare = false;
public static requireCredential = false;
private channelId: string;
private typers: Record<User['id'], Date> = {};
private emitTypersIntervalId: ReturnType<typeof setInterval>;
@autobind
public async init(params: any) {
this.channelId = params.channelId as string;
// Subscribe stream
this.subscriber.on('notesStream', this.onNote);
this.subscriber.on(`channelStream:${this.channelId}`, this.onEvent);
this.emitTypersIntervalId = setInterval(this.emitTypers, 5000);
}
@autobind
private async onNote(note: Packed<'Note'>) {
if (note.channelId !== this.channelId) return;
// リプライなら再pack
if (note.replyId != null) {
note.reply = await Notes.pack(note.replyId, this.user, {
detail: true
});
}
// Renoteなら再pack
if (note.renoteId != null) {
note.renote = await Notes.pack(note.renoteId, this.user, {
detail: true
});
}
// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
if (isMutedUserRelated(note, this.muting)) return;
// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
if (isBlockerUserRelated(note, this.blocking)) return;
this.connection.cacheNote(note);
this.send('note', note);
}
@autobind
private onEvent(data: StreamMessages['channel']['payload']) {
if (data.type === 'typing') {
const id = data.body;
const begin = this.typers[id] == null;
this.typers[id] = new Date();
if (begin) {
this.emitTypers();
}
}
}
@autobind
private async emitTypers() {
const now = new Date();
// Remove not typing users
for (const [userId, date] of Object.entries(this.typers)) {
if (now.getTime() - date.getTime() > 5000) delete this.typers[userId];
}
const users = await Users.packMany(Object.keys(this.typers), null, { detail: false });
this.send({
type: 'typers',
body: users,
});
}
@autobind
public dispose() {
// Unsubscribe events
this.subscriber.off('notesStream', this.onNote);
this.subscriber.off(`channelStream:${this.channelId}`, this.onEvent);
clearInterval(this.emitTypersIntervalId);
}
}