From 20e2a6e95aefea2a84943e4846ad9bfc26755afd Mon Sep 17 00:00:00 2001
From: Hazelnoot <acomputerdog@gmail.com>
Date: Thu, 27 Feb 2025 10:27:48 -0500
Subject: add SkFetchNote to render a note by ID

---
 packages/frontend/src/components/SkFetchNote.vue | 74 ++++++++++++++++++++++++
 1 file changed, 74 insertions(+)
 create mode 100644 packages/frontend/src/components/SkFetchNote.vue

(limited to 'packages/frontend/src/components/SkFetchNote.vue')

diff --git a/packages/frontend/src/components/SkFetchNote.vue b/packages/frontend/src/components/SkFetchNote.vue
new file mode 100644
index 0000000000..57577aa15b
--- /dev/null
+++ b/packages/frontend/src/components/SkFetchNote.vue
@@ -0,0 +1,74 @@
+<!--
+SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors
+SPDX-License-Identifier: AGPL-3.0-only
+-->
+
+<template>
+<MkLazy @show="showing = true">
+	<MkLoading v-if="state === 'loading'"/>
+
+	<div v-if="state === 'error'">{{ i18n.ts.cannotLoadNote }}</div>
+
+	<DynamicNote v-if="state === 'done' && note" :note="note"/>
+</MkLazy>
+</template>
+
+<script setup lang="ts">
+import { ref, watch } from 'vue';
+import * as Misskey from 'misskey-js';
+import { i18n } from '@/i18n.js';
+import { misskeyApi } from '@/scripts/misskey-api';
+import DynamicNote from '@/components/DynamicNote.vue';
+
+const props = withDefaults(defineProps<{
+	noteId: string,
+	lazy?: boolean,
+}>(), {
+	lazy: true,
+});
+
+// Lazy-load, unless props.lazy is false.
+// eslint-disable-next-line vue/no-setup-props-reactivity-loss
+const showing = ref(!props.lazy);
+const state = ref<'loading' | 'error' | 'done'>('loading');
+const note = ref<Misskey.entities.Note | null>(null);
+
+watch(
+	[
+		() => props.noteId,
+		() => showing.value,
+	],
+	async ([noteId, show]) => {
+		// Wait until the note is visible to avoid bombarding the API with requests.
+		if (!show) return;
+
+		// Unload the old note
+		note.value = null;
+		state.value = 'loading';
+
+		// Fetch the new note
+		const newNote = await misskeyApi('notes/show', { noteId }).catch(() => null);
+
+		// Check for race conditions (ex. the note changed again while the first request was still running)
+		if (noteId !== props.noteId) return;
+
+		// Check for errors
+		if (!newNote) {
+			state.value = 'error';
+			return;
+		}
+
+		// Display the new note
+		note.value = newNote;
+		state.value = 'done';
+	},
+	{
+		immediate: true,
+	},
+);
+
+</script>
+
+<style module lang="scss">
+
+</style>
-- 
cgit v1.2.3-freya


From c02fd478111ae2369022b1d0a069f88a4444229d Mon Sep 17 00:00:00 2001
From: Hazelnoot <acomputerdog@gmail.com>
Date: Thu, 27 Feb 2025 11:18:53 -0500
Subject: fix formatting in SkFetchNote

---
 packages/frontend/src/components/SkFetchNote.vue | 5 -----
 1 file changed, 5 deletions(-)

(limited to 'packages/frontend/src/components/SkFetchNote.vue')

diff --git a/packages/frontend/src/components/SkFetchNote.vue b/packages/frontend/src/components/SkFetchNote.vue
index 57577aa15b..ab702c28f8 100644
--- a/packages/frontend/src/components/SkFetchNote.vue
+++ b/packages/frontend/src/components/SkFetchNote.vue
@@ -66,9 +66,4 @@ watch(
 		immediate: true,
 	},
 );
-
 </script>
-
-<style module lang="scss">
-
-</style>
-- 
cgit v1.2.3-freya

