@threenine/nuxstr-comments 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +2 -2
- package/dist/runtime/classes/NostrManager.d.ts +1 -1
- package/dist/runtime/classes/NostrManager.js +4 -1
- package/dist/runtime/components/CommentView.vue +1 -1
- package/dist/runtime/components/NuxstrComments.d.vue.ts +9 -1
- package/dist/runtime/components/NuxstrComments.vue +73 -53
- package/dist/runtime/components/NuxstrComments.vue.d.ts +9 -1
- package/dist/runtime/components/ScaffoldComment.vue +13 -15
- package/dist/runtime/components/SignInModal.d.vue.ts +10 -0
- package/dist/runtime/components/SignInModal.vue +53 -0
- package/dist/runtime/components/SignInModal.vue.d.ts +10 -0
- package/dist/runtime/components/signin/Extension.d.vue.ts +7 -0
- package/dist/runtime/components/signin/Extension.vue +56 -0
- package/dist/runtime/components/signin/Extension.vue.d.ts +7 -0
- package/dist/runtime/composables/useComments.js +19 -12
- package/dist/runtime/composables/useNostr.d.ts +1 -1
- package/dist/runtime/composables/useNostr.js +2 -2
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Find and replace all on all files (CMD+SHIFT+F):
|
|
|
6
6
|
- Package name: @threenine/nuxstr-comments
|
|
7
7
|
- Description: Nuxstr Comments
|
|
8
8
|
-->
|
|
9
|
-
|
|
9
|
+

|
|
10
10
|
# Nuxstr Comments
|
|
11
11
|
|
|
12
12
|
[![npm version][npm-version-src]][npm-version-href]
|
|
@@ -14,6 +14,7 @@ Find and replace all on all files (CMD+SHIFT+F):
|
|
|
14
14
|
[![License][license-src]][license-href]
|
|
15
15
|
[![Nuxt][nuxt-src]][nuxt-href]
|
|
16
16
|
|
|
17
|
+
![]()
|
|
17
18
|
Enable [nostr protocol](https://nostr.com/) based comment system on your Nuxt 4 based applications.
|
|
18
19
|
|
|
19
20
|
- [✨ Release Notes](/CHANGELOG.md)
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -31,10 +31,10 @@ const module$1 = defineNuxtModule({
|
|
|
31
31
|
nuxt.hook("nitro:config", (nitroConfig) => {
|
|
32
32
|
nitroConfig.externals = nitroConfig.externals || {};
|
|
33
33
|
nitroConfig.externals.inline = nitroConfig.externals.inline || [];
|
|
34
|
-
nitroConfig.externals.inline.push("
|
|
34
|
+
nitroConfig.externals.inline.push("nostr-tools", "defu");
|
|
35
35
|
});
|
|
36
36
|
nuxt.options.build.transpile = nuxt.options.build.transpile || [];
|
|
37
|
-
nuxt.options.build.transpile.push("
|
|
37
|
+
nuxt.options.build.transpile.push("nostr-tools", "defu");
|
|
38
38
|
nuxt.options.runtimeConfig.public.nuxstrComments = defu(nuxt.options.runtimeConfig.public.nuxstrComments || {}, options);
|
|
39
39
|
addPlugin(resolver.resolve("./runtime/plugin"));
|
|
40
40
|
addImports([
|
|
@@ -5,7 +5,7 @@ export declare class NostrManager {
|
|
|
5
5
|
private relays;
|
|
6
6
|
private constructor();
|
|
7
7
|
static getInstance(relays: string[]): NostrManager;
|
|
8
|
-
subscribe(filter: Filter, onEvent: (event: NToolEvent) => void): import("nostr-tools/abstract-pool").SubCloser;
|
|
8
|
+
subscribe(filter: Filter, onEvent: (event: NToolEvent) => void, onEose?: () => void): import("nostr-tools/abstract-pool").SubCloser;
|
|
9
9
|
publish(event: NToolEvent): Promise<void>;
|
|
10
10
|
getEvent(filter: Filter): Promise<NToolEvent | null>;
|
|
11
11
|
close(): Promise<void>;
|
|
@@ -19,12 +19,15 @@ export class NostrManager {
|
|
|
19
19
|
}
|
|
20
20
|
return NostrManager.instance;
|
|
21
21
|
}
|
|
22
|
-
subscribe(filter, onEvent) {
|
|
22
|
+
subscribe(filter, onEvent, onEose) {
|
|
23
23
|
return this.pool.subscribeMany(this.relays, filter, {
|
|
24
24
|
onevent(event) {
|
|
25
25
|
if (verifyEvent(event)) {
|
|
26
26
|
onEvent(event);
|
|
27
27
|
}
|
|
28
|
+
},
|
|
29
|
+
oneose() {
|
|
30
|
+
if (onEose) onEose();
|
|
28
31
|
}
|
|
29
32
|
});
|
|
30
33
|
}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
type __VLS_Props = {
|
|
2
2
|
contentId?: string;
|
|
3
3
|
};
|
|
4
|
-
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
4
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
5
|
+
querying: (...args: any[]) => void;
|
|
6
|
+
completed: (...args: any[]) => void;
|
|
7
|
+
"no-comments": (...args: any[]) => void;
|
|
8
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
9
|
+
onQuerying?: ((...args: any[]) => any) | undefined;
|
|
10
|
+
onCompleted?: ((...args: any[]) => any) | undefined;
|
|
11
|
+
"onNo-comments"?: ((...args: any[]) => any) | undefined;
|
|
12
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
5
13
|
declare const _default: typeof __VLS_export;
|
|
6
14
|
export default _default;
|
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { onMounted } from "vue";
|
|
2
|
+
import { onMounted, ref, watch } from "vue";
|
|
3
3
|
import useNuxstr from "../composables/useNuxstr";
|
|
4
4
|
import useComments from "../composables/useComments";
|
|
5
|
+
import SignInModal from "./SignInModal.vue";
|
|
5
6
|
const props = defineProps({
|
|
6
7
|
contentId: { type: String, required: false }
|
|
7
8
|
});
|
|
8
|
-
const
|
|
9
|
+
const emit = defineEmits(["querying", "completed", "no-comments"]);
|
|
10
|
+
const { isLoggedIn } = useNuxstr();
|
|
9
11
|
const { comments, subscribeComments, loading } = useComments(props.contentId);
|
|
12
|
+
const isSignInModalOpen = ref(false);
|
|
13
|
+
watch(loading, (isLoading) => {
|
|
14
|
+
if (isLoading) {
|
|
15
|
+
emit("querying");
|
|
16
|
+
} else {
|
|
17
|
+
emit("completed");
|
|
18
|
+
if (comments.value.length === 0) {
|
|
19
|
+
emit("no-comments");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
});
|
|
10
23
|
onMounted(() => {
|
|
11
24
|
subscribeComments();
|
|
12
25
|
});
|
|
@@ -23,66 +36,73 @@ onMounted(() => {
|
|
|
23
36
|
v-if="!isLoggedIn"
|
|
24
37
|
class="text-sm text-muted-foreground"
|
|
25
38
|
>
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
39
|
+
<UButton
|
|
40
|
+
color="primary"
|
|
41
|
+
variant="solid"
|
|
42
|
+
leading-icon="game-icons:ostrich"
|
|
43
|
+
@click="isSignInModalOpen = true"
|
|
44
|
+
>
|
|
45
|
+
Sign in
|
|
46
|
+
</UButton>
|
|
47
|
+
|
|
48
|
+
<SignInModal v-model:open="isSignInModalOpen" />
|
|
36
49
|
</div>
|
|
37
50
|
</div>
|
|
38
|
-
|
|
51
|
+
|
|
52
|
+
<div
|
|
53
|
+
v-if="isLoggedIn"
|
|
54
|
+
class="text-sm text-muted-foreground"
|
|
55
|
+
>
|
|
56
|
+
<PostComment :content-id="contentId" />
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<div class="space-y-4">
|
|
39
60
|
<div
|
|
40
|
-
v-if="
|
|
41
|
-
class="
|
|
61
|
+
v-if="loading"
|
|
62
|
+
class="space-y-4"
|
|
42
63
|
>
|
|
43
|
-
<
|
|
64
|
+
<scaffold-comment
|
|
65
|
+
v-for="n in 3"
|
|
66
|
+
:key="n"
|
|
67
|
+
/>
|
|
44
68
|
</div>
|
|
45
|
-
</ClientOnly>
|
|
46
|
-
<ClientOnly>
|
|
47
|
-
<div class="space-y-4">
|
|
48
|
-
<div
|
|
49
|
-
v-if="loading"
|
|
50
|
-
>
|
|
51
|
-
<scaffold-comment />
|
|
52
|
-
</div>
|
|
53
69
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
v-else
|
|
64
|
-
:key="c.id"
|
|
70
|
+
<div
|
|
71
|
+
v-else
|
|
72
|
+
class="space-y-6"
|
|
73
|
+
>
|
|
74
|
+
<div v-if="comments.length === 0">
|
|
75
|
+
<UEmpty
|
|
76
|
+
icon="i-lucide-message-square-off"
|
|
77
|
+
title="No comments yet"
|
|
78
|
+
description="Be the first to share your thoughts!"
|
|
65
79
|
variant="subtle"
|
|
66
|
-
|
|
67
|
-
:ui="{ header: 'flex items-center gap-1.5 text-dimmed' }"
|
|
68
|
-
>
|
|
69
|
-
<comment-author
|
|
70
|
-
:profile="c.profile"
|
|
71
|
-
:created-at="c.created_at"
|
|
72
|
-
/>
|
|
73
|
-
<comment-view
|
|
74
|
-
:id="c.id"
|
|
75
|
-
:content="c.content"
|
|
76
|
-
/>
|
|
77
|
-
</UCard>
|
|
78
|
-
|
|
79
|
-
<div
|
|
80
|
-
v-if="isLoggedIn"
|
|
81
|
-
class=" mt-5"
|
|
80
|
+
size="sm"
|
|
82
81
|
/>
|
|
83
82
|
</div>
|
|
83
|
+
<UCard
|
|
84
|
+
v-for="c in comments"
|
|
85
|
+
v-else
|
|
86
|
+
:key="c.id"
|
|
87
|
+
variant="subtle"
|
|
88
|
+
class="mt-auto"
|
|
89
|
+
:ui="{ header: 'flex items-center gap-1.5 text-dimmed' }"
|
|
90
|
+
>
|
|
91
|
+
<comment-author
|
|
92
|
+
:profile="c.profile"
|
|
93
|
+
:created-at="c.created_at"
|
|
94
|
+
/>
|
|
95
|
+
<comment-view
|
|
96
|
+
:id="c.id"
|
|
97
|
+
:content="c.content"
|
|
98
|
+
/>
|
|
99
|
+
</UCard>
|
|
100
|
+
|
|
101
|
+
<div
|
|
102
|
+
v-if="isLoggedIn"
|
|
103
|
+
class=" mt-5"
|
|
104
|
+
/>
|
|
84
105
|
</div>
|
|
85
|
-
</
|
|
86
|
-
<client-only />
|
|
106
|
+
</div>
|
|
87
107
|
</div>
|
|
88
108
|
</template>
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
type __VLS_Props = {
|
|
2
2
|
contentId?: string;
|
|
3
3
|
};
|
|
4
|
-
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
4
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
5
|
+
querying: (...args: any[]) => void;
|
|
6
|
+
completed: (...args: any[]) => void;
|
|
7
|
+
"no-comments": (...args: any[]) => void;
|
|
8
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
9
|
+
onQuerying?: ((...args: any[]) => any) | undefined;
|
|
10
|
+
onCompleted?: ((...args: any[]) => any) | undefined;
|
|
11
|
+
"onNo-comments"?: ((...args: any[]) => any) | undefined;
|
|
12
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
5
13
|
declare const _default: typeof __VLS_export;
|
|
6
14
|
export default _default;
|
|
@@ -3,21 +3,19 @@
|
|
|
3
3
|
</script>
|
|
4
4
|
|
|
5
5
|
<template>
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class="
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
</UCard>
|
|
20
|
-
</div>
|
|
6
|
+
<UCard
|
|
7
|
+
variant="subtle"
|
|
8
|
+
class="mt-auto"
|
|
9
|
+
:ui="{ header: 'flex items-center gap-1.5 text-dimmed' }"
|
|
10
|
+
>
|
|
11
|
+
<div class="flex items-center gap-1.5">
|
|
12
|
+
<USkeleton class="h-4 w-5 rounded-full" /><USkeleton class="h-4" />
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<div class="mt-3 space-y-2">
|
|
16
|
+
<USkeleton class="h-4" />
|
|
17
|
+
</div>
|
|
18
|
+
</UCard>
|
|
21
19
|
</template>
|
|
22
20
|
|
|
23
21
|
<style scoped>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type __VLS_ModelProps = {
|
|
2
|
+
'open'?: boolean;
|
|
3
|
+
};
|
|
4
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
5
|
+
"update:open": (value: boolean) => any;
|
|
6
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
7
|
+
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
8
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
9
|
+
declare const _default: typeof __VLS_export;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import Extension from "./signin/Extension.vue";
|
|
3
|
+
const open = defineModel("open", { type: Boolean, ...{ default: false } });
|
|
4
|
+
function handleSuccess() {
|
|
5
|
+
open.value = false;
|
|
6
|
+
}
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<UModal
|
|
11
|
+
v-model:open="open"
|
|
12
|
+
title="Sign in to Comment"
|
|
13
|
+
description="Choose your preferred way to sign in with Nostr."
|
|
14
|
+
>
|
|
15
|
+
<template #body>
|
|
16
|
+
<div class="space-y-6">
|
|
17
|
+
<!-- Nostr Education -->
|
|
18
|
+
<div class="p-4 rounded-lg bg-muted/50">
|
|
19
|
+
<div class="flex items-center gap-2 mb-2 text-sm font-semibold">
|
|
20
|
+
<UIcon
|
|
21
|
+
name="i-lucide-help-circle"
|
|
22
|
+
class="w-4 h-4"
|
|
23
|
+
/>
|
|
24
|
+
What is Nostr?
|
|
25
|
+
</div>
|
|
26
|
+
<p class="text-xs leading-relaxed text-muted-foreground">
|
|
27
|
+
Nostr is a decentralized protocol for social media. Instead of a username and password, you use a cryptographic key pair.
|
|
28
|
+
Your "public key" is your identity, and your "private key" is used to sign messages. <a
|
|
29
|
+
href="https://threenine.blog/posts/what-is-nostr"
|
|
30
|
+
target="_blank"
|
|
31
|
+
class="underline hover:text-primary text-primary"
|
|
32
|
+
>Learn more...</a>
|
|
33
|
+
</p>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<!-- Sign-in Options -->
|
|
37
|
+
<div class="space-y-4">
|
|
38
|
+
<Extension @login-success="handleSuccess" />
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<!-- Footer Info -->
|
|
42
|
+
<div class="pt-4 border-t border-border">
|
|
43
|
+
<p class="text-[10px] text-center text-muted-foreground uppercase tracking-wider font-medium">
|
|
44
|
+
Privacy First
|
|
45
|
+
</p>
|
|
46
|
+
<p class="mt-1 text-xs text-center text-muted-foreground">
|
|
47
|
+
We never see your private key. Signing happens directly in your browser or extension.
|
|
48
|
+
</p>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</template>
|
|
52
|
+
</UModal>
|
|
53
|
+
</template>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type __VLS_ModelProps = {
|
|
2
|
+
'open'?: boolean;
|
|
3
|
+
};
|
|
4
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
5
|
+
"update:open": (value: boolean) => any;
|
|
6
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
7
|
+
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
8
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
9
|
+
declare const _default: typeof __VLS_export;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
2
|
+
"login-success": (...args: any[]) => void;
|
|
3
|
+
}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{
|
|
4
|
+
"onLogin-success"?: ((...args: any[]) => any) | undefined;
|
|
5
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import useNuxstr from "../../composables/useNuxstr";
|
|
3
|
+
const { login } = useNuxstr();
|
|
4
|
+
const emit = defineEmits(["login-success"]);
|
|
5
|
+
async function handleLogin() {
|
|
6
|
+
await login();
|
|
7
|
+
emit("login-success");
|
|
8
|
+
}
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<div class="flex flex-col gap-4">
|
|
13
|
+
<div class="flex items-start gap-3 p-4 border rounded-lg border-primary/20 bg-primary/5">
|
|
14
|
+
<UIcon
|
|
15
|
+
name="i-lucide-info"
|
|
16
|
+
class="w-5 h-5 mt-0.5 text-primary"
|
|
17
|
+
/>
|
|
18
|
+
<div class="text-sm">
|
|
19
|
+
<p class="font-medium text-primary">
|
|
20
|
+
Browser Extension (NIP-07)
|
|
21
|
+
</p>
|
|
22
|
+
<p class="mt-1 text-muted-foreground">
|
|
23
|
+
Use a browser extension like Diogel, Alby or nos2x. This is the most secure way to sign in without sharing your private key.
|
|
24
|
+
</p>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<UButton
|
|
29
|
+
block
|
|
30
|
+
color="primary"
|
|
31
|
+
size="lg"
|
|
32
|
+
icon="game-icons:ostrich"
|
|
33
|
+
label="Sign in with Extension"
|
|
34
|
+
@click="handleLogin"
|
|
35
|
+
/>
|
|
36
|
+
|
|
37
|
+
<p class="text-xs text-center text-muted-foreground">
|
|
38
|
+
Don't have an extension?
|
|
39
|
+
<a
|
|
40
|
+
href="https://threenine.io/products/diogel"
|
|
41
|
+
target="_blank"
|
|
42
|
+
class="underline hover:text-primary"
|
|
43
|
+
>Diogel</a> or
|
|
44
|
+
<a
|
|
45
|
+
href="https://getalby.com/"
|
|
46
|
+
target="_blank"
|
|
47
|
+
class="underline hover:text-primary"
|
|
48
|
+
>Get Alby</a> or
|
|
49
|
+
<a
|
|
50
|
+
href="https://github.com/fiatjaf/nos2x"
|
|
51
|
+
target="_blank"
|
|
52
|
+
class="underline hover:text-primary"
|
|
53
|
+
>nos2x</a>
|
|
54
|
+
</p>
|
|
55
|
+
</div>
|
|
56
|
+
</template>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
2
|
+
"login-success": (...args: any[]) => void;
|
|
3
|
+
}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{
|
|
4
|
+
"onLogin-success"?: ((...args: any[]) => any) | undefined;
|
|
5
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -33,24 +33,31 @@ function useComments(customContentId) {
|
|
|
33
33
|
return `${siteUrl()}${path}`;
|
|
34
34
|
}
|
|
35
35
|
async function subscribeComments() {
|
|
36
|
+
loading.value = true;
|
|
36
37
|
const filter = {
|
|
37
38
|
kinds: [1111],
|
|
38
39
|
// NDKKind.GenericReply is 22
|
|
39
40
|
["#t"]: [tagValue()],
|
|
40
41
|
limit: 100
|
|
41
42
|
};
|
|
42
|
-
subscribe(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
id
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
43
|
+
subscribe(
|
|
44
|
+
filter,
|
|
45
|
+
async (event) => {
|
|
46
|
+
if (commentsData.value.some((c) => c.id === event.id)) return;
|
|
47
|
+
const comment = {
|
|
48
|
+
id: event.id,
|
|
49
|
+
pubkey: event.pubkey,
|
|
50
|
+
created_at: event.created_at,
|
|
51
|
+
content: event.content,
|
|
52
|
+
profile: void 0
|
|
53
|
+
};
|
|
54
|
+
comment.profile = await fetchProfile(event.pubkey);
|
|
55
|
+
commentsData.value.push(comment);
|
|
56
|
+
},
|
|
57
|
+
() => {
|
|
58
|
+
loading.value = false;
|
|
59
|
+
}
|
|
60
|
+
);
|
|
54
61
|
}
|
|
55
62
|
async function postComment(comment) {
|
|
56
63
|
const { publish } = useNostr();
|
|
@@ -2,7 +2,7 @@ import type { Filter, Event } from 'nostr-tools';
|
|
|
2
2
|
import { NostrManager } from '../classes/NostrManager.js';
|
|
3
3
|
export declare const useNostr: (relays?: string[]) => {
|
|
4
4
|
nostrManager: NostrManager;
|
|
5
|
-
subscribe: (filter: Filter, onEvent: (event: Event) => void) => import("nostr-tools/abstract-pool").SubCloser;
|
|
5
|
+
subscribe: (filter: Filter, onEvent: (event: Event) => void, onEose?: () => void) => import("nostr-tools/abstract-pool").SubCloser;
|
|
6
6
|
publish: (event: Event) => Promise<void>;
|
|
7
7
|
getEvent: (filter: Filter) => Promise<import("nostr-tools").NostrEvent | null>;
|
|
8
8
|
};
|
|
@@ -5,8 +5,8 @@ export const useNostr = (relays) => {
|
|
|
5
5
|
const opts = config.public?.nuxstrComments || {};
|
|
6
6
|
const effectiveRelays = relays || opts.relays || [];
|
|
7
7
|
const nostrManager = NostrManager.getInstance(effectiveRelays);
|
|
8
|
-
const subscribe = (filter, onEvent) => {
|
|
9
|
-
return nostrManager.subscribe(filter, onEvent);
|
|
8
|
+
const subscribe = (filter, onEvent, onEose) => {
|
|
9
|
+
return nostrManager.subscribe(filter, onEvent, onEose);
|
|
10
10
|
};
|
|
11
11
|
const publish = (event) => {
|
|
12
12
|
console.log("publishing Comment", event);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@threenine/nuxstr-comments",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Nuxt module to enable Nostr Comments on Nuxt 4 based websites",
|
|
5
5
|
"repository": "threenine/nuxstr-comments",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,12 +30,12 @@
|
|
|
30
30
|
"@nuxt/devtools": "^2.6.2",
|
|
31
31
|
"@nuxt/eslint": "1.9.0",
|
|
32
32
|
"@nuxt/eslint-config": "^1.9.0",
|
|
33
|
-
"@nuxt/kit": "^4.
|
|
33
|
+
"@nuxt/kit": "^4.3.1",
|
|
34
34
|
"@nuxt/module-builder": "^1.0.2",
|
|
35
35
|
"@nuxt/schema": "^4.2.1",
|
|
36
36
|
"@nuxt/scripts": "0.11.10",
|
|
37
37
|
"@nuxt/test-utils": "^3.19.2",
|
|
38
|
-
"@nuxt/ui": "^4.
|
|
38
|
+
"@nuxt/ui": "^4.5.1",
|
|
39
39
|
"@testing-library/jest-dom": "^6.8.0",
|
|
40
40
|
"@testing-library/vue": "^8.1.0",
|
|
41
41
|
"@types/node": "latest",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"changelogen": "^0.6.2",
|
|
44
44
|
"eslint": "^9.35.0",
|
|
45
45
|
"jsdom": "^26.1.0",
|
|
46
|
-
"nuxt": "^4.
|
|
46
|
+
"nuxt": "^4.3.1",
|
|
47
47
|
"typescript": "~5.9.2",
|
|
48
48
|
"vitest": "^3.2.4",
|
|
49
49
|
"vue-tsc": "^3.0.6"
|