merge upstream 2025-02-03

This commit is contained in:
Hazelnoot 2025-02-03 14:31:26 -05:00
commit a4e86758c1
264 changed files with 15775 additions and 4919 deletions

View file

@ -4,10 +4,10 @@
*/
import { Inject, Injectable } from '@nestjs/common';
import { In } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { EmojisRepository } from '@/models/_.js';
import type { EmojisRepository, MiRole, RolesRepository } from '@/models/_.js';
import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/Blocking.js';
import type { MiEmoji } from '@/models/Emoji.js';
import { bindThis } from '@/decorators.js';
@ -16,6 +16,8 @@ export class EmojiEntityService {
constructor(
@Inject(DI.emojisRepository)
private emojisRepository: EmojisRepository,
@Inject(DI.rolesRepository)
private rolesRepository: RolesRepository,
) {
}
@ -68,8 +70,90 @@ export class EmojiEntityService {
@bindThis
public packDetailedMany(
emojis: any[],
) {
): Promise<Packed<'EmojiDetailed'>[]> {
return Promise.all(emojis.map(x => this.packDetailed(x)));
}
@bindThis
public async packDetailedAdmin(
src: MiEmoji['id'] | MiEmoji,
hint?: {
roles?: Map<MiRole['id'], MiRole>
},
): Promise<Packed<'EmojiDetailedAdmin'>> {
const emoji = typeof src === 'object' ? src : await this.emojisRepository.findOneByOrFail({ id: src });
const roles = Array.of<MiRole>();
if (emoji.roleIdsThatCanBeUsedThisEmojiAsReaction.length > 0) {
if (hint?.roles) {
const hintRoles = hint.roles;
roles.push(
...emoji.roleIdsThatCanBeUsedThisEmojiAsReaction
.filter(x => hintRoles.has(x))
.map(x => hintRoles.get(x)!),
);
} else {
roles.push(
...await this.rolesRepository.findBy({ id: In(emoji.roleIdsThatCanBeUsedThisEmojiAsReaction) }),
);
}
roles.sort((a, b) => {
if (a.displayOrder !== b.displayOrder) {
return b.displayOrder - a.displayOrder;
}
return a.id.localeCompare(b.id);
});
}
return {
id: emoji.id,
updatedAt: emoji.updatedAt?.toISOString() ?? null,
name: emoji.name,
host: emoji.host,
uri: emoji.uri,
type: emoji.type,
aliases: emoji.aliases,
category: emoji.category,
publicUrl: emoji.publicUrl,
originalUrl: emoji.originalUrl,
license: emoji.license,
localOnly: emoji.localOnly,
isSensitive: emoji.isSensitive,
roleIdsThatCanBeUsedThisEmojiAsReaction: roles.map(it => ({ id: it.id, name: it.name })),
};
}
@bindThis
public async packDetailedAdminMany(
emojis: MiEmoji['id'][] | MiEmoji[],
hint?: {
roles?: Map<MiRole['id'], MiRole>
},
): Promise<Packed<'EmojiDetailedAdmin'>[]> {
// IDのみの要素をピックアップし、DBからレコードを取り出して他の値を補完する
const emojiEntities = emojis.filter(x => typeof x === 'object') as MiEmoji[];
const emojiIdOnlyList = emojis.filter(x => typeof x === 'string') as string[];
if (emojiIdOnlyList.length > 0) {
emojiEntities.push(...await this.emojisRepository.findBy({ id: In(emojiIdOnlyList) }));
}
// 特定ロール専用の絵文字である場合、そのロール情報をあらかじめまとめて取得しておくpack側で都度取得も出来るが負荷が高いので
let hintRoles: Map<MiRole['id'], MiRole>;
if (hint?.roles) {
hintRoles = hint.roles;
} else {
const roles = Array.of<MiRole>();
const roleIds = [...new Set(emojiEntities.flatMap(x => x.roleIdsThatCanBeUsedThisEmojiAsReaction))];
if (roleIds.length > 0) {
roles.push(...await this.rolesRepository.findBy({ id: In(roleIds) }));
}
hintRoles = new Map(roles.map(x => [x.id, x]));
}
return Promise.all(emojis.map(x => this.packDetailedAdmin(x, { roles: hintRoles })));
}
}

View file

@ -145,6 +145,7 @@ export class MetaEntityService {
enableUrlPreview: instance.urlPreviewEnabled,
noteSearchableScope: (this.config.meilisearch == null || this.config.meilisearch.scope !== 'local') ? 'global' : 'local',
maxFileSize: this.config.maxFileSize,
federation: this.meta.federation,
};
return packed;

View file

@ -110,8 +110,7 @@ export class NoteEntityService implements OnModuleInit {
}
@bindThis
private async hideNote(packedNote: Packed<'Note'>, meId: MiUser['id'] | null): Promise<void> {
// FIXME: このvisibility変更処理が当関数にあるのは若干不自然かもしれない(関数名を treatVisibility とかに変える手もある)
private treatVisibility(packedNote: Packed<'Note'>): Packed<'Note'>['visibility'] {
if (packedNote.visibility === 'public' || packedNote.visibility === 'home') {
const followersOnlyBefore = packedNote.user.makeNotesFollowersOnlyBefore;
if ((followersOnlyBefore != null)
@ -123,7 +122,11 @@ export class NoteEntityService implements OnModuleInit {
packedNote.visibility = 'followers';
}
}
return packedNote.visibility;
}
@bindThis
private async hideNote(packedNote: Packed<'Note'>, meId: MiUser['id'] | null): Promise<void> {
if (meId === packedNote.userId) return;
// TODO: isVisibleForMe を使うようにしても良さそう(型違うけど)
@ -500,6 +503,8 @@ export class NoteEntityService implements OnModuleInit {
} : {}),
});
this.treatVisibility(packed);
if (!opts.skipHide) {
await this.hideNote(packed, meId);
}