enhance: TLキャッシュ容量を設定できるように
This commit is contained in:
parent
5fd0cb31f6
commit
17b83ff4c1
12 changed files with 251 additions and 74 deletions
1
locales/index.d.ts
vendored
1
locales/index.d.ts
vendored
|
@ -1131,6 +1131,7 @@ export interface Locale {
|
||||||
"fileAttachedOnly": string;
|
"fileAttachedOnly": string;
|
||||||
"showRepliesToOthersInTimeline": string;
|
"showRepliesToOthersInTimeline": string;
|
||||||
"hideRepliesToOthersInTimeline": string;
|
"hideRepliesToOthersInTimeline": string;
|
||||||
|
"externalServices": string;
|
||||||
"_announcement": {
|
"_announcement": {
|
||||||
"forExistingUsers": string;
|
"forExistingUsers": string;
|
||||||
"forExistingUsersDescription": string;
|
"forExistingUsersDescription": string;
|
||||||
|
|
|
@ -1128,6 +1128,7 @@ mutualFollow: "相互フォロー"
|
||||||
fileAttachedOnly: "ファイル付きのみ"
|
fileAttachedOnly: "ファイル付きのみ"
|
||||||
showRepliesToOthersInTimeline: "TLに他の人への返信を含める"
|
showRepliesToOthersInTimeline: "TLに他の人への返信を含める"
|
||||||
hideRepliesToOthersInTimeline: "TLに他の人への返信を含めない"
|
hideRepliesToOthersInTimeline: "TLに他の人への返信を含めない"
|
||||||
|
externalServices: "外部サービス"
|
||||||
|
|
||||||
_announcement:
|
_announcement:
|
||||||
forExistingUsers: "既存ユーザーのみ"
|
forExistingUsers: "既存ユーザーのみ"
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and other misskey contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
export class MetaCacheSettings1696373953614 {
|
||||||
|
name = 'MetaCacheSettings1696373953614'
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "perLocalUserUserTimelineCacheMax" integer NOT NULL DEFAULT '300'`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "perRemoteUserUserTimelineCacheMax" integer NOT NULL DEFAULT '100'`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "perUserHomeTimelineCacheMax" integer NOT NULL DEFAULT '300'`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "perUserListTimelineCacheMax" integer NOT NULL DEFAULT '300'`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "perUserListTimelineCacheMax"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "perUserHomeTimelineCacheMax"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "perRemoteUserUserTimelineCacheMax"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "perLocalUserUserTimelineCacheMax"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -803,6 +803,8 @@ export class NoteCreateService implements OnApplicationShutdown {
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async pushToTl(note: MiNote, user: { id: MiUser['id']; host: MiUser['host']; }) {
|
private async pushToTl(note: MiNote, user: { id: MiUser['id']; host: MiUser['host']; }) {
|
||||||
|
const meta = await this.metaService.fetch();
|
||||||
|
|
||||||
const redisPipeline = this.redisForTimelines.pipeline();
|
const redisPipeline = this.redisForTimelines.pipeline();
|
||||||
|
|
||||||
if (note.channelId) {
|
if (note.channelId) {
|
||||||
|
@ -816,14 +818,14 @@ export class NoteCreateService implements OnApplicationShutdown {
|
||||||
for (const channelFollowing of channelFollowings) {
|
for (const channelFollowing of channelFollowings) {
|
||||||
redisPipeline.xadd(
|
redisPipeline.xadd(
|
||||||
`homeTimeline:${channelFollowing.followerId}`,
|
`homeTimeline:${channelFollowing.followerId}`,
|
||||||
'MAXLEN', '~', '200',
|
'MAXLEN', '~', meta.perUserHomeTimelineCacheMax.toString(),
|
||||||
'*',
|
'*',
|
||||||
'note', note.id);
|
'note', note.id);
|
||||||
|
|
||||||
if (note.fileIds.length > 0) {
|
if (note.fileIds.length > 0) {
|
||||||
redisPipeline.xadd(
|
redisPipeline.xadd(
|
||||||
`homeTimelineWithFiles:${channelFollowing.followerId}`,
|
`homeTimelineWithFiles:${channelFollowing.followerId}`,
|
||||||
'MAXLEN', '~', '100',
|
'MAXLEN', '~', (meta.perUserHomeTimelineCacheMax / 2).toString(),
|
||||||
'*',
|
'*',
|
||||||
'note', note.id);
|
'note', note.id);
|
||||||
}
|
}
|
||||||
|
@ -855,14 +857,14 @@ export class NoteCreateService implements OnApplicationShutdown {
|
||||||
|
|
||||||
redisPipeline.xadd(
|
redisPipeline.xadd(
|
||||||
`homeTimeline:${following.followerId}`,
|
`homeTimeline:${following.followerId}`,
|
||||||
'MAXLEN', '~', '200',
|
'MAXLEN', '~', meta.perUserHomeTimelineCacheMax.toString(),
|
||||||
'*',
|
'*',
|
||||||
'note', note.id);
|
'note', note.id);
|
||||||
|
|
||||||
if (note.fileIds.length > 0) {
|
if (note.fileIds.length > 0) {
|
||||||
redisPipeline.xadd(
|
redisPipeline.xadd(
|
||||||
`homeTimelineWithFiles:${following.followerId}`,
|
`homeTimelineWithFiles:${following.followerId}`,
|
||||||
'MAXLEN', '~', '100',
|
'MAXLEN', '~', (meta.perUserHomeTimelineCacheMax / 2).toString(),
|
||||||
'*',
|
'*',
|
||||||
'note', note.id);
|
'note', note.id);
|
||||||
}
|
}
|
||||||
|
@ -882,14 +884,14 @@ export class NoteCreateService implements OnApplicationShutdown {
|
||||||
|
|
||||||
redisPipeline.xadd(
|
redisPipeline.xadd(
|
||||||
`userListTimeline:${userListMembership.userListId}`,
|
`userListTimeline:${userListMembership.userListId}`,
|
||||||
'MAXLEN', '~', '200',
|
'MAXLEN', '~', meta.perUserListTimelineCacheMax.toString(),
|
||||||
'*',
|
'*',
|
||||||
'note', note.id);
|
'note', note.id);
|
||||||
|
|
||||||
if (note.fileIds.length > 0) {
|
if (note.fileIds.length > 0) {
|
||||||
redisPipeline.xadd(
|
redisPipeline.xadd(
|
||||||
`userListTimelineWithFiles:${userListMembership.userListId}`,
|
`userListTimelineWithFiles:${userListMembership.userListId}`,
|
||||||
'MAXLEN', '~', '100',
|
'MAXLEN', '~', (meta.perUserListTimelineCacheMax / 2).toString(),
|
||||||
'*',
|
'*',
|
||||||
'note', note.id);
|
'note', note.id);
|
||||||
}
|
}
|
||||||
|
@ -898,14 +900,14 @@ export class NoteCreateService implements OnApplicationShutdown {
|
||||||
{ // 自分自身のHTL
|
{ // 自分自身のHTL
|
||||||
redisPipeline.xadd(
|
redisPipeline.xadd(
|
||||||
`homeTimeline:${user.id}`,
|
`homeTimeline:${user.id}`,
|
||||||
'MAXLEN', '~', '200',
|
'MAXLEN', '~', meta.perUserHomeTimelineCacheMax.toString(),
|
||||||
'*',
|
'*',
|
||||||
'note', note.id);
|
'note', note.id);
|
||||||
|
|
||||||
if (note.fileIds.length > 0) {
|
if (note.fileIds.length > 0) {
|
||||||
redisPipeline.xadd(
|
redisPipeline.xadd(
|
||||||
`homeTimelineWithFiles:${user.id}`,
|
`homeTimelineWithFiles:${user.id}`,
|
||||||
'MAXLEN', '~', '100',
|
'MAXLEN', '~', (meta.perUserHomeTimelineCacheMax / 2).toString(),
|
||||||
'*',
|
'*',
|
||||||
'note', note.id);
|
'note', note.id);
|
||||||
}
|
}
|
||||||
|
@ -916,20 +918,20 @@ export class NoteCreateService implements OnApplicationShutdown {
|
||||||
if (note.replyId && note.replyUserId !== note.userId) {
|
if (note.replyId && note.replyUserId !== note.userId) {
|
||||||
redisPipeline.xadd(
|
redisPipeline.xadd(
|
||||||
`userTimelineWithReplies:${user.id}`,
|
`userTimelineWithReplies:${user.id}`,
|
||||||
'MAXLEN', '~', '1000',
|
'MAXLEN', '~', note.userHost == null ? meta.perLocalUserUserTimelineCacheMax.toString() : meta.perRemoteUserUserTimelineCacheMax.toString(),
|
||||||
'*',
|
'*',
|
||||||
'note', note.id);
|
'note', note.id);
|
||||||
} else {
|
} else {
|
||||||
redisPipeline.xadd(
|
redisPipeline.xadd(
|
||||||
`userTimeline:${user.id}`,
|
`userTimeline:${user.id}`,
|
||||||
'MAXLEN', '~', '1000',
|
'MAXLEN', '~', note.userHost == null ? meta.perLocalUserUserTimelineCacheMax.toString() : meta.perRemoteUserUserTimelineCacheMax.toString(),
|
||||||
'*',
|
'*',
|
||||||
'note', note.id);
|
'note', note.id);
|
||||||
|
|
||||||
if (note.fileIds.length > 0) {
|
if (note.fileIds.length > 0) {
|
||||||
redisPipeline.xadd(
|
redisPipeline.xadd(
|
||||||
`userTimelineWithFiles:${user.id}`,
|
`userTimelineWithFiles:${user.id}`,
|
||||||
'MAXLEN', '~', '500',
|
'MAXLEN', '~', note.userHost == null ? (meta.perLocalUserUserTimelineCacheMax / 2).toString() : (meta.perRemoteUserUserTimelineCacheMax / 2).toString(),
|
||||||
'*',
|
'*',
|
||||||
'note', note.id);
|
'note', note.id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -471,4 +471,24 @@ export class MiMeta {
|
||||||
length: 1024, array: true, default: '{ "admin", "administrator", "root", "system", "maintainer", "host", "mod", "moderator", "owner", "superuser", "staff", "auth", "i", "me", "everyone", "all", "mention", "mentions", "example", "user", "users", "account", "accounts", "official", "help", "helps", "support", "supports", "info", "information", "informations", "announce", "announces", "announcement", "announcements", "notice", "notification", "notifications", "dev", "developer", "developers", "tech", "misskey" }',
|
length: 1024, array: true, default: '{ "admin", "administrator", "root", "system", "maintainer", "host", "mod", "moderator", "owner", "superuser", "staff", "auth", "i", "me", "everyone", "all", "mention", "mentions", "example", "user", "users", "account", "accounts", "official", "help", "helps", "support", "supports", "info", "information", "informations", "announce", "announces", "announcement", "announcements", "notice", "notification", "notifications", "dev", "developer", "developers", "tech", "misskey" }',
|
||||||
})
|
})
|
||||||
public preservedUsernames: string[];
|
public preservedUsernames: string[];
|
||||||
|
|
||||||
|
@Column('integer', {
|
||||||
|
default: 300,
|
||||||
|
})
|
||||||
|
public perLocalUserUserTimelineCacheMax: number;
|
||||||
|
|
||||||
|
@Column('integer', {
|
||||||
|
default: 100,
|
||||||
|
})
|
||||||
|
public perRemoteUserUserTimelineCacheMax: number;
|
||||||
|
|
||||||
|
@Column('integer', {
|
||||||
|
default: 300,
|
||||||
|
})
|
||||||
|
public perUserHomeTimelineCacheMax: number;
|
||||||
|
|
||||||
|
@Column('integer', {
|
||||||
|
default: 300,
|
||||||
|
})
|
||||||
|
public perUserListTimelineCacheMax: number;
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,40 +105,32 @@ export const meta = {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
userStarForReactionFallback: {
|
|
||||||
type: 'boolean',
|
|
||||||
optional: true, nullable: false,
|
|
||||||
},
|
|
||||||
pinnedUsers: {
|
pinnedUsers: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
optional: true, nullable: false,
|
optional: false, nullable: false,
|
||||||
items: {
|
items: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: false, nullable: false,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
hiddenTags: {
|
hiddenTags: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
optional: true, nullable: false,
|
optional: false, nullable: false,
|
||||||
items: {
|
items: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: false, nullable: false,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
blockedHosts: {
|
blockedHosts: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
optional: true, nullable: false,
|
optional: false, nullable: false,
|
||||||
items: {
|
items: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: false, nullable: false,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
sensitiveWords: {
|
sensitiveWords: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
optional: true, nullable: false,
|
optional: false, nullable: false,
|
||||||
items: {
|
items: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: false, nullable: false,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
preservedUsernames: {
|
preservedUsernames: {
|
||||||
|
@ -146,129 +138,124 @@ export const meta = {
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
items: {
|
items: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: false, nullable: false,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
hcaptchaSecretKey: {
|
hcaptchaSecretKey: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
recaptchaSecretKey: {
|
recaptchaSecretKey: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
turnstileSecretKey: {
|
turnstileSecretKey: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
sensitiveMediaDetection: {
|
sensitiveMediaDetection: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
sensitiveMediaDetectionSensitivity: {
|
sensitiveMediaDetectionSensitivity: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
setSensitiveFlagAutomatically: {
|
setSensitiveFlagAutomatically: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: true, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
enableSensitiveMediaDetectionForVideos: {
|
enableSensitiveMediaDetectionForVideos: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: true, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
proxyAccountId: {
|
proxyAccountId: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: true,
|
optional: false, nullable: true,
|
||||||
format: 'id',
|
format: 'id',
|
||||||
},
|
},
|
||||||
summaryProxy: {
|
|
||||||
type: 'string',
|
|
||||||
optional: true, nullable: true,
|
|
||||||
},
|
|
||||||
email: {
|
email: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
smtpSecure: {
|
smtpSecure: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: true, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
smtpHost: {
|
smtpHost: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
smtpPort: {
|
smtpPort: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
optional: true, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
smtpUser: {
|
smtpUser: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
smtpPass: {
|
smtpPass: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
swPrivateKey: {
|
swPrivateKey: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
useObjectStorage: {
|
useObjectStorage: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: true, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
objectStorageBaseUrl: {
|
objectStorageBaseUrl: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
objectStorageBucket: {
|
objectStorageBucket: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
objectStoragePrefix: {
|
objectStoragePrefix: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
objectStorageEndpoint: {
|
objectStorageEndpoint: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
objectStorageRegion: {
|
objectStorageRegion: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
objectStoragePort: {
|
objectStoragePort: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
optional: true, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
objectStorageAccessKey: {
|
objectStorageAccessKey: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
objectStorageSecretKey: {
|
objectStorageSecretKey: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: true,
|
optional: false, nullable: true,
|
||||||
},
|
},
|
||||||
objectStorageUseSSL: {
|
objectStorageUseSSL: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: true, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
objectStorageUseProxy: {
|
objectStorageUseProxy: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: true, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
objectStorageSetPublicRead: {
|
objectStorageSetPublicRead: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: true, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
enableIpLogging: {
|
enableIpLogging: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: true, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
enableActiveEmailValidation: {
|
enableActiveEmailValidation: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: true, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
enableChartsForRemoteUser: {
|
enableChartsForRemoteUser: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
@ -288,12 +275,28 @@ export const meta = {
|
||||||
},
|
},
|
||||||
manifestJsonOverride: {
|
manifestJsonOverride: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: true, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
policies: {
|
policies: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
|
perLocalUserUserTimelineCacheMax: {
|
||||||
|
type: 'number',
|
||||||
|
optional: false, nullable: false,
|
||||||
|
},
|
||||||
|
perRemoteUserUserTimelineCacheMax: {
|
||||||
|
type: 'number',
|
||||||
|
optional: false, nullable: false,
|
||||||
|
},
|
||||||
|
perUserHomeTimelineCacheMax: {
|
||||||
|
type: 'number',
|
||||||
|
optional: false, nullable: false,
|
||||||
|
},
|
||||||
|
perUserListTimelineCacheMax: {
|
||||||
|
type: 'number',
|
||||||
|
optional: false, nullable: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -313,7 +316,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
|
|
||||||
private metaService: MetaService,
|
private metaService: MetaService,
|
||||||
) {
|
) {
|
||||||
super(meta, paramDef, async (ps, me) => {
|
super(meta, paramDef, async () => {
|
||||||
const instance = await this.metaService.fetch(true);
|
const instance = await this.metaService.fetch(true);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -399,6 +402,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
enableIdenticonGeneration: instance.enableIdenticonGeneration,
|
enableIdenticonGeneration: instance.enableIdenticonGeneration,
|
||||||
policies: { ...DEFAULT_POLICIES, ...instance.policies },
|
policies: { ...DEFAULT_POLICIES, ...instance.policies },
|
||||||
manifestJsonOverride: instance.manifestJsonOverride,
|
manifestJsonOverride: instance.manifestJsonOverride,
|
||||||
|
perLocalUserUserTimelineCacheMax: instance.perLocalUserUserTimelineCacheMax,
|
||||||
|
perRemoteUserUserTimelineCacheMax: instance.perRemoteUserUserTimelineCacheMax,
|
||||||
|
perUserHomeTimelineCacheMax: instance.perUserHomeTimelineCacheMax,
|
||||||
|
perUserListTimelineCacheMax: instance.perUserListTimelineCacheMax,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,6 +108,10 @@ export const paramDef = {
|
||||||
serverRules: { type: 'array', items: { type: 'string' } },
|
serverRules: { type: 'array', items: { type: 'string' } },
|
||||||
preservedUsernames: { type: 'array', items: { type: 'string' } },
|
preservedUsernames: { type: 'array', items: { type: 'string' } },
|
||||||
manifestJsonOverride: { type: 'string' },
|
manifestJsonOverride: { type: 'string' },
|
||||||
|
perLocalUserUserTimelineCacheMax: { type: 'integer' },
|
||||||
|
perRemoteUserUserTimelineCacheMax: { type: 'integer' },
|
||||||
|
perUserHomeTimelineCacheMax: { type: 'integer' },
|
||||||
|
perUserListTimelineCacheMax: { type: 'integer' },
|
||||||
},
|
},
|
||||||
required: [],
|
required: [],
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -441,6 +445,22 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
set.manifestJsonOverride = ps.manifestJsonOverride;
|
set.manifestJsonOverride = ps.manifestJsonOverride;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ps.perLocalUserUserTimelineCacheMax !== undefined) {
|
||||||
|
set.perLocalUserUserTimelineCacheMax = ps.perLocalUserUserTimelineCacheMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ps.perRemoteUserUserTimelineCacheMax !== undefined) {
|
||||||
|
set.perRemoteUserUserTimelineCacheMax = ps.perRemoteUserUserTimelineCacheMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ps.perUserHomeTimelineCacheMax !== undefined) {
|
||||||
|
set.perUserHomeTimelineCacheMax = ps.perUserHomeTimelineCacheMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ps.perUserListTimelineCacheMax !== undefined) {
|
||||||
|
set.perUserListTimelineCacheMax = ps.perUserListTimelineCacheMax;
|
||||||
|
}
|
||||||
|
|
||||||
const before = await this.metaService.fetch(true);
|
const before = await this.metaService.fetch(true);
|
||||||
|
|
||||||
await this.metaService.update(set);
|
await this.metaService.update(set);
|
||||||
|
|
|
@ -214,11 +214,11 @@ export const meta = {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
localTimeLine: {
|
localTimeline: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
globalTimeLine: {
|
globalTimeline: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
|
|
81
packages/frontend/src/pages/admin/external-services.vue
Normal file
81
packages/frontend/src/pages/admin/external-services.vue
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
<!--
|
||||||
|
SPDX-FileCopyrightText: syuilo and other misskey contributors
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<MkStickyContainer>
|
||||||
|
<template #header><XHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||||
|
<MkSpacer :contentMax="700" :marginMin="16" :marginMax="32">
|
||||||
|
<FormSuspense :p="init">
|
||||||
|
<FormSection>
|
||||||
|
<template #label>DeepL Translation</template>
|
||||||
|
|
||||||
|
<div class="_gaps_m">
|
||||||
|
<MkInput v-model="deeplAuthKey">
|
||||||
|
<template #prefix><i class="ti ti-key"></i></template>
|
||||||
|
<template #label>DeepL Auth Key</template>
|
||||||
|
</MkInput>
|
||||||
|
<MkSwitch v-model="deeplIsPro">
|
||||||
|
<template #label>Pro account</template>
|
||||||
|
</MkSwitch>
|
||||||
|
</div>
|
||||||
|
</FormSection>
|
||||||
|
</FormSuspense>
|
||||||
|
</MkSpacer>
|
||||||
|
<template #footer>
|
||||||
|
<div :class="$style.footer">
|
||||||
|
<MkSpacer :contentMax="700" :marginMin="16" :marginMax="16">
|
||||||
|
<MkButton primary rounded @click="save"><i class="ti ti-check"></i> {{ i18n.ts.save }}</MkButton>
|
||||||
|
</MkSpacer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</MkStickyContainer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { } from 'vue';
|
||||||
|
import XHeader from './_header_.vue';
|
||||||
|
import MkInput from '@/components/MkInput.vue';
|
||||||
|
import MkButton from '@/components/MkButton.vue';
|
||||||
|
import FormSuspense from '@/components/form/suspense.vue';
|
||||||
|
import FormSection from '@/components/form/section.vue';
|
||||||
|
import * as os from '@/os.js';
|
||||||
|
import { fetchInstance } from '@/instance.js';
|
||||||
|
import { i18n } from '@/i18n.js';
|
||||||
|
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
||||||
|
|
||||||
|
let deeplAuthKey: string = $ref('');
|
||||||
|
let deeplIsPro: boolean = $ref(false);
|
||||||
|
|
||||||
|
async function init() {
|
||||||
|
const meta = await os.api('admin/meta');
|
||||||
|
deeplAuthKey = meta.deeplAuthKey;
|
||||||
|
deeplIsPro = meta.deeplIsPro;
|
||||||
|
}
|
||||||
|
|
||||||
|
function save() {
|
||||||
|
os.apiWithDialog('admin/update-meta', {
|
||||||
|
deeplAuthKey,
|
||||||
|
deeplIsPro,
|
||||||
|
}).then(() => {
|
||||||
|
fetchInstance();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const headerActions = $computed(() => []);
|
||||||
|
|
||||||
|
const headerTabs = $computed(() => []);
|
||||||
|
|
||||||
|
definePageMetadata({
|
||||||
|
title: i18n.ts.instanceBlocking,
|
||||||
|
icon: 'ti ti-ban',
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" module>
|
||||||
|
.footer {
|
||||||
|
-webkit-backdrop-filter: var(--blur, blur(15px));
|
||||||
|
backdrop-filter: var(--blur, blur(15px));
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -198,6 +198,11 @@ const menuDef = $computed(() => [{
|
||||||
text: i18n.ts.proxyAccount,
|
text: i18n.ts.proxyAccount,
|
||||||
to: '/admin/proxy-account',
|
to: '/admin/proxy-account',
|
||||||
active: currentPage?.route.name === 'proxy-account',
|
active: currentPage?.route.name === 'proxy-account',
|
||||||
|
}, {
|
||||||
|
icon: 'ti ti-link',
|
||||||
|
text: i18n.ts.externalServices,
|
||||||
|
to: '/admin/external-services',
|
||||||
|
active: currentPage?.route.name === 'external-services',
|
||||||
}, {
|
}, {
|
||||||
icon: 'ti ti-adjustments',
|
icon: 'ti ti-adjustments',
|
||||||
text: i18n.ts.other,
|
text: i18n.ts.other,
|
||||||
|
|
|
@ -81,16 +81,24 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</FormSection>
|
</FormSection>
|
||||||
|
|
||||||
<FormSection>
|
<FormSection>
|
||||||
<template #label>DeepL Translation</template>
|
<template #label>Timeline caching</template>
|
||||||
|
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
<MkInput v-model="deeplAuthKey">
|
<MkInput v-model="perLocalUserUserTimelineCacheMax" type="number">
|
||||||
<template #prefix><i class="ti ti-key"></i></template>
|
<template #label>perLocalUserUserTimelineCacheMax</template>
|
||||||
<template #label>DeepL Auth Key</template>
|
</MkInput>
|
||||||
|
|
||||||
|
<MkInput v-model="perRemoteUserUserTimelineCacheMax" type="number">
|
||||||
|
<template #label>perRemoteUserUserTimelineCacheMax</template>
|
||||||
|
</MkInput>
|
||||||
|
|
||||||
|
<MkInput v-model="perUserHomeTimelineCacheMax" type="number">
|
||||||
|
<template #label>perUserHomeTimelineCacheMax</template>
|
||||||
|
</MkInput>
|
||||||
|
|
||||||
|
<MkInput v-model="perUserListTimelineCacheMax" type="number">
|
||||||
|
<template #label>perUserListTimelineCacheMax</template>
|
||||||
</MkInput>
|
</MkInput>
|
||||||
<MkSwitch v-model="deeplIsPro">
|
|
||||||
<template #label>Pro account</template>
|
|
||||||
</MkSwitch>
|
|
||||||
</div>
|
</div>
|
||||||
</FormSection>
|
</FormSection>
|
||||||
</div>
|
</div>
|
||||||
|
@ -133,8 +141,10 @@ let cacheRemoteSensitiveFiles: boolean = $ref(false);
|
||||||
let enableServiceWorker: boolean = $ref(false);
|
let enableServiceWorker: boolean = $ref(false);
|
||||||
let swPublicKey: any = $ref(null);
|
let swPublicKey: any = $ref(null);
|
||||||
let swPrivateKey: any = $ref(null);
|
let swPrivateKey: any = $ref(null);
|
||||||
let deeplAuthKey: string = $ref('');
|
let perLocalUserUserTimelineCacheMax: number = $ref(0);
|
||||||
let deeplIsPro: boolean = $ref(false);
|
let perRemoteUserUserTimelineCacheMax: number = $ref(0);
|
||||||
|
let perUserHomeTimelineCacheMax: number = $ref(0);
|
||||||
|
let perUserListTimelineCacheMax: number = $ref(0);
|
||||||
|
|
||||||
async function init(): Promise<void> {
|
async function init(): Promise<void> {
|
||||||
const meta = await os.api('admin/meta');
|
const meta = await os.api('admin/meta');
|
||||||
|
@ -149,8 +159,10 @@ async function init(): Promise<void> {
|
||||||
enableServiceWorker = meta.enableServiceWorker;
|
enableServiceWorker = meta.enableServiceWorker;
|
||||||
swPublicKey = meta.swPublickey;
|
swPublicKey = meta.swPublickey;
|
||||||
swPrivateKey = meta.swPrivateKey;
|
swPrivateKey = meta.swPrivateKey;
|
||||||
deeplAuthKey = meta.deeplAuthKey;
|
perLocalUserUserTimelineCacheMax = meta.perLocalUserUserTimelineCacheMax;
|
||||||
deeplIsPro = meta.deeplIsPro;
|
perRemoteUserUserTimelineCacheMax = meta.perRemoteUserUserTimelineCacheMax;
|
||||||
|
perUserHomeTimelineCacheMax = meta.perUserHomeTimelineCacheMax;
|
||||||
|
perUserListTimelineCacheMax = meta.perUserListTimelineCacheMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
function save(): void {
|
function save(): void {
|
||||||
|
@ -166,8 +178,10 @@ function save(): void {
|
||||||
enableServiceWorker,
|
enableServiceWorker,
|
||||||
swPublicKey,
|
swPublicKey,
|
||||||
swPrivateKey,
|
swPrivateKey,
|
||||||
deeplAuthKey,
|
perLocalUserUserTimelineCacheMax,
|
||||||
deeplIsPro,
|
perRemoteUserUserTimelineCacheMax,
|
||||||
|
perUserHomeTimelineCacheMax,
|
||||||
|
perUserListTimelineCacheMax,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
fetchInstance();
|
fetchInstance();
|
||||||
});
|
});
|
||||||
|
|
|
@ -435,6 +435,10 @@ export const routes = [{
|
||||||
path: '/proxy-account',
|
path: '/proxy-account',
|
||||||
name: 'proxy-account',
|
name: 'proxy-account',
|
||||||
component: page(() => import('./pages/admin/proxy-account.vue')),
|
component: page(() => import('./pages/admin/proxy-account.vue')),
|
||||||
|
}, {
|
||||||
|
path: '/external-services',
|
||||||
|
name: 'external-services',
|
||||||
|
component: page(() => import('./pages/admin/external-services.vue')),
|
||||||
}, {
|
}, {
|
||||||
path: '/other-settings',
|
path: '/other-settings',
|
||||||
name: 'other-settings',
|
name: 'other-settings',
|
||||||
|
|
Loading…
Reference in a new issue