summaryrefslogtreecommitdiff
path: root/packages/client/src/scripts/use-note-capture.ts
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2022-01-14 10:25:51 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2022-01-14 10:25:51 +0900
commit28193f12ca0fd20544b0c9807661fb9a7e7c2a0e (patch)
tree97839b54fbec0e4e07c84e8ecbf8c939817bc94f /packages/client/src/scripts/use-note-capture.ts
parent:art: (diff)
downloadsharkey-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.ts123
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);
+ }
+ });
+}