diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2022-01-14 10:25:51 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2022-01-14 10:25:51 +0900 |
| commit | 28193f12ca0fd20544b0c9807661fb9a7e7c2a0e (patch) | |
| tree | 97839b54fbec0e4e07c84e8ecbf8c939817bc94f /packages/client/src/scripts/use-note-capture.ts | |
| parent | :art: (diff) | |
| download | sharkey-28193f12ca0fd20544b0c9807661fb9a7e7c2a0e.tar.gz sharkey-28193f12ca0fd20544b0c9807661fb9a7e7c2a0e.tar.bz2 sharkey-28193f12ca0fd20544b0c9807661fb9a7e7c2a0e.zip | |
wip: refactor(client): migrate paging components to composition api
Diffstat (limited to 'packages/client/src/scripts/use-note-capture.ts')
| -rw-r--r-- | packages/client/src/scripts/use-note-capture.ts | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/packages/client/src/scripts/use-note-capture.ts b/packages/client/src/scripts/use-note-capture.ts new file mode 100644 index 0000000000..bb00e464e3 --- /dev/null +++ b/packages/client/src/scripts/use-note-capture.ts @@ -0,0 +1,123 @@ +import { onUnmounted, Ref } from 'vue'; +import * as misskey from 'misskey-js'; +import { stream } from '@/stream'; +import { $i } from '@/account'; + +export function useNoteCapture(props: { + rootEl: Ref<HTMLElement>; + appearNote: Ref<misskey.entities.Note>; +}) { + const appearNote = props.appearNote; + const connection = $i ? stream : null; + + function onStreamNoteUpdated(data): void { + const { type, id, body } = data; + + if (id !== appearNote.value.id) return; + + switch (type) { + case 'reacted': { + const reaction = body.reaction; + + const updated = JSON.parse(JSON.stringify(appearNote.value)); + + if (body.emoji) { + const emojis = appearNote.value.emojis || []; + if (!emojis.includes(body.emoji)) { + updated.emojis = [...emojis, body.emoji]; + } + } + + // TODO: reactionsプロパティがない場合ってあったっけ? なければ || {} は消せる + const currentCount = (appearNote.value.reactions || {})[reaction] || 0; + + updated.reactions[reaction] = currentCount + 1; + + if ($i && (body.userId === $i.id)) { + updated.myReaction = reaction; + } + + appearNote.value = updated; + break; + } + + case 'unreacted': { + const reaction = body.reaction; + + const updated = JSON.parse(JSON.stringify(appearNote.value)); + + // TODO: reactionsプロパティがない場合ってあったっけ? なければ || {} は消せる + const currentCount = (appearNote.value.reactions || {})[reaction] || 0; + + updated.reactions[reaction] = Math.max(0, currentCount - 1); + + if ($i && (body.userId === $i.id)) { + updated.myReaction = null; + } + + appearNote.value = updated; + break; + } + + case 'pollVoted': { + const choice = body.choice; + + const updated = JSON.parse(JSON.stringify(appearNote.value)); + + const choices = [...appearNote.value.poll.choices]; + choices[choice] = { + ...choices[choice], + votes: choices[choice].votes + 1, + ...($i && (body.userId === $i.id) ? { + isVoted: true + } : {}) + }; + + updated.poll.choices = choices; + + appearNote.value = updated; + break; + } + + case 'deleted': { + const updated = JSON.parse(JSON.stringify(appearNote.value)); + updated.value = true; + appearNote.value = updated; + break; + } + } + } + + function capture(withHandler = false): void { + if (connection) { + // TODO: このノートがストリーミング経由で流れてきた場合のみ sr する + connection.send(document.body.contains(props.rootEl.value) ? 'sr' : 's', { id: appearNote.value.id }); + if (withHandler) connection.on('noteUpdated', onStreamNoteUpdated); + } + } + + function decapture(withHandler = false): void { + if (connection) { + connection.send('un', { + id: appearNote.value.id, + }); + if (withHandler) connection.off('noteUpdated', onStreamNoteUpdated); + } + } + + function onStreamConnected() { + capture(false); + } + + capture(true); + if (connection) { + connection.on('_connected_', onStreamConnected); + } + + onUnmounted(() => { + decapture(true); + if (connection) { + connection.off('_connected_', onStreamConnected); + } + }); +} |