summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2023-10-04 08:46:27 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2023-10-04 08:46:27 +0900
commit17b83ff4c13e873b63262c349ea9c7bade0d656a (patch)
treef4b8e18a2a4d5b5f9c22c53f10ea50a6cf440053
parentfix: deck uiでuser listを見たときにリプライが表示されない (... (diff)
downloadsharkey-17b83ff4c13e873b63262c349ea9c7bade0d656a.tar.gz
sharkey-17b83ff4c13e873b63262c349ea9c7bade0d656a.tar.bz2
sharkey-17b83ff4c13e873b63262c349ea9c7bade0d656a.zip
enhance: TLキャッシュ容量を設定できるように
-rw-r--r--locales/index.d.ts1
-rw-r--r--locales/ja-JP.yml1
-rw-r--r--packages/backend/migration/1696373953614-meta-cache-settings.js22
-rw-r--r--packages/backend/src/core/NoteCreateService.ts24
-rw-r--r--packages/backend/src/models/Meta.ts20
-rw-r--r--packages/backend/src/server/api/endpoints/admin/meta.ts103
-rw-r--r--packages/backend/src/server/api/endpoints/admin/update-meta.ts20
-rw-r--r--packages/backend/src/server/api/endpoints/meta.ts4
-rw-r--r--packages/frontend/src/pages/admin/external-services.vue81
-rw-r--r--packages/frontend/src/pages/admin/index.vue5
-rw-r--r--packages/frontend/src/pages/admin/settings.vue40
-rw-r--r--packages/frontend/src/router.ts4
12 files changed, 251 insertions, 74 deletions
diff --git a/locales/index.d.ts b/locales/index.d.ts
index 418e1c67ff..172cdcb754 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -1131,6 +1131,7 @@ export interface Locale {
"fileAttachedOnly": string;
"showRepliesToOthersInTimeline": string;
"hideRepliesToOthersInTimeline": string;
+ "externalServices": string;
"_announcement": {
"forExistingUsers": string;
"forExistingUsersDescription": string;
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 80e4466a74..1136f67baf 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -1128,6 +1128,7 @@ mutualFollow: "相互フォロー"
fileAttachedOnly: "ファイル付きのみ"
showRepliesToOthersInTimeline: "TLに他の人への返信を含める"
hideRepliesToOthersInTimeline: "TLに他の人への返信を含めない"
+externalServices: "外部サービス"
_announcement:
forExistingUsers: "既存ユーザーのみ"
diff --git a/packages/backend/migration/1696373953614-meta-cache-settings.js b/packages/backend/migration/1696373953614-meta-cache-settings.js
new file mode 100644
index 0000000000..f994b76ef2
--- /dev/null
+++ b/packages/backend/migration/1696373953614-meta-cache-settings.js
@@ -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"`);
+ }
+}
diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts
index 8fb34fd637..7e1c0b5c22 100644
--- a/packages/backend/src/core/NoteCreateService.ts
+++ b/packages/backend/src/core/NoteCreateService.ts
@@ -803,6 +803,8 @@ export class NoteCreateService implements OnApplicationShutdown {
@bindThis
private async pushToTl(note: MiNote, user: { id: MiUser['id']; host: MiUser['host']; }) {
+ const meta = await this.metaService.fetch();
+
const redisPipeline = this.redisForTimelines.pipeline();
if (note.channelId) {
@@ -816,14 +818,14 @@ export class NoteCreateService implements OnApplicationShutdown {
for (const channelFollowing of channelFollowings) {
redisPipeline.xadd(
`homeTimeline:${channelFollowing.followerId}`,
- 'MAXLEN', '~', '200',
+ 'MAXLEN', '~', meta.perUserHomeTimelineCacheMax.toString(),
'*',
'note', note.id);
if (note.fileIds.length > 0) {
redisPipeline.xadd(
`homeTimelineWithFiles:${channelFollowing.followerId}`,
- 'MAXLEN', '~', '100',
+ 'MAXLEN', '~', (meta.perUserHomeTimelineCacheMax / 2).toString(),
'*',
'note', note.id);
}
@@ -855,14 +857,14 @@ export class NoteCreateService implements OnApplicationShutdown {
redisPipeline.xadd(
`homeTimeline:${following.followerId}`,
- 'MAXLEN', '~', '200',
+ 'MAXLEN', '~', meta.perUserHomeTimelineCacheMax.toString(),
'*',
'note', note.id);
if (note.fileIds.length > 0) {
redisPipeline.xadd(
`homeTimelineWithFiles:${following.followerId}`,
- 'MAXLEN', '~', '100',
+ 'MAXLEN', '~', (meta.perUserHomeTimelineCacheMax / 2).toString(),
'*',
'note', note.id);
}
@@ -882,14 +884,14 @@ export class NoteCreateService implements OnApplicationShutdown {
redisPipeline.xadd(
`userListTimeline:${userListMembership.userListId}`,
- 'MAXLEN', '~', '200',
+ 'MAXLEN', '~', meta.perUserListTimelineCacheMax.toString(),
'*',
'note', note.id);
if (note.fileIds.length > 0) {
redisPipeline.xadd(
`userListTimelineWithFiles:${userListMembership.userListId}`,
- 'MAXLEN', '~', '100',
+ 'MAXLEN', '~', (meta.perUserListTimelineCacheMax / 2).toString(),
'*',
'note', note.id);
}
@@ -898,14 +900,14 @@ export class NoteCreateService implements OnApplicationShutdown {
{ // 自分自身のHTL
redisPipeline.xadd(
`homeTimeline:${user.id}`,
- 'MAXLEN', '~', '200',
+ 'MAXLEN', '~', meta.perUserHomeTimelineCacheMax.toString(),
'*',
'note', note.id);
if (note.fileIds.length > 0) {
redisPipeline.xadd(
`homeTimelineWithFiles:${user.id}`,
- 'MAXLEN', '~', '100',
+ 'MAXLEN', '~', (meta.perUserHomeTimelineCacheMax / 2).toString(),
'*',
'note', note.id);
}
@@ -916,20 +918,20 @@ export class NoteCreateService implements OnApplicationShutdown {
if (note.replyId && note.replyUserId !== note.userId) {
redisPipeline.xadd(
`userTimelineWithReplies:${user.id}`,
- 'MAXLEN', '~', '1000',
+ 'MAXLEN', '~', note.userHost == null ? meta.perLocalUserUserTimelineCacheMax.toString() : meta.perRemoteUserUserTimelineCacheMax.toString(),
'*',
'note', note.id);
} else {
redisPipeline.xadd(
`userTimeline:${user.id}`,
- 'MAXLEN', '~', '1000',
+ 'MAXLEN', '~', note.userHost == null ? meta.perLocalUserUserTimelineCacheMax.toString() : meta.perRemoteUserUserTimelineCacheMax.toString(),
'*',
'note', note.id);
if (note.fileIds.length > 0) {
redisPipeline.xadd(
`userTimelineWithFiles:${user.id}`,
- 'MAXLEN', '~', '500',
+ 'MAXLEN', '~', note.userHost == null ? (meta.perLocalUserUserTimelineCacheMax / 2).toString() : (meta.perRemoteUserUserTimelineCacheMax / 2).toString(),
'*',
'note', note.id);
}
diff --git a/packages/backend/src/models/Meta.ts b/packages/backend/src/models/Meta.ts
index e69bef8e98..491d446723 100644
--- a/packages/backend/src/models/Meta.ts
+++ b/packages/backend/src/models/Meta.ts
@@ -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" }',
})
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;
}
diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts
index c3ba07cdd0..53e3672784 100644
--- a/packages/backend/src/server/api/endpoints/admin/meta.ts
+++ b/packages/backend/src/server/api/endpoints/admin/meta.ts
@@ -105,40 +105,32 @@ export const meta = {
type: 'boolean',
optional: false, nullable: false,
},
- userStarForReactionFallback: {
- type: 'boolean',
- optional: true, nullable: false,
- },
pinnedUsers: {
type: 'array',
- optional: true, nullable: false,
+ optional: false, nullable: false,
items: {
type: 'string',
- optional: false, nullable: false,
},
},
hiddenTags: {
type: 'array',
- optional: true, nullable: false,
+ optional: false, nullable: false,
items: {
type: 'string',
- optional: false, nullable: false,
},
},
blockedHosts: {
type: 'array',
- optional: true, nullable: false,
+ optional: false, nullable: false,
items: {
type: 'string',
- optional: false, nullable: false,
},
},
sensitiveWords: {
type: 'array',
- optional: true, nullable: false,
+ optional: false, nullable: false,
items: {
type: 'string',
- optional: false, nullable: false,
},
},
preservedUsernames: {
@@ -146,129 +138,124 @@ export const meta = {
optional: false, nullable: false,
items: {
type: 'string',
- optional: false, nullable: false,
},
},
hcaptchaSecretKey: {
type: 'string',
- optional: true, nullable: true,
+ optional: false, nullable: true,
},
recaptchaSecretKey: {
type: 'string',
- optional: true, nullable: true,
+ optional: false, nullable: true,
},
turnstileSecretKey: {
type: 'string',
- optional: true, nullable: true,
+ optional: false, nullable: true,
},
sensitiveMediaDetection: {
type: 'string',
- optional: true, nullable: false,
+ optional: false, nullable: false,
},
sensitiveMediaDetectionSensitivity: {
type: 'string',
- optional: true, nullable: false,
+ optional: false, nullable: false,
},
setSensitiveFlagAutomatically: {
type: 'boolean',
- optional: true, nullable: false,
+ optional: false, nullable: false,
},
enableSensitiveMediaDetectionForVideos: {
type: 'boolean',
- optional: true, nullable: false,
+ optional: false, nullable: false,
},
proxyAccountId: {
type: 'string',
- optional: true, nullable: true,
+ optional: false, nullable: true,
format: 'id',
},
- summaryProxy: {
- type: 'string',
- optional: true, nullable: true,
- },
email: {
type: 'string',
- optional: true, nullable: true,
+ optional: false, nullable: true,
},
smtpSecure: {
type: 'boolean',
- optional: true, nullable: false,
+ optional: false, nullable: false,
},
smtpHost: {
type: 'string',
- optional: true, nullable: true,
+ optional: false, nullable: true,
},
smtpPort: {
type: 'number',
- optional: true, nullable: true,
+ optional: false, nullable: true,
},
smtpUser: {
type: 'string',
- optional: true, nullable: true,
+ optional: false, nullable: true,
},
smtpPass: {
type: 'string',
- optional: true, nullable: true,
+ optional: false, nullable: true,
},
swPrivateKey: {
type: 'string',
- optional: true, nullable: true,
+ optional: false, nullable: true,
},
useObjectStorage: {
type: 'boolean',
- optional: true, nullable: false,
+ optional: false, nullable: false,
},
objectStorageBaseUrl: {
type: 'string',
- optional: true, nullable: true,
+ optional: false, nullable: true,
},
objectStorageBucket: {
type: 'string',
- optional: true, nullable: true,
+ optional: false, nullable: true,
},
objectStoragePrefix: {
type: 'string',
- optional: true, nullable: true,
+ optional: false, nullable: true,
},
objectStorageEndpoint: {
type: 'string',
- optional: true, nullable: true,
+ optional: false, nullable: true,
},
objectStorageRegion: {
type: 'string',
- optional: true, nullable: true,
+ optional: false, nullable: true,
},
objectStoragePort: {
type: 'number',
- optional: true, nullable: true,
+ optional: false, nullable: true,
},
objectStorageAccessKey: {
type: 'string',
- optional: true, nullable: true,
+ optional: false, nullable: true,
},
objectStorageSecretKey: {
type: 'string',
- optional: true, nullable: true,
+ optional: false, nullable: true,
},
objectStorageUseSSL: {
type: 'boolean',
- optional: true, nullable: false,
+ optional: false, nullable: false,
},
objectStorageUseProxy: {
type: 'boolean',
- optional: true, nullable: false,
+ optional: false, nullable: false,
},
objectStorageSetPublicRead: {
type: 'boolean',
- optional: true, nullable: false,
+ optional: false, nullable: false,
},
enableIpLogging: {
type: 'boolean',
- optional: true, nullable: false,
+ optional: false, nullable: false,
},
enableActiveEmailValidation: {
type: 'boolean',
- optional: true, nullable: false,
+ optional: false, nullable: false,
},
enableChartsForRemoteUser: {
type: 'boolean',
@@ -288,12 +275,28 @@ export const meta = {
},
manifestJsonOverride: {
type: 'string',
- optional: true, nullable: false,
+ optional: false, nullable: false,
},
policies: {
type: 'object',
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;
@@ -313,7 +316,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private metaService: MetaService,
) {
- super(meta, paramDef, async (ps, me) => {
+ super(meta, paramDef, async () => {
const instance = await this.metaService.fetch(true);
return {
@@ -399,6 +402,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
enableIdenticonGeneration: instance.enableIdenticonGeneration,
policies: { ...DEFAULT_POLICIES, ...instance.policies },
manifestJsonOverride: instance.manifestJsonOverride,
+ perLocalUserUserTimelineCacheMax: instance.perLocalUserUserTimelineCacheMax,
+ perRemoteUserUserTimelineCacheMax: instance.perRemoteUserUserTimelineCacheMax,
+ perUserHomeTimelineCacheMax: instance.perUserHomeTimelineCacheMax,
+ perUserListTimelineCacheMax: instance.perUserListTimelineCacheMax,
};
});
}
diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts
index ea6ebdd1fe..247d3ba4e0 100644
--- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts
+++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts
@@ -108,6 +108,10 @@ export const paramDef = {
serverRules: { type: 'array', items: { type: 'string' } },
preservedUsernames: { type: 'array', items: { type: 'string' } },
manifestJsonOverride: { type: 'string' },
+ perLocalUserUserTimelineCacheMax: { type: 'integer' },
+ perRemoteUserUserTimelineCacheMax: { type: 'integer' },
+ perUserHomeTimelineCacheMax: { type: 'integer' },
+ perUserListTimelineCacheMax: { type: 'integer' },
},
required: [],
} as const;
@@ -441,6 +445,22 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
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);
await this.metaService.update(set);
diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts
index fa6486ed18..271b3f6fb2 100644
--- a/packages/backend/src/server/api/endpoints/meta.ts
+++ b/packages/backend/src/server/api/endpoints/meta.ts
@@ -214,11 +214,11 @@ export const meta = {
type: 'boolean',
optional: false, nullable: false,
},
- localTimeLine: {
+ localTimeline: {
type: 'boolean',
optional: false, nullable: false,
},
- globalTimeLine: {
+ globalTimeline: {
type: 'boolean',
optional: false, nullable: false,
},
diff --git a/packages/frontend/src/pages/admin/external-services.vue b/packages/frontend/src/pages/admin/external-services.vue
new file mode 100644
index 0000000000..5944bf500a
--- /dev/null
+++ b/packages/frontend/src/pages/admin/external-services.vue
@@ -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>
diff --git a/packages/frontend/src/pages/admin/index.vue b/packages/frontend/src/pages/admin/index.vue
index 944ba7b950..a508c20cf3 100644
--- a/packages/frontend/src/pages/admin/index.vue
+++ b/packages/frontend/src/pages/admin/index.vue
@@ -199,6 +199,11 @@ const menuDef = $computed(() => [{
to: '/admin/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',
text: i18n.ts.other,
to: '/admin/other-settings',
diff --git a/packages/frontend/src/pages/admin/settings.vue b/packages/frontend/src/pages/admin/settings.vue
index f93678d728..09a6cc7e2c 100644
--- a/packages/frontend/src/pages/admin/settings.vue
+++ b/packages/frontend/src/pages/admin/settings.vue
@@ -81,16 +81,24 @@ SPDX-License-Identifier: AGPL-3.0-only
</FormSection>
<FormSection>
- <template #label>DeepL Translation</template>
+ <template #label>Timeline caching</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 v-model="perLocalUserUserTimelineCacheMax" type="number">
+ <template #label>perLocalUserUserTimelineCacheMax</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>
- <MkSwitch v-model="deeplIsPro">
- <template #label>Pro account</template>
- </MkSwitch>
</div>
</FormSection>
</div>
@@ -133,8 +141,10 @@ let cacheRemoteSensitiveFiles: boolean = $ref(false);
let enableServiceWorker: boolean = $ref(false);
let swPublicKey: any = $ref(null);
let swPrivateKey: any = $ref(null);
-let deeplAuthKey: string = $ref('');
-let deeplIsPro: boolean = $ref(false);
+let perLocalUserUserTimelineCacheMax: number = $ref(0);
+let perRemoteUserUserTimelineCacheMax: number = $ref(0);
+let perUserHomeTimelineCacheMax: number = $ref(0);
+let perUserListTimelineCacheMax: number = $ref(0);
async function init(): Promise<void> {
const meta = await os.api('admin/meta');
@@ -149,8 +159,10 @@ async function init(): Promise<void> {
enableServiceWorker = meta.enableServiceWorker;
swPublicKey = meta.swPublickey;
swPrivateKey = meta.swPrivateKey;
- deeplAuthKey = meta.deeplAuthKey;
- deeplIsPro = meta.deeplIsPro;
+ perLocalUserUserTimelineCacheMax = meta.perLocalUserUserTimelineCacheMax;
+ perRemoteUserUserTimelineCacheMax = meta.perRemoteUserUserTimelineCacheMax;
+ perUserHomeTimelineCacheMax = meta.perUserHomeTimelineCacheMax;
+ perUserListTimelineCacheMax = meta.perUserListTimelineCacheMax;
}
function save(): void {
@@ -166,8 +178,10 @@ function save(): void {
enableServiceWorker,
swPublicKey,
swPrivateKey,
- deeplAuthKey,
- deeplIsPro,
+ perLocalUserUserTimelineCacheMax,
+ perRemoteUserUserTimelineCacheMax,
+ perUserHomeTimelineCacheMax,
+ perUserListTimelineCacheMax,
}).then(() => {
fetchInstance();
});
diff --git a/packages/frontend/src/router.ts b/packages/frontend/src/router.ts
index 415d2f1974..20314711a4 100644
--- a/packages/frontend/src/router.ts
+++ b/packages/frontend/src/router.ts
@@ -436,6 +436,10 @@ export const routes = [{
name: 'proxy-account',
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',
name: 'other-settings',
component: page(() => import('./pages/admin/other-settings.vue')),