From 1d6f43aa30a932b1b7539f417f19d0b239cde511 Mon Sep 17 00:00:00 2001 From: CyberRex Date: Mon, 20 Mar 2023 12:58:06 +0900 Subject: [PATCH 01/42] feat: drive cleaner (#10366) * feat: drive-cleaner * Update CHANGELOG.md --- CHANGELOG.md | 1 + locales/ja-JP.yml | 5 + .../src/server/api/endpoints/drive/files.ts | 10 + .../src/pages/settings/drive-cleaner.vue | 193 ++++++++++++++++++ .../frontend/src/pages/settings/drive.vue | 3 + packages/frontend/src/router.ts | 4 + 6 files changed, 216 insertions(+) create mode 100644 packages/frontend/src/pages/settings/drive-cleaner.vue diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fb090f267..30b0ac018c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ - Bookwyrmのユーザーのプロフィールページで「リモートで表示」をタップしても反応がない問題を修正 - 非ログイン時の「Misskeyについて」の表示を修正 - PC版にて「設定」「コントロールパネル」のリンクを2度以上続けてクリックした際に空白のページが表示される問題を修正 +- ドライブクリーナーを追加 ### Server - OpenAPIエンドポイントを復旧 diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index c4e86fc64a..54742cef96 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -977,6 +977,7 @@ notesSearchNotAvailable: "ノート検索は利用できません。" license: "ライセンス" unfavoriteConfirm: "お気に入り解除しますか?" myClips: "自分のクリップ" +drivecleaner: "ドライブクリーナー" _achievements: earnedAt: "獲得日時" @@ -1922,3 +1923,7 @@ _dialog: _disabledTimeline: title: "無効化されたタイムライン" description: "現在のロールでは、このタイムラインを使用することはできません。" + +_drivecleaner: + orderBySizeDesc: "サイズが大きい順" + orderByCreatedAtAsc: "追加日が古い順" \ No newline at end of file diff --git a/packages/backend/src/server/api/endpoints/drive/files.ts b/packages/backend/src/server/api/endpoints/drive/files.ts index f6fad50fd9..4609307774 100644 --- a/packages/backend/src/server/api/endpoints/drive/files.ts +++ b/packages/backend/src/server/api/endpoints/drive/files.ts @@ -31,6 +31,7 @@ export const paramDef = { untilId: { type: 'string', format: 'misskey:id' }, folderId: { type: 'string', format: 'misskey:id', nullable: true, default: null }, type: { type: 'string', nullable: true, pattern: /^[a-zA-Z\/\-*]+$/.toString().slice(1, -1) }, + sort: { type: 'string', nullable: true, enum: ['+createdAt', '-createdAt', '+name', '-name', '+size', '-size'] }, }, required: [], } as const; @@ -63,6 +64,15 @@ export default class extends Endpoint { } } + switch (ps.sort) { + case '+createdAt': query.orderBy('file.createdAt', 'DESC'); break; + case '-createdAt': query.orderBy('file.createdAt', 'ASC'); break; + case '+name': query.orderBy('file.name', 'DESC'); break; + case '-name': query.orderBy('file.name', 'ASC'); break; + case '+size': query.orderBy('file.size', 'DESC'); break; + case '-size': query.orderBy('file.size', 'ASC'); break; + } + const files = await query.take(ps.limit).getMany(); return await this.driveFileEntityService.packMany(files, { detail: false, self: true }); diff --git a/packages/frontend/src/pages/settings/drive-cleaner.vue b/packages/frontend/src/pages/settings/drive-cleaner.vue new file mode 100644 index 0000000000..ce8ab214e4 --- /dev/null +++ b/packages/frontend/src/pages/settings/drive-cleaner.vue @@ -0,0 +1,193 @@ + + + + + diff --git a/packages/frontend/src/pages/settings/drive.vue b/packages/frontend/src/pages/settings/drive.vue index a23bdfe69e..d3fb422e01 100644 --- a/packages/frontend/src/pages/settings/drive.vue +++ b/packages/frontend/src/pages/settings/drive.vue @@ -32,6 +32,9 @@ + + {{ i18n.ts.drivecleaner }} + diff --git a/packages/frontend/src/router.ts b/packages/frontend/src/router.ts index 590c5765fd..c8077edd28 100644 --- a/packages/frontend/src/router.ts +++ b/packages/frontend/src/router.ts @@ -65,6 +65,10 @@ export const routes = [{ path: '/drive', name: 'drive', component: page(() => import('./pages/settings/drive.vue')), + }, { + path: '/drive/cleaner', + name: 'drive', + component: page(() => import('./pages/settings/drive-cleaner.vue')), }, { path: '/notifications', name: 'notifications', From bf5706ef6e47c90a112fdbb9ce3ad405828d1151 Mon Sep 17 00:00:00 2001 From: syuilo Date: Mon, 20 Mar 2023 12:58:55 +0900 Subject: [PATCH 02/42] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30b0ac018c..9403763aa8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ ### Client - 設定から自分のロールを確認できるように - 広告一覧ページを追加 +- ドライブクリーナーを追加 - DM作成時にメンションも含むように - フォロー申請のボタンのデザインを改善 - 付箋ウィジェットの高さを設定可能に @@ -43,7 +44,6 @@ - Bookwyrmのユーザーのプロフィールページで「リモートで表示」をタップしても反応がない問題を修正 - 非ログイン時の「Misskeyについて」の表示を修正 - PC版にて「設定」「コントロールパネル」のリンクを2度以上続けてクリックした際に空白のページが表示される問題を修正 -- ドライブクリーナーを追加 ### Server - OpenAPIエンドポイントを復旧 From 32c60c774c87f67f3308d01be12bc9cff89fab12 Mon Sep 17 00:00:00 2001 From: syuilo Date: Mon, 20 Mar 2023 13:00:21 +0900 Subject: [PATCH 03/42] fix indentation --- packages/backend/src/misc/correct-filename.ts | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/backend/src/misc/correct-filename.ts b/packages/backend/src/misc/correct-filename.ts index 3357d8c1bd..23a0699f39 100644 --- a/packages/backend/src/misc/correct-filename.ts +++ b/packages/backend/src/misc/correct-filename.ts @@ -1,15 +1,15 @@ // 与えられた拡張子とファイル名が一致しているかどうかを確認し、 // 一致していない場合は拡張子を付与して返す export function correctFilename(filename: string, ext: string | null) { - const dotExt = ext ? ext.startsWith('.') ? ext : `.${ext}` : '.unknown'; - if (filename.endsWith(dotExt)) { - return filename; - } - if (ext === 'jpg' && filename.endsWith('.jpeg')) { - return filename; - } - if (ext === 'tif' && filename.endsWith('.tiff')) { - return filename; - } - return `${filename}${dotExt}`; + const dotExt = ext ? ext.startsWith('.') ? ext : `.${ext}` : '.unknown'; + if (filename.endsWith(dotExt)) { + return filename; + } + if (ext === 'jpg' && filename.endsWith('.jpeg')) { + return filename; + } + if (ext === 'tif' && filename.endsWith('.tiff')) { + return filename; + } + return `${filename}${dotExt}`; } From 3d6aaa7aaab988bce402ee3c6bac4c4bc0fc93fa Mon Sep 17 00:00:00 2001 From: syuilo Date: Mon, 20 Mar 2023 13:20:21 +0900 Subject: [PATCH 04/42] tweak drive-cleaner --- .../frontend/src/components/MkDrive.file.vue | 96 +--------- .../src/pages/settings/drive-cleaner.vue | 171 +++++++----------- .../src/scripts/get-drive-file-menu.ts | 93 ++++++++++ 3 files changed, 164 insertions(+), 196 deletions(-) create mode 100644 packages/frontend/src/scripts/get-drive-file-menu.ts diff --git a/packages/frontend/src/components/MkDrive.file.vue b/packages/frontend/src/components/MkDrive.file.vue index 8c17c0530a..ab408b5008 100644 --- a/packages/frontend/src/components/MkDrive.file.vue +++ b/packages/frontend/src/components/MkDrive.file.vue @@ -32,14 +32,14 @@ diff --git a/packages/frontend/src/scripts/get-drive-file-menu.ts b/packages/frontend/src/scripts/get-drive-file-menu.ts new file mode 100644 index 0000000000..56ab516038 --- /dev/null +++ b/packages/frontend/src/scripts/get-drive-file-menu.ts @@ -0,0 +1,93 @@ +import * as Misskey from 'misskey-js'; +import { defineAsyncComponent } from 'vue'; +import { i18n } from '@/i18n'; +import copyToClipboard from '@/scripts/copy-to-clipboard'; +import * as os from '@/os'; + +function rename(file: Misskey.entities.DriveFile) { + os.inputText({ + title: i18n.ts.renameFile, + placeholder: i18n.ts.inputNewFileName, + default: file.name, + }).then(({ canceled, result: name }) => { + if (canceled) return; + os.api('drive/files/update', { + fileId: file.id, + name: name, + }); + }); +} + +function describe(file: Misskey.entities.DriveFile) { + os.popup(defineAsyncComponent(() => import('@/components/MkFileCaptionEditWindow.vue')), { + default: file.comment != null ? file.comment : '', + file: file, + }, { + done: caption => { + os.api('drive/files/update', { + fileId: file.id, + comment: caption.length === 0 ? null : caption, + }); + }, + }, 'closed'); +} + +function toggleSensitive(file: Misskey.entities.DriveFile) { + os.api('drive/files/update', { + fileId: file.id, + isSensitive: !file.isSensitive, + }); +} + +function copyUrl(file: Misskey.entities.DriveFile) { + copyToClipboard(file.url); + os.success(); +} +/* +function addApp() { + alert('not implemented yet'); +} +*/ +async function deleteFile(file: Misskey.entities.DriveFile) { + const { canceled } = await os.confirm({ + type: 'warning', + text: i18n.t('driveFileDeleteConfirm', { name: file.name }), + }); + + if (canceled) return; + os.api('drive/files/delete', { + fileId: file.id, + }); +} + +export function getDriveFileMenu(file: Misskey.entities.DriveFile) { + return [{ + text: i18n.ts.rename, + icon: 'ti ti-forms', + action: rename, + }, { + text: file.isSensitive ? i18n.ts.unmarkAsSensitive : i18n.ts.markAsSensitive, + icon: file.isSensitive ? 'ti ti-eye' : 'ti ti-eye-off', + action: toggleSensitive, + }, { + text: i18n.ts.describeFile, + icon: 'ti ti-text-caption', + action: describe, + }, null, { + text: i18n.ts.copyUrl, + icon: 'ti ti-link', + action: copyUrl, + }, { + type: 'a', + href: file.url, + target: '_blank', + text: i18n.ts.download, + icon: 'ti ti-download', + download: file.name, + }, null, { + text: i18n.ts.delete, + icon: 'ti ti-trash', + danger: true, + action: deleteFile, + }]; +} From e1520479126a5ca79012a49e4b1a6872f1dc481a Mon Sep 17 00:00:00 2001 From: nenohi Date: Mon, 20 Mar 2023 14:24:18 +0900 Subject: [PATCH 05/42] =?UTF-8?q?=E7=B5=B5=E6=96=87=E5=AD=97=E3=81=AE?= =?UTF-8?q?=E5=90=8D=E5=89=8D=E3=81=AB@=E3=82=84:=E3=81=8C=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E3=81=A7=E3=81=8D=E3=82=8B=20(#9964)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(#9918)名前の一致でもエラーとするように * 判定を逆に * )の位置間違えてる * カテゴリ分けとかしたときにエラーになる * エラー消し * こういうこと・・・? --- .../src/server/api/endpoints/admin/emoji/update.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/update.ts b/packages/backend/src/server/api/endpoints/admin/emoji/update.ts index dad0e3ef86..1c649db93e 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/update.ts @@ -19,6 +19,11 @@ export const meta = { code: 'NO_SUCH_EMOJI', id: '684dec9d-a8c2-4364-9aa8-456c49cb1dc8', }, + alreadyexistsemoji: { + message: 'Emoji already exists', + code: 'EMOJI_ALREADY_EXISTS', + id: '7180fe9d-1ee3-bff9-647d-fe9896d2ffb8', + }, }, } as const; @@ -26,7 +31,7 @@ export const paramDef = { type: 'object', properties: { id: { type: 'string', format: 'misskey:id' }, - name: { type: 'string' }, + name: { type: 'string', pattern: '^[a-zA-Z0-9_]+$' }, category: { type: 'string', nullable: true, @@ -57,9 +62,9 @@ export default class extends Endpoint { ) { super(meta, paramDef, async (ps, me) => { const emoji = await this.emojisRepository.findOneBy({ id: ps.id }); - + const emojiname = await this.emojisRepository.findOneBy({ name: ps.name }); if (emoji == null) throw new ApiError(meta.errors.noSuchEmoji); - + if (emojiname != null && emojiname.id !== ps.id) throw new ApiError(meta.errors.alreadyexistsemoji); await this.emojisRepository.update(emoji.id, { updatedAt: new Date(), name: ps.name, From 3014e3e5f88ec18ef741ec343794af7057194009 Mon Sep 17 00:00:00 2001 From: syuilo Date: Mon, 20 Mar 2023 14:25:21 +0900 Subject: [PATCH 06/42] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9403763aa8..a4a3e2a927 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,7 @@ - リテンション分析が上手く機能しないことがあるのを修正 - 空のアンテナが作成できないように修正 - 特定の条件で通報が見れない問題を修正 +- 絵文字の名前に任意の文字が使用できる問題を修正 ## 13.9.2 (2023/03/06) From eb5781465b9a810a1f26e3be4d24776a227e39ec Mon Sep 17 00:00:00 2001 From: choco <8362391+choco14t@users.noreply.github.com> Date: Mon, 20 Mar 2023 14:26:11 +0900 Subject: [PATCH 07/42] =?UTF-8?q?fix(users/show):=20=E3=83=A6=E3=83=BC?= =?UTF-8?q?=E3=82=B6=E3=83=BC=E3=81=8C=E8=A6=8B=E3=81=A4=E3=81=8B=E3=82=89?= =?UTF-8?q?=E3=81=AA=E3=81=8B=E3=81=A3=E3=81=9F=E5=A0=B4=E5=90=88=E3=81=AB?= =?UTF-8?q?404=E3=82=B9=E3=83=86=E3=83=BC=E3=82=BF=E3=82=B9=E3=82=B3?= =?UTF-8?q?=E3=83=BC=E3=83=89=E3=82=92=E8=BF=94=E3=81=99=20(#10344)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(users/show): ユーザーが見つからなかった場合に404ステータスコードを返す * test(users/show): ステータスコードの期待値を修正 --- packages/backend/src/server/api/endpoints/users/show.ts | 1 + packages/backend/test/e2e/endpoints.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/server/api/endpoints/users/show.ts b/packages/backend/src/server/api/endpoints/users/show.ts index 29f24b045a..ba432c273b 100644 --- a/packages/backend/src/server/api/endpoints/users/show.ts +++ b/packages/backend/src/server/api/endpoints/users/show.ts @@ -48,6 +48,7 @@ export const meta = { message: 'No such user.', code: 'NO_SUCH_USER', id: '4362f8dc-731f-4ad8-a694-be5a88922a24', + httpStatusCode: 404, }, }, } as const; diff --git a/packages/backend/test/e2e/endpoints.ts b/packages/backend/test/e2e/endpoints.ts index 0a45a320f9..afb72c84d4 100644 --- a/packages/backend/test/e2e/endpoints.ts +++ b/packages/backend/test/e2e/endpoints.ts @@ -162,14 +162,14 @@ describe('Endpoints', () => { const res = await api('/users/show', { userId: '000000000000000000000000', }); - assert.strictEqual(res.status, 400); + assert.strictEqual(res.status, 404); }); test('間違ったIDで怒られる', async () => { const res = await api('/users/show', { userId: 'kyoppie', }); - assert.strictEqual(res.status, 400); + assert.strictEqual(res.status, 404); }); }); From 54630edb0f8cf91480e19f4e8e56c05158bc3a8f Mon Sep 17 00:00:00 2001 From: syuilo Date: Mon, 20 Mar 2023 20:12:38 +0900 Subject: [PATCH 08/42] =?UTF-8?q?enhance:=20=E4=BD=BF=E3=82=8F=E3=82=8C?= =?UTF-8?q?=E3=81=A6=E3=81=AA=E3=81=84=E3=82=A2=E3=83=B3=E3=83=86=E3=83=8A?= =?UTF-8?q?=E3=81=AF=E8=87=AA=E5=8B=95=E5=81=9C=E6=AD=A2=E3=81=95=E3=82=8C?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolve #9373 --- CHANGELOG.md | 1 + .../migration/1679309757174-antenna-active.js | 17 +++++++++++++++++ packages/backend/src/core/AntennaService.ts | 6 +++++- .../src/core/entities/AntennaEntityService.ts | 1 + packages/backend/src/models/entities/Antenna.ts | 10 ++++++++++ .../backend/src/models/json-schema/antenna.ts | 4 ++++ .../queue/processors/CleanProcessorService.ts | 15 +++++++++++++-- .../src/server/api/endpoints/antennas/create.ts | 5 ++++- .../src/server/api/endpoints/antennas/notes.ts | 4 ++++ 9 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 packages/backend/migration/1679309757174-antenna-active.js diff --git a/CHANGELOG.md b/CHANGELOG.md index a4a3e2a927..4e2ea11028 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ - ロールの並び順を設定可能に - カスタム絵文字にライセンス情報を付与できるように - 指定した文字列を含む投稿の公開範囲をホームにできるように +- 使われてないアンテナは自動停止されるように ### Client - 設定から自分のロールを確認できるように diff --git a/packages/backend/migration/1679309757174-antenna-active.js b/packages/backend/migration/1679309757174-antenna-active.js new file mode 100644 index 0000000000..69e845c142 --- /dev/null +++ b/packages/backend/migration/1679309757174-antenna-active.js @@ -0,0 +1,17 @@ +export class antennaActive1679309757174 { + name = 'antennaActive1679309757174' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "antenna" ADD "lastUsedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT 'now'`); + await queryRunner.query(`ALTER TABLE "antenna" ADD "isActive" boolean NOT NULL DEFAULT true`); + await queryRunner.query(`CREATE INDEX "IDX_084c2abb8948ef59a37dce6ac1" ON "antenna" ("lastUsedAt") `); + await queryRunner.query(`CREATE INDEX "IDX_36ef5192a1ce55ed0e40aa4db5" ON "antenna" ("isActive") `); + } + + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "public"."IDX_36ef5192a1ce55ed0e40aa4db5"`); + await queryRunner.query(`DROP INDEX "public"."IDX_084c2abb8948ef59a37dce6ac1"`); + await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "isActive"`); + await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "lastUsedAt"`); + } +} diff --git a/packages/backend/src/core/AntennaService.ts b/packages/backend/src/core/AntennaService.ts index 35fbb53e81..aaa26a8321 100644 --- a/packages/backend/src/core/AntennaService.ts +++ b/packages/backend/src/core/AntennaService.ts @@ -71,12 +71,14 @@ export class AntennaService implements OnApplicationShutdown { this.antennas.push({ ...body, createdAt: new Date(body.createdAt), + lastUsedAt: new Date(body.lastUsedAt), }); break; case 'antennaUpdated': this.antennas[this.antennas.findIndex(a => a.id === body.id)] = { ...body, createdAt: new Date(body.createdAt), + lastUsedAt: new Date(body.lastUsedAt), }; break; case 'antennaDeleted': @@ -217,7 +219,9 @@ export class AntennaService implements OnApplicationShutdown { @bindThis public async getAntennas() { if (!this.antennasFetched) { - this.antennas = await this.antennasRepository.find(); + this.antennas = await this.antennasRepository.findBy({ + isActive: true, + }); this.antennasFetched = true; } diff --git a/packages/backend/src/core/entities/AntennaEntityService.ts b/packages/backend/src/core/entities/AntennaEntityService.ts index 89137c0ec0..e02daefd64 100644 --- a/packages/backend/src/core/entities/AntennaEntityService.ts +++ b/packages/backend/src/core/entities/AntennaEntityService.ts @@ -37,6 +37,7 @@ export class AntennaEntityService { notify: antenna.notify, withReplies: antenna.withReplies, withFile: antenna.withFile, + isActive: antenna.isActive, hasUnreadNote, }; } diff --git a/packages/backend/src/models/entities/Antenna.ts b/packages/backend/src/models/entities/Antenna.ts index 5b2164ef17..e63e7f2c72 100644 --- a/packages/backend/src/models/entities/Antenna.ts +++ b/packages/backend/src/models/entities/Antenna.ts @@ -13,6 +13,10 @@ export class Antenna { }) public createdAt: Date; + @Index() + @Column('timestamp with time zone') + public lastUsedAt: Date; + @Index() @Column({ ...id(), @@ -83,4 +87,10 @@ export class Antenna { @Column('boolean') public notify: boolean; + + @Index() + @Column('boolean', { + default: true, + }) + public isActive: boolean; } diff --git a/packages/backend/src/models/json-schema/antenna.ts b/packages/backend/src/models/json-schema/antenna.ts index f0994e48f7..4483510610 100644 --- a/packages/backend/src/models/json-schema/antenna.ts +++ b/packages/backend/src/models/json-schema/antenna.ts @@ -75,6 +75,10 @@ export const packedAntennaSchema = { type: 'boolean', optional: false, nullable: false, }, + isActive: { + type: 'boolean', + optional: false, nullable: false, + }, hasUnreadNote: { type: 'boolean', optional: false, nullable: false, diff --git a/packages/backend/src/queue/processors/CleanProcessorService.ts b/packages/backend/src/queue/processors/CleanProcessorService.ts index 7fd2cde9c0..9534454fd7 100644 --- a/packages/backend/src/queue/processors/CleanProcessorService.ts +++ b/packages/backend/src/queue/processors/CleanProcessorService.ts @@ -1,7 +1,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { In, LessThan } from 'typeorm'; import { DI } from '@/di-symbols.js'; -import type { AntennaNotesRepository, MutedNotesRepository, NotificationsRepository, RoleAssignmentsRepository, UserIpsRepository } from '@/models/index.js'; +import type { AntennaNotesRepository, AntennasRepository, MutedNotesRepository, NotificationsRepository, RoleAssignmentsRepository, UserIpsRepository } from '@/models/index.js'; import type { Config } from '@/config.js'; import type Logger from '@/logger.js'; import { bindThis } from '@/decorators.js'; @@ -26,6 +26,9 @@ export class CleanProcessorService { @Inject(DI.mutedNotesRepository) private mutedNotesRepository: MutedNotesRepository, + @Inject(DI.antennasRepository) + private antennasRepository: AntennasRepository, + @Inject(DI.antennaNotesRepository) private antennaNotesRepository: AntennaNotesRepository, @@ -55,8 +58,16 @@ export class CleanProcessorService { reason: 'word', }); - this.antennaNotesRepository.delete({ + this.mutedNotesRepository.delete({ id: LessThan(this.idService.genId(new Date(Date.now() - (1000 * 60 * 60 * 24 * 90)))), + reason: 'word', + }); + + // 7日以上使われてないアンテナを停止 + this.antennasRepository.update({ + lastUsedAt: LessThan(new Date(Date.now() - (1000 * 60 * 60 * 24 * 7))), + }, { + isActive: false, }); const expiredRoleAssignments = await this.roleAssignmentsRepository.createQueryBuilder('assign') diff --git a/packages/backend/src/server/api/endpoints/antennas/create.ts b/packages/backend/src/server/api/endpoints/antennas/create.ts index b57906a688..d147ddb7f1 100644 --- a/packages/backend/src/server/api/endpoints/antennas/create.ts +++ b/packages/backend/src/server/api/endpoints/antennas/create.ts @@ -103,9 +103,12 @@ export default class extends Endpoint { } } + const now = new Date(); + const antenna = await this.antennasRepository.insert({ id: this.idService.genId(), - createdAt: new Date(), + createdAt: now, + lastUsedAt: now, userId: me.id, name: ps.name, src: ps.src, diff --git a/packages/backend/src/server/api/endpoints/antennas/notes.ts b/packages/backend/src/server/api/endpoints/antennas/notes.ts index fbb5acf617..039ba1115a 100644 --- a/packages/backend/src/server/api/endpoints/antennas/notes.ts +++ b/packages/backend/src/server/api/endpoints/antennas/notes.ts @@ -101,6 +101,10 @@ export default class extends Endpoint { this.noteReadService.read(me.id, notes); } + this.antennasRepository.update(antenna.id, { + lastUsedAt: new Date(), + }); + return await this.noteEntityService.packMany(notes, me); }); } From 21b10603fea5a709535ec1450a05f68314701c45 Mon Sep 17 00:00:00 2001 From: Ekke Date: Mon, 20 Mar 2023 20:21:54 +0900 Subject: [PATCH 09/42] =?UTF-8?q?feat(frontend):=20=E3=83=8A=E3=83=93?= =?UTF-8?q?=E3=82=B2=E3=83=BC=E3=82=B7=E3=83=A7=E3=83=B3=E3=83=90=E3=83=BC?= =?UTF-8?q?=E3=81=AE=E3=82=AB=E3=82=B9=E3=82=BF=E3=83=9E=E3=82=A4=E3=82=BA?= =?UTF-8?q?=E3=82=92=E3=83=89=E3=83=A9=E3=83=83=E3=82=B0&=E3=83=89?= =?UTF-8?q?=E3=83=AD=E3=83=83=E3=83=97=E3=81=A7=E8=A1=8C=E3=81=88=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B=20(#10356)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(frontend): ナビゲーションバーのカスタマイズをドラッグ&ドロップで行えるようにする * eslintのエラーを修正 * ハンドルをつかんでドラッグするように変更 * eslintのエラーを修正 * デザインの軽微な変更 * 修正 * Update CHANGELOG.md * Update CHANGELOG.md * ドラッグハンドルを3本線から2本線に --------- Co-authored-by: root --- CHANGELOG.md | 3 + .../frontend/src/pages/settings/navbar.vue | 131 +++++++++++++++--- 2 files changed, 117 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e2ea11028..fc016c4646 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,9 @@ - APオブジェクトを入力してフェッチする機能とユーザーやノートの検索機能を分離 - ナビゲーションバーの項目に「プロフィール」を追加できるように - AiScriptを0.13.1に更新 +- ナビゲーションバーのカスタマイズをドラッグ&ドロップで行えるように + +### Bugfixes - oEmbedをサポートしているウェブサイトのプレビューができるように - YouTubeをoEmbedでロードし、プレビューで共有ボタンを押すとOSの共有画面がでるように - ([FirefoxでSpotifyのプレビューを開けるとフルサイズじゃなくプレビューサイズだけ再生できる問題](https://bugzilla.mozilla.org/show_bug.cgi?id=1792395)があります) diff --git a/packages/frontend/src/pages/settings/navbar.vue b/packages/frontend/src/pages/settings/navbar.vue index ead551e7c4..dc13477268 100644 --- a/packages/frontend/src/pages/settings/navbar.vue +++ b/packages/frontend/src/pages/settings/navbar.vue @@ -1,9 +1,34 @@ + From 5e1014c0725684f85bb3c8d73fb59b9d047c3ce3 Mon Sep 17 00:00:00 2001 From: syuilo Date: Mon, 20 Mar 2023 20:22:24 +0900 Subject: [PATCH 10/42] Update CHANGELOG.md --- CHANGELOG.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc016c4646..557379a663 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,10 +33,8 @@ - 付箋ウィジェットの高さを設定可能に - APオブジェクトを入力してフェッチする機能とユーザーやノートの検索機能を分離 - ナビゲーションバーの項目に「プロフィール」を追加できるように -- AiScriptを0.13.1に更新 - ナビゲーションバーのカスタマイズをドラッグ&ドロップで行えるように - -### Bugfixes +- AiScriptを0.13.1に更新 - oEmbedをサポートしているウェブサイトのプレビューができるように - YouTubeをoEmbedでロードし、プレビューで共有ボタンを押すとOSの共有画面がでるように - ([FirefoxでSpotifyのプレビューを開けるとフルサイズじゃなくプレビューサイズだけ再生できる問題](https://bugzilla.mozilla.org/show_bug.cgi?id=1792395)があります) From dac4fbcb1eb5be0ac8d67a642b5aeefd5ea46041 Mon Sep 17 00:00:00 2001 From: syuilo Date: Mon, 20 Mar 2023 20:35:49 +0900 Subject: [PATCH 11/42] tweak settings/navbar.vue --- .../frontend/src/pages/settings/navbar.vue | 136 ++++++++---------- 1 file changed, 57 insertions(+), 79 deletions(-) diff --git a/packages/frontend/src/pages/settings/navbar.vue b/packages/frontend/src/pages/settings/navbar.vue index dc13477268..b3b33b8026 100644 --- a/packages/frontend/src/pages/settings/navbar.vue +++ b/packages/frontend/src/pages/settings/navbar.vue @@ -5,27 +5,27 @@
- {{ i18n.ts.addItem }} + {{ i18n.ts.addItem }} {{ i18n.ts.default }} {{ i18n.ts.save }}
@@ -56,7 +56,10 @@ import { deepClone } from '@/scripts/clone'; const Sortable = defineAsyncComponent(() => import('vuedraggable').then(x => x.default)); -const items = ref(deepClone(defaultStore.state.menu)); +const items = ref(defaultStore.state.menu.map(x => ({ + id: Math.random().toString(), + type: x, +}))); const menuDisplay = computed(defaultStore.makeGetterSetter('menuDisplay')); @@ -81,7 +84,10 @@ async function addItem() { }], }); if (canceled) return; - items.value = [...items.value, item]; + items.value = [...items.value, { + id: Math.random().toString(), + type: item, + }]; } function removeItem(index: number) { @@ -89,12 +95,15 @@ function removeItem(index: number) { } async function save() { - defaultStore.set('menu', items.value); + defaultStore.set('menu', items.value.map(x => x.type)); await reloadAsk(); } function reset() { - items.value = defaultStore.def.menu.default; + items.value = defaultStore.def.menu.default.map(x => ({ + id: Math.random().toString(), + type: x, + })); } watch(menuDisplay, async () => { @@ -110,75 +119,44 @@ definePageMetadata({ icon: 'ti ti-list', }); - From 75888a55c35eb8bb81186fc44abcf7d476db6d74 Mon Sep 17 00:00:00 2001 From: syuilo Date: Mon, 20 Mar 2023 20:49:10 +0900 Subject: [PATCH 12/42] New Crowdin updates (#10369) * New translations ja-JP.yml (German) * New translations ja-JP.yml (English) --- locales/de-DE.yml | 4 ++++ locales/en-US.yml | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/locales/de-DE.yml b/locales/de-DE.yml index 08808ea6a4..0716bcc4ad 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -977,6 +977,7 @@ notesSearchNotAvailable: "Die Notizsuche ist nicht verfügbar." license: "Lizenz" unfavoriteConfirm: "Wirklich aus Favoriten entfernen?" myClips: "Meine Clips" +drivecleaner: "Drive-Reiniger" _achievements: earnedAt: "Freigeschaltet am" _types: @@ -1868,3 +1869,6 @@ _dialog: _disabledTimeline: title: "Chronik deaktiviert" description: "Mit deinen jetzigen Rollen ist diese Chronik nicht verfügbar." +_drivecleaner: + orderBySizeDesc: "Absteigende Dateigrößen" + orderByCreatedAtAsc: "Aufsteigendes Erstelldatum" diff --git a/locales/en-US.yml b/locales/en-US.yml index 9e018ce2ac..5efb7b7d1e 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -530,7 +530,7 @@ nothing: "There's nothing to see here" installedDate: "Authorized at" lastUsedDate: "Last used at" state: "State" -sort: "Sort" +sort: "Sorting order" ascendingOrder: "Ascending" descendingOrder: "Descending" scratchpad: "Scratchpad" @@ -977,6 +977,7 @@ notesSearchNotAvailable: "Note search is unavailable." license: "License" unfavoriteConfirm: "Really remove from favorites?" myClips: "My clips" +drivecleaner: "Drive Cleaner" _achievements: earnedAt: "Unlocked at" _types: @@ -1868,3 +1869,6 @@ _dialog: _disabledTimeline: title: "Timeline disabled" description: "You cannot use this timeline under your current roles." +_drivecleaner: + orderBySizeDesc: "Descending Filesizes" + orderByCreatedAtAsc: "Ascending Dates" From 7331de0bcef74bde0789259830f98be2b063de57 Mon Sep 17 00:00:00 2001 From: CyberRex Date: Wed, 22 Mar 2023 08:58:23 +0900 Subject: [PATCH 13/42] feat: queue force promote (#10370) * feat: queue force promote * Update CHANGELOG.md * small fix --- CHANGELOG.md | 1 + locales/ja-JP.yml | 3 ++ .../backend/src/server/api/EndpointsModule.ts | 4 ++ packages/backend/src/server/api/endpoints.ts | 2 + .../api/endpoints/admin/queue/promote.ts | 52 +++++++++++++++++++ packages/frontend/src/pages/admin/queue.vue | 15 ++++++ 6 files changed, 77 insertions(+) create mode 100644 packages/backend/src/server/api/endpoints/admin/queue/promote.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 557379a663..c5fe52bc80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ - APオブジェクトを入力してフェッチする機能とユーザーやノートの検索機能を分離 - ナビゲーションバーの項目に「プロフィール」を追加できるように - ナビゲーションバーのカスタマイズをドラッグ&ドロップで行えるように +- ジョブキューの再試行をワンクリックでできるように - AiScriptを0.13.1に更新 - oEmbedをサポートしているウェブサイトのプレビューができるように - YouTubeをoEmbedでロードし、プレビューで共有ボタンを押すとOSの共有画面がでるように diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 54742cef96..2011ca3636 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -978,6 +978,9 @@ license: "ライセンス" unfavoriteConfirm: "お気に入り解除しますか?" myClips: "自分のクリップ" drivecleaner: "ドライブクリーナー" +retryAllQueuesNow: "すべてのキューを今すぐ再試行" +retryAllQueuesConfirmTitle: "今すぐ再試行しますか?" +retryAllQueuesConfirmText: "一時的にサーバーの負荷が増大することがあります。" _achievements: earnedAt: "獲得日時" diff --git a/packages/backend/src/server/api/EndpointsModule.ts b/packages/backend/src/server/api/EndpointsModule.ts index 516e90dcb3..835e884193 100644 --- a/packages/backend/src/server/api/EndpointsModule.ts +++ b/packages/backend/src/server/api/EndpointsModule.ts @@ -42,6 +42,7 @@ import * as ep___admin_promo_create from './endpoints/admin/promo/create.js'; import * as ep___admin_queue_clear from './endpoints/admin/queue/clear.js'; import * as ep___admin_queue_deliverDelayed from './endpoints/admin/queue/deliver-delayed.js'; import * as ep___admin_queue_inboxDelayed from './endpoints/admin/queue/inbox-delayed.js'; +import * as ep___admin_queue_promote from './endpoints/admin/queue/promote.js'; import * as ep___admin_queue_stats from './endpoints/admin/queue/stats.js'; import * as ep___admin_relays_add from './endpoints/admin/relays/add.js'; import * as ep___admin_relays_list from './endpoints/admin/relays/list.js'; @@ -370,6 +371,7 @@ const $admin_promo_create: Provider = { provide: 'ep:admin/promo/create', useCla const $admin_queue_clear: Provider = { provide: 'ep:admin/queue/clear', useClass: ep___admin_queue_clear.default }; const $admin_queue_deliverDelayed: Provider = { provide: 'ep:admin/queue/deliver-delayed', useClass: ep___admin_queue_deliverDelayed.default }; const $admin_queue_inboxDelayed: Provider = { provide: 'ep:admin/queue/inbox-delayed', useClass: ep___admin_queue_inboxDelayed.default }; +const $admin_queue_promote: Provider = { provide: 'ep:admin/queue/promote', useClass: ep___admin_queue_promote.default }; const $admin_queue_stats: Provider = { provide: 'ep:admin/queue/stats', useClass: ep___admin_queue_stats.default }; const $admin_relays_add: Provider = { provide: 'ep:admin/relays/add', useClass: ep___admin_relays_add.default }; const $admin_relays_list: Provider = { provide: 'ep:admin/relays/list', useClass: ep___admin_relays_list.default }; @@ -702,6 +704,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $admin_queue_clear, $admin_queue_deliverDelayed, $admin_queue_inboxDelayed, + $admin_queue_promote, $admin_queue_stats, $admin_relays_add, $admin_relays_list, @@ -1028,6 +1031,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $admin_queue_clear, $admin_queue_deliverDelayed, $admin_queue_inboxDelayed, + $admin_queue_promote, $admin_queue_stats, $admin_relays_add, $admin_relays_list, diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts index 2930468a22..f6fc79fc70 100644 --- a/packages/backend/src/server/api/endpoints.ts +++ b/packages/backend/src/server/api/endpoints.ts @@ -42,6 +42,7 @@ import * as ep___admin_promo_create from './endpoints/admin/promo/create.js'; import * as ep___admin_queue_clear from './endpoints/admin/queue/clear.js'; import * as ep___admin_queue_deliverDelayed from './endpoints/admin/queue/deliver-delayed.js'; import * as ep___admin_queue_inboxDelayed from './endpoints/admin/queue/inbox-delayed.js'; +import * as ep___admin_queue_promote from './endpoints/admin/queue/promote.js'; import * as ep___admin_queue_stats from './endpoints/admin/queue/stats.js'; import * as ep___admin_relays_add from './endpoints/admin/relays/add.js'; import * as ep___admin_relays_list from './endpoints/admin/relays/list.js'; @@ -368,6 +369,7 @@ const eps = [ ['admin/queue/clear', ep___admin_queue_clear], ['admin/queue/deliver-delayed', ep___admin_queue_deliverDelayed], ['admin/queue/inbox-delayed', ep___admin_queue_inboxDelayed], + ['admin/queue/promote', ep___admin_queue_promote], ['admin/queue/stats', ep___admin_queue_stats], ['admin/relays/add', ep___admin_relays_add], ['admin/relays/list', ep___admin_relays_list], diff --git a/packages/backend/src/server/api/endpoints/admin/queue/promote.ts b/packages/backend/src/server/api/endpoints/admin/queue/promote.ts new file mode 100644 index 0000000000..4e57e6613e --- /dev/null +++ b/packages/backend/src/server/api/endpoints/admin/queue/promote.ts @@ -0,0 +1,52 @@ +import { Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; +import { QueueService } from '@/core/QueueService.js'; + +export const meta = { + tags: ['admin'], + + requireCredential: true, + requireModerator: true, +} as const; + +export const paramDef = { + type: 'object', + properties: { + type: { type: 'string', enum: ['deliver', 'inbox'] }, + }, + required: ['type'], +} as const; + +// eslint-disable-next-line import/no-default-export +@Injectable() +export default class extends Endpoint { + constructor( + private moderationLogService: ModerationLogService, + private queueService: QueueService, + ) { + super(meta, paramDef, async (ps, me) => { + let delayedQueues; + + switch (ps.type) { + case 'deliver': + delayedQueues = await this.queueService.deliverQueue.getDelayed(); + for (let queueIndex = 0; queueIndex < delayedQueues.length; queueIndex++) { + const queue = delayedQueues[queueIndex]; + await queue.promote(); + } + break; + + case 'inbox': + delayedQueues = await this.queueService.inboxQueue.getDelayed(); + for (let queueIndex = 0; queueIndex < delayedQueues.length; queueIndex++) { + const queue = delayedQueues[queueIndex]; + await queue.promote(); + } + break; + } + + this.moderationLogService.insertModerationLog(me, 'promoteQueue'); + }); + } +} diff --git a/packages/frontend/src/pages/admin/queue.vue b/packages/frontend/src/pages/admin/queue.vue index 80e97fed93..509d329eb1 100644 --- a/packages/frontend/src/pages/admin/queue.vue +++ b/packages/frontend/src/pages/admin/queue.vue @@ -4,6 +4,8 @@ +
+ {{ i18n.ts.retryAllQueuesNow }}
@@ -15,6 +17,7 @@ import * as os from '@/os'; import * as config from '@/config'; import { i18n } from '@/i18n'; import { definePageMetadata } from '@/scripts/page-metadata'; +import MkButton from '@/components/MkButton.vue'; let tab = $ref('deliver'); @@ -30,6 +33,18 @@ function clear() { }); } +function promoteAllQueues() { + os.confirm({ + type: 'warning', + title: i18n.ts.retryAllQueuesConfirmTitle, + text: i18n.ts.retryAllQueuesConfirmText, + }).then(({ canceled }) => { + if (canceled) return; + + os.apiWithDialog('admin/queue/promote', { type: tab }); + }); +} + const headerActions = $computed(() => [{ asFullButton: true, icon: 'ti ti-external-link', From 9a40a4e315bb4a33ec21ef62397e9db98695cc59 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 22 Mar 2023 08:59:50 +0900 Subject: [PATCH 14/42] Update packages/backend/test/utils.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Acid Chicken (硫酸鶏) --- packages/backend/test/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/test/utils.ts b/packages/backend/test/utils.ts index 879d5ec79a..4f501a8726 100644 --- a/packages/backend/test/utils.ts +++ b/packages/backend/test/utils.ts @@ -1,4 +1,4 @@ -import * as assert from 'assert'; +import * as assert from 'node:assert'; import { readFile } from 'node:fs/promises'; import { isAbsolute, basename } from 'node:path'; import { inspect } from 'node:util'; From 78a3d78a7f6c5bc423b5e2eec84fe9d831edb4a5 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 22 Mar 2023 09:09:43 +0900 Subject: [PATCH 15/42] fix drive-cleaner --- packages/frontend/src/pages/settings/drive-cleaner.vue | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/frontend/src/pages/settings/drive-cleaner.vue b/packages/frontend/src/pages/settings/drive-cleaner.vue index 2342280ca7..8178343bbb 100644 --- a/packages/frontend/src/pages/settings/drive-cleaner.vue +++ b/packages/frontend/src/pages/settings/drive-cleaner.vue @@ -43,7 +43,7 @@