note
This commit is contained in:
parent
c9926414a0
commit
677a6aae2a
|
@ -3,13 +3,13 @@ import { Note } from '@/models/entities/note';
|
||||||
import { User } from '@/models/entities/user';
|
import { User } from '@/models/entities/user';
|
||||||
import { UserListJoinings, UserGroupJoinings } from '@/models/index';
|
import { UserListJoinings, UserGroupJoinings } from '@/models/index';
|
||||||
import { getFullApAccount } from './convert-host';
|
import { getFullApAccount } from './convert-host';
|
||||||
import { PackedNote } from '../models/repositories/note';
|
|
||||||
import { parseAcct } from '@/misc/acct';
|
import { parseAcct } from '@/misc/acct';
|
||||||
|
import { Packed } from './schema';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* noteUserFollowers / antennaUserFollowing はどちらか一方が指定されていればよい
|
* noteUserFollowers / antennaUserFollowing はどちらか一方が指定されていればよい
|
||||||
*/
|
*/
|
||||||
export async function checkHitAntenna(antenna: Antenna, note: (Note | PackedNote), noteUser: { username: string; host: string | null; }, noteUserFollowers?: User['id'][], antennaUserFollowing?: User['id'][]): Promise<boolean> {
|
export async function checkHitAntenna(antenna: Antenna, note: (Note | Packed<'Note'>), noteUser: { username: string; host: string | null; }, noteUserFollowers?: User['id'][], antennaUserFollowing?: User['id'][]): Promise<boolean> {
|
||||||
if (note.visibility === 'specified') return false;
|
if (note.visibility === 'specified') return false;
|
||||||
|
|
||||||
if (note.visibility === 'followers') {
|
if (note.visibility === 'followers') {
|
||||||
|
|
|
@ -3,15 +3,13 @@ import * as mfm from 'mfm-js';
|
||||||
import { Note } from '@/models/entities/note';
|
import { Note } from '@/models/entities/note';
|
||||||
import { User } from '@/models/entities/user';
|
import { User } from '@/models/entities/user';
|
||||||
import { Users, PollVotes, DriveFiles, NoteReactions, Followings, Polls, Channels } from '../index';
|
import { Users, PollVotes, DriveFiles, NoteReactions, Followings, Polls, Channels } from '../index';
|
||||||
import { SchemaType } from '@/misc/schema';
|
import { Packed } from '@/misc/schema';
|
||||||
import { nyaize } from '@/misc/nyaize';
|
import { nyaize } from '@/misc/nyaize';
|
||||||
import { awaitAll } from '@/prelude/await-all';
|
import { awaitAll } from '@/prelude/await-all';
|
||||||
import { convertLegacyReaction, convertLegacyReactions, decodeReaction } from '@/misc/reaction-lib';
|
import { convertLegacyReaction, convertLegacyReactions, decodeReaction } from '@/misc/reaction-lib';
|
||||||
import { NoteReaction } from '@/models/entities/note-reaction';
|
import { NoteReaction } from '@/models/entities/note-reaction';
|
||||||
import { aggregateNoteEmojis, populateEmojis, prefetchEmojis } from '@/misc/populate-emojis';
|
import { aggregateNoteEmojis, populateEmojis, prefetchEmojis } from '@/misc/populate-emojis';
|
||||||
|
|
||||||
export type PackedNote = SchemaType<typeof packedNoteSchema>;
|
|
||||||
|
|
||||||
@EntityRepository(Note)
|
@EntityRepository(Note)
|
||||||
export class NoteRepository extends Repository<Note> {
|
export class NoteRepository extends Repository<Note> {
|
||||||
public validateCw(x: string) {
|
public validateCw(x: string) {
|
||||||
|
@ -67,7 +65,7 @@ export class NoteRepository extends Repository<Note> {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async hideNote(packedNote: PackedNote, meId: User['id'] | null) {
|
private async hideNote(packedNote: Packed<'Note'>, meId: User['id'] | null) {
|
||||||
// TODO: isVisibleForMe を使うようにしても良さそう(型違うけど)
|
// TODO: isVisibleForMe を使うようにしても良さそう(型違うけど)
|
||||||
let hide = false;
|
let hide = false;
|
||||||
|
|
||||||
|
@ -137,7 +135,7 @@ export class NoteRepository extends Repository<Note> {
|
||||||
myReactions: Map<Note['id'], NoteReaction | null>;
|
myReactions: Map<Note['id'], NoteReaction | null>;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
): Promise<PackedNote> {
|
): Promise<Packed<'Note'>> {
|
||||||
const opts = Object.assign({
|
const opts = Object.assign({
|
||||||
detail: true,
|
detail: true,
|
||||||
skipHide: false
|
skipHide: false
|
||||||
|
|
|
@ -3,8 +3,8 @@ import Channel from '../channel';
|
||||||
import { Notes, Users } from '@/models/index';
|
import { Notes, Users } from '@/models/index';
|
||||||
import { isMutedUserRelated } from '@/misc/is-muted-user-related';
|
import { isMutedUserRelated } from '@/misc/is-muted-user-related';
|
||||||
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
|
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
|
||||||
import { PackedNote } from '@/models/repositories/note';
|
|
||||||
import { User } from '@/models/entities/user';
|
import { User } from '@/models/entities/user';
|
||||||
|
import { Packed } from '@/misc/schema';
|
||||||
|
|
||||||
export default class extends Channel {
|
export default class extends Channel {
|
||||||
public readonly chName = 'channel';
|
public readonly chName = 'channel';
|
||||||
|
@ -25,7 +25,7 @@ export default class extends Channel {
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
private async onNote(note: PackedNote) {
|
private async onNote(note: Packed<'Note'>) {
|
||||||
if (note.channelId !== this.channelId) return;
|
if (note.channelId !== this.channelId) return;
|
||||||
|
|
||||||
// リプライなら再pack
|
// リプライなら再pack
|
||||||
|
|
|
@ -3,9 +3,9 @@ import { isMutedUserRelated } from '@/misc/is-muted-user-related';
|
||||||
import Channel from '../channel';
|
import Channel from '../channel';
|
||||||
import { fetchMeta } from '@/misc/fetch-meta';
|
import { fetchMeta } from '@/misc/fetch-meta';
|
||||||
import { Notes } from '@/models/index';
|
import { Notes } from '@/models/index';
|
||||||
import { PackedNote } from '@/models/repositories/note';
|
|
||||||
import { checkWordMute } from '@/misc/check-word-mute';
|
import { checkWordMute } from '@/misc/check-word-mute';
|
||||||
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
|
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
|
||||||
|
import { Packed } from '@/misc/schema';
|
||||||
|
|
||||||
export default class extends Channel {
|
export default class extends Channel {
|
||||||
public readonly chName = 'globalTimeline';
|
public readonly chName = 'globalTimeline';
|
||||||
|
@ -24,7 +24,7 @@ export default class extends Channel {
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
private async onNote(note: PackedNote) {
|
private async onNote(note: Packed<'Note'>) {
|
||||||
if (note.visibility !== 'public') return;
|
if (note.visibility !== 'public') return;
|
||||||
if (note.channelId != null) return;
|
if (note.channelId != null) return;
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,9 @@ import autobind from 'autobind-decorator';
|
||||||
import { isMutedUserRelated } from '@/misc/is-muted-user-related';
|
import { isMutedUserRelated } from '@/misc/is-muted-user-related';
|
||||||
import Channel from '../channel';
|
import Channel from '../channel';
|
||||||
import { Notes } from '@/models/index';
|
import { Notes } from '@/models/index';
|
||||||
import { PackedNote } from '@/models/repositories/note';
|
|
||||||
import { normalizeForSearch } from '@/misc/normalize-for-search';
|
import { normalizeForSearch } from '@/misc/normalize-for-search';
|
||||||
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
|
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
|
||||||
|
import { Packed } from '@/misc/schema';
|
||||||
|
|
||||||
export default class extends Channel {
|
export default class extends Channel {
|
||||||
public readonly chName = 'hashtag';
|
public readonly chName = 'hashtag';
|
||||||
|
@ -23,7 +23,7 @@ export default class extends Channel {
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
private async onNote(note: PackedNote) {
|
private async onNote(note: Packed<'Note'>) {
|
||||||
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;
|
||||||
|
|
|
@ -2,9 +2,9 @@ import autobind from 'autobind-decorator';
|
||||||
import { isMutedUserRelated } from '@/misc/is-muted-user-related';
|
import { isMutedUserRelated } from '@/misc/is-muted-user-related';
|
||||||
import Channel from '../channel';
|
import Channel from '../channel';
|
||||||
import { Notes } from '@/models/index';
|
import { Notes } from '@/models/index';
|
||||||
import { PackedNote } from '@/models/repositories/note';
|
|
||||||
import { checkWordMute } from '@/misc/check-word-mute';
|
import { checkWordMute } from '@/misc/check-word-mute';
|
||||||
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
|
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
|
||||||
|
import { Packed } from '@/misc/schema';
|
||||||
|
|
||||||
export default class extends Channel {
|
export default class extends Channel {
|
||||||
public readonly chName = 'homeTimeline';
|
public readonly chName = 'homeTimeline';
|
||||||
|
@ -18,7 +18,7 @@ export default class extends Channel {
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
private async onNote(note: PackedNote) {
|
private async onNote(note: Packed<'Note'>) {
|
||||||
if (note.channelId) {
|
if (note.channelId) {
|
||||||
if (!this.followingChannels.has(note.channelId)) return;
|
if (!this.followingChannels.has(note.channelId)) return;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -3,9 +3,9 @@ import { isMutedUserRelated } from '@/misc/is-muted-user-related';
|
||||||
import Channel from '../channel';
|
import Channel from '../channel';
|
||||||
import { fetchMeta } from '@/misc/fetch-meta';
|
import { fetchMeta } from '@/misc/fetch-meta';
|
||||||
import { Notes } from '@/models/index';
|
import { Notes } from '@/models/index';
|
||||||
import { PackedNote } from '@/models/repositories/note';
|
|
||||||
import { checkWordMute } from '@/misc/check-word-mute';
|
import { checkWordMute } from '@/misc/check-word-mute';
|
||||||
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
|
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
|
||||||
|
import { Packed } from '@/misc/schema';
|
||||||
|
|
||||||
export default class extends Channel {
|
export default class extends Channel {
|
||||||
public readonly chName = 'hybridTimeline';
|
public readonly chName = 'hybridTimeline';
|
||||||
|
@ -22,7 +22,7 @@ export default class extends Channel {
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
private async onNote(note: PackedNote) {
|
private async onNote(note: Packed<'Note'>) {
|
||||||
// チャンネルの投稿ではなく、自分自身の投稿 または
|
// チャンネルの投稿ではなく、自分自身の投稿 または
|
||||||
// チャンネルの投稿ではなく、その投稿のユーザーをフォローしている または
|
// チャンネルの投稿ではなく、その投稿のユーザーをフォローしている または
|
||||||
// チャンネルの投稿ではなく、全体公開のローカルの投稿 または
|
// チャンネルの投稿ではなく、全体公開のローカルの投稿 または
|
||||||
|
|
|
@ -3,9 +3,9 @@ import { isMutedUserRelated } from '@/misc/is-muted-user-related';
|
||||||
import Channel from '../channel';
|
import Channel from '../channel';
|
||||||
import { fetchMeta } from '@/misc/fetch-meta';
|
import { fetchMeta } from '@/misc/fetch-meta';
|
||||||
import { Notes } from '@/models/index';
|
import { Notes } from '@/models/index';
|
||||||
import { PackedNote } from '@/models/repositories/note';
|
|
||||||
import { checkWordMute } from '@/misc/check-word-mute';
|
import { checkWordMute } from '@/misc/check-word-mute';
|
||||||
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
|
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
|
||||||
|
import { Packed } from '@/misc/schema';
|
||||||
|
|
||||||
export default class extends Channel {
|
export default class extends Channel {
|
||||||
public readonly chName = 'localTimeline';
|
public readonly chName = 'localTimeline';
|
||||||
|
@ -24,7 +24,7 @@ export default class extends Channel {
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
private async onNote(note: PackedNote) {
|
private async onNote(note: Packed<'Note'>) {
|
||||||
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;
|
||||||
|
|
|
@ -3,8 +3,8 @@ import Channel from '../channel';
|
||||||
import { Notes, UserListJoinings, UserLists } from '@/models/index';
|
import { Notes, UserListJoinings, UserLists } from '@/models/index';
|
||||||
import { isMutedUserRelated } from '@/misc/is-muted-user-related';
|
import { isMutedUserRelated } from '@/misc/is-muted-user-related';
|
||||||
import { User } from '@/models/entities/user';
|
import { User } from '@/models/entities/user';
|
||||||
import { PackedNote } from '@/models/repositories/note';
|
|
||||||
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
|
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
|
||||||
|
import { Packed } from '@/misc/schema';
|
||||||
|
|
||||||
export default class extends Channel {
|
export default class extends Channel {
|
||||||
public readonly chName = 'userList';
|
public readonly chName = 'userList';
|
||||||
|
@ -47,7 +47,7 @@ export default class extends Channel {
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
private async onNote(note: PackedNote) {
|
private async onNote(note: Packed<'Note'>) {
|
||||||
if (!this.listUsers.includes(note.userId)) return;
|
if (!this.listUsers.includes(note.userId)) return;
|
||||||
|
|
||||||
if (['followers', 'specified'].includes(note.visibility)) {
|
if (['followers', 'specified'].includes(note.visibility)) {
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { AccessToken } from '@/models/entities/access-token';
|
||||||
import { UserProfile } from '@/models/entities/user-profile';
|
import { UserProfile } from '@/models/entities/user-profile';
|
||||||
import { publishChannelStream, publishGroupMessagingStream, publishMessagingStream } from '@/services/stream';
|
import { publishChannelStream, publishGroupMessagingStream, publishMessagingStream } from '@/services/stream';
|
||||||
import { UserGroup } from '@/models/entities/user-group';
|
import { UserGroup } from '@/models/entities/user-group';
|
||||||
import { PackedNote } from '@/models/repositories/note';
|
import { Packed } from '@/misc/schema';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main stream connection
|
* Main stream connection
|
||||||
|
@ -31,7 +31,7 @@ export default class Connection {
|
||||||
public subscriber: EventEmitter;
|
public subscriber: EventEmitter;
|
||||||
private channels: Channel[] = [];
|
private channels: Channel[] = [];
|
||||||
private subscribingNotes: any = {};
|
private subscribingNotes: any = {};
|
||||||
private cachedNotes: PackedNote[] = [];
|
private cachedNotes: Packed<'Note'>[] = [];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
wsConnection: websocket.connection,
|
wsConnection: websocket.connection,
|
||||||
|
@ -150,8 +150,8 @@ export default class Connection {
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
public cacheNote(note: PackedNote) {
|
public cacheNote(note: Packed<'Note'>) {
|
||||||
const add = (note: PackedNote) => {
|
const add = (note: Packed<'Note'>) => {
|
||||||
const existIndex = this.cachedNotes.findIndex(n => n.id === note.id);
|
const existIndex = this.cachedNotes.findIndex(n => n.id === note.id);
|
||||||
if (existIndex > -1) {
|
if (existIndex > -1) {
|
||||||
this.cachedNotes[existIndex] = note;
|
this.cachedNotes[existIndex] = note;
|
||||||
|
|
|
@ -6,15 +6,15 @@ import { Not, IsNull, In } from 'typeorm';
|
||||||
import { Channel } from '@/models/entities/channel';
|
import { Channel } from '@/models/entities/channel';
|
||||||
import { checkHitAntenna } from '@/misc/check-hit-antenna';
|
import { checkHitAntenna } from '@/misc/check-hit-antenna';
|
||||||
import { getAntennas } from '@/misc/antenna-cache';
|
import { getAntennas } from '@/misc/antenna-cache';
|
||||||
import { PackedNote } from '@/models/repositories/note';
|
|
||||||
import { readNotificationByQuery } from '@/server/api/common/read-notification';
|
import { readNotificationByQuery } from '@/server/api/common/read-notification';
|
||||||
|
import { Packed } from '@/misc/schema';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark notes as read
|
* Mark notes as read
|
||||||
*/
|
*/
|
||||||
export default async function(
|
export default async function(
|
||||||
userId: User['id'],
|
userId: User['id'],
|
||||||
notes: (Note | PackedNote)[],
|
notes: (Note | Packed<'Note'>)[],
|
||||||
info?: {
|
info?: {
|
||||||
following: Set<User['id']>;
|
following: Set<User['id']>;
|
||||||
followingChannels: Set<Channel['id']>;
|
followingChannels: Set<Channel['id']>;
|
||||||
|
@ -34,10 +34,10 @@ export default async function(
|
||||||
})).map(x => x.followeeId));
|
})).map(x => x.followeeId));
|
||||||
|
|
||||||
const myAntennas = (await getAntennas()).filter(a => a.userId === userId);
|
const myAntennas = (await getAntennas()).filter(a => a.userId === userId);
|
||||||
const readMentions: (Note | PackedNote)[] = [];
|
const readMentions: (Note | Packed<'Note'>)[] = [];
|
||||||
const readSpecifiedNotes: (Note | PackedNote)[] = [];
|
const readSpecifiedNotes: (Note | Packed<'Note'>)[] = [];
|
||||||
const readChannelNotes: (Note | PackedNote)[] = [];
|
const readChannelNotes: (Note | Packed<'Note'>)[] = [];
|
||||||
const readAntennaNotes: (Note | PackedNote)[] = [];
|
const readAntennaNotes: (Note | Packed<'Note'>)[] = [];
|
||||||
|
|
||||||
for (const note of notes) {
|
for (const note of notes) {
|
||||||
if (note.mentions && note.mentions.includes(userId)) {
|
if (note.mentions && note.mentions.includes(userId)) {
|
||||||
|
@ -52,7 +52,7 @@ export default async function(
|
||||||
|
|
||||||
if (note.user != null) { // たぶんnullになることは無いはずだけど一応
|
if (note.user != null) { // たぶんnullになることは無いはずだけど一応
|
||||||
for (const antenna of myAntennas) {
|
for (const antenna of myAntennas) {
|
||||||
if (checkHitAntenna(antenna, note, note.user as any, undefined, Array.from(following))) {
|
if (await checkHitAntenna(antenna, note, note.user as any, undefined, Array.from(following))) {
|
||||||
readAntennaNotes.push(note);
|
readAntennaNotes.push(note);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue