diff --git a/CHANGELOG.md b/CHANGELOG.md index 21bf164e58..47fa72b62a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,15 @@ You should also include the user name that made the change. --> +## 12.x.x (unreleased) + +### Improvements +- + +### Bugfixes +- クライアント: 削除したノートがタイムラインから自動で消えない問題を修正 @syuilo +- クライアント: リアクション数が正しくないことがある問題を修正 @syuilo + ## 12.106.1 (2022/02/11) ### Bugfixes diff --git a/packages/client/src/components/note.vue b/packages/client/src/components/note.vue index 6c596fb60d..7cf5fb0474 100644 --- a/packages/client/src/components/note.vue +++ b/packages/client/src/components/note.vue @@ -138,11 +138,13 @@ const props = defineProps<{ const inChannel = inject('inChannel', null); +const note = $ref(JSON.parse(JSON.stringify(props.note))); + const isRenote = ( - props.note.renote != null && - props.note.text == null && - props.note.fileIds.length === 0 && - props.note.poll == null + note.renote != null && + note.text == null && + note.fileIds.length === 0 && + note.poll == null ); const el = ref(); @@ -150,8 +152,8 @@ const menuButton = ref(); const renoteButton = ref>(); const renoteTime = ref(); const reactButton = ref(); -let appearNote = $ref(isRenote ? props.note.renote as misskey.entities.Note : props.note); -const isMyRenote = $i && ($i.id === props.note.userId); +let appearNote = $ref(isRenote ? note.renote as misskey.entities.Note : note); +const isMyRenote = $i && ($i.id === note.userId); const showContent = ref(false); const collapsed = ref(appearNote.cw == null && appearNote.text != null && ( (appearNote.text.split('\n').length > 9) || @@ -176,8 +178,9 @@ const keymap = { }; useNoteCapture({ - appearNote: $$(appearNote), rootEl: el, + note: $$(appearNote), + isDeletedRef: $$(isDeleted), }); function reply(viaKeyboard = false): void { @@ -225,12 +228,12 @@ function onContextmenu(ev: MouseEvent): void { ev.preventDefault(); react(); } else { - os.contextMenu(getNoteMenu({ note: props.note, translating, translation, menuButton }), ev).then(focus); + os.contextMenu(getNoteMenu({ note: note, translating, translation, menuButton }), ev).then(focus); } } function menu(viaKeyboard = false): void { - os.popupMenu(getNoteMenu({ note: props.note, translating, translation, menuButton }), menuButton.value, { + os.popupMenu(getNoteMenu({ note: note, translating, translation, menuButton }), menuButton.value, { viaKeyboard }).then(focus); } @@ -243,7 +246,7 @@ function showRenoteMenu(viaKeyboard = false): void { danger: true, action: () => { os.api('notes/delete', { - noteId: props.note.id + noteId: note.id }); isDeleted.value = true; } diff --git a/packages/client/src/scripts/use-note-capture.ts b/packages/client/src/scripts/use-note-capture.ts index b7cf99d5e1..b2a96062c7 100644 --- a/packages/client/src/scripts/use-note-capture.ts +++ b/packages/client/src/scripts/use-note-capture.ts @@ -5,34 +5,35 @@ import { $i } from '@/account'; export function useNoteCapture(props: { rootEl: Ref; - appearNote: Ref; + note: Ref; + isDeletedRef: Ref; }) { - const appearNote = props.appearNote; + const note = props.note; const connection = $i ? stream : null; function onStreamNoteUpdated(data): void { const { type, id, body } = data; - if (id !== appearNote.value.id) return; + if (id !== note.value.id) return; switch (type) { case 'reacted': { const reaction = body.reaction; if (body.emoji) { - const emojis = appearNote.value.emojis || []; + const emojis = note.value.emojis || []; if (!emojis.includes(body.emoji)) { - appearNote.value.emojis = [...emojis, body.emoji]; + note.value.emojis = [...emojis, body.emoji]; } } // TODO: reactionsプロパティがない場合ってあったっけ? なければ || {} は消せる - const currentCount = (appearNote.value.reactions || {})[reaction] || 0; + const currentCount = (note.value.reactions || {})[reaction] || 0; - appearNote.value.reactions[reaction] = currentCount + 1; + note.value.reactions[reaction] = currentCount + 1; if ($i && (body.userId === $i.id)) { - appearNote.value.myReaction = reaction; + note.value.myReaction = reaction; } break; } @@ -41,12 +42,12 @@ export function useNoteCapture(props: { const reaction = body.reaction; // TODO: reactionsプロパティがない場合ってあったっけ? なければ || {} は消せる - const currentCount = (appearNote.value.reactions || {})[reaction] || 0; + const currentCount = (note.value.reactions || {})[reaction] || 0; - appearNote.value.reactions[reaction] = Math.max(0, currentCount - 1); + note.value.reactions[reaction] = Math.max(0, currentCount - 1); if ($i && (body.userId === $i.id)) { - appearNote.value.myReaction = null; + note.value.myReaction = null; } break; } @@ -54,7 +55,7 @@ export function useNoteCapture(props: { case 'pollVoted': { const choice = body.choice; - const choices = [...appearNote.value.poll.choices]; + const choices = [...note.value.poll.choices]; choices[choice] = { ...choices[choice], votes: choices[choice].votes + 1, @@ -63,12 +64,12 @@ export function useNoteCapture(props: { } : {}) }; - appearNote.value.poll.choices = choices; + note.value.poll.choices = choices; break; } case 'deleted': { - appearNote.value.deletedAt = new Date(); + props.isDeletedRef.value = true; break; } } @@ -77,7 +78,7 @@ export function useNoteCapture(props: { function capture(withHandler = false): void { if (connection) { // TODO: このノートがストリーミング経由で流れてきた場合のみ sr する - connection.send(document.body.contains(props.rootEl.value) ? 'sr' : 's', { id: appearNote.value.id }); + connection.send(document.body.contains(props.rootEl.value) ? 'sr' : 's', { id: note.value.id }); if (withHandler) connection.on('noteUpdated', onStreamNoteUpdated); } } @@ -85,7 +86,7 @@ export function useNoteCapture(props: { function decapture(withHandler = false): void { if (connection) { connection.send('un', { - id: appearNote.value.id, + id: note.value.id, }); if (withHandler) connection.off('noteUpdated', onStreamNoteUpdated); }