Enable reply update/display in detailed view. (#9606)
This PR establishes a new replied note stream update for subscribed notes, which gets fired off whenever a note receives a reply and the user is subscribed to the note for updates. It specifically does not provide note details as part of the update, just the note id of the reply, so that they must go and retrieve the note and be subject to the proper permission and visibility checks. The detailed note component has then been updated to watch for the replied notification so it can add new replies to the thread as they are created. This allows both seeing new replies while on the page, and also to see your own replies appear after you post them without having to reload the page. This PR relies on https://codeberg.org/calckey/calckey.js/pulls/2 to add the replied type to the calkey.js module. Co-authored-by: Kaity A <supakaity@blahaj.zone> Reviewed-on: https://codeberg.org/calckey/calckey/pulls/9606 Co-authored-by: Kaity A <supakaity@noreply.codeberg.org> Co-committed-by: Kaity A <supakaity@noreply.codeberg.org>
This commit is contained in:
parent
ace8350043
commit
653c71dad5
|
@ -135,6 +135,9 @@ export interface NoteStreamTypes {
|
||||||
reaction: string;
|
reaction: string;
|
||||||
userId: User["id"];
|
userId: User["id"];
|
||||||
};
|
};
|
||||||
|
replied: {
|
||||||
|
id: Note["id"];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
type NoteStreamEventTypes = {
|
type NoteStreamEventTypes = {
|
||||||
[key in keyof NoteStreamTypes]: {
|
[key in keyof NoteStreamTypes]: {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "mfm-js";
|
||||||
import es from "../../db/elasticsearch.js";
|
import es from "../../db/elasticsearch.js";
|
||||||
import { publishMainStream, publishNotesStream } from "@/services/stream.js";
|
import { publishMainStream, publishNotesStream, publishNoteStream } from "@/services/stream.js";
|
||||||
import DeliverManager from "@/remote/activitypub/deliver-manager.js";
|
import DeliverManager from "@/remote/activitypub/deliver-manager.js";
|
||||||
import renderNote from "@/remote/activitypub/renderer/note.js";
|
import renderNote from "@/remote/activitypub/renderer/note.js";
|
||||||
import renderCreate from "@/remote/activitypub/renderer/create.js";
|
import renderCreate from "@/remote/activitypub/renderer/create.js";
|
||||||
|
@ -430,6 +430,12 @@ export default async (
|
||||||
}
|
}
|
||||||
|
|
||||||
publishNotesStream(note);
|
publishNotesStream(note);
|
||||||
|
if (note.replyId != null) {
|
||||||
|
// Only provide the reply note id here as the recipient may not be authorized to see the note.
|
||||||
|
publishNoteStream(note.replyId, "replied", {
|
||||||
|
id: note.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const webhooks = await getActiveWebhooks().then((webhooks) =>
|
const webhooks = await getActiveWebhooks().then((webhooks) =>
|
||||||
webhooks.filter((x) => x.userId === user.id && x.on.includes("note")),
|
webhooks.filter((x) => x.userId === user.id && x.on.includes("note")),
|
||||||
|
|
|
@ -142,6 +142,8 @@ import { i18n } from '@/i18n';
|
||||||
import { getNoteMenu } from '@/scripts/get-note-menu';
|
import { getNoteMenu } from '@/scripts/get-note-menu';
|
||||||
import { useNoteCapture } from '@/scripts/use-note-capture';
|
import { useNoteCapture } from '@/scripts/use-note-capture';
|
||||||
import { deepClone } from '@/scripts/clone';
|
import { deepClone } from '@/scripts/clone';
|
||||||
|
import { stream } from '@/stream';
|
||||||
|
import { NoteUpdatedEvent } from 'calckey-js/built/streaming.types';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
@ -302,6 +304,31 @@ if (appearNote.replyId) {
|
||||||
conversation.value = res.reverse();
|
conversation.value = res.reverse();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onNoteReplied(noteData: NoteUpdatedEvent): void {
|
||||||
|
const { type, id, body } = noteData;
|
||||||
|
if (type === 'replied' && id === appearNote.id) {
|
||||||
|
const { id: createdId } = body;
|
||||||
|
|
||||||
|
os.api('notes/show', {
|
||||||
|
noteId: createdId,
|
||||||
|
}).then(note => {
|
||||||
|
if (note.replyId === appearNote.id) {
|
||||||
|
replies.value.unshift(note);
|
||||||
|
directReplies.value.unshift(note);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
stream.on("noteUpdated", onNoteReplied);
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
stream.off("noteUpdated", onNoteReplied);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
Loading…
Reference in New Issue