From 8cfd147555312b98854ba39966f9240ea25a83e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Thu, 16 Oct 2025 11:17:47 +0900 Subject: [PATCH 01/10] =?UTF-8?q?fix(frontend):=20=E3=83=AD=E3=83=BC?= =?UTF-8?q?=E3=83=AB=E3=83=9D=E3=83=AA=E3=82=B7=E3=83=BC=E3=81=AB=E3=82=88?= =?UTF-8?q?=E3=82=8A=E3=83=80=E3=82=A4=E3=83=AC=E3=82=AF=E3=83=88=E3=83=A1?= =?UTF-8?q?=E3=83=83=E3=82=BB=E3=83=BC=E3=82=B8=E3=81=8C=E7=84=A1=E5=8A=B9?= =?UTF-8?q?=E5=8C=96=E3=81=95=E3=82=8C=E3=81=A6=E3=81=84=E3=82=8B=E9=9A=9B?= =?UTF-8?q?=E3=81=AE=E3=83=87=E3=83=83=E3=82=AD=E3=81=AE=E3=83=80=E3=82=A4?= =?UTF-8?q?=E3=83=AC=E3=82=AF=E3=83=88=E3=83=A1=E3=83=83=E3=82=BB=E3=83=BC?= =?UTF-8?q?=E3=82=B8=E3=82=AB=E3=83=A9=E3=83=A0=E3=81=AE=E6=8C=99=E5=8B=95?= =?UTF-8?q?=E3=82=92=E6=94=B9=E5=96=84=20(#16656)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(frontend): ロールポリシーによりダイレクトメッセージが無効化されている際のデッキのダイレクトメッセージカラムの挙動を改善 * Update Changelog --- CHANGELOG.md | 1 + packages/frontend/src/ui/deck.vue | 2 +- packages/frontend/src/ui/deck/chat-column.vue | 11 ++++++++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96b9554c6a..26acc75c7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - Fix: バナー画像の幅が表示領域と一致していない問題を修正 - Fix: 一部のブラウザでバナー画像が上下中央に表示されない問題を修正 - Fix: ナビゲーションバーの設定で削除した項目をその場で再追加できない問題を修正 +- Fix: ロールポリシーによりダイレクトメッセージが無効化されている際のデッキのダイレクトメッセージカラムの挙動を改善 ### Server - diff --git a/packages/frontend/src/ui/deck.vue b/packages/frontend/src/ui/deck.vue index e2ee4b658e..ff8e91663a 100644 --- a/packages/frontend/src/ui/deck.vue +++ b/packages/frontend/src/ui/deck.vue @@ -167,7 +167,7 @@ const columnsEl = useTemplateRef('columnsEl'); const addColumn = async (ev) => { const { canceled, result: column } = await os.select({ title: i18n.ts._deck.addColumn, - items: columnTypes.map(column => ({ + items: columnTypes.filter(column => column !== 'chat' || $i == null || $i.policies.chatAvailability !== 'unavailable').map(column => ({ value: column, label: i18n.ts._deck._columns[column], })), }); diff --git a/packages/frontend/src/ui/deck/chat-column.vue b/packages/frontend/src/ui/deck/chat-column.vue index 791af2e44c..0015447e22 100644 --- a/packages/frontend/src/ui/deck/chat-column.vue +++ b/packages/frontend/src/ui/deck/chat-column.vue @@ -7,21 +7,26 @@ SPDX-License-Identifier: AGPL-3.0-only -
- +
+ {{ i18n.ts._chat.chatIsReadOnlyForThisAccountOrServer }} + {{ i18n.ts._chat.chatNotAvailableForThisAccountOrServer }} +
From a132a1d3e14b624fbb793ecf9db0e796fb5305bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Thu, 16 Oct 2025 18:01:25 +0900 Subject: [PATCH 02/10] =?UTF-8?q?fix(frontend):=20=E5=A4=96=E9=83=A8?= =?UTF-8?q?=E3=82=A2=E3=83=97=E3=83=AA=E8=A8=AD=E5=AE=9A=E3=81=AE=E3=82=A2?= =?UTF-8?q?=E3=83=97=E3=83=AA=E3=82=A2=E3=82=A4=E3=82=B3=E3=83=B3=E3=81=AB?= =?UTF-8?q?=E5=A4=89=E3=81=AA=E4=BD=99=E7=99=BD=E3=81=8C=E5=85=A5=E3=81=A3?= =?UTF-8?q?=E3=81=A6=E3=81=84=E3=82=8B=E3=81=AE=E3=82=92=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=20(#16660)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/settings/apps.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/frontend/src/pages/settings/apps.vue b/packages/frontend/src/pages/settings/apps.vue index 54e214241b..10901f737b 100644 --- a/packages/frontend/src/pages/settings/apps.vue +++ b/packages/frontend/src/pages/settings/apps.vue @@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -86,6 +86,7 @@ definePage(() => ({ From 29892d2a01d902166b762dbfe2d2487169a8d048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Thu, 16 Oct 2025 22:45:37 +0900 Subject: [PATCH 04/10] =?UTF-8?q?enhance:=20=E3=83=AA=E3=83=A2=E3=83=BC?= =?UTF-8?q?=E3=83=88=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E3=81=AE=E3=83=AD?= =?UTF-8?q?=E3=83=BC=E3=83=AB=E3=83=90=E3=83=83=E3=82=B8=E3=82=92=E8=A1=A8?= =?UTF-8?q?=E7=A4=BA=E3=81=99=E3=82=8B=E3=81=8B=E3=81=A9=E3=81=86=E3=81=8B?= =?UTF-8?q?=E3=82=92=E3=82=B5=E3=83=BC=E3=83=90=E3=83=BC=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E8=80=85=E3=81=8C=E8=A8=AD=E5=AE=9A=E3=81=A7=E3=81=8D=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=20(#16661)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * enhance: リモートユーザーのロールバッジを表示するかどうかをサーバー管理者が設定できるように * Update Changelog * build misskey-js with types --- CHANGELOG.md | 2 ++ locales/index.d.ts | 4 ++++ locales/ja-JP.yml | 1 + .../1760607435831-RoleBadgesRemoteUsers.js | 16 ++++++++++++++++ .../src/core/entities/UserEntityService.ts | 4 ++-- packages/backend/src/models/Meta.ts | 5 +++++ .../src/server/api/endpoints/admin/meta.ts | 5 +++++ .../server/api/endpoints/admin/update-meta.ts | 5 +++++ .../frontend/src/pages/admin/performance.vue | 18 ++++++++++++++++++ packages/misskey-js/src/autogen/types.ts | 2 ++ 10 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 packages/backend/migration/1760607435831-RoleBadgesRemoteUsers.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 26acc75c7e..7d20ef5c6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ ## 2025.10.1 ### General +- Enhance: リモートユーザーのロールバッジを表示できるように(オプトイン) + パフォーマンス上の問題からデフォルトで無効化されています。「コントロールパネル > パフォーマンス」から有効化できます。 - 依存関係の更新 ### Client diff --git a/locales/index.d.ts b/locales/index.d.ts index b54763a8a2..7391e197c4 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -4706,6 +4706,10 @@ export interface Locale extends ILocale { * ユーザーごとのIdenticon生成を有効にする */ "enableIdenticonGeneration": string; + /** + * リモートユーザーのロールバッジを表示する + */ + "showRoleBadgesOfRemoteUsers": string; /** * オフにするとパフォーマンスが向上します。 */ diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 3c9f0a5853..9ee3224441 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1172,6 +1172,7 @@ installed: "インストール済み" branding: "ブランディング" enableServerMachineStats: "サーバーのマシン情報を公開する" enableIdenticonGeneration: "ユーザーごとのIdenticon生成を有効にする" +showRoleBadgesOfRemoteUsers: "リモートユーザーのロールバッジを表示する" turnOffToImprovePerformance: "オフにするとパフォーマンスが向上します。" createInviteCode: "招待コードを作成" createWithOptions: "オプションを指定して作成" diff --git a/packages/backend/migration/1760607435831-RoleBadgesRemoteUsers.js b/packages/backend/migration/1760607435831-RoleBadgesRemoteUsers.js new file mode 100644 index 0000000000..483d35a91b --- /dev/null +++ b/packages/backend/migration/1760607435831-RoleBadgesRemoteUsers.js @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class RoleBadgesRemoteUsers1760607435831 { + name = 'RoleBadgesRemoteUsers1760607435831' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "showRoleBadgesOfRemoteUsers" boolean NOT NULL DEFAULT false`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "showRoleBadgesOfRemoteUsers"`); + } +} diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index 47021359e1..ac5b855096 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -512,8 +512,8 @@ export class UserEntityService implements OnModuleInit { } : undefined) : undefined, emojis: this.customEmojiService.populateEmojis(user.emojis, user.host), onlineStatus: this.getOnlineStatus(user), - // パフォーマンス上の理由でローカルユーザーのみ - badgeRoles: user.host == null ? this.roleService.getUserBadgeRoles(user.id).then((rs) => rs + // パフォーマンス上の理由で、明示的に設定しない場合はローカルユーザーのみ取得 + badgeRoles: (this.meta.showRoleBadgesOfRemoteUsers || user.host == null) ? this.roleService.getUserBadgeRoles(user.id).then((rs) => rs .filter((r) => r.isPublic || iAmModerator) .sort((a, b) => b.displayOrder - a.displayOrder) .map((r) => ({ diff --git a/packages/backend/src/models/Meta.ts b/packages/backend/src/models/Meta.ts index f8021a7a84..205c9eeb89 100644 --- a/packages/backend/src/models/Meta.ts +++ b/packages/backend/src/models/Meta.ts @@ -717,6 +717,11 @@ export class MiMeta { }) public remoteNotesCleaningExpiryDaysForEachNotes: number; + @Column('boolean', { + default: false, + }) + public showRoleBadgesOfRemoteUsers: boolean; + @Column('jsonb', { default: { }, }) diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts index 21099c0a8c..2c7f793584 100644 --- a/packages/backend/src/server/api/endpoints/admin/meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/meta.ts @@ -593,6 +593,10 @@ export const meta = { type: 'number', optional: false, nullable: false, }, + showRoleBadgesOfRemoteUsers: { + type: 'boolean', + optional: false, nullable: false, + }, }, }, } as const; @@ -748,6 +752,7 @@ export default class extends Endpoint { // eslint- enableRemoteNotesCleaning: instance.enableRemoteNotesCleaning, remoteNotesCleaningExpiryDaysForEachNotes: instance.remoteNotesCleaningExpiryDaysForEachNotes, remoteNotesCleaningMaxProcessingDurationInMinutes: instance.remoteNotesCleaningMaxProcessingDurationInMinutes, + showRoleBadgesOfRemoteUsers: instance.showRoleBadgesOfRemoteUsers, }; }); } 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 a1a2a99d6e..b3c2cecc67 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts @@ -209,6 +209,7 @@ export const paramDef = { enableRemoteNotesCleaning: { type: 'boolean' }, remoteNotesCleaningExpiryDaysForEachNotes: { type: 'number' }, remoteNotesCleaningMaxProcessingDurationInMinutes: { type: 'number' }, + showRoleBadgesOfRemoteUsers: { type: 'boolean' }, }, required: [], } as const; @@ -743,6 +744,10 @@ export default class extends Endpoint { // eslint- set.remoteNotesCleaningMaxProcessingDurationInMinutes = ps.remoteNotesCleaningMaxProcessingDurationInMinutes; } + if (ps.showRoleBadgesOfRemoteUsers !== undefined) { + set.showRoleBadgesOfRemoteUsers = ps.showRoleBadgesOfRemoteUsers; + } + const before = await this.metaService.fetch(true); await this.metaService.update(set); diff --git a/packages/frontend/src/pages/admin/performance.vue b/packages/frontend/src/pages/admin/performance.vue index e3021778e7..c5f3c2d4f0 100644 --- a/packages/frontend/src/pages/admin/performance.vue +++ b/packages/frontend/src/pages/admin/performance.vue @@ -53,6 +53,15 @@ SPDX-License-Identifier: AGPL-3.0-only
+ +
+ + + + +
+
+ @@ -188,6 +197,7 @@ const enableIdenticonGeneration = ref(meta.enableIdenticonGeneration); const enableChartsForRemoteUser = ref(meta.enableChartsForRemoteUser); const enableStatsForFederatedInstances = ref(meta.enableStatsForFederatedInstances); const enableChartsForFederatedInstances = ref(meta.enableChartsForFederatedInstances); +const showRoleBadgesOfRemoteUsers = ref(meta.showRoleBadgesOfRemoteUsers); function onChange_enableServerMachineStats(value: boolean) { os.apiWithDialog('admin/update-meta', { @@ -229,6 +239,14 @@ function onChange_enableChartsForFederatedInstances(value: boolean) { }); } +function onChange_showRoleBadgesOfRemoteUsers(value: boolean) { + os.apiWithDialog('admin/update-meta', { + showRoleBadgesOfRemoteUsers: value, + }).then(() => { + fetchInstance(true); + }); +} + const fttForm = useForm({ enableFanoutTimeline: meta.enableFanoutTimeline, enableFanoutTimelineDbFallback: meta.enableFanoutTimelineDbFallback, diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index 7edd43bf9b..3e95651071 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -9460,6 +9460,7 @@ export interface operations { enableRemoteNotesCleaning: boolean; remoteNotesCleaningExpiryDaysForEachNotes: number; remoteNotesCleaningMaxProcessingDurationInMinutes: number; + showRoleBadgesOfRemoteUsers: boolean; }; }; }; @@ -12780,6 +12781,7 @@ export interface operations { enableRemoteNotesCleaning?: boolean; remoteNotesCleaningExpiryDaysForEachNotes?: number; remoteNotesCleaningMaxProcessingDurationInMinutes?: number; + showRoleBadgesOfRemoteUsers?: boolean; }; }; }; From 44930342a80fec860f1ca843a3d429e46267e030 Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Sun, 19 Oct 2025 11:34:34 +0900 Subject: [PATCH 05/10] Revert typeorm patches (#16664) * chore: remove patches * chore: remove unnecessary 'DEFAULT NULL's * chore: add patches with .gitkeep --- package.json | 3 --- .../1760790899857-unnecessary-null-default.js | 26 +++++++++++++++++++ patches/.gitkeep | 0 patches/typeorm.patch | 17 ------------ pnpm-lock.yaml | 9 ++----- 5 files changed, 28 insertions(+), 27 deletions(-) create mode 100644 packages/backend/migration/1760790899857-unnecessary-null-default.js create mode 100644 patches/.gitkeep delete mode 100644 patches/typeorm.patch diff --git a/package.json b/package.json index 55286bc5a7..28441a7bea 100644 --- a/package.json +++ b/package.json @@ -85,9 +85,6 @@ "pnpm": { "overrides": { "@aiscript-dev/aiscript-languageserver": "-" - }, - "patchedDependencies": { - "typeorm": "patches/typeorm.patch" } } } diff --git a/packages/backend/migration/1760790899857-unnecessary-null-default.js b/packages/backend/migration/1760790899857-unnecessary-null-default.js new file mode 100644 index 0000000000..d34758315f --- /dev/null +++ b/packages/backend/migration/1760790899857-unnecessary-null-default.js @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class UnnecessaryNullDefault1760790899857 { + name = 'UnnecessaryNullDefault1760790899857' + + /** + * @param {QueryRunner} queryRunner + */ + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "abuse_report_notification_recipient" ALTER COLUMN "userId" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "abuse_report_notification_recipient" ALTER COLUMN "systemWebhookId" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "urlPreviewUserAgent" DROP DEFAULT`); + } + + /** + * @param {QueryRunner} queryRunner + */ + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "urlPreviewUserAgent" SET DEFAULT NULL`); + await queryRunner.query(`ALTER TABLE "abuse_report_notification_recipient" ALTER COLUMN "systemWebhookId" SET DEFAULT NULL`); + await queryRunner.query(`ALTER TABLE "abuse_report_notification_recipient" ALTER COLUMN "userId" SET DEFAULT NULL`); + } +} diff --git a/patches/.gitkeep b/patches/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/patches/typeorm.patch b/patches/typeorm.patch deleted file mode 100644 index 6b30cddb66..0000000000 --- a/patches/typeorm.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff --git a/driver/postgres/PostgresDriver.js b/driver/postgres/PostgresDriver.js -index e13b903c73b71113bb529552e59fb4ce0ca8af0c..50de6a60120ece7ebf49009eac588a5313343f39 100644 ---- a/driver/postgres/PostgresDriver.js -+++ b/driver/postgres/PostgresDriver.js -@@ -819,10 +819,10 @@ class PostgresDriver { - const tableColumnDefault = typeof tableColumn.default === "string" - ? JSON.parse(tableColumn.default.substring(1, tableColumn.default.length - 1)) - : tableColumn.default; -- return OrmUtils_1.OrmUtils.deepCompare(columnMetadata.default, tableColumnDefault); -+ return OrmUtils_1.OrmUtils.deepCompare(columnMetadata.default, tableColumnDefault ?? null); - } - const columnDefault = this.lowerDefaultValueIfNecessary(this.normalizeDefault(columnMetadata)); -- return columnDefault === tableColumn.default; -+ return columnDefault === tableColumn.default || columnDefault === undefined && tableColumn.default.toLowerCase() === 'null'; - } - /** - * Normalizes "isUnique" value of the column. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3fc2f76c70..689250d4e2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,11 +9,6 @@ overrides: lodash: 4.17.21 '@aiscript-dev/aiscript-languageserver': '-' -patchedDependencies: - typeorm: - hash: b1141d7fd5ff7abdae28a93b2a634f595c7848518643c08d120698da1d2b4ebc - path: patches/typeorm.patch - importers: .: @@ -430,7 +425,7 @@ importers: version: 4.2.0 typeorm: specifier: 0.3.27 - version: 0.3.27(patch_hash=b1141d7fd5ff7abdae28a93b2a634f595c7848518643c08d120698da1d2b4ebc)(ioredis@5.8.0)(pg@8.16.3)(reflect-metadata@0.2.2) + version: 0.3.27(ioredis@5.8.0)(pg@8.16.3)(reflect-metadata@0.2.2) typescript: specifier: 5.9.3 version: 5.9.3 @@ -22133,7 +22128,7 @@ snapshots: typedarray@0.0.6: {} - typeorm@0.3.27(patch_hash=b1141d7fd5ff7abdae28a93b2a634f595c7848518643c08d120698da1d2b4ebc)(ioredis@5.8.0)(pg@8.16.3)(reflect-metadata@0.2.2): + typeorm@0.3.27(ioredis@5.8.0)(pg@8.16.3)(reflect-metadata@0.2.2): dependencies: '@sqltools/formatter': 1.2.5 ansis: 3.17.0 From d98bf012b59b343559dd679f0b4ae370ebd75079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Sun, 19 Oct 2025 11:36:00 +0900 Subject: [PATCH 06/10] =?UTF-8?q?refactor(frontend):=20=E3=82=AB=E3=82=B9?= =?UTF-8?q?=E3=82=BF=E3=83=A0=E3=83=87=E3=82=A3=E3=83=AC=E3=82=AF=E3=83=86?= =?UTF-8?q?=E3=82=A3=E3=83=96=E3=81=AE=E5=9E=8B=E4=BB=98=E3=81=91=20(#1665?= =?UTF-8?q?9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor(frontend): カスタムディレクティブの型付け * fix --- .../frontend/src/directives/adaptive-bg.ts | 6 +- .../src/directives/adaptive-border.ts | 8 +-- packages/frontend/src/directives/anim.ts | 8 +-- packages/frontend/src/directives/appear.ts | 14 ++-- .../frontend/src/directives/click-anime.ts | 6 +- .../frontend/src/directives/follow-append.ts | 12 ++-- packages/frontend/src/directives/get-size.ts | 10 +-- packages/frontend/src/directives/hotkey.ts | 11 +++- packages/frontend/src/directives/index.ts | 66 ++++++++++++------- packages/frontend/src/directives/panel.ts | 6 +- packages/frontend/src/directives/ripple.ts | 7 +- packages/frontend/src/directives/tooltip.ts | 48 ++++++++++---- .../frontend/src/directives/user-preview.ts | 50 ++++++++------ 13 files changed, 158 insertions(+), 94 deletions(-) diff --git a/packages/frontend/src/directives/adaptive-bg.ts b/packages/frontend/src/directives/adaptive-bg.ts index a68cd1b18b..25e9ae1c9e 100644 --- a/packages/frontend/src/directives/adaptive-bg.ts +++ b/packages/frontend/src/directives/adaptive-bg.ts @@ -6,8 +6,8 @@ import type { Directive } from 'vue'; import { getBgColor } from '@/utility/get-bg-color.js'; -export default { - mounted(src, binding, vn) { +export const adaptiveBgDirective = { + mounted(src) { const parentBg = getBgColor(src.parentElement) ?? 'transparent'; const myBg = window.getComputedStyle(src).backgroundColor; @@ -18,4 +18,4 @@ export default { src.style.backgroundColor = myBg; } }, -} as Directive; +} as Directive; diff --git a/packages/frontend/src/directives/adaptive-border.ts b/packages/frontend/src/directives/adaptive-border.ts index 8072a1ffd9..749861fd94 100644 --- a/packages/frontend/src/directives/adaptive-border.ts +++ b/packages/frontend/src/directives/adaptive-border.ts @@ -9,8 +9,8 @@ import { globalEvents } from '@/events.js'; const handlerMap = new WeakMap(); -export default { - mounted(src, binding, vn) { +export const adaptiveBorderDirective = { + mounted(src) { function calc() { const parentBg = getBgColor(src.parentElement) ?? 'transparent'; @@ -30,7 +30,7 @@ export default { globalEvents.on('themeChanged', calc); }, - unmounted(src, binding, vn) { + unmounted(src) { globalEvents.off('themeChanged', handlerMap.get(src)); }, -} as Directive; +} as Directive; diff --git a/packages/frontend/src/directives/anim.ts b/packages/frontend/src/directives/anim.ts index ad0cb5ed81..a165fa11e0 100644 --- a/packages/frontend/src/directives/anim.ts +++ b/packages/frontend/src/directives/anim.ts @@ -5,8 +5,8 @@ import type { Directive } from 'vue'; -export default { - beforeMount(src, binding, vn) { +export const animDirective = { + beforeMount(src) { src.style.opacity = '0'; src.style.transform = 'scale(0.9)'; // ページネーションと相性が悪いので @@ -14,10 +14,10 @@ export default { src.classList.add('_zoom'); }, - mounted(src, binding, vn) { + mounted(src) { window.setTimeout(() => { src.style.opacity = '1'; src.style.transform = 'none'; }, 1); }, -} as Directive; +} as Directive; diff --git a/packages/frontend/src/directives/appear.ts b/packages/frontend/src/directives/appear.ts index f5fec108dc..f714871420 100644 --- a/packages/frontend/src/directives/appear.ts +++ b/packages/frontend/src/directives/appear.ts @@ -6,12 +6,16 @@ import { throttle } from 'throttle-debounce'; import type { Directive } from 'vue'; -export default { - mounted(src, binding, vn) { +interface HTMLElementWithObserver extends HTMLElement { + _observer_?: IntersectionObserver; +} + +export const appearDirective = { + mounted(src, binding) { const fn = binding.value; if (fn == null) return; - const check = throttle(1000, (entries) => { + const check = throttle(1000, (entries) => { if (entries.some(entry => entry.isIntersecting)) { fn(); } @@ -24,7 +28,7 @@ export default { src._observer_ = observer; }, - unmounted(src, binding, vn) { + unmounted(src) { if (src._observer_) src._observer_.disconnect(); }, -} as Directive; +} as Directive void>; diff --git a/packages/frontend/src/directives/click-anime.ts b/packages/frontend/src/directives/click-anime.ts index c34f351fb3..7891e8092c 100644 --- a/packages/frontend/src/directives/click-anime.ts +++ b/packages/frontend/src/directives/click-anime.ts @@ -6,8 +6,8 @@ import type { Directive } from 'vue'; import { prefer } from '@/preferences.js'; -export default { - mounted(el: HTMLElement, binding, vn) { +export const clickAnimeDirective = { + mounted(el) { if (!prefer.s.animation) return; const target = el.children[0]; @@ -37,4 +37,4 @@ export default { target.classList.add('_anime_bounce_standBy'); }); }, -} as Directive; +} as Directive; diff --git a/packages/frontend/src/directives/follow-append.ts b/packages/frontend/src/directives/follow-append.ts index f3eaac10e3..303dcb842a 100644 --- a/packages/frontend/src/directives/follow-append.ts +++ b/packages/frontend/src/directives/follow-append.ts @@ -6,8 +6,12 @@ import type { Directive } from 'vue'; import { getScrollContainer, getScrollPosition } from '@@/js/scroll.js'; -export default { - mounted(src, binding, vn) { +interface HTMLElementWithRO extends HTMLElement { + _ro_?: ResizeObserver; +} + +export const followAppendDirective = { + mounted(src, binding) { if (binding.value === false) return; let isBottom = true; @@ -34,7 +38,7 @@ export default { src._ro_ = ro; }, - unmounted(src, binding, vn) { + unmounted(src) { if (src._ro_) src._ro_.unobserve(src); }, -} as Directive; +} as Directive; diff --git a/packages/frontend/src/directives/get-size.ts b/packages/frontend/src/directives/get-size.ts index 488f201a0d..42660987dd 100644 --- a/packages/frontend/src/directives/get-size.ts +++ b/packages/frontend/src/directives/get-size.ts @@ -37,8 +37,10 @@ function calc(src: Element) { info.fn(width, height); } -export default { - mounted(src, binding, vn) { +type SizeCallback = (w: number, h: number) => void; + +export const getSizeDirective = { + mounted(src, binding) { const resize = new ResizeObserver((entries, observer) => { calc(src); }); @@ -48,7 +50,7 @@ export default { calc(src); }, - unmounted(src, binding, vn) { + unmounted(src, binding) { binding.value(0, 0); const info = mountings.get(src); if (!info) return; @@ -56,4 +58,4 @@ export default { if (info.intersection) info.intersection.disconnect(); mountings.delete(src); }, -} as Directive void>; +} as Directive; diff --git a/packages/frontend/src/directives/hotkey.ts b/packages/frontend/src/directives/hotkey.ts index 63637ab2ba..d8fdfe647a 100644 --- a/packages/frontend/src/directives/hotkey.ts +++ b/packages/frontend/src/directives/hotkey.ts @@ -5,8 +5,14 @@ import type { Directive } from 'vue'; import { makeHotkey } from '@/utility/hotkey.js'; +import type { Keymap } from '@/utility/hotkey.js'; -export default { +interface HTMLElementWithHotkey extends HTMLElement { + _hotkey_global?: boolean; + _keyHandler?: (ev: KeyboardEvent) => void; +} + +export const hotkeyDirective = { mounted(el, binding) { el._hotkey_global = binding.modifiers.global === true; @@ -20,10 +26,11 @@ export default { }, unmounted(el) { + if (el._keyHandler == null) return; if (el._hotkey_global) { window.document.removeEventListener('keydown', el._keyHandler); } else { el.removeEventListener('keydown', el._keyHandler); } }, -} as Directive; +} as Directive; diff --git a/packages/frontend/src/directives/index.ts b/packages/frontend/src/directives/index.ts index 9555045afe..07b756b95d 100644 --- a/packages/frontend/src/directives/index.ts +++ b/packages/frontend/src/directives/index.ts @@ -3,19 +3,19 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import type { App } from 'vue'; +import type { App, Directive } from 'vue'; -import userPreview from './user-preview.js'; -import getSize from './get-size.js'; -import ripple from './ripple.js'; -import tooltip from './tooltip.js'; -import hotkey from './hotkey.js'; -import appear from './appear.js'; -import anim from './anim.js'; -import clickAnime from './click-anime.js'; -import panel from './panel.js'; -import adaptiveBorder from './adaptive-border.js'; -import adaptiveBg from './adaptive-bg.js'; +import { userPreviewDirective } from './user-preview.js'; +import { getSizeDirective } from './get-size.js'; +import { rippleDirective } from './ripple.js'; +import { tooltipDirective } from './tooltip.js'; +import { hotkeyDirective } from './hotkey.js'; +import { appearDirective } from './appear.js'; +import { animDirective } from './anim.js'; +import { clickAnimeDirective } from './click-anime.js'; +import { panelDirective } from './panel.js'; +import { adaptiveBorderDirective } from './adaptive-border.js'; +import { adaptiveBgDirective } from './adaptive-bg.js'; export default function(app: App) { for (const [key, value] of Object.entries(directives)) { @@ -24,16 +24,32 @@ export default function(app: App) { } export const directives = { - 'userPreview': userPreview, - 'user-preview': userPreview, - 'get-size': getSize, - 'ripple': ripple, - 'tooltip': tooltip, - 'hotkey': hotkey, - 'appear': appear, - 'anim': anim, - 'click-anime': clickAnime, - 'panel': panel, - 'adaptive-border': adaptiveBorder, - 'adaptive-bg': adaptiveBg, -}; + 'userPreview': userPreviewDirective, + 'user-preview': userPreviewDirective, + 'get-size': getSizeDirective, + 'ripple': rippleDirective, + 'tooltip': tooltipDirective, + 'hotkey': hotkeyDirective, + 'appear': appearDirective, + 'anim': animDirective, + 'click-anime': clickAnimeDirective, + 'panel': panelDirective, + 'adaptive-border': adaptiveBorderDirective, + 'adaptive-bg': adaptiveBgDirective, +} as Record; + +declare module 'vue' { + export interface ComponentCustomProperties { + vUserPreview: typeof userPreviewDirective; + vGetSize: typeof getSizeDirective; + vRipple: typeof rippleDirective; + vTooltip: typeof tooltipDirective; + vHotkey: typeof hotkeyDirective; + vAppear: typeof appearDirective; + vAnim: typeof animDirective; + vClickAnime: typeof clickAnimeDirective; + vPanel: typeof panelDirective; + vAdaptiveBorder: typeof adaptiveBorderDirective; + vAdaptiveBg: typeof adaptiveBgDirective; + } +} diff --git a/packages/frontend/src/directives/panel.ts b/packages/frontend/src/directives/panel.ts index 0af19e6ca3..7913baefe4 100644 --- a/packages/frontend/src/directives/panel.ts +++ b/packages/frontend/src/directives/panel.ts @@ -6,8 +6,8 @@ import type { Directive } from 'vue'; import { getBgColor } from '@/utility/get-bg-color.js'; -export default { - mounted(src, binding, vn) { +export const panelDirective = { + mounted(src) { const parentBg = getBgColor(src.parentElement) ?? 'transparent'; const myBg = getComputedStyle(window.document.documentElement).getPropertyValue('--MI_THEME-panel'); @@ -18,4 +18,4 @@ export default { src.style.backgroundColor = 'var(--MI_THEME-panel)'; } }, -} as Directive; +} as Directive; diff --git a/packages/frontend/src/directives/ripple.ts b/packages/frontend/src/directives/ripple.ts index 614cd37011..bacf49ab72 100644 --- a/packages/frontend/src/directives/ripple.ts +++ b/packages/frontend/src/directives/ripple.ts @@ -3,12 +3,13 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import type { Directive } from 'vue'; import MkRippleEffect from '@/components/MkRippleEffect.vue'; import { prefer } from '@/preferences.js'; import { popup } from '@/os.js'; -export default { - mounted(el, binding, vn) { +export const rippleDirective = { + mounted(el, binding) { // 明示的に false であればバインドしない if (binding.value === false) return; if (!prefer.s.animation) return; @@ -24,4 +25,4 @@ export default { }); }); }, -}; +} as Directive; diff --git a/packages/frontend/src/directives/tooltip.ts b/packages/frontend/src/directives/tooltip.ts index 62aecbc87c..9cfa8d657d 100644 --- a/packages/frontend/src/directives/tooltip.ts +++ b/packages/frontend/src/directives/tooltip.ts @@ -14,13 +14,30 @@ import { popup, alert } from '@/os.js'; const start = isTouchUsing ? 'touchstart' : 'mouseenter'; const end = isTouchUsing ? 'touchend' : 'mouseleave'; -export default { - mounted(el: HTMLElement, binding, vn) { +type TooltipDirectiveState = { + text: string; + _close: null | (() => void); + showTimer: number | null; + hideTimer: number | null; + checkTimer: number | null; + show: () => void; + close: () => void; +}; + +interface TooltipDirectiveElement extends HTMLElement { + _tooltipDirective_?: TooltipDirectiveState; +} + +type TooltipDirectiveModifiers = 'left' | 'right' | 'top' | 'bottom' | 'mfm' | 'noDelay'; +type TooltipDirectiveArg = 'dialog'; + +export const tooltipDirective = { + mounted(el, binding) { const delay = binding.modifiers.noDelay ? 0 : 100; - const self = (el as any)._tooltipDirective_ = {} as any; + const self = el._tooltipDirective_ = {} as TooltipDirectiveState; - self.text = binding.value as string; + self.text = binding.value; self._close = null; self.showTimer = null; self.hideTimer = null; @@ -28,7 +45,7 @@ export default { self.close = () => { if (self._close) { - window.clearInterval(self.checkTimer); + if (self.checkTimer) window.clearInterval(self.checkTimer); self._close(); self._close = null; } @@ -72,8 +89,8 @@ export default { }); el.addEventListener(start, (ev) => { - window.clearTimeout(self.showTimer); - window.clearTimeout(self.hideTimer); + if (self.showTimer) window.clearTimeout(self.showTimer); + if (self.hideTimer) window.clearTimeout(self.hideTimer); if (delay === 0) { self.show(); } else { @@ -82,8 +99,8 @@ export default { }, { passive: true }); el.addEventListener(end, () => { - window.clearTimeout(self.showTimer); - window.clearTimeout(self.hideTimer); + if (self.showTimer) window.clearTimeout(self.showTimer); + if (self.hideTimer) window.clearTimeout(self.hideTimer); if (delay === 0) { self.close(); } else { @@ -92,18 +109,23 @@ export default { }, { passive: true }); el.addEventListener('click', () => { - window.clearTimeout(self.showTimer); + if (self.showTimer) window.clearTimeout(self.showTimer); self.close(); }); }, updated(el, binding) { const self = el._tooltipDirective_; + if (self == null) return; self.text = binding.value as string; }, - unmounted(el, binding, vn) { + unmounted(el) { const self = el._tooltipDirective_; - window.clearInterval(self.checkTimer); + if (self == null) return; + if (self.showTimer) window.clearTimeout(self.showTimer); + if (self.hideTimer) window.clearTimeout(self.hideTimer); + if (self.checkTimer) window.clearTimeout(self.checkTimer); + self.close(); }, -} as Directive; +} as Directive; diff --git a/packages/frontend/src/directives/user-preview.ts b/packages/frontend/src/directives/user-preview.ts index b11ef8f088..76e345a108 100644 --- a/packages/frontend/src/directives/user-preview.ts +++ b/packages/frontend/src/directives/user-preview.ts @@ -5,18 +5,19 @@ import { defineAsyncComponent, ref } from 'vue'; import type { Directive } from 'vue'; +import * as Misskey from 'misskey-js'; import { popup } from '@/os.js'; import { isTouchUsing } from '@/utility/touch.js'; export class UserPreview { - private el; - private user; - private showTimer; - private hideTimer; - private checkTimer; - private promise; + private el: HTMLElement; + private user: string | Misskey.entities.UserDetailed; + private showTimer: number | null = null; + private hideTimer: number | null = null; + private checkTimer: number | null = null; + private promise: null | { cancel: () => void } = null; - constructor(el, user) { + constructor(el: HTMLElement, user: string | Misskey.entities.UserDetailed) { this.el = el; this.user = user; @@ -43,10 +44,10 @@ export class UserPreview { source: this.el, }, { mouseover: () => { - window.clearTimeout(this.hideTimer); + if (this.hideTimer) window.clearTimeout(this.hideTimer); }, mouseleave: () => { - window.clearTimeout(this.showTimer); + if (this.showTimer) window.clearTimeout(this.showTimer); this.hideTimer = window.setTimeout(this.close, 500); }, closed: () => dispose(), @@ -60,8 +61,8 @@ export class UserPreview { this.checkTimer = window.setInterval(() => { if (!window.document.body.contains(this.el)) { - window.clearTimeout(this.showTimer); - window.clearTimeout(this.hideTimer); + if (this.showTimer) window.clearTimeout(this.showTimer); + if (this.hideTimer) window.clearTimeout(this.hideTimer); this.close(); } }, 1000); @@ -69,26 +70,26 @@ export class UserPreview { private close() { if (this.promise) { - window.clearInterval(this.checkTimer); + if (this.checkTimer) window.clearInterval(this.checkTimer); this.promise.cancel(); this.promise = null; } } private onMouseover() { - window.clearTimeout(this.showTimer); - window.clearTimeout(this.hideTimer); + if (this.showTimer) window.clearTimeout(this.showTimer); + if (this.hideTimer) window.clearTimeout(this.hideTimer); this.showTimer = window.setTimeout(this.show, 500); } private onMouseleave() { - window.clearTimeout(this.showTimer); - window.clearTimeout(this.hideTimer); + if (this.showTimer) window.clearTimeout(this.showTimer); + if (this.hideTimer) window.clearTimeout(this.hideTimer); this.hideTimer = window.setTimeout(this.close, 500); } private onClick() { - window.clearTimeout(this.showTimer); + if (this.showTimer) window.clearTimeout(this.showTimer); this.close(); } @@ -105,8 +106,14 @@ export class UserPreview { } } -export default { - mounted(el: HTMLElement, binding, vn) { +interface UserPreviewDirectiveElement extends HTMLElement { + _userPreviewDirective_?: { + preview: UserPreview; + }; +} + +export const userPreviewDirective = { + mounted(el, binding) { if (binding.value == null) return; if (isTouchUsing) return; @@ -117,10 +124,11 @@ export default { self.preview = new UserPreview(el, binding.value); }, - unmounted(el, binding, vn) { + unmounted(el, binding) { if (binding.value == null) return; const self = el._userPreviewDirective_; + if (self == null) return; self.preview.detach(); }, -} as Directive; +} as Directive; From b48233eb4caee05463843639eeea77a5b66b2d7c Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Sun, 19 Oct 2025 13:19:56 +0900 Subject: [PATCH 07/10] New Crowdin updates (#16657) * New translations ja-jp.yml (Catalan) * New translations ja-jp.yml (Chinese Simplified) * New translations ja-jp.yml (Chinese Traditional) * New translations ja-jp.yml (Chinese Simplified) * New translations ja-jp.yml (Italian) * New translations ja-jp.yml (Spanish) * New translations ja-jp.yml (Catalan) * New translations ja-jp.yml (Korean) --- locales/ca-ES.yml | 2 ++ locales/es-ES.yml | 2 ++ locales/it-IT.yml | 18 +++++++++--------- locales/ko-KR.yml | 2 ++ locales/zh-CN.yml | 2 ++ locales/zh-TW.yml | 3 ++- 6 files changed, 19 insertions(+), 10 deletions(-) diff --git a/locales/ca-ES.yml b/locales/ca-ES.yml index 0f7152ba00..27f1b4a8fc 100644 --- a/locales/ca-ES.yml +++ b/locales/ca-ES.yml @@ -775,6 +775,7 @@ lockedAccountInfo: "Tret que establiu la visibilitat de la nota a \"Només segui alwaysMarkSensitive: "Marcar com a sensible per defecte" loadRawImages: "Carregar les imatges originals en comptes de miniatures " disableShowingAnimatedImages: "No reproduir imatges animades" +disableShowingAnimatedImages_caption: "Si les imatges animades no es reprodueixen, independentment d'aquesta configuració, és possible que la configuració d'accessibilitat del navegador i el sistema operatiu, els modes d'estalvi d'energia i similars estiguin interferint." highlightSensitiveMedia: "Ressalta els medis marcats com a sensibles" verificationEmailSent: "S'ha enviat un correu electrònic de verificació. Fes clic a l'enllaç per completar la verificació." notSet: "Sense definir" @@ -1171,6 +1172,7 @@ installed: "Instal·lats " branding: "Marca" enableServerMachineStats: "Publicar estadístiques del maquinari del servidor" enableIdenticonGeneration: "Activar la generació d'icones d'identificació " +showRoleBadgesOfRemoteUsers: "Mostrar insígnies de rols d'instàncies remotes " turnOffToImprovePerformance: "Desactivant aquesta opció es pot millorar el rendiment." createInviteCode: "Crear codi d'invitació " createWithOptions: "Crear invitació amb opcions" diff --git a/locales/es-ES.yml b/locales/es-ES.yml index e0fcf1126e..d851ac9f41 100644 --- a/locales/es-ES.yml +++ b/locales/es-ES.yml @@ -775,6 +775,7 @@ lockedAccountInfo: "A menos que configures la visibilidad de tus notas como \"S alwaysMarkSensitive: "Marcar los medios de comunicación como contenido sensible por defecto" loadRawImages: "Cargar las imágenes originales en lugar de mostrar las miniaturas" disableShowingAnimatedImages: "No reproducir imágenes animadas" +disableShowingAnimatedImages_caption: "Si las imágenes animadas no se reproducen independientemente de esta configuración, es posible que la configuración de accesibilidad del navegador o del sistema operativo, los modos de ahorro de energía o funciones similares estén interfiriendo." highlightSensitiveMedia: "Resaltar medios marcados como sensibles" verificationEmailSent: "Se le ha enviado un correo electrónico de confirmación. Por favor, acceda al enlace proporcionado en el correo electrónico para completar la configuración." notSet: "Sin especificar" @@ -1171,6 +1172,7 @@ installed: "Instalado" branding: "Marca" enableServerMachineStats: "Publicar estadísticas de hardware del servidor" enableIdenticonGeneration: "Activar generación de identicon por usuario" +showRoleBadgesOfRemoteUsers: "Mostrar insignias de rol de usuarios remotos" turnOffToImprovePerformance: "Desactivar esto puede aumentar el rendimiento." createInviteCode: "Generar invitación" createWithOptions: "Generar con opciones" diff --git a/locales/it-IT.yml b/locales/it-IT.yml index e041134be9..d5ac402bf3 100644 --- a/locales/it-IT.yml +++ b/locales/it-IT.yml @@ -458,7 +458,7 @@ setupOf2fa: "Impostare l'autenticazione a due fattori" totp: "App di autenticazione a due fattori (2FA/MFA)" totpDescription: "Puoi autenticarti inserendo un codice OTP tramite la tua App di autenticazione a due fattori (2FA/MFA)" moderator: "Moderatore" -moderation: "moderazione" +moderation: "Moderazione" moderationNote: "Promemoria di moderazione" moderationNoteDescription: "Puoi scrivere promemoria condivisi solo tra moderatori." addModerationNote: "Aggiungi promemoria di moderazione" @@ -902,7 +902,7 @@ useBlurEffect: "Utilizza effetto sfocatura" learnMore: "Per saperne di più" misskeyUpdated: "Misskey è stato aggiornato!" whatIsNew: "Informazioni sull'aggiornamento" -translate: "Traduci" +translate: "Traduzione" translatedFrom: "Traduzione da {x}" accountDeletionInProgress: "È in corso l'eliminazione del profilo" usernameInfo: "Un nome per identificare univocamente il tuo profilo sull'istanza. Puoi utilizzare caratteri alfanumerici maiuscoli, minuscoli e il trattino basso (_). Non potrai cambiare nome utente in seguito." @@ -913,7 +913,7 @@ pubSub: "Publish/Subscribe del profilo" lastCommunication: "La comunicazione più recente" resolved: "Risolto" unresolved: "Non risolto" -breakFollow: "Rimuovi Follower" +breakFollow: "Rimuovere Follower" breakFollowConfirm: "Vuoi davvero togliere questo Follower?" itsOn: "Abilitato" itsOff: "Disabilitato" @@ -1293,7 +1293,7 @@ sensitiveMediaRevealConfirm: "Questo allegato è esplicito, vuoi vederlo?" createdLists: "Liste create" createdAntennas: "Antenne create" fromX: "Da {x}" -genEmbedCode: "Ottieni il codice di incorporamento" +genEmbedCode: "Ottieni il codice per incorporare" noteOfThisUser: "Elenco di Note di questo profilo" clipNoteLimitExceeded: "Non è possibile aggiungere ulteriori Note a questa Clip." performance: "Prestazioni" @@ -1347,7 +1347,7 @@ postForm: "Finestra di pubblicazione" textCount: "Il numero di caratteri" information: "Informazioni" chat: "Chat" -directMessage: "Chatta con questa persona" +directMessage: "Chattare insieme" directMessage_short: "Messaggio" migrateOldSettings: "Migrare le vecchie impostazioni" migrateOldSettings_description: "Di solito, viene fatto automaticamente. Se per qualche motivo non fossero migrate con successo, è possibile avviare il processo di migrazione manualmente, sovrascrivendo le configurazioni attuali." @@ -1385,7 +1385,7 @@ pluginsAreDisabledBecauseSafeMode: "Tutti i plugin sono disattivati, poiché la customCssIsDisabledBecauseSafeMode: "Il CSS personalizzato non è stato applicato, poiché la modalità sicura è attiva." themeIsDefaultBecauseSafeMode: "Quando la modalità sicura è attiva, viene utilizzato il tema predefinito. Quando la modalità sicura viene disattivata, il tema torna a essere quello precedente." thankYouForTestingBeta: "Grazie per la tua collaborazione nella verifica delle versioni beta!" -createUserSpecifiedNote: "Creare Nota personalizzata" +createUserSpecifiedNote: "Crea Nota privata" schedulePost: "Pianificare la pubblicazione" scheduleToPostOnX: "Pianificare la pubblicazione {x}" scheduledToPostOnX: "Pubblicazione pianificata {x}" @@ -3052,7 +3052,7 @@ _customEmojisManager: confirmClearEmojisDescription: "Annullare le modifiche e cancella le emoji nell'elenco. Confermi?" confirmUploadEmojisDescription: "Caricamento sul Drive di {count} file locali. Vuoi davvero procedere?" _embedCodeGen: - title: "Personalizza il codice di incorporamento" + title: "Personalizza il codice per incorporare" header: "Mostra la testata" autoload: "Carica automaticamente di più (sconsigliato)" maxHeight: "Altezza massima" @@ -3061,8 +3061,8 @@ _embedCodeGen: previewIsNotActual: "Poiché supera l'intervallo che può essere visualizzato in anteprima, la visualizzazione vera e propria sarà diversa quando effettivamente incorporata." rounded: "Bordo arrotondato" border: "Aggiungi un bordo al contenitore" - applyToPreview: "Applica all'anteprima" - generateCode: "Crea il codice di incorporamento" + applyToPreview: "Aggiorna l'anteprima" + generateCode: "Crea il codice per incorporare" codeGenerated: "Codice generato" codeGeneratedDescription: "Incolla il codice appena generato sul tuo sito web." _selfXssPrevention: diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 77b6476107..1a68375a45 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -775,6 +775,7 @@ lockedAccountInfo: "팔로우를 승인으로 승인받더라도 노트의 공 alwaysMarkSensitive: "미디어를 항상 열람 주의로 설정" loadRawImages: "첨부한 이미지의 썸네일을 원본화질로 표시" disableShowingAnimatedImages: "움직이는 이미지를 자동으로 재생하지 않음" +disableShowingAnimatedImages_caption: "이 설정에 상관없이 애니메이션 이미지가 재생되지 않을 때는 브라우저·OS의 액티비티 설정이나 절전 모드 설정 등이 간섭하고 있는 경우가 있습니다." highlightSensitiveMedia: "미디어가 민감한 내용이라는 것을 알기 쉽게 표시" verificationEmailSent: "확인 메일을 발송하였습니다. 설정을 완료하려면 메일에 첨부된 링크를 확인해 주세요." notSet: "설정되지 않음" @@ -1171,6 +1172,7 @@ installed: "설치됨" branding: "브랜딩" enableServerMachineStats: "서버의 머신 사양을 공개하기" enableIdenticonGeneration: "유저마다의 Identicon 생성 유효화" +showRoleBadgesOfRemoteUsers: "리모트 유저의 역할 배지 표시" turnOffToImprovePerformance: "이 기능을 끄면 성능이 향상될 수 있습니다." createInviteCode: "초대 코드 생성" createWithOptions: "옵션을 지정하여 생성" diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index a60aee5f97..9994e45cfc 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -775,6 +775,7 @@ lockedAccountInfo: "即使启用该功能,只要帖子可见范围不是「仅 alwaysMarkSensitive: "默认将媒体文件标记为敏感内容" loadRawImages: "添加附件图像的缩略图时使用原始图像质量" disableShowingAnimatedImages: "不播放动画" +disableShowingAnimatedImages_caption: "如果即使关闭了此设置但动画仍无法播放,则可能是浏览器或操作系统的辅助功能设置,又或者是省电设置等产生了干扰。" highlightSensitiveMedia: "高亮显示敏感媒体" verificationEmailSent: "已发送确认电子邮件。请访问电子邮件中的链接以完成设置。" notSet: "未设置" @@ -1171,6 +1172,7 @@ installed: "已安装" branding: "品牌" enableServerMachineStats: "公开服务器硬件统计信息" enableIdenticonGeneration: "启用生成用户 Identicon" +showRoleBadgesOfRemoteUsers: "显示远程用户的角色徽章" turnOffToImprovePerformance: "关闭该选项可以提高性能。" createInviteCode: "生成邀请码" createWithOptions: "使用选项来创建" diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index cd4b91ec04..b75a3d707b 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -775,6 +775,7 @@ lockedAccountInfo: "即使追隨需要核准,除非你將貼文的可見性設 alwaysMarkSensitive: "預設標記檔案為敏感內容" loadRawImages: "以原始圖檔顯示附件圖檔的縮圖" disableShowingAnimatedImages: "不播放動態圖檔" +disableShowingAnimatedImages_caption: "無論這個設定如何,如果動畫圖片無法播放,可能是因為瀏覽器或作業系統的無障礙設定、省電設定等產生了干擾。" highlightSensitiveMedia: "強調敏感標記" verificationEmailSent: "已發送驗證電子郵件。請點擊進入電子郵件中的連結以完成驗證。" notSet: "未設定" @@ -3175,7 +3176,7 @@ _uploader: abortConfirm: "有些檔案尚未上傳,您要中止嗎?" doneConfirm: "有些檔案尚未上傳,是否要完成上傳?" maxFileSizeIsX: "可上傳的最大檔案大小為 {x}。" - allowedTypes: "可上傳的檔案類型" + allowedTypes: "可上傳的檔案類型。" tip: "檔案尚未上傳。您可以在此對話框中進行上傳前的確認、重新命名、壓縮、裁切等操作。準備完成後,請點選「上傳」按鈕開始上傳。\n" _clientPerformanceIssueTip: title: "如果覺得電池消耗過快的話" From 579499a7df458ddd8e04393caf3575b5f4d57747 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 19 Oct 2025 04:22:23 +0000 Subject: [PATCH 08/10] Bump version to 2025.10.1-alpha.3 --- package.json | 2 +- packages/misskey-js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 28441a7bea..1376b90cfa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "2025.10.1-alpha.2", + "version": "2025.10.1-alpha.3", "codename": "nasubi", "repository": { "type": "git", diff --git a/packages/misskey-js/package.json b/packages/misskey-js/package.json index 1757e6861e..8c395d527e 100644 --- a/packages/misskey-js/package.json +++ b/packages/misskey-js/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "misskey-js", - "version": "2025.10.1-alpha.2", + "version": "2025.10.1-alpha.3", "description": "Misskey SDK for JavaScript", "license": "MIT", "main": "./built/index.js", From 8a21202281e75857c1477181a887e6510ac95e1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Sun, 19 Oct 2025 23:04:57 +0900 Subject: [PATCH 09/10] =?UTF-8?q?fix(frontend):=20=E3=83=AA=E3=83=A2?= =?UTF-8?q?=E3=83=BC=E3=83=88=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E3=81=AE?= =?UTF-8?q?=E3=83=AD=E3=83=BC=E3=83=AB=E3=83=90=E3=83=83=E3=82=B8=E8=A1=A8?= =?UTF-8?q?=E7=A4=BA=E3=81=AE=E6=96=87=E8=A8=80=E3=82=92=E3=82=8F=E3=81=8B?= =?UTF-8?q?=E3=82=8A=E3=82=84=E3=81=99=E3=81=8F=20(#16672)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locales/index.d.ts | 2 +- locales/ja-JP.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/index.d.ts b/locales/index.d.ts index 7391e197c4..d79db121db 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -4707,7 +4707,7 @@ export interface Locale extends ILocale { */ "enableIdenticonGeneration": string; /** - * リモートユーザーのロールバッジを表示する + * リモートユーザーに付与したロールバッジを表示する */ "showRoleBadgesOfRemoteUsers": string; /** diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 9ee3224441..5d1c37740c 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1172,7 +1172,7 @@ installed: "インストール済み" branding: "ブランディング" enableServerMachineStats: "サーバーのマシン情報を公開する" enableIdenticonGeneration: "ユーザーごとのIdenticon生成を有効にする" -showRoleBadgesOfRemoteUsers: "リモートユーザーのロールバッジを表示する" +showRoleBadgesOfRemoteUsers: "リモートユーザーに付与したロールバッジを表示する" turnOffToImprovePerformance: "オフにするとパフォーマンスが向上します。" createInviteCode: "招待コードを作成" createWithOptions: "オプションを指定して作成" From 43919a3fe3255b17decca2e8c32a5300f25d92ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Mon, 20 Oct 2025 00:22:25 +0900 Subject: [PATCH 10/10] Update CHANGELOG.md (follow-up of #16672) --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d20ef5c6c..3e024a3043 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ## 2025.10.1 ### General -- Enhance: リモートユーザーのロールバッジを表示できるように(オプトイン) +- Enhance: リモートユーザーに付与したロールバッジを表示できるように(オプトイン) パフォーマンス上の問題からデフォルトで無効化されています。「コントロールパネル > パフォーマンス」から有効化できます。 - 依存関係の更新