diff --git a/CHANGELOG_CHERRYPICK.md b/CHANGELOG_CHERRYPICK.md
index efeeb88960..1e1100ac6c 100644
--- a/CHANGELOG_CHERRYPICK.md
+++ b/CHANGELOG_CHERRYPICK.md
@@ -63,6 +63,15 @@ Misskey의 전체 변경 사항을 확인하려면, [CHANGELOG.md#2024xx](CHANGE
- Feat: 모바일 환경에서 하단 내비게이션 바를 개인화할 수 있음
- `설정` - `내비게이션 바`의 `하단 내비게이션 바`에서 설정할 수 있습니다.
- Feat: 리버시 대전 중에 상대방에게 리액션을 보낼 수 있음 (misskey-dev/misskey#13119)
+- Feat: 노트 자동 번역 기능
+ - 노트 자동 번역은 번역 서비스의 API 제한을 방지하기 위해 자동으로 활성화되지 않으며, 기본적으로 비활성화되어 있습니다.
+ - `역할`에서 `자동 번역 기능 이용 가능 여부`를 활성화 하면 자동 번역을 사용할 수 있는 상태가 됩니다.
+ - 이후, 각 사용자별로 `설정` - `일반`에서 `노트 자동 번역`을 활성화한 사용자는 자동 번역을 사용할 수 있습니다.
+ - 노트가 아래와 같이 설정된 경우에는 노트 자동 번역을 사용하지 않습니다.
+ - 노트가 `내용 가리기`로 설정되어 있음
+ - 노트의 내용이 긺
+ - 노트에 파일이 포함되어 있음
+ - `자동 번역 기능 이용 가능 여부` 역할의 권한을 상실하게 되면 모든 사용자의 `노트 자동 번역` 설정도 자동으로 비활성화 됩니다.
### Client
- Enhance: CherryPick 업데이트 페이지를 제어판 목록에 추가함
@@ -88,6 +97,7 @@ Misskey의 전체 변경 사항을 확인하려면, [CHANGELOG.md#2024xx](CHANGE
- Fix: 이미지 자르기를 할 때 이미지 크기 전체를 표시하지 못할 수 있음
- Fix: 페이지에서 페이지 생성 버튼이 본문에 중복으로 표시됨
- Fix: 노트 본문의 사용자 멘션 영역을 클릭하면 노트 상세 페이지가 표시됨
+- Fix: 역할 권한에 의해 번역 기능을 사용할 수 없을 때도 번역 버튼이 표시됨
### Server
- Enhance: 보안 향상을 위해 비밀번호 해싱 알고리즘이 `bcrypt`에서 `argon2`로 변경됨 (kokonect-link/cherrypick#511), (1673beta/cherrypick#88)
diff --git a/locales/en-US.yml b/locales/en-US.yml
index 902b35f077..d8c740bbf6 100644
--- a/locales/en-US.yml
+++ b/locales/en-US.yml
@@ -1,5 +1,7 @@
---
_lang_: "English"
+useAutoTranslate: "Automatic translation of notes"
+useAutoTranslateDescription: "The server administrator has disabled this feature.\nContact your server administrator to use the feature."
widgets: "Widgets"
postNote: "Post note"
bottomNavbar: "Bottom navigation bar"
diff --git a/locales/index.d.ts b/locales/index.d.ts
index 84a08564ab..d022882abd 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -13,6 +13,15 @@ export interface Locale extends ILocale {
* 日本語
*/
"_lang_": string;
+ /**
+ * ノートを自動翻訳
+ */
+ "useAutoTranslate": string;
+ /**
+ * サーバー管理者がこの機能を無効にしました。
+ * 機能を使用するには、サーバー管理者にお問い合わせください。
+ */
+ "useAutoTranslateDescription": string;
/**
* ウィジェット
*/
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 7dfe486332..7b4784299a 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -1,5 +1,7 @@
_lang_: "日本語"
+useAutoTranslate: "ノートを自動翻訳"
+useAutoTranslateDescription: "サーバー管理者がこの機能を無効にしました。\n機能を使用するには、サーバー管理者にお問い合わせください。"
widgets: "ウィジェット"
postNote: "ノートを作成"
bottomNavbar: "下のナビゲーションバー"
diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml
index c085f31509..027c4a43df 100644
--- a/locales/ko-KR.yml
+++ b/locales/ko-KR.yml
@@ -1,5 +1,7 @@
---
_lang_: "한국어"
+useAutoTranslate: "노트 자동 번역"
+useAutoTranslateDescription: "서버 관리자가 이 기능을 사용할 수 없도록 설정했어요.\n기능을 사용하려면 서버 관리자에게 문의해 주세요."
widgets: "위젯"
postNote: "노트 작성"
bottomNavbar: "하단 내비게이션 바"
@@ -1991,6 +1993,7 @@ _role:
canHideAds: "광고 숨기기"
canSearchNotes: "노트 검색 이용 가능 여부"
canUseTranslator: "번역 기능 이용 가능 여부"
+ canUseAutoTranslate: "자동 번역 기능 이용 가능 여부"
avatarDecorationLimit: "최대로 붙일 수 있는 아바타 장식 개수"
canImportAntennas: "안테나 가져오기 허용"
canImportBlocking: "차단 목록 가져오기 허용"
diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts
index f7d0b4025d..c8c8a64c4b 100644
--- a/packages/backend/src/core/RoleService.ts
+++ b/packages/backend/src/core/RoleService.ts
@@ -45,6 +45,7 @@ export type RolePolicies = {
canManageAvatarDecorations: boolean;
canSearchNotes: boolean;
canUseTranslator: boolean;
+ canUseAutoTranslate: boolean;
canHideAds: boolean;
driveCapacityMb: number;
alwaysMarkNsfw: boolean;
@@ -80,6 +81,7 @@ export const DEFAULT_POLICIES: RolePolicies = {
canManageAvatarDecorations: false,
canSearchNotes: false,
canUseTranslator: true,
+ canUseAutoTranslate: false,
canHideAds: false,
driveCapacityMb: 100,
alwaysMarkNsfw: false,
@@ -386,6 +388,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
canManageAvatarDecorations: calc('canManageAvatarDecorations', vs => vs.some(v => v === true)),
canSearchNotes: calc('canSearchNotes', vs => vs.some(v => v === true)),
canUseTranslator: calc('canUseTranslator', vs => vs.some(v => v === true)),
+ canUseAutoTranslate: calc('canUseAutoTranslate', vs => vs.some(v => v === true)),
canHideAds: calc('canHideAds', vs => vs.some(v => v === true)),
driveCapacityMb: calc('driveCapacityMb', vs => Math.max(...vs)),
alwaysMarkNsfw: calc('alwaysMarkNsfw', vs => vs.some(v => v === true)),
diff --git a/packages/backend/src/models/json-schema/role.ts b/packages/backend/src/models/json-schema/role.ts
index d52896d0ba..84d8e2a79c 100644
--- a/packages/backend/src/models/json-schema/role.ts
+++ b/packages/backend/src/models/json-schema/role.ts
@@ -216,6 +216,10 @@ export const packedRolePoliciesSchema = {
type: 'boolean',
optional: false, nullable: false,
},
+ canUseAutoTranslate: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
canHideAds: {
type: 'boolean',
optional: false, nullable: false,
diff --git a/packages/cherrypick-js/src/autogen/types.ts b/packages/cherrypick-js/src/autogen/types.ts
index 4044484940..3dd0e714c7 100644
--- a/packages/cherrypick-js/src/autogen/types.ts
+++ b/packages/cherrypick-js/src/autogen/types.ts
@@ -5174,6 +5174,7 @@ export type components = {
canManageAvatarDecorations: boolean;
canSearchNotes: boolean;
canUseTranslator: boolean;
+ canUseAutoTranslate: boolean;
canHideAds: boolean;
driveCapacityMb: number;
alwaysMarkNsfw: boolean;
diff --git a/packages/frontend-shared/js/const.ts b/packages/frontend-shared/js/const.ts
index d7f90bfa80..5b56d97870 100644
--- a/packages/frontend-shared/js/const.ts
+++ b/packages/frontend-shared/js/const.ts
@@ -88,6 +88,7 @@ export const ROLE_POLICIES = [
'canManageAvatarDecorations',
'canSearchNotes',
'canUseTranslator',
+ 'canUseAutoTranslate',
'canHideAds',
'driveCapacityMb',
'alwaysMarkNsfw',
diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue
index 864df87476..ecda25d338 100644
--- a/packages/frontend/src/components/MkNote.vue
+++ b/packages/frontend/src/components/MkNote.vue
@@ -92,7 +92,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:enableEmojiMenu="true"
:enableEmojiMenuReaction="true"
/>
-