enhance(frontend): 노트를 편집한 시간이 개별적으로 표시됨
This commit is contained in:
commit
526565db72
|
@ -32,6 +32,7 @@ Misskey의 전체 변경 사항을 확인하려면, [CHANGELOG.md#2023xx](CHANGE
|
|||
- Feat: 노트 편집 시 토스트 알림을 표시하고 사운드를 재생
|
||||
- Enhance: 노트를 편집할 때 편집 중인 노트임을 강조함
|
||||
- Enhance: 타임라인에서 새 노트가 20개 이상이면 '20+'로 표기
|
||||
- Enhance: 노트를 편집한 시간이 개별적으로 표시됨
|
||||
- Fix: '새 노트 알림'을 '노트 수 표시'로 설정했을 때 한국어 이외의 언어에서 내용이 표시되지 않음
|
||||
|
||||
### Server
|
||||
|
|
|
@ -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"`);
|
||||
}
|
||||
|
||||
}
|
|
@ -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, {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -74,10 +74,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // 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!],
|
||||
});
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -221,6 +221,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<div :class="$style.historyMain">
|
||||
<div :class="$style.historyHeader">
|
||||
<MkUserName :user="appearNote.user" :nowrap="true"/>
|
||||
<MkTime :class="$style.updatedAt" :time="appearNote.updatedAtHistory![index]"/>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
|
@ -236,6 +237,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="appearNote.noteEditHistory == null" class="_fullinfo">
|
||||
<img :src="infoImageUrl" class="_ghost"/>
|
||||
<div>{{ i18n.ts.nothing }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue