diff --git a/CHANGELOG.md b/CHANGELOG.md index a761b79b8246..3b60b67d7bc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ - Feat: ユーザーごとに他ユーザーへの返信をタイムラインに含めるか設定可能になりました - Feat: ユーザーリスト内のメンバーごとに他ユーザーへの返信をユーザーリストタイムラインに含めるか設定可能になりました - Enhance: ソフトワードミュートとハードワードミュートは統合されました +- Enhance: 編集したノートの履歴を確認できるように ### Client - Enhance: 二要素認証のバックアップコード一覧をテキストファイルでダウンロード可能に diff --git a/packages/backend/migration/1696044626209-noteEditHistory.js b/packages/backend/migration/1696044626209-noteEditHistory.js new file mode 100644 index 000000000000..37a542aa1e09 --- /dev/null +++ b/packages/backend/migration/1696044626209-noteEditHistory.js @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class NoteEditHistory1696044626209 { + name = 'NoteEditHistory1696044626209' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "note" ADD "noteEditHistory" varchar(3000) array DEFAULT '{}'`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "note" DROP "noteEditHistory"`); + } +} diff --git a/packages/backend/migration/1696318192428-noteUpdatedAtHistory.js b/packages/backend/migration/1696318192428-noteUpdatedAtHistory.js new file mode 100644 index 000000000000..5dfc4950e0a9 --- /dev/null +++ b/packages/backend/migration/1696318192428-noteUpdatedAtHistory.js @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class NoteUpdateAtHistory1696318192428 { + name = 'NoteUpdateAtHistory1696318192428' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "note" ADD "updatedAtHistory" TIMESTAMP WITH TIME ZONE array`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "note" DROP "updatedAtHistory"`); + } + +} diff --git a/packages/backend/src/core/entities/NoteEntityService.ts b/packages/backend/src/core/entities/NoteEntityService.ts index cf0abd917453..48b9b02e581a 100644 --- a/packages/backend/src/core/entities/NoteEntityService.ts +++ b/packages/backend/src/core/entities/NoteEntityService.ts @@ -309,6 +309,8 @@ export class NoteEntityService implements OnModuleInit { id: note.id, createdAt: note.createdAt.toISOString(), updatedAt: note.updatedAt ? note.updatedAt.toISOString() : undefined, + updatedAtHistory: note.updatedAtHistory ? note.updatedAtHistory.map(x => x.toISOString()) : undefined, + noteEditHistory: note.noteEditHistory.length ? note.noteEditHistory : undefined, userId: note.userId, user: this.userEntityService.pack(note.user ?? note.userId, me, { detail: false, diff --git a/packages/backend/src/models/Note.ts b/packages/backend/src/models/Note.ts index f396a0cd7a83..1efda129fb0f 100644 --- a/packages/backend/src/models/Note.ts +++ b/packages/backend/src/models/Note.ts @@ -29,6 +29,19 @@ export class MiNote { }) public updatedAt: Date | null; + @Column('timestamp with time zone', { + array: true, + default: null, + }) + public updatedAtHistory: Date[] | null; + + @Column('varchar', { + length: 3000, + array: true, + default: '{}', + }) + public noteEditHistory: string[]; + @Index() @Column({ ...id(), diff --git a/packages/backend/src/models/json-schema/note.ts b/packages/backend/src/models/json-schema/note.ts index ad0cb3c45d6a..40205accc84a 100644 --- a/packages/backend/src/models/json-schema/note.ts +++ b/packages/backend/src/models/json-schema/note.ts @@ -22,6 +22,19 @@ export const packedNoteSchema = { optional: true, nullable: true, format: 'date-time', }, + updatedAtHistory: { + type: 'array', + optional: true, nullable: true, + items: { + type: 'string', + optional: false, nullable: false, + format: 'date-time', + }, + }, + noteEditHistory: { + type: 'array', + optional: true, nullable: false, + }, deletedAt: { type: 'string', optional: true, nullable: true, diff --git a/packages/backend/src/server/api/endpoints/notes/update.ts b/packages/backend/src/server/api/endpoints/notes/update.ts index cdf7f085e0f1..87e908c33f76 100644 --- a/packages/backend/src/server/api/endpoints/notes/update.ts +++ b/packages/backend/src/server/api/endpoints/notes/update.ts @@ -73,11 +73,13 @@ export default class extends Endpoint { // eslint- if (note.userId !== me.id) { throw new ApiError(meta.errors.noSuchNote); } - + const updatedAtHistory = note.updatedAtHistory ? note.updatedAtHistory : []; await this.notesRepository.update({ id: note.id }, { updatedAt: new Date(), cw: ps.cw, text: ps.text, + updatedAtHistory: [...updatedAtHistory, new Date()], + noteEditHistory: [...note.noteEditHistory, note.text!], }); this.globalEventService.publishNoteStream(note.id, 'updated', { diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index a9da5a3a6240..137b4a23f6ae 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -137,6 +137,7 @@ SPDX-License-Identifier: AGPL-3.0-only +
@@ -173,6 +174,31 @@ SPDX-License-Identifier: AGPL-3.0-only
+
+
+
+ +
+
+ + +
+
+
+ +
+ +
+
+
+
+
@@ -187,7 +213,7 @@ SPDX-License-Identifier: AGPL-3.0-only