Merge remote-tracking branch 'misskey-original/develop' into develop
# Conflicts: # locales/index.d.ts # locales/ja-JP.yml # package.json # packages/backend/src/core/entities/NoteEntityService.ts # packages/backend/src/models/Note.ts # packages/backend/src/server/api/endpoints/roles/notes.ts # packages/backend/src/server/api/stream/channels/global-timeline.ts # packages/backend/src/server/api/stream/channels/home-timeline.ts # packages/backend/src/server/api/stream/channels/hybrid-timeline.ts # packages/backend/src/server/api/stream/channels/local-timeline.ts # packages/frontend/src/components/MkFollowButton.vue # packages/frontend/src/pages/settings/general.vue # packages/frontend/src/pages/timeline.vue # packages/frontend/src/pages/user/home.vue # packages/frontend/src/store.ts
This commit is contained in:
commit
eacb74cb44
246 changed files with 2381 additions and 1867 deletions
|
|
@ -9,6 +9,7 @@ import type { AbuseUserReportsRepository } from '@/models/_.js';
|
|||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import type { MiAbuseUserReport } from '@/models/AbuseUserReport.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -18,6 +19,7 @@ export class AbuseUserReportEntityService {
|
|||
private abuseUserReportsRepository: AbuseUserReportsRepository,
|
||||
|
||||
private userEntityService: UserEntityService,
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -29,7 +31,7 @@ export class AbuseUserReportEntityService {
|
|||
|
||||
return await awaitAll({
|
||||
id: report.id,
|
||||
createdAt: report.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(report.id).date.toISOString(),
|
||||
comment: report.comment,
|
||||
resolved: report.resolved,
|
||||
reporterId: report.reporterId,
|
||||
|
|
|
|||
|
|
@ -9,12 +9,15 @@ import type { AntennasRepository } from '@/models/_.js';
|
|||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { MiAntenna } from '@/models/Antenna.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
|
||||
@Injectable()
|
||||
export class AntennaEntityService {
|
||||
constructor(
|
||||
@Inject(DI.antennasRepository)
|
||||
private antennasRepository: AntennasRepository,
|
||||
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -26,7 +29,7 @@ export class AntennaEntityService {
|
|||
|
||||
return {
|
||||
id: antenna.id,
|
||||
createdAt: antenna.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(antenna.id).date.toISOString(),
|
||||
name: antenna.name,
|
||||
keywords: antenna.keywords,
|
||||
excludeKeywords: antenna.excludeKeywords,
|
||||
|
|
@ -34,6 +37,7 @@ export class AntennaEntityService {
|
|||
userListId: antenna.userListId,
|
||||
users: antenna.users,
|
||||
caseSensitive: antenna.caseSensitive,
|
||||
localOnly: antenna.localOnly,
|
||||
notify: antenna.notify,
|
||||
withReplies: antenna.withReplies,
|
||||
withFile: antenna.withFile,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import type { Packed } from '@/misc/json-schema.js';
|
|||
import type { MiBlocking } from '@/models/Blocking.js';
|
||||
import type { MiUser } from '@/models/User.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -20,6 +21,7 @@ export class BlockingEntityService {
|
|||
private blockingsRepository: BlockingsRepository,
|
||||
|
||||
private userEntityService: UserEntityService,
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -32,7 +34,7 @@ export class BlockingEntityService {
|
|||
|
||||
return await awaitAll({
|
||||
id: blocking.id,
|
||||
createdAt: blocking.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(blocking.id).date.toISOString(),
|
||||
blockeeId: blocking.blockeeId,
|
||||
blockee: this.userEntityService.pack(blocking.blockeeId, me, {
|
||||
detail: true,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import type { } from '@/models/Blocking.js';
|
|||
import type { MiUser } from '@/models/User.js';
|
||||
import type { MiChannel } from '@/models/Channel.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { DriveFileEntityService } from './DriveFileEntityService.js';
|
||||
import { NoteEntityService } from './NoteEntityService.js';
|
||||
import { In } from 'typeorm';
|
||||
|
|
@ -38,6 +39,7 @@ export class ChannelEntityService {
|
|||
|
||||
private noteEntityService: NoteEntityService,
|
||||
private driveFileEntityService: DriveFileEntityService,
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -81,7 +83,7 @@ export class ChannelEntityService {
|
|||
|
||||
return {
|
||||
id: channel.id,
|
||||
createdAt: channel.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(channel.id).date.toISOString(),
|
||||
lastNotedAt: channel.lastNotedAt ? channel.lastNotedAt.toISOString() : null,
|
||||
name: channel.name,
|
||||
description: channel.description,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import type { Packed } from '@/misc/json-schema.js';
|
|||
import type { } from '@/models/Blocking.js';
|
||||
import type { MiClip } from '@/models/Clip.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -23,6 +24,7 @@ export class ClipEntityService {
|
|||
private clipFavoritesRepository: ClipFavoritesRepository,
|
||||
|
||||
private userEntityService: UserEntityService,
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -36,7 +38,7 @@ export class ClipEntityService {
|
|||
|
||||
return await awaitAll({
|
||||
id: clip.id,
|
||||
createdAt: clip.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(clip.id).date.toISOString(),
|
||||
lastClippedAt: clip.lastClippedAt ? clip.lastClippedAt.toISOString() : null,
|
||||
userId: clip.userId,
|
||||
user: this.userEntityService.pack(clip.user ?? clip.userId),
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import { deepClone } from '@/misc/clone.js';
|
|||
import { bindThis } from '@/decorators.js';
|
||||
import { isMimeImage } from '@/misc/is-mime-image.js';
|
||||
import { isNotNull } from '@/misc/is-not-null.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { UtilityService } from '../UtilityService.js';
|
||||
import { VideoProcessingService } from '../VideoProcessingService.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
|
|
@ -44,6 +45,7 @@ export class DriveFileEntityService {
|
|||
private utilityService: UtilityService,
|
||||
private driveFolderEntityService: DriveFolderEntityService,
|
||||
private videoProcessingService: VideoProcessingService,
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -88,7 +90,7 @@ export class DriveFileEntityService {
|
|||
if (file.type.startsWith('video')) {
|
||||
if (file.thumbnailUrl) return file.thumbnailUrl;
|
||||
|
||||
return this.videoProcessingService.getExternalVideoThumbnailUrl(file.webpublicUrl ?? file.url ?? file.uri);
|
||||
return this.videoProcessingService.getExternalVideoThumbnailUrl(file.webpublicUrl ?? file.url);
|
||||
} else if (file.uri != null && file.userHost != null && this.config.externalMediaProxyEnabled) {
|
||||
// 動画ではなくリモートかつメディアプロキシ
|
||||
return this.getProxiedUrl(file.uri, 'static');
|
||||
|
|
@ -143,7 +145,7 @@ export class DriveFileEntityService {
|
|||
.select('SUM(file.size)', 'sum')
|
||||
.getRawOne();
|
||||
|
||||
return parseInt(sum, 10) ?? 0;
|
||||
return parseInt(sum, 10) || 0;
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
|
@ -155,7 +157,7 @@ export class DriveFileEntityService {
|
|||
.select('SUM(file.size)', 'sum')
|
||||
.getRawOne();
|
||||
|
||||
return parseInt(sum, 10) ?? 0;
|
||||
return parseInt(sum, 10) || 0;
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
|
@ -167,7 +169,7 @@ export class DriveFileEntityService {
|
|||
.select('SUM(file.size)', 'sum')
|
||||
.getRawOne();
|
||||
|
||||
return parseInt(sum, 10) ?? 0;
|
||||
return parseInt(sum, 10) || 0;
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
|
@ -179,7 +181,7 @@ export class DriveFileEntityService {
|
|||
.select('SUM(file.size)', 'sum')
|
||||
.getRawOne();
|
||||
|
||||
return parseInt(sum, 10) ?? 0;
|
||||
return parseInt(sum, 10) || 0;
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
|
@ -196,7 +198,7 @@ export class DriveFileEntityService {
|
|||
|
||||
return await awaitAll<Packed<'DriveFile'>>({
|
||||
id: file.id,
|
||||
createdAt: file.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(file.id).date.toISOString(),
|
||||
name: file.name,
|
||||
type: file.type,
|
||||
md5: file.md5,
|
||||
|
|
@ -231,7 +233,7 @@ export class DriveFileEntityService {
|
|||
|
||||
return await awaitAll<Packed<'DriveFile'>>({
|
||||
id: file.id,
|
||||
createdAt: file.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(file.id).date.toISOString(),
|
||||
name: file.name,
|
||||
type: file.type,
|
||||
md5: file.md5,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import type { Packed } from '@/misc/json-schema.js';
|
|||
import type { } from '@/models/Blocking.js';
|
||||
import type { MiDriveFolder } from '@/models/DriveFolder.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
|
||||
@Injectable()
|
||||
export class DriveFolderEntityService {
|
||||
|
|
@ -20,6 +21,8 @@ export class DriveFolderEntityService {
|
|||
|
||||
@Inject(DI.driveFilesRepository)
|
||||
private driveFilesRepository: DriveFilesRepository,
|
||||
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -38,7 +41,7 @@ export class DriveFolderEntityService {
|
|||
|
||||
return await awaitAll({
|
||||
id: folder.id,
|
||||
createdAt: folder.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(folder.id).date.toISOString(),
|
||||
name: folder.name,
|
||||
parentId: folder.parentId,
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import type { } from '@/models/Blocking.js';
|
|||
import type { MiUser } from '@/models/User.js';
|
||||
import type { MiFlash } from '@/models/Flash.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -24,6 +25,7 @@ export class FlashEntityService {
|
|||
private flashLikesRepository: FlashLikesRepository,
|
||||
|
||||
private userEntityService: UserEntityService,
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -37,7 +39,7 @@ export class FlashEntityService {
|
|||
|
||||
return await awaitAll({
|
||||
id: flash.id,
|
||||
createdAt: flash.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(flash.id).date.toISOString(),
|
||||
updatedAt: flash.updatedAt.toISOString(),
|
||||
userId: flash.userId,
|
||||
user: this.userEntityService.pack(flash.user ?? flash.userId, me), // { detail: true } すると無限ループするので注意
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import type { } from '@/models/Blocking.js';
|
|||
import type { MiUser } from '@/models/User.js';
|
||||
import type { MiFollowing } from '@/models/Following.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
|
||||
type LocalFollowerFollowing = MiFollowing & {
|
||||
|
|
@ -45,6 +46,7 @@ export class FollowingEntityService {
|
|||
private followingsRepository: FollowingsRepository,
|
||||
|
||||
private userEntityService: UserEntityService,
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +85,7 @@ export class FollowingEntityService {
|
|||
|
||||
return await awaitAll({
|
||||
id: following.id,
|
||||
createdAt: following.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(following.id).date.toISOString(),
|
||||
followeeId: following.followeeId,
|
||||
followerId: following.followerId,
|
||||
followee: opts.populateFollowee ? this.userEntityService.pack(following.followee ?? following.followeeId, me, {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import type { } from '@/models/Blocking.js';
|
|||
import type { MiUser } from '@/models/User.js';
|
||||
import type { MiGalleryPost } from '@/models/GalleryPost.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
import { DriveFileEntityService } from './DriveFileEntityService.js';
|
||||
|
||||
|
|
@ -26,6 +27,7 @@ export class GalleryPostEntityService {
|
|||
|
||||
private userEntityService: UserEntityService,
|
||||
private driveFileEntityService: DriveFileEntityService,
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -39,7 +41,7 @@ export class GalleryPostEntityService {
|
|||
|
||||
return await awaitAll({
|
||||
id: post.id,
|
||||
createdAt: post.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(post.id).date.toISOString(),
|
||||
updatedAt: post.updatedAt.toISOString(),
|
||||
userId: post.userId,
|
||||
user: this.userEntityService.pack(post.user ?? post.userId, me),
|
||||
|
|
|
|||
|
|
@ -3,9 +3,8 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { } from '@/models/Blocking.js';
|
||||
import type { MiInstance } from '@/models/Instance.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
@ -43,6 +42,7 @@ export class InstanceEntityService {
|
|||
description: instance.description,
|
||||
maintainerName: instance.maintainerName,
|
||||
maintainerEmail: instance.maintainerEmail,
|
||||
isSilenced: this.utilityService.isSilencedHost(meta.silencedHosts, instance.host),
|
||||
iconUrl: instance.iconUrl,
|
||||
faviconUrl: instance.faviconUrl,
|
||||
themeColor: instance.themeColor,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import type { Packed } from '@/misc/json-schema.js';
|
|||
import type { MiUser } from '@/models/User.js';
|
||||
import type { MiRegistrationTicket } from '@/models/RegistrationTicket.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -20,6 +21,7 @@ export class InviteCodeEntityService {
|
|||
private registrationTicketsRepository: RegistrationTicketsRepository,
|
||||
|
||||
private userEntityService: UserEntityService,
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -39,7 +41,7 @@ export class InviteCodeEntityService {
|
|||
id: target.id,
|
||||
code: target.code,
|
||||
expiresAt: target.expiresAt ? target.expiresAt.toISOString() : null,
|
||||
createdAt: target.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(target.id).date.toISOString(),
|
||||
createdBy: target.createdBy ? await this.userEntityService.pack(target.createdBy, me) : null,
|
||||
usedBy: target.usedBy ? await this.userEntityService.pack(target.usedBy, me) : null,
|
||||
usedAt: target.usedAt ? target.usedAt.toISOString() : null,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { awaitAll } from '@/misc/prelude/await-all.js';
|
|||
import type { } from '@/models/Blocking.js';
|
||||
import type { MiModerationLog } from '@/models/ModerationLog.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -19,6 +20,7 @@ export class ModerationLogEntityService {
|
|||
private moderationLogsRepository: ModerationLogsRepository,
|
||||
|
||||
private userEntityService: UserEntityService,
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -30,7 +32,7 @@ export class ModerationLogEntityService {
|
|||
|
||||
return await awaitAll({
|
||||
id: log.id,
|
||||
createdAt: log.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(log.id).date.toISOString(),
|
||||
type: log.type,
|
||||
info: log.info,
|
||||
userId: log.userId,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import type { } from '@/models/Blocking.js';
|
|||
import type { MiUser } from '@/models/User.js';
|
||||
import type { MiMuting } from '@/models/Muting.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -21,6 +22,7 @@ export class MutingEntityService {
|
|||
private mutingsRepository: MutingsRepository,
|
||||
|
||||
private userEntityService: UserEntityService,
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -33,7 +35,7 @@ export class MutingEntityService {
|
|||
|
||||
return await awaitAll({
|
||||
id: muting.id,
|
||||
createdAt: muting.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(muting.id).date.toISOString(),
|
||||
expiresAt: muting.expiresAt ? muting.expiresAt.toISOString() : null,
|
||||
muteeId: muting.muteeId,
|
||||
mutee: this.userEntityService.pack(muting.muteeId, me, {
|
||||
|
|
|
|||
|
|
@ -5,11 +5,9 @@
|
|||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { In } from 'typeorm';
|
||||
import * as mfm from 'mfm-js';
|
||||
import { ModuleRef } from '@nestjs/core';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import { nyaize } from '@/misc/nyaize.js';
|
||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import type { MiUser } from '@/models/User.js';
|
||||
import type { MiNote } from '@/models/Note.js';
|
||||
|
|
@ -18,6 +16,7 @@ import type { UsersRepository, NotesRepository, FollowingsRepository, PollsRepos
|
|||
import { bindThis } from '@/decorators.js';
|
||||
import { isNotNull } from '@/misc/is-not-null.js';
|
||||
import { DebounceLoader } from '@/misc/loader.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import type { OnModuleInit } from '@nestjs/common';
|
||||
import type { CustomEmojiService } from '../CustomEmojiService.js';
|
||||
import type { ReactionService } from '../ReactionService.js';
|
||||
|
|
@ -30,6 +29,7 @@ export class NoteEntityService implements OnModuleInit {
|
|||
private driveFileEntityService: DriveFileEntityService;
|
||||
private customEmojiService: CustomEmojiService;
|
||||
private reactionService: ReactionService;
|
||||
private idService: IdService;
|
||||
private noteLoader = new DebounceLoader(this.findNoteOrFail);
|
||||
|
||||
constructor(
|
||||
|
|
@ -68,6 +68,7 @@ export class NoteEntityService implements OnModuleInit {
|
|||
this.driveFileEntityService = this.moduleRef.get('DriveFileEntityService');
|
||||
this.customEmojiService = this.moduleRef.get('CustomEmojiService');
|
||||
this.reactionService = this.moduleRef.get('ReactionService');
|
||||
this.idService = this.moduleRef.get('IdService');
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
|
@ -169,11 +170,11 @@ export class NoteEntityService implements OnModuleInit {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
private async populateMyReaction(note: MiNote, meId: MiUser['id'], _hint_?: {
|
||||
public async populateMyReaction(noteId: MiNote['id'], meId: MiUser['id'], _hint_?: {
|
||||
myReactions: Map<MiNote['id'], MiNoteReaction | null>;
|
||||
}) {
|
||||
if (_hint_?.myReactions) {
|
||||
const reaction = _hint_.myReactions.get(note.id);
|
||||
const reaction = _hint_.myReactions.get(noteId);
|
||||
if (reaction) {
|
||||
return this.reactionService.convertLegacyReaction(reaction.reaction);
|
||||
} else if (reaction === null) {
|
||||
|
|
@ -182,14 +183,14 @@ export class NoteEntityService implements OnModuleInit {
|
|||
// 実装上抜けがあるだけかもしれないので、「ヒントに含まれてなかったら(=undefinedなら)return」のようにはしない
|
||||
}
|
||||
|
||||
// パフォーマンスのためノートが作成されてから1秒以上経っていない場合はリアクションを取得しない
|
||||
if (note.createdAt.getTime() + 1000 > Date.now()) {
|
||||
// パフォーマンスのためノートが作成されてから2秒以上経っていない場合はリアクションを取得しない
|
||||
if (this.idService.parse(noteId).date.getTime() + 2000 > Date.now()) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const reaction = await this.noteReactionsRepository.findOneBy({
|
||||
userId: meId,
|
||||
noteId: note.id,
|
||||
noteId: noteId,
|
||||
});
|
||||
|
||||
if (reaction) {
|
||||
|
|
@ -309,7 +310,7 @@ export class NoteEntityService implements OnModuleInit {
|
|||
|
||||
const packed: Packed<'Note'> = await awaitAll({
|
||||
id: note.id,
|
||||
createdAt: note.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(note.id).date.toISOString(),
|
||||
updatedAt: note.updatedAt ? note.updatedAt.toISOString() : undefined,
|
||||
userId: note.userId,
|
||||
user: this.userEntityService.pack(note.user ?? note.userId, me, {
|
||||
|
|
@ -318,7 +319,7 @@ export class NoteEntityService implements OnModuleInit {
|
|||
text: text,
|
||||
cw: note.cw,
|
||||
visibility: note.visibility,
|
||||
localOnly: note.localOnly ?? undefined,
|
||||
localOnly: note.localOnly,
|
||||
reactionAcceptance: note.reactionAcceptance,
|
||||
visibleUserIds: note.visibility === 'specified' ? note.visibleUserIds : undefined,
|
||||
renoteCount: note.renoteCount,
|
||||
|
|
@ -358,30 +359,11 @@ export class NoteEntityService implements OnModuleInit {
|
|||
poll: note.hasPoll ? this.populatePoll(note, meId) : undefined,
|
||||
|
||||
...(meId ? {
|
||||
myReaction: this.populateMyReaction(note, meId, options?._hint_),
|
||||
myReaction: this.populateMyReaction(note.id, meId, options?._hint_),
|
||||
} : {}),
|
||||
} : {}),
|
||||
});
|
||||
|
||||
if (packed.user.isCat && packed.text) {
|
||||
const tokens = packed.text ? mfm.parse(packed.text) : [];
|
||||
function nyaizeNode(node: mfm.MfmNode) {
|
||||
if (node.type === 'quote') return;
|
||||
if (node.type === 'text') {
|
||||
node.props.text = nyaize(node.props.text);
|
||||
}
|
||||
if (node.children) {
|
||||
for (const child of node.children) {
|
||||
nyaizeNode(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const node of tokens) {
|
||||
nyaizeNode(node);
|
||||
}
|
||||
packed.text = mfm.toString(tokens);
|
||||
}
|
||||
|
||||
if (!opts.skipHide) {
|
||||
await this.hideNote(packed, meId);
|
||||
}
|
||||
|
|
@ -404,8 +386,9 @@ export class NoteEntityService implements OnModuleInit {
|
|||
const myReactionsMap = new Map<MiNote['id'], MiNoteReaction | null>();
|
||||
if (meId) {
|
||||
const renoteIds = notes.filter(n => n.renoteId != null).map(n => n.renoteId!);
|
||||
// パフォーマンスのためノートが作成されてから1秒以上経っていない場合はリアクションを取得しない
|
||||
const targets = [...notes.filter(n => n.createdAt.getTime() + 1000 < Date.now()).map(n => n.id), ...renoteIds];
|
||||
// パフォーマンスのためノートが作成されてから2秒以上経っていない場合はリアクションを取得しない
|
||||
const oldId = this.idService.gen(Date.now() - 2000);
|
||||
const targets = [...notes.filter(n => n.id < oldId).map(n => n.id), ...renoteIds];
|
||||
const myReactions = await this.noteReactionsRepository.findBy({
|
||||
userId: meId,
|
||||
noteId: In(targets),
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import type { } from '@/models/Blocking.js';
|
|||
import type { MiUser } from '@/models/User.js';
|
||||
import type { MiNoteFavorite } from '@/models/NoteFavorite.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { NoteEntityService } from './NoteEntityService.js';
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -19,6 +20,7 @@ export class NoteFavoriteEntityService {
|
|||
private noteFavoritesRepository: NoteFavoritesRepository,
|
||||
|
||||
private noteEntityService: NoteEntityService,
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -31,7 +33,7 @@ export class NoteFavoriteEntityService {
|
|||
|
||||
return {
|
||||
id: favorite.id,
|
||||
createdAt: favorite.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(favorite.id).date.toISOString(),
|
||||
noteId: favorite.noteId,
|
||||
note: await this.noteEntityService.pack(favorite.note ?? favorite.noteId, me),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { DI } from '@/di-symbols.js';
|
|||
import type { NoteReactionsRepository } from '@/models/_.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import type { OnModuleInit } from '@nestjs/common';
|
||||
import type { } from '@/models/Blocking.js';
|
||||
import type { MiUser } from '@/models/User.js';
|
||||
|
|
@ -22,6 +23,7 @@ export class NoteReactionEntityService implements OnModuleInit {
|
|||
private userEntityService: UserEntityService;
|
||||
private noteEntityService: NoteEntityService;
|
||||
private reactionService: ReactionService;
|
||||
private idService: IdService;
|
||||
|
||||
constructor(
|
||||
private moduleRef: ModuleRef,
|
||||
|
|
@ -32,6 +34,7 @@ export class NoteReactionEntityService implements OnModuleInit {
|
|||
//private userEntityService: UserEntityService,
|
||||
//private noteEntityService: NoteEntityService,
|
||||
//private reactionService: ReactionService,
|
||||
//private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -39,6 +42,7 @@ export class NoteReactionEntityService implements OnModuleInit {
|
|||
this.userEntityService = this.moduleRef.get('UserEntityService');
|
||||
this.noteEntityService = this.moduleRef.get('NoteEntityService');
|
||||
this.reactionService = this.moduleRef.get('ReactionService');
|
||||
this.idService = this.moduleRef.get('IdService');
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
|
@ -57,7 +61,7 @@ export class NoteReactionEntityService implements OnModuleInit {
|
|||
|
||||
return {
|
||||
id: reaction.id,
|
||||
createdAt: reaction.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(reaction.id).date.toISOString(),
|
||||
user: await this.userEntityService.pack(reaction.user ?? reaction.userId, me),
|
||||
type: this.reactionService.convertLegacyReaction(reaction.reaction),
|
||||
...(opts.withNote ? {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import type { MiUser } from '@/models/User.js';
|
|||
import type { MiPage } from '@/models/Page.js';
|
||||
import type { MiDriveFile } from '@/models/DriveFile.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
import { DriveFileEntityService } from './DriveFileEntityService.js';
|
||||
|
||||
|
|
@ -30,6 +31,7 @@ export class PageEntityService {
|
|||
|
||||
private userEntityService: UserEntityService,
|
||||
private driveFileEntityService: DriveFileEntityService,
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -85,7 +87,7 @@ export class PageEntityService {
|
|||
|
||||
return await awaitAll({
|
||||
id: page.id,
|
||||
createdAt: page.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(page.id).date.toISOString(),
|
||||
updatedAt: page.updatedAt.toISOString(),
|
||||
userId: page.userId,
|
||||
user: this.userEntityService.pack(page.user ?? page.userId, me), // { detail: true } すると無限ループするので注意
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import type { } from '@/models/Blocking.js';
|
|||
import type { MiUser } from '@/models/User.js';
|
||||
import type { MiRenoteMuting } from '@/models/RenoteMuting.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -21,6 +22,7 @@ export class RenoteMutingEntityService {
|
|||
private renoteMutingsRepository: RenoteMutingsRepository,
|
||||
|
||||
private userEntityService: UserEntityService,
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -33,7 +35,7 @@ export class RenoteMutingEntityService {
|
|||
|
||||
return await awaitAll({
|
||||
id: muting.id,
|
||||
createdAt: muting.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(muting.id).date.toISOString(),
|
||||
muteeId: muting.muteeId,
|
||||
mutee: this.userEntityService.pack(muting.muteeId, me, {
|
||||
detail: true,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import type { MiUser } from '@/models/User.js';
|
|||
import type { MiRole } from '@/models/Role.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
|
||||
@Injectable()
|
||||
export class RoleEntityService {
|
||||
|
|
@ -21,6 +22,8 @@ export class RoleEntityService {
|
|||
|
||||
@Inject(DI.roleAssignmentsRepository)
|
||||
private roleAssignmentsRepository: RoleAssignmentsRepository,
|
||||
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -51,7 +54,7 @@ export class RoleEntityService {
|
|||
|
||||
return await awaitAll({
|
||||
id: role.id,
|
||||
createdAt: role.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(role.id).date.toISOString(),
|
||||
updatedAt: role.updatedAt.toISOString(),
|
||||
name: role.name,
|
||||
description: role.description,
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import { bindThis } from '@/decorators.js';
|
|||
import { RoleService } from '@/core/RoleService.js';
|
||||
import { ApPersonService } from '@/core/activitypub/models/ApPersonService.js';
|
||||
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import type { OnModuleInit } from '@nestjs/common';
|
||||
import type { AnnouncementService } from '../AnnouncementService.js';
|
||||
import type { CustomEmojiService } from '../CustomEmojiService.js';
|
||||
|
|
@ -60,6 +61,7 @@ export class UserEntityService implements OnModuleInit {
|
|||
private announcementService: AnnouncementService;
|
||||
private roleService: RoleService;
|
||||
private federatedInstanceService: FederatedInstanceService;
|
||||
private idService: IdService;
|
||||
|
||||
constructor(
|
||||
private moduleRef: ModuleRef,
|
||||
|
|
@ -111,13 +113,6 @@ export class UserEntityService implements OnModuleInit {
|
|||
|
||||
@Inject(DI.userMemosRepository)
|
||||
private userMemosRepository: UserMemoRepository,
|
||||
|
||||
//private noteEntityService: NoteEntityService,
|
||||
//private driveFileEntityService: DriveFileEntityService,
|
||||
//private pageEntityService: PageEntityService,
|
||||
//private customEmojiService: CustomEmojiService,
|
||||
//private antennaService: AntennaService,
|
||||
//private roleService: RoleService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -130,6 +125,7 @@ export class UserEntityService implements OnModuleInit {
|
|||
this.announcementService = this.moduleRef.get('AnnouncementService');
|
||||
this.roleService = this.moduleRef.get('RoleService');
|
||||
this.federatedInstanceService = this.moduleRef.get('FederatedInstanceService');
|
||||
this.idService = this.moduleRef.get('IdService');
|
||||
}
|
||||
|
||||
//#region Validators
|
||||
|
|
@ -337,8 +333,8 @@ export class UserEntityService implements OnModuleInit {
|
|||
host: user.host,
|
||||
avatarUrl: user.avatarUrl ?? this.getIdenticonUrl(user),
|
||||
avatarBlurhash: user.avatarBlurhash,
|
||||
isBot: user.isBot ?? falsy,
|
||||
isCat: user.isCat ?? falsy,
|
||||
isBot: user.isBot,
|
||||
isCat: user.isCat,
|
||||
instance: user.host ? this.federatedInstanceService.federatedInstanceCache.fetch(user.host).then(instance => instance ? {
|
||||
name: instance.name,
|
||||
softwareName: instance.softwareName,
|
||||
|
|
@ -364,14 +360,14 @@ export class UserEntityService implements OnModuleInit {
|
|||
? Promise.all(user.alsoKnownAs.map(uri => this.apPersonService.fetchPerson(uri).then(user => user?.id).catch(() => null)))
|
||||
.then(xs => xs.length === 0 ? null : xs.filter(x => x != null) as string[])
|
||||
: null,
|
||||
createdAt: user.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(user.id).date.toISOString(),
|
||||
updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null,
|
||||
lastFetchedAt: user.lastFetchedAt ? user.lastFetchedAt.toISOString() : null,
|
||||
bannerUrl: user.bannerUrl,
|
||||
bannerBlurhash: user.bannerBlurhash,
|
||||
isLocked: user.isLocked,
|
||||
isSilenced: this.roleService.getUserPolicies(user.id).then(r => !r.canPublicNote),
|
||||
isSuspended: user.isSuspended ?? falsy,
|
||||
isSuspended: user.isSuspended,
|
||||
description: profile!.description,
|
||||
location: profile!.location,
|
||||
birthday: profile!.birthday,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import type { Packed } from '@/misc/json-schema.js';
|
|||
import type { } from '@/models/Blocking.js';
|
||||
import type { MiUserList } from '@/models/UserList.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -22,6 +23,7 @@ export class UserListEntityService {
|
|||
private userListMembershipsRepository: UserListMembershipsRepository,
|
||||
|
||||
private userEntityService: UserEntityService,
|
||||
private idService: IdService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -37,7 +39,7 @@ export class UserListEntityService {
|
|||
|
||||
return {
|
||||
id: userList.id,
|
||||
createdAt: userList.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(userList.id).date.toISOString(),
|
||||
name: userList.name,
|
||||
userIds: users.map(x => x.userId),
|
||||
isPublic: userList.isPublic,
|
||||
|
|
@ -50,7 +52,7 @@ export class UserListEntityService {
|
|||
) {
|
||||
return Promise.all(memberships.map(async x => ({
|
||||
id: x.id,
|
||||
createdAt: x.createdAt.toISOString(),
|
||||
createdAt: this.idService.parse(x.id).date.toISOString(),
|
||||
userId: x.userId,
|
||||
user: await this.userEntityService.pack(x.userId),
|
||||
withReplies: x.withReplies,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue