diff --git a/CHANGELOG_CHERRYPICK.md b/CHANGELOG_CHERRYPICK.md index c2b8f67d81..7386bd8117 100644 --- a/CHANGELOG_CHERRYPICK.md +++ b/CHANGELOG_CHERRYPICK.md @@ -32,6 +32,7 @@ Misskey의 전체 변경 사항을 확인하려면, [CHANGELOG.md#2023xx](CHANGE - Feat: 노트 편집 시 토스트 알림을 표시하고 사운드를 재생 - Enhance: 노트를 편집할 때 편집 중인 노트임을 강조함 - Enhance: 타임라인에서 새 노트가 20개 이상이면 '20+'로 표기 +- Enhance: 노트를 편집한 시간이 개별적으로 표시됨 - Fix: '새 노트 알림'을 '노트 수 표시'로 설정했을 때 한국어 이외의 언어에서 내용이 표시되지 않음 ### Server diff --git a/packages/backend/migration/1696318192428-noteUpdatedAtHistory.js b/packages/backend/migration/1696318192428-noteUpdatedAtHistory.js new file mode 100644 index 0000000000..70220f3058 --- /dev/null +++ b/packages/backend/migration/1696318192428-noteUpdatedAtHistory.js @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey, cherrypick 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 301d7e87eb..d8b952bc69 100644 --- a/packages/backend/src/core/entities/NoteEntityService.ts +++ b/packages/backend/src/core/entities/NoteEntityService.ts @@ -339,6 +339,7 @@ export class NoteEntityService implements OnModuleInit { id: note.id, createdAt: this.idService.parse(note.id).date.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, { diff --git a/packages/backend/src/models/Note.ts b/packages/backend/src/models/Note.ts index 672de12e7b..2573334dec 100644 --- a/packages/backend/src/models/Note.ts +++ b/packages/backend/src/models/Note.ts @@ -23,6 +23,12 @@ 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, diff --git a/packages/backend/src/models/json-schema/note.ts b/packages/backend/src/models/json-schema/note.ts index 08b1afdc34..4357de6f15 100644 --- a/packages/backend/src/models/json-schema/note.ts +++ b/packages/backend/src/models/json-schema/note.ts @@ -22,6 +22,15 @@ 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, diff --git a/packages/backend/src/server/api/endpoints/notes/update.ts b/packages/backend/src/server/api/endpoints/notes/update.ts index 311a0aafd2..b02d5bebb7 100644 --- a/packages/backend/src/server/api/endpoints/notes/update.ts +++ b/packages/backend/src/server/api/endpoints/notes/update.ts @@ -74,10 +74,12 @@ export default class extends Endpoint { // eslint- 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!], }); diff --git a/packages/cherrypick-js/src/entities.ts b/packages/cherrypick-js/src/entities.ts index a01a1b67d7..f461d82e27 100644 --- a/packages/cherrypick-js/src/entities.ts +++ b/packages/cherrypick-js/src/entities.ts @@ -181,6 +181,7 @@ export type Note = { id: ID; createdAt: DateString; updatedAt?: DateString | null; + updatedAtHistory: DateString[] | null; noteEditHistory: string[]; text: string | null; cw: string | null; diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index 563203e53a..7fca9080d1 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -221,6 +221,7 @@ SPDX-License-Identifier: AGPL-3.0-only
+
@@ -236,6 +237,10 @@ SPDX-License-Identifier: AGPL-3.0-only
+
+ +
{{ i18n.ts.nothing }}
+
@@ -289,7 +294,7 @@ import MkPagination, { Paging } from '@/components/MkPagination.vue'; import MkReactionIcon from '@/components/MkReactionIcon.vue'; import MkButton from '@/components/MkButton.vue'; import { miLocalStorage } from '@/local-storage.js'; -import { instance } from '@/instance.js'; +import { infoImageUrl, instance } from '@/instance.js'; import MkPostForm from '@/components/MkPostFormSimple.vue'; import { deviceKind } from '@/scripts/device-kind.js'; @@ -1082,11 +1087,12 @@ onMounted(() => { } .historyHeader { + display: flex; margin-bottom: 2px; font-weight: bold; width: 100%; overflow: clip; - text-overflow: ellipsis; + text-overflow: ellipsis; } .avatar { flex-shrink: 0 !important; @@ -1098,6 +1104,12 @@ onMounted(() => { pointer-events: none !important; } +.updatedAt { + flex-shrink: 0; + margin-left: auto; + font-size: 0.9em; +} + .muted { padding: 8px; text-align: center;