From ee8679e2398ffa3432a52f9b0fe990939a5a531c Mon Sep 17 00:00:00 2001 From: laozhoubuluo <laozhoubuluo@gmail.com> Date: Thu, 4 Jul 2024 02:56:16 +0900 Subject: [PATCH 01/17] refactor: use dont federate initially flag instead of visibility hack Co-authored-by: naskya <m@naskya.net> --- packages/backend/src/misc/post.ts | 6 +- .../processors/db/import-firefish-post.ts | 39 +++++---- .../queue/processors/db/import-masto-post.ts | 85 +++++++++++++++---- packages/backend/src/services/note/create.ts | 7 +- 4 files changed, 98 insertions(+), 39 deletions(-) diff --git a/packages/backend/src/misc/post.ts b/packages/backend/src/misc/post.ts index 0b107ed009..fd89a4d7e3 100644 --- a/packages/backend/src/misc/post.ts +++ b/packages/backend/src/misc/post.ts @@ -1,3 +1,5 @@ +import { noteVisibilities } from "@/types.js"; + export type Post = { text: string | undefined; cw: string | null; @@ -12,7 +14,9 @@ export function parse(acct: any): Post { cw: acct.cw, localOnly: acct.localOnly, createdAt: new Date(acct.createdAt), - visibility: `hidden${acct.visibility || ""}`, + visibility: noteVisibilities.includes(acct.visibility) + ? acct.visibility + : "specified", }; } diff --git a/packages/backend/src/queue/processors/db/import-firefish-post.ts b/packages/backend/src/queue/processors/db/import-firefish-post.ts index 34a27c4c7a..8d318a0d2a 100644 --- a/packages/backend/src/queue/processors/db/import-firefish-post.ts +++ b/packages/backend/src/queue/processors/db/import-firefish-post.ts @@ -92,22 +92,29 @@ export async function importCkPost( logger.info("Post updated"); } if (note == null) { - note = await create(user, { - createdAt: createdAt, - files: files.length === 0 ? undefined : files, - poll: undefined, - text: text || undefined, - reply: post.replyId ? job.data.parent : null, - renote: post.renoteId ? job.data.parent : null, - cw: cw, - localOnly, - visibility: visibility, - visibleUsers: [], - channel: null, - apMentions: new Array(0), - apHashtags: undefined, - apEmojis: undefined, - }); + note = await create( + user, + { + createdAt: createdAt, + scheduledAt: undefined, + files: files.length === 0 ? undefined : files, + poll: undefined, + text: text || undefined, + reply: post.replyId ? job.data.parent : null, + renote: post.renoteId ? job.data.parent : null, + cw: cw, + localOnly, + visibility: visibility, + visibleUsers: [], + channel: null, + apMentions: new Array(0), + apHashtags: undefined, + apEmojis: undefined, + }, + false, + undefined, + true, + ); logger.debug("New post has been created"); } else { logger.info("This post already exists"); diff --git a/packages/backend/src/queue/processors/db/import-masto-post.ts b/packages/backend/src/queue/processors/db/import-masto-post.ts index 532c288dba..f87c44e98e 100644 --- a/packages/backend/src/queue/processors/db/import-masto-post.ts +++ b/packages/backend/src/queue/processors/db/import-masto-post.ts @@ -10,6 +10,10 @@ import type { DriveFile } from "@/models/entities/drive-file.js"; import { Notes, NoteEdits } from "@/models/index.js"; import type { Note } from "@/models/entities/note.js"; import { genId } from "backend-rs"; +import promiseLimit from "promise-limit"; +import { unique, concat } from "@/prelude/array.js"; +import type { CacheableUser } from "@/models/entities/user.js"; +import { resolvePerson } from "@/remote/activitypub/models/person.js"; const logger = queueLogger.createSubLogger("import-masto-post"); @@ -118,24 +122,57 @@ export async function importMastoPost( logger.info("Post updated"); } if (note == null) { - note = await create(user, { - createdAt: isRenote - ? new Date(post.published) - : new Date(post.object.published), - files: files.length === 0 ? undefined : files, - poll: undefined, - text: text || undefined, - reply, - renote, - cw: !isRenote && post.object.sensitive ? post.object.summary : undefined, - localOnly: false, - visibility: "hiddenpublic", - visibleUsers: [], - channel: null, - apMentions: new Array(0), - apHashtags: undefined, - apEmojis: undefined, - }); + let visibility = "specified"; + let visibleUsers: CacheableUser[] = []; + if (isPublic(post.to)) { + visibility = "public"; + } else if (isPublic(post.cc)) { + visibility = "home"; + } else if (isFollowers(post.cc)) { + visibility = "followers"; + } else { + try { + const visibleUsersList = unique(concat([post.to, post.cc])); + + const limit = promiseLimit<CacheableUser | null>(2); + visibleUsers = ( + await Promise.all( + visibleUsersList.map((id) => + limit(() => resolvePerson(id).catch(() => null)), + ), + ) + ).filter((x): x is CacheableUser => x != null); + } catch { + // nothing need to do. + } + } + + note = await create( + user, + { + createdAt: isRenote + ? new Date(post.published) + : new Date(post.object.published), + scheduledAt: undefined, + files: files.length === 0 ? undefined : files, + poll: undefined, + text: text || undefined, + reply, + renote, + cw: + !isRenote && post.object.sensitive ? post.object.summary : undefined, + localOnly: false, + visibility, + visibleUsers, + channel: null, + apMentions: new Array(0), + apHashtags: undefined, + apEmojis: undefined, + }, + false, + undefined, + true, + ); logger.debug("New post has been created"); } else { logger.info("This post already exists"); @@ -145,3 +182,15 @@ export async function importMastoPost( logger.info("Imported"); } + +function isPublic(id: string) { + return [ + "https://www.w3.org/ns/activitystreams#Public", + "as:Public", + "Public", + ].includes(id); +} + +function isFollowers(id: string) { + return id.endsWith("/followers"); +} diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index 03ca4f7578..c5b71925a0 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -162,11 +162,12 @@ export default async ( data: NoteLike, silent = false, waitToPublish?: (note: Note) => Promise<void>, + dontFederateInitially = false, ) => // biome-ignore lint/suspicious/noAsyncPromiseExecutor: FIXME new Promise<Note>(async (res, rej) => { - const dontFederateInitially = - data.visibility?.startsWith("hidden") === true; + dontFederateInitially = + dontFederateInitially || data.visibility?.startsWith("hidden"); // Whether this is a scheduled "draft" post (yet to be published) const isDraft = data.scheduledAt != null; @@ -204,8 +205,6 @@ export default async ( if (data.channel != null) data.visibility = "public"; if (data.channel != null) data.visibleUsers = []; if (data.channel != null) data.localOnly = true; - if (data.visibility.startsWith("hidden") && data.visibility !== "hidden") - data.visibility = data.visibility.slice(6); // enforce silent clients on server if ( From 1e348f6a7fdca2a05dd130e970860e9f00d76f7e Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Thu, 4 Jul 2024 02:58:10 +0900 Subject: [PATCH 02/17] chore: reduce code duplication --- .../src/queue/processors/db/import-masto-post.ts | 15 ++------------- .../backend/src/remote/activitypub/audience.ts | 4 ++-- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/packages/backend/src/queue/processors/db/import-masto-post.ts b/packages/backend/src/queue/processors/db/import-masto-post.ts index f87c44e98e..54308b7e97 100644 --- a/packages/backend/src/queue/processors/db/import-masto-post.ts +++ b/packages/backend/src/queue/processors/db/import-masto-post.ts @@ -14,6 +14,7 @@ import promiseLimit from "promise-limit"; import { unique, concat } from "@/prelude/array.js"; import type { CacheableUser } from "@/models/entities/user.js"; import { resolvePerson } from "@/remote/activitypub/models/person.js"; +import { isPublic } from "@/remote/activitypub/audience.js"; const logger = queueLogger.createSubLogger("import-masto-post"); @@ -128,7 +129,7 @@ export async function importMastoPost( visibility = "public"; } else if (isPublic(post.cc)) { visibility = "home"; - } else if (isFollowers(post.cc)) { + } else if ((post.cc as string).endsWith("/followers")) { visibility = "followers"; } else { try { @@ -182,15 +183,3 @@ export async function importMastoPost( logger.info("Imported"); } - -function isPublic(id: string) { - return [ - "https://www.w3.org/ns/activitystreams#Public", - "as:Public", - "Public", - ].includes(id); -} - -function isFollowers(id: string) { - return id.endsWith("/followers"); -} diff --git a/packages/backend/src/remote/activitypub/audience.ts b/packages/backend/src/remote/activitypub/audience.ts index 9d840bc574..ec4ac6d317 100644 --- a/packages/backend/src/remote/activitypub/audience.ts +++ b/packages/backend/src/remote/activitypub/audience.ts @@ -90,7 +90,7 @@ function groupingAudience(ids: string[], actor: CacheableRemoteUser) { return groups; } -function isPublic(id: string) { +export function isPublic(id: string) { return [ "https://www.w3.org/ns/activitystreams#Public", "as:Public", @@ -98,6 +98,6 @@ function isPublic(id: string) { ].includes(id); } -function isFollowers(id: string, actor: CacheableRemoteUser) { +export function isFollowers(id: string, actor: CacheableRemoteUser) { return id === (actor.followersUri || `${actor.uri}/followers`); } From ee9e2ad60950a0a751f0d6c1499b4a78c435b992 Mon Sep 17 00:00:00 2001 From: laozhoubuluo <laozhoubuluo@gmail.com> Date: Thu, 4 Jul 2024 03:03:32 +0900 Subject: [PATCH 03/17] fix: unsure string[] -> string Co-authored-by: naskya <m@naskya.net> --- .../backend/src/queue/processors/db/import-masto-post.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/backend/src/queue/processors/db/import-masto-post.ts b/packages/backend/src/queue/processors/db/import-masto-post.ts index 54308b7e97..4bf351e8ec 100644 --- a/packages/backend/src/queue/processors/db/import-masto-post.ts +++ b/packages/backend/src/queue/processors/db/import-masto-post.ts @@ -125,11 +125,11 @@ export async function importMastoPost( if (note == null) { let visibility = "specified"; let visibleUsers: CacheableUser[] = []; - if (isPublic(post.to)) { + if ((post.to as string[]).some(isPublic)) { visibility = "public"; - } else if (isPublic(post.cc)) { + } else if ((post.cc as string[]).some(isPublic)) { visibility = "home"; - } else if ((post.cc as string).endsWith("/followers")) { + } else if ((post.cc as string[]).some((cc) => cc.endsWith("/followers"))) { visibility = "followers"; } else { try { From f8bc3962ba276b024f8980d3c305cfcb9585d4d1 Mon Sep 17 00:00:00 2001 From: CI <project_7_bot_1bfaee5701aed20091a86249a967a6c1@noreply.firefish.dev> Date: Wed, 3 Jul 2024 20:05:19 +0000 Subject: [PATCH 04/17] chore(deps): update dependency ws to v8.18.0 --- packages/backend/package.json | 2 +- pnpm-lock.yaml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index a46afb52f4..72b4c1b642 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -171,6 +171,6 @@ "type-fest": "4.21.0", "typescript": "5.5.3", "webpack": "5.92.1", - "ws": "8.17.1" + "ws": "8.18.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 98089abd76..3f2ef738c7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -491,8 +491,8 @@ importers: specifier: 5.92.1 version: 5.92.1 ws: - specifier: 8.17.1 - version: 8.17.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + specifier: 8.18.0 + version: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) packages/backend-rs: devDependencies: @@ -7007,8 +7007,8 @@ packages: utf-8-validate: optional: true - ws@8.17.1: - resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -11383,7 +11383,7 @@ snapshots: whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 whatwg-url: 14.0.0 - ws: 8.17.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) xml-name-validator: 5.0.0 transitivePeerDependencies: - bufferutil @@ -13625,7 +13625,7 @@ snapshots: bufferutil: 4.0.8 utf-8-validate: 5.0.10 - ws@8.17.1(bufferutil@4.0.8)(utf-8-validate@5.0.10): + ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): optionalDependencies: bufferutil: 4.0.8 utf-8-validate: 5.0.10 From 603c0e53acdb2366f13ff1254dbfdd519478a728 Mon Sep 17 00:00:00 2001 From: CI <project_7_bot_1bfaee5701aed20091a86249a967a6c1@noreply.firefish.dev> Date: Wed, 3 Jul 2024 20:05:35 +0000 Subject: [PATCH 05/17] fix(deps): update dependency aws-sdk to v2.1654.0 --- packages/backend/package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index a46afb52f4..8d7b3ce009 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -33,7 +33,7 @@ "adm-zip": "0.5.14", "ajv": "8.16.0", "archiver": "7.0.1", - "aws-sdk": "2.1653.0", + "aws-sdk": "2.1654.0", "axios": "1.7.2", "backend-rs": "workspace:*", "blurhash": "2.0.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 98089abd76..b23f88fc8d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -82,8 +82,8 @@ importers: specifier: 7.0.1 version: 7.0.1 aws-sdk: - specifier: 2.1653.0 - version: 2.1653.0 + specifier: 2.1654.0 + version: 2.1654.0 axios: specifier: 1.7.2 version: 1.7.2 @@ -2935,8 +2935,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - aws-sdk@2.1653.0: - resolution: {integrity: sha512-9f42kuLpMcL1EPZOsLM8u6wlnOMtFwED1b24SN0fBbi/N7N1xTLZ7vbEMt/haz06Lc3Vr3VMDyv0atfMmkboBw==} + aws-sdk@2.1654.0: + resolution: {integrity: sha512-b5ryvXipBJod9Uh1GUfQNgi5tIIiluxJbyqr/hZ/mr5U8WxrrfjVq3nGnx5JjevFKYRqXIywhumsVyanfACzFA==} engines: {node: '>= 10.0.0'} axios@0.24.0: @@ -9204,7 +9204,7 @@ snapshots: dependencies: possible-typed-array-names: 1.0.0 - aws-sdk@2.1653.0: + aws-sdk@2.1654.0: dependencies: buffer: 4.9.2 events: 1.1.1 From 119e59d06444da617f53d3b525d867d5a5882846 Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Thu, 4 Jul 2024 12:40:16 +0900 Subject: [PATCH 06/17] docs: update notice-for-admins.md --- docs/notice-for-admins.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/notice-for-admins.md b/docs/notice-for-admins.md index fbc58623fe..d8369050b4 100644 --- a/docs/notice-for-admins.md +++ b/docs/notice-for-admins.md @@ -10,7 +10,15 @@ Please take a look at #10947. ### For all users -This is not related to the recent changes, but we have added a new section called "[Maintain the server](https://firefish.dev/firefish/firefish/-/blob/develop/docs/install.md#maintain-the-server)" in the installation guide. We suggest that you take a look at it. (and we welcome your docs contributions!) +This is not related to the recent changes, but we have added a new section called "[Maintain the server](https://firefish.dev/firefish/firefish/-/blob/develop/docs/install.md#maintain-the-server)" in the installation guide. We suggest that you take a look at it (and we welcome your docs contributions)! + +### For systemd/pm2 users + +[Node.js will release a new security fix on July 8th](<https://nodejs.org/en/blog/vulnerability/july-2024-security-releases>). It is highly recommended that you upgrade your Node.js version once it's released. + +### For Docker/Podman users + +[Node.js will release a new security fix on July 8th](<https://nodejs.org/en/blog/vulnerability/july-2024-security-releases>). Once it's released and the [docker.io/node](<https://hub.docker.com/_/node>) image is updated, we'll rebuild the OCI image based on the new `docker.io/node` image and reupload it as [`registry.firefish.dev/firefish/firefish:latest`](<https://firefish.dev/firefish/firefish/container_registry/1>). ## v20240607 From 1a201a7007a5eb6ecbf9ca10b873dd2bae66a6ae Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Thu, 4 Jul 2024 12:50:40 +0900 Subject: [PATCH 07/17] style: highlight Lookup button in the post search box --- packages/client/src/components/MkPostSearch.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/components/MkPostSearch.vue b/packages/client/src/components/MkPostSearch.vue index 7c732ca2c6..0c56a235ba 100644 --- a/packages/client/src/components/MkPostSearch.vue +++ b/packages/client/src/components/MkPostSearch.vue @@ -78,7 +78,7 @@ <MkButton inline primary @click="search" >{{ i18n.ts.search }} </MkButton> - <MkButton inline @click="lookup">{{ i18n.ts.lookup }}</MkButton> + <MkButton inline primary @click="lookup">{{ i18n.ts.lookup }}</MkButton> <MkButton inline @click="cancel">{{ i18n.ts.cancel }}</MkButton> </div> </div> From 143e40928afc7381d06a7b01accc59faf1e65e16 Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Thu, 4 Jul 2024 14:20:13 +0900 Subject: [PATCH 08/17] meta: update merge request template --- .gitlab/merge_request_templates/default.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.gitlab/merge_request_templates/default.md b/.gitlab/merge_request_templates/default.md index 6d09072a87..7a37db2c9e 100644 --- a/.gitlab/merge_request_templates/default.md +++ b/.gitlab/merge_request_templates/default.md @@ -6,9 +6,7 @@ ## Contribution Guidelines By submitting this merge request, you agree to follow our [Contribution Guidelines](https://firefish.dev/firefish/firefish/-/blob/develop/CONTRIBUTING.md) -- [ ] This closes issue #0000 (please substitute the number) -- [ ] This is a minor bug fix or refactoring - +- [ ] This closes #0000 (please substitute the issue number or open a new one unless this is a minor fix/refactor) - [ ] I agree to follow this project's Contribution Guidelines - [ ] I have made sure to test this merge request - [ ] I have made sure to run `pnpm run format` before submitting this merge request From f4ae3c7ec3dc10f66c4b229d8aa081682cb3b53b Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Thu, 4 Jul 2024 14:34:55 +0900 Subject: [PATCH 09/17] meta: update issue templates --- .gitlab/issue_templates/default.md | 2 ++ .gitlab/issue_templates/feature.md | 2 ++ .gitlab/issue_templates/refactor.md | 2 ++ 3 files changed, 6 insertions(+) diff --git a/.gitlab/issue_templates/default.md b/.gitlab/issue_templates/default.md index f5823ea666..db5fc81666 100644 --- a/.gitlab/issue_templates/default.md +++ b/.gitlab/issue_templates/default.md @@ -90,6 +90,8 @@ By submitting this issue, you agree to follow our [Contribution Guidelines](http However, we are currently so understaffed that it is virtually impossible to respond to every single proposal. So, feel free to implement it if there is no response for more than a week or there is a thumbs-up emoji reaction from the project maintainer(s). + + Many thanks for your involvement! --> diff --git a/.gitlab/issue_templates/feature.md b/.gitlab/issue_templates/feature.md index a99265161b..eb12540da1 100644 --- a/.gitlab/issue_templates/feature.md +++ b/.gitlab/issue_templates/feature.md @@ -58,6 +58,8 @@ By submitting this issue, you agree to follow our [Contribution Guidelines](http However, we are currently so understaffed that it is virtually impossible to respond to every single proposal. So, feel free to implement it if there is no response for more than a week or there is a thumbs-up emoji reaction from the project maintainer(s). + + Many thanks for your involvement! --> diff --git a/.gitlab/issue_templates/refactor.md b/.gitlab/issue_templates/refactor.md index e9f9ffe05f..33b0077403 100644 --- a/.gitlab/issue_templates/refactor.md +++ b/.gitlab/issue_templates/refactor.md @@ -58,6 +58,8 @@ By submitting this issue, you agree to follow our [Contribution Guidelines](http However, we are currently so understaffed that it is virtually impossible to respond to every single proposal. So, feel free to implement it if there is no response for more than a week or there is a thumbs-up emoji reaction from the project maintainer(s). + + Many thanks for your involvement! --> From 71ebea0cd1828cfef59d690ccc225b211383301a Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Thu, 4 Jul 2024 16:46:38 +0900 Subject: [PATCH 10/17] fix (client): set default values of the instance data --- packages/backend/src/boot/master.ts | 3 +- packages/client/src/instance.ts | 64 ++++++++++++++++++++++++++--- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/packages/backend/src/boot/master.ts b/packages/backend/src/boot/master.ts index dbf51c08c5..801d2cf5fa 100644 --- a/packages/backend/src/boot/master.ts +++ b/packages/backend/src/boot/master.ts @@ -25,10 +25,11 @@ export async function masterMain() { // initialize app try { greet(); - showEnvironment(); showServerInfo(); + showEnvironment(); showNodejsVersion(); await connectDb(); + await updateMetaCache(); } catch (e) { bootLogger.error( `Fatal error occurred during initialization:\n${inspect(e)}`, diff --git a/packages/client/src/instance.ts b/packages/client/src/instance.ts index f4ea4d431e..4092a901c0 100644 --- a/packages/client/src/instance.ts +++ b/packages/client/src/instance.ts @@ -6,7 +6,65 @@ import { set, get } from "idb-keyval"; // TODO: 他のタブと永続化されたstateを同期 // TODO: get("instance") requires top-level await -let instance: entities.DetailedInstanceMetadata; +// TODO: fallback to defaults more nicely +// default values +let instance: entities.DetailedInstanceMetadata = { + maintainerName: "", + maintainerEmail: "", + version: "", + name: null, + uri: "", + tosUrl: null, + description: null, + disableRegistration: true, + disableLocalTimeline: false, + disableGlobalTimeline: false, + disableRecommendedTimeline: true, + enableGuestTimeline: false, + driveCapacityPerLocalUserMb: 1000, + driveCapacityPerRemoteUserMb: 0, + antennaLimit: 5, + enableHcaptcha: false, + hcaptchaSiteKey: null, + enableRecaptcha: false, + recaptchaSiteKey: null, + swPublickey: null, + maxNoteTextLength: 3000, + maxCaptionTextLength: 1500, + enableEmail: false, + enableServiceWorker: false, + markLocalFilesNsfwByDefault: false, + emojis: [], + ads: [], + langs: [], + moreUrls: {}, + repositoryUrl: "https://firefish.dev/firefish/firefish", + feedbackUrl: "https://firefish.dev/firefish/firefish/-/issues", + defaultDarkTheme: null, + defaultLightTheme: null, + defaultReaction: "⭐", + cacheRemoteFiles: false, + proxyAccountName: null, + emailRequiredForSignup: false, + mascotImageUrl: "", + bannerUrl: "", + backgroundImageUrl: "", + errorImageUrl: "", + iconUrl: null, + requireSetup: false, + translatorAvailable: false, + features: { + registration: false, + localTimeLine: true, + recommendedTimeLine: false, + globalTimeLine: true, + searchFilters: true, + hcaptcha: false, + recaptcha: false, + objectStorage: false, + serviceWorker: false, + }, +}; export function getInstanceInfo(): entities.DetailedInstanceMetadata { return instance; @@ -27,13 +85,9 @@ export async function updateInstanceCache(): Promise<void> { detail: true, }); - // TODO: set default values - instance = {} as entities.DetailedInstanceMetadata; - for (const [k, v] of Object.entries(meta)) { instance[k] = v; } - set("instance", JSON.stringify(instance)); } From 28576b518ab8ca054ae6623d484d080d4572e739 Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Thu, 4 Jul 2024 16:46:38 +0900 Subject: [PATCH 11/17] fix (client): missing variables --- packages/client/src/ui/visitor/b.vue | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/client/src/ui/visitor/b.vue b/packages/client/src/ui/visitor/b.vue index fb8bfe5aaf..0d1f6a77d5 100644 --- a/packages/client/src/ui/visitor/b.vue +++ b/packages/client/src/ui/visitor/b.vue @@ -110,6 +110,10 @@ provideMetadataReceiver((info) => { }); const root = computed(() => mainRouter.currentRoute.value?.name === "index"); +const showMenu = ref(false); +const isDesktop = ref(window.innerWidth >= DESKTOP_THRESHOLD); +const narrow = ref(window.innerWidth < 1280); +const meta = ref(); os.api("meta", { detail: true }).then((res) => { meta.value = res; From 1e5d63b6179cd44d58b04c675eb08276b49a2695 Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Thu, 4 Jul 2024 16:46:38 +0900 Subject: [PATCH 12/17] chore (client): rename instance variable --- packages/client/src/instance.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/client/src/instance.ts b/packages/client/src/instance.ts index 4092a901c0..dd0c98fbd6 100644 --- a/packages/client/src/instance.ts +++ b/packages/client/src/instance.ts @@ -5,10 +5,9 @@ import { set, get } from "idb-keyval"; // TODO: 他のタブと永続化されたstateを同期 -// TODO: get("instance") requires top-level await -// TODO: fallback to defaults more nicely +// TODO: fallback to defaults more nicely (with #10947) // default values -let instance: entities.DetailedInstanceMetadata = { +let instanceMeta: entities.DetailedInstanceMetadata = { maintainerName: "", maintainerEmail: "", version: "", @@ -66,15 +65,16 @@ let instance: entities.DetailedInstanceMetadata = { }, }; +// get("instanceMeta") requires top-level await export function getInstanceInfo(): entities.DetailedInstanceMetadata { - return instance; + return instanceMeta; } export async function initializeInstanceCache(): Promise<void> { // Is the data stored in IndexDB? - const fromIdb = await get<string>("instance"); + const fromIdb = await get<string>("instanceMeta"); if (fromIdb != null) { - instance = JSON.parse(fromIdb); + instanceMeta = JSON.parse(fromIdb); } // Call API updateInstanceCache(); @@ -86,24 +86,24 @@ export async function updateInstanceCache(): Promise<void> { }); for (const [k, v] of Object.entries(meta)) { - instance[k] = v; + instanceMeta[k] = v; } - set("instance", JSON.stringify(instance)); + set("instanceMeta", JSON.stringify(instanceMeta)); } export const emojiCategories = computed(() => { - if (instance.emojis == null) return []; + if (instanceMeta.emojis == null) return []; const categories = new Set(); - for (const emoji of instance.emojis) { + for (const emoji of instanceMeta.emojis) { categories.add(emoji.category); } return Array.from(categories); }); export const emojiTags = computed(() => { - if (instance.emojis == null) return []; + if (instanceMeta.emojis == null) return []; const tags = new Set(); - for (const emoji of instance.emojis) { + for (const emoji of instanceMeta.emojis) { for (const tag of emoji.aliases) { tags.add(tag); } From 32573b8f32a0e6b772180d993e5aa20ed7427dbd Mon Sep 17 00:00:00 2001 From: syuilo <Syuilotan@yahoo.co.jp> Date: Thu, 4 Jul 2024 16:46:38 +0900 Subject: [PATCH 13/17] chore (client): make sure to remove splash screen DOM element https://github.com/misskey-dev/misskey/commit/c23c97d303d227f6a0e2b3c775189f90772c1dfa Co-authored-by: naskya <m@naskya.net> --- packages/client/src/init.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/client/src/init.ts b/packages/client/src/init.ts index 16750c26e0..51d837c959 100644 --- a/packages/client/src/init.ts +++ b/packages/client/src/init.ts @@ -61,9 +61,11 @@ function checkForSplash() { if (splash) { splash.style.opacity = "0"; splash.style.pointerEvents = "none"; - splash.addEventListener("transitionend", () => { + + // remove splash screen + window.setTimeout(() => { splash.remove(); - }); + }, 1000); } } From 9aaafce3b6b490a73d9776eb2418fd81b65f5cf4 Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Thu, 4 Jul 2024 16:46:39 +0900 Subject: [PATCH 14/17] fix (client, firefish-js): fix type of moreUrls --- packages/client/src/instance.ts | 2 +- packages/firefish-js/src/entities.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/client/src/instance.ts b/packages/client/src/instance.ts index dd0c98fbd6..10249d909f 100644 --- a/packages/client/src/instance.ts +++ b/packages/client/src/instance.ts @@ -36,7 +36,7 @@ let instanceMeta: entities.DetailedInstanceMetadata = { emojis: [], ads: [], langs: [], - moreUrls: {}, + moreUrls: [], repositoryUrl: "https://firefish.dev/firefish/firefish", feedbackUrl: "https://firefish.dev/firefish/firefish/-/issues", defaultDarkTheme: null, diff --git a/packages/firefish-js/src/entities.ts b/packages/firefish-js/src/entities.ts index 7da946ba95..2541b255c9 100644 --- a/packages/firefish-js/src/entities.ts +++ b/packages/firefish-js/src/entities.ts @@ -395,7 +395,7 @@ export type DetailedInstanceMetadata = LiteInstanceMetadata & { miauth?: boolean; }; langs: string[]; - moreUrls: object; + moreUrls: { name: string; url: string }[]; repositoryUrl: string; feedbackUrl: string; defaultDarkTheme: string | null; From fa9a004f27164ee1136bd21ecd17b29444bf5a51 Mon Sep 17 00:00:00 2001 From: CI <project_7_bot_1bfaee5701aed20091a86249a967a6c1@noreply.firefish.dev> Date: Thu, 4 Jul 2024 12:05:03 +0000 Subject: [PATCH 15/17] fix(deps): update dependency @redocly/openapi-core to v1.17.1 --- packages/backend/package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 32f519c526..c8ec5030e9 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -28,7 +28,7 @@ "@koa/router": "12.0.1", "@ladjs/koa-views": "9.0.0", "@peertube/http-signature": "1.7.0", - "@redocly/openapi-core": "1.17.0", + "@redocly/openapi-core": "1.17.1", "@sinonjs/fake-timers": "11.2.2", "adm-zip": "0.5.14", "ajv": "8.16.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 90f731111f..b84512d886 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -67,8 +67,8 @@ importers: specifier: 1.7.0 version: 1.7.0 '@redocly/openapi-core': - specifier: 1.17.0 - version: 1.17.0 + specifier: 1.17.1 + version: 1.17.1 '@sinonjs/fake-timers': specifier: 11.2.2 version: 11.2.2 @@ -2177,8 +2177,8 @@ packages: '@redocly/config@0.6.2': resolution: {integrity: sha512-c3K5u64eMnr2ootPcpEI0ioIRLE8QP8ptvLxG9MwAmb2sU8HMRfVwXDU3AZiMVY2w4Ts0mDc+Xv4HTIk8DRqFw==} - '@redocly/openapi-core@1.17.0': - resolution: {integrity: sha512-XoNIuksnOGAzAcfpyJkHrMxwurXaQfglnovNE7/pTx4OEjik3OT91+tKAyRCkklVCdMtAA3YokGMZzdhjViUWA==} + '@redocly/openapi-core@1.17.1': + resolution: {integrity: sha512-PQxDLLNk5cBatJBBxvfk49HFw/nVozw1XZ6Dw/GX0Tviq+WxeEjEuLAKfnLVvb5L0wgs4TNmVG4Y+JyofSPu1A==} engines: {node: '>=14.19.0', npm: '>=7.0.0'} '@rollup/plugin-alias@5.1.0': @@ -8390,7 +8390,7 @@ snapshots: '@redocly/config@0.6.2': {} - '@redocly/openapi-core@1.17.0': + '@redocly/openapi-core@1.17.1': dependencies: '@redocly/ajv': 8.11.0 '@redocly/config': 0.6.2 From 1d03376d9e08aa7230c412fd8657e69589a59167 Mon Sep 17 00:00:00 2001 From: CI <project_7_bot_1bfaee5701aed20091a86249a967a6c1@noreply.firefish.dev> Date: Thu, 4 Jul 2024 12:05:34 +0000 Subject: [PATCH 16/17] fix(deps): update dependency bull to v4.15.1 --- packages/backend/package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 32f519c526..29dad7e06a 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -37,7 +37,7 @@ "axios": "1.7.2", "backend-rs": "workspace:*", "blurhash": "2.0.5", - "bull": "4.15.0", + "bull": "4.15.1", "cacheable-lookup": "git+https://github.com/TheEssem/cacheable-lookup.git#dd2fb616366a3c68dcf321a57a67295967b204bf", "cbor-x": "1.5.9", "chalk": "5.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 90f731111f..0ac6a43005 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -94,8 +94,8 @@ importers: specifier: 2.0.5 version: 2.0.5 bull: - specifier: 4.15.0 - version: 4.15.0 + specifier: 4.15.1 + version: 4.15.1 cacheable-lookup: specifier: git+https://github.com/TheEssem/cacheable-lookup.git#dd2fb616366a3c68dcf321a57a67295967b204bf version: https://codeload.github.com/TheEssem/cacheable-lookup/tar.gz/dd2fb616366a3c68dcf321a57a67295967b204bf @@ -3080,8 +3080,8 @@ packages: resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} engines: {node: '>=6.14.2'} - bull@4.15.0: - resolution: {integrity: sha512-nOEAfUXwUXtFbRPQP3bWCwpQ/NAerAu2Nym/ucv5C1E+Qh2x6RGdKKsYIfZam4mYncayTynTUN/HLhRgGi2N8w==} + bull@4.15.1: + resolution: {integrity: sha512-knVKiZdrXbRkB+fWqNryDz85b3JfsT3dBrZexkztwvTH/AFmpHvsC933VB3JX18aJCz47E+xdO57xbDvxljoAg==} engines: {node: '>=12'} busboy@1.6.0: @@ -9407,7 +9407,7 @@ snapshots: dependencies: node-gyp-build: 4.8.1 - bull@4.15.0: + bull@4.15.1: dependencies: cron-parser: 4.9.0 get-port: 5.1.1 From c855681b0c7c41afa9fef925970be83a101874fb Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Fri, 5 Jul 2024 01:24:14 +0900 Subject: [PATCH 17/17] feat: add ability to disable the cat language conversion --- docs/api-change.md | 4 ++ docs/changelog.md | 1 + docs/downgrade.sql | 4 ++ locales/en-US.yml | 1 + packages/backend-rs/index.d.ts | 3 ++ packages/backend-rs/index.js | 1 + packages/backend-rs/src/database/cache.rs | 2 + packages/backend-rs/src/misc/mod.rs | 1 + packages/backend-rs/src/misc/should_nyaify.rs | 39 +++++++++++++++++++ packages/backend-rs/src/model/entity/user.rs | 2 + .../1720107645050-turn-off-cat-language.ts | 16 ++++++++ packages/backend/src/models/entities/user.ts | 6 +++ .../backend/src/models/repositories/note.ts | 15 ++++++- .../backend/src/models/repositories/user.ts | 3 +- .../src/server/api/endpoints/i/update.ts | 3 ++ .../client/src/pages/settings/general.vue | 12 ++++++ packages/firefish-js/src/api.types.ts | 2 + packages/firefish-js/src/entities.ts | 1 + packages/firefish-js/src/schema/user.ts | 5 +++ 19 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 packages/backend-rs/src/misc/should_nyaify.rs create mode 100644 packages/backend/src/migration/1720107645050-turn-off-cat-language.ts diff --git a/docs/api-change.md b/docs/api-change.md index 2ae2275707..4147316c87 100644 --- a/docs/api-change.md +++ b/docs/api-change.md @@ -2,6 +2,10 @@ Breaking changes are indicated by the :warning: icon. +## Unreleased + +- Added `readCatLanguage` field to the response of `i` and request of `i/update` (optional). + ## v20240607 - `GET` request is now allowed for the `latest-version` endpoint. diff --git a/docs/changelog.md b/docs/changelog.md index 513370dd63..dc8873931d 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -7,6 +7,7 @@ Critical security updates are indicated by the :warning: icon. ## Unreleased +- Add ability to disable the cat language conversion (nyaification) - Fix bugs ## [v20240630](https://firefish.dev/firefish/firefish/-/merge_requests/11072/commits) diff --git a/docs/downgrade.sql b/docs/downgrade.sql index 895046087a..b7a993beba 100644 --- a/docs/downgrade.sql +++ b/docs/downgrade.sql @@ -1,6 +1,7 @@ BEGIN; DELETE FROM "migrations" WHERE name IN ( + 'TurnOffCatLanguage1720107645050', 'RefactorScheduledPosts1716804636187', 'RemoveEnumTypenameSuffix1716462794927', 'CreateScheduledNote1714728200194', @@ -34,6 +35,9 @@ DELETE FROM "migrations" WHERE name IN ( 'RemoveNativeUtilsMigration1705877093218' ); +-- turn-off-cat-language +ALTER TABLE "user" DROP COLUMN "readCatLanguage"; + -- refactor-scheduled-post CREATE TABLE "scheduled_note" ( "id" character varying(32) NOT NULL PRIMARY KEY, diff --git a/locales/en-US.yml b/locales/en-US.yml index 261b0d5673..3a09448ac1 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1240,6 +1240,7 @@ showNoAltTextWarning: "Show a warning if you attempt to post files without a des showAddFileDescriptionAtFirstPost: "Automatically open a form to write a description when you attempt to post files without a description" addAlt4MeTag: "Automatically append #Alt4Me hashtag to your post if attached file has no description" +turnOffCatLanguage: "Turn off cat language conversion" _emojiModPerm: unauthorized: "None" diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index 52e4e1af1a..6967d64bf0 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -1295,6 +1295,8 @@ export interface Services { outbound: Array<Outbound> } +export declare function shouldNyaify(readerUserId: string): Promise<boolean> + /** Prints the server hardware information as the server info log. */ export declare function showServerInfo(): void @@ -1416,6 +1418,7 @@ export interface User { emojiModPerm: UserEmojiModPerm isIndexable: boolean alsoKnownAs: Array<string> | null + readCatLanguage: boolean } export const USER_ACTIVE_THRESHOLD: number diff --git a/packages/backend-rs/index.js b/packages/backend-rs/index.js index 9cb1779766..7edce9047d 100644 --- a/packages/backend-rs/index.js +++ b/packages/backend-rs/index.js @@ -432,6 +432,7 @@ module.exports.removeOldAttestationChallenges = nativeBinding.removeOldAttestati module.exports.safeForSql = nativeBinding.safeForSql module.exports.SECOND = nativeBinding.SECOND module.exports.sendPushNotification = nativeBinding.sendPushNotification +module.exports.shouldNyaify = nativeBinding.shouldNyaify module.exports.showServerInfo = nativeBinding.showServerInfo module.exports.sqlLikeEscape = nativeBinding.sqlLikeEscape module.exports.storageUsage = nativeBinding.storageUsage diff --git a/packages/backend-rs/src/database/cache.rs b/packages/backend-rs/src/database/cache.rs index 2fe192cb1e..60abea56e8 100644 --- a/packages/backend-rs/src/database/cache.rs +++ b/packages/backend-rs/src/database/cache.rs @@ -9,6 +9,7 @@ pub enum Category { FetchUrl, Block, Follow, + CatLang, #[cfg(test)] Test, } @@ -33,6 +34,7 @@ fn categorize(category: Category, key: &str) -> String { Category::FetchUrl => "fetchUrl", Category::Block => "blocking", Category::Follow => "following", + Category::CatLang => "catlang", #[cfg(test)] Category::Test => "usedOnlyForTesting", }; diff --git a/packages/backend-rs/src/misc/mod.rs b/packages/backend-rs/src/misc/mod.rs index e3eb23a2eb..ca08b14f86 100644 --- a/packages/backend-rs/src/misc/mod.rs +++ b/packages/backend-rs/src/misc/mod.rs @@ -16,4 +16,5 @@ pub mod nyaify; pub mod password; pub mod reaction; pub mod remove_old_attestation_challenges; +pub mod should_nyaify; pub mod system_info; diff --git a/packages/backend-rs/src/misc/should_nyaify.rs b/packages/backend-rs/src/misc/should_nyaify.rs new file mode 100644 index 0000000000..93ed5a1e7e --- /dev/null +++ b/packages/backend-rs/src/misc/should_nyaify.rs @@ -0,0 +1,39 @@ +//! Determine whether to enable the cat language conversion + +use crate::{ + database::{cache, db_conn}, + model::entity::user, +}; +use sea_orm::{DbErr, EntityTrait, QuerySelect, SelectColumns}; + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[doc = "database error"] + #[error(transparent)] + Db(#[from] DbErr), + #[doc = "cache error"] + #[error(transparent)] + Cache(#[from] cache::Error), + #[error("user {0} not found")] + NotFound(String), +} + +#[macros::export] +pub async fn should_nyaify(reader_user_id: &str) -> Result<bool, Error> { + let cached_value = cache::get_one::<bool>(cache::Category::CatLang, reader_user_id).await?; + if let Some(value) = cached_value { + return Ok(value); + } + + let fetched_value = user::Entity::find_by_id(reader_user_id) + .select_only() + .select_column(user::Column::ReadCatLanguage) + .into_tuple::<bool>() + .one(db_conn().await?) + .await? + .ok_or_else(|| Error::NotFound(reader_user_id.to_owned()))?; + + cache::set_one(cache::Category::CatLang, reader_user_id, &fetched_value, 10 * 60).await?; + + Ok(fetched_value) +} diff --git a/packages/backend-rs/src/model/entity/user.rs b/packages/backend-rs/src/model/entity/user.rs index f11e1e43d9..f13dc4c9af 100644 --- a/packages/backend-rs/src/model/entity/user.rs +++ b/packages/backend-rs/src/model/entity/user.rs @@ -77,6 +77,8 @@ pub struct Model { pub is_indexable: bool, #[sea_orm(column_name = "alsoKnownAs")] pub also_known_as: Option<Vec<String>>, + #[sea_orm(column_name = "readCatLanguage")] + pub read_cat_language: bool, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/packages/backend/src/migration/1720107645050-turn-off-cat-language.ts b/packages/backend/src/migration/1720107645050-turn-off-cat-language.ts new file mode 100644 index 0000000000..8503ce96e9 --- /dev/null +++ b/packages/backend/src/migration/1720107645050-turn-off-cat-language.ts @@ -0,0 +1,16 @@ +import type { MigrationInterface, QueryRunner } from "typeorm"; + +export class TurnOffCatLanguage1720107645050 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query( + `ALTER TABLE "user" ADD COLUMN "readCatLanguage" boolean NOT NULL DEFAULT true`, + ); + await queryRunner.query( + `COMMENT ON COLUMN "user"."readCatLanguage" IS 'Whether to enable the cat language conversion.'`, + ); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "readCatLanguage"`); + } +} diff --git a/packages/backend/src/models/entities/user.ts b/packages/backend/src/models/entities/user.ts index 65780eb44d..e71e04ef8d 100644 --- a/packages/backend/src/models/entities/user.ts +++ b/packages/backend/src/models/entities/user.ts @@ -159,6 +159,12 @@ export class User { }) public speakAsCat: boolean; + @Column("boolean", { + default: true, + comment: "Whether to enable the cat language conversion.", + }) + public readCatLanguage: boolean; + @Column("boolean", { default: false, comment: "Whether the User is the admin.", diff --git a/packages/backend/src/models/repositories/note.ts b/packages/backend/src/models/repositories/note.ts index 062973a741..3a24c0b80d 100644 --- a/packages/backend/src/models/repositories/note.ts +++ b/packages/backend/src/models/repositories/note.ts @@ -13,7 +13,12 @@ import { Notes, } from "../index.js"; import type { Packed } from "@/misc/schema.js"; -import { countReactions, decodeReaction, nyaify } from "backend-rs"; +import { + countReactions, + decodeReaction, + nyaify, + shouldNyaify, +} from "backend-rs"; import { awaitAll } from "@/prelude/await-all.js"; import type { NoteReaction } from "@/models/entities/note-reaction.js"; import { @@ -285,7 +290,13 @@ export const NoteRepository = db.getRepository(Note).extend({ lang: note.lang, }); - if (packed.user.isCat && packed.user.speakAsCat && packed.text) { + if ( + packed.user.isCat && + packed.user.speakAsCat && + packed.text != null && + meId != null && + (await shouldNyaify(meId)) + ) { const tokens = packed.text ? mfm.parse(packed.text) : []; function nyaifyNode(node: mfm.MfmNode) { if (node.type === "quote") return; diff --git a/packages/backend/src/models/repositories/user.ts b/packages/backend/src/models/repositories/user.ts index c07473d0ea..e6c8f2517c 100644 --- a/packages/backend/src/models/repositories/user.ts +++ b/packages/backend/src/models/repositories/user.ts @@ -464,7 +464,8 @@ export const UserRepository = db.getRepository(User).extend({ isLocked: user.isLocked, isIndexable: user.isIndexable, isCat: user.isCat || falsy, - speakAsCat: user.speakAsCat || falsy, + speakAsCat: user.speakAsCat, + readCatLanguage: user.readCatLanguage, instance: user.host ? userInstanceCache .fetch( diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index 98d760ddb5..dd0511cfed 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -114,6 +114,7 @@ export const paramDef = { isBot: { type: "boolean" }, isCat: { type: "boolean" }, speakAsCat: { type: "boolean", nullable: true }, + readCatLanguage: { type: "boolean", nullable: true }, isIndexable: { type: "boolean" }, injectFeaturedNote: { type: "boolean" }, receiveAnnouncementEmail: { type: "boolean" }, @@ -220,6 +221,8 @@ export default define(meta, paramDef, async (ps, _user, token) => { profileUpdates.isIndexable = ps.isIndexable; } if (typeof ps.speakAsCat === "boolean") updates.speakAsCat = ps.speakAsCat; + if (typeof ps.readCatLanguage === "boolean") + updates.readCatLanguage = ps.readCatLanguage; if (typeof ps.injectFeaturedNote === "boolean") profileUpdates.injectFeaturedNote = ps.injectFeaturedNote; if (typeof ps.receiveAnnouncementEmail === "boolean") diff --git a/packages/client/src/pages/settings/general.vue b/packages/client/src/pages/settings/general.vue index 54b9f4aa62..aa6d2a9ad5 100644 --- a/packages/client/src/pages/settings/general.vue +++ b/packages/client/src/pages/settings/general.vue @@ -200,6 +200,11 @@ i18n.ts.expandOnNoteClickDesc }}</template> </FormSwitch> + <FormSwitch v-model="turnOffCatLanguage" @update:modelValue="save()" class="_formBlock" + >{{ i18n.ts.turnOffCatLanguage }}<template #caption>{{ + i18n.ts.reflectMayTakeTime + }}</template> + </FormSwitch> <FormSwitch v-model="advancedMfm" class="_formBlock"> {{ i18n.ts._mfm.advanced }}<template #caption>{{ @@ -423,6 +428,13 @@ const serverLang = ref(me?.lang); const translateLang = ref(localStorage.getItem("translateLang")); const fontSize = ref(localStorage.getItem("fontSize")); const useSystemFont = ref(localStorage.getItem("useSystemFont") !== "f"); +const turnOffCatLanguage = ref(!me?.readCatLanguage); + +function save() { + os.api("i/update", { + readCatLanguage: !turnOffCatLanguage.value, + }); +} async function reloadAsk() { const { canceled } = await os.confirm({ diff --git a/packages/firefish-js/src/api.types.ts b/packages/firefish-js/src/api.types.ts index 140667741f..58ef766991 100644 --- a/packages/firefish-js/src/api.types.ts +++ b/packages/firefish-js/src/api.types.ts @@ -598,6 +598,8 @@ export type Endpoints = { preventAiLearning?: boolean; isBot?: boolean; isCat?: boolean; + speakAsCat?: boolean; + readCatLanguage?: boolean; injectFeaturedNote?: boolean; receiveAnnouncementEmail?: boolean; alwaysMarkNsfw?: boolean; diff --git a/packages/firefish-js/src/entities.ts b/packages/firefish-js/src/entities.ts index 2541b255c9..83ebc2514c 100644 --- a/packages/firefish-js/src/entities.ts +++ b/packages/firefish-js/src/entities.ts @@ -30,6 +30,7 @@ export type UserLite = { isIndexable: boolean; isCat?: boolean; speakAsCat?: boolean; + readCatLanguage?: boolean; driveCapacityOverrideMb: number | null; }; diff --git a/packages/firefish-js/src/schema/user.ts b/packages/firefish-js/src/schema/user.ts index c7417ce0e4..702a8b380a 100644 --- a/packages/firefish-js/src/schema/user.ts +++ b/packages/firefish-js/src/schema/user.ts @@ -76,6 +76,11 @@ export const packedUserLiteSchema = { nullable: false, optional: true, }, + readCatLanguage: { + type: "boolean", + nullable: false, + optional: true, + }, emojis: { type: "array", nullable: false,