@threenine/nuxstr-comments 1.5.3 → 1.5.4

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 CHANGED
@@ -23,12 +23,37 @@ Enable [nostr protocol](https://nostr.com/) based comment system on your Nuxt 4
23
23
  ## Features
24
24
 
25
25
  - Nostr-powered comments for Nuxt Content blog posts
26
- - NIP-07 login prompt if user is not authenticated
27
- - Comments are written in Markdown and rendered via @nuxt/content's ContentRendererMarkdown
26
+ - [NIP-07](https://github.com/nostr-protocol/nips/blob/master/07.md) Browser Extension login prompt if user is not authenticated
27
+ - [NIP-22](https://github.com/nostr-protocol/nips/blob/master/22.md) Plain Text Content - (no HTML, Markdown, or other formatting)
28
28
  - Configurable relay list and tagging strategy
29
+ - Comments are published as kind:1111 as Website Url
30
+ ```json
31
+ {
32
+ "kind": 1111,
33
+ "content": "Nice article!",
34
+ "tags": [
35
+ // referencing the root url
36
+ ["I", "https://abc.com/articles/1"],
37
+ // the root "kind": for an url
38
+ ["K", "web"],
39
+
40
+ // the parent reference (same as root for top-level comments)
41
+ ["i", "https://abc.com/articles/1"],
42
+ // the parent "kind": for an url
43
+ ["k", "web"]
44
+ ]
45
+ // other fields
46
+ }
47
+ ```
29
48
 
30
- ## Quick Setup
31
49
 
50
+ > [!WARNING]
51
+ > NuxstrComments [NIP-22] MUST NOT be used to reply to kind 1 notes.
52
+ > NIP-10 should instead be followed.
53
+
54
+
55
+ ## Quick Setup
56
+
32
57
  Install the module to your Nuxt application with one command:
33
58
 
34
59
  ```bash
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@threenine/nuxstr-comments",
3
3
  "configKey": "nuxstrComments",
4
- "version": "1.5.3",
4
+ "version": "1.5.4",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -1,23 +1,28 @@
1
1
  <script setup>
2
- import { onMounted } from "vue";
3
- import { marked } from "marked";
4
- const props = defineProps({
2
+ defineProps({
5
3
  content: { type: String, required: true },
6
4
  id: { type: String, required: true }
7
5
  });
8
- async function renderMarkdown(md) {
9
- return marked.parse(md);
10
- }
11
- onMounted(async () => {
12
- const targetEl = document.getElementById("comment-content");
13
- if (!targetEl) return;
14
- targetEl.innerHTML = await renderMarkdown(props.content);
15
- });
16
6
  </script>
17
7
 
18
8
  <template>
19
9
  <div class="mt-2 mb-2">
20
- <div id="comment-content" />
21
- <ReplyButton :content-id="props.id" />
10
+ <UCard
11
+ variant="subtle"
12
+ class="mt-auto"
13
+ :ui="{ header: 'flex items-center gap-1.5 text-dimmed' }"
14
+ >
15
+ <UTextarea
16
+ :model-value="content"
17
+ color="neutral"
18
+ variant="none"
19
+ autoresize
20
+ readonly
21
+ :rows="4"
22
+ class="w-full"
23
+ :ui="{ base: 'p-0 resize-none' }"
24
+ />
25
+ </ucard>
26
+ <ReplyButton :content-id="id" />
22
27
  </div>
23
28
  </template>
@@ -23,14 +23,16 @@ onMounted(() => {
23
23
  v-if="!isLoggedIn"
24
24
  class="text-sm text-muted-foreground"
25
25
  >
26
- <UButton
27
- color="primary"
28
- variant="solid"
29
- leading-icon="game-icons:ostrich"
30
- @click="login"
31
- >
32
- Sign in
33
- </UButton>
26
+ <u-tooltip text="Sign in with NIP07 browser extension like Alby or nos2fx to comment">
27
+ <UButton
28
+ color="primary"
29
+ variant="solid"
30
+ leading-icon="game-icons:ostrich"
31
+ @click="login"
32
+ >
33
+ Sign in
34
+ </UButton>
35
+ </u-tooltip>
34
36
  </div>
35
37
  </div>
36
38
  <ClientOnly>
@@ -56,11 +58,13 @@ onMounted(() => {
56
58
  <div v-if="comments.length === 0">
57
59
  <scaffold-comment />
58
60
  </div>
59
- <div
61
+ <UCard
60
62
  v-for="c in comments"
61
63
  v-else
62
64
  :key="c.id"
63
- class="rounded border border-gray-900 p-3 mt-2 mb-2"
65
+ variant="subtle"
66
+ class="mt-auto"
67
+ :ui="{ header: 'flex items-center gap-1.5 text-dimmed' }"
64
68
  >
65
69
  <comment-author
66
70
  :profile="c.profile"
@@ -70,7 +74,7 @@ onMounted(() => {
70
74
  :id="c.id"
71
75
  :content="c.content"
72
76
  />
73
- </div>
77
+ </UCard>
74
78
 
75
79
  <div
76
80
  v-if="isLoggedIn"
@@ -23,27 +23,34 @@ async function handlePost() {
23
23
  </script>
24
24
 
25
25
  <template>
26
- <div class="text-sm text-muted-foreground border border-green mt-4 p-6">
27
- <div class="flex gap-2">
28
- <div class="flex-1">
29
- <UTextarea
30
- v-model="comment"
31
- class="w-full mb-4"
32
- placeholder="Write a comment ...."
33
- :rows="4"
34
- />
35
- </div>
36
- <div class="flex flex-col justify-center items-center p-2">
37
- <UButton
38
- icon="mingcute:send-line"
39
- color="primary"
40
- variant="solid"
41
- :disabled="!comment.trim()"
42
- class=""
43
- size="xl"
44
- @click="handlePost"
45
- />
26
+ <UCard
27
+ variant="subtle"
28
+ class="mt-auto"
29
+ :ui="{ header: 'flex items-center gap-1.5 text-dimmed' }"
30
+ >
31
+ <form @submit.prevent="handlePost">
32
+ <UTextarea
33
+ v-model="comment"
34
+ color="neutral"
35
+ variant="none"
36
+ required
37
+ autoresize
38
+ placeholder="Write your comment..."
39
+ :rows="4"
40
+ class="w-full"
41
+ :ui="{ base: 'p-0 resize-none' }"
42
+ />
43
+
44
+ <div class="flex items-center justify-end">
45
+ <div class="flex items-center justify-end gap-2">
46
+ <UButton
47
+ type="submit"
48
+ color="primary"
49
+ label="Comment"
50
+ icon="i-lucide-send"
51
+ />
52
+ </div>
46
53
  </div>
47
- </div>
48
- </div>
54
+ </form>
55
+ </UCard>
49
56
  </template>
@@ -23,25 +23,32 @@ async function postReply(comment) {
23
23
  </script>
24
24
 
25
25
  <template>
26
- <div class="text-sm text-muted-foreground mt-4 p-6">
27
- <div class="flex gap-2">
28
- <div class="flex-1">
29
- <UTextarea
30
- v-model="content"
31
- class="w-full mb-4 rounded-xl"
32
- placeholder="Write a reply to this comment ...."
33
- :rows="4"
34
- />
35
- </div>
36
- <div class="flex flex-col justify-center items-center p-2">
26
+ <UCard
27
+ variant="subtle"
28
+ class="mt-auto"
29
+ :ui="{ header: 'flex items-center gap-1.5 text-dimmed' }"
30
+ >
31
+ <UTextarea
32
+ v-model="content"
33
+ color="neutral"
34
+ variant="none"
35
+ required
36
+ autoresize
37
+ placeholder="Write your comment..."
38
+ :rows="4"
39
+ class="w-full"
40
+ :ui="{ base: 'p-0 resize-none' }"
41
+ />
42
+ <div class="flex items-center justify-end">
43
+ <div class="flex items-center justify-end gap-2">
37
44
  <UButton
38
- icon="mingcute:send-line"
39
- size="xl"
45
+ type="submit"
40
46
  color="primary"
41
- variant="solid"
47
+ label="Reply"
48
+ icon="i-lucide-send"
42
49
  @click="postReply(content)"
43
50
  />
44
51
  </div>
45
52
  </div>
46
- </div>
53
+ </UCard>
47
54
  </template>
@@ -6,10 +6,12 @@ const props = defineProps({
6
6
 
7
7
  <template>
8
8
  <div class="px-10 py-4">
9
- <div
9
+ <UCard
10
10
  v-for="reply in props.replies"
11
11
  :key="reply.id"
12
- class="rounded-md border p-3 mt-2 mb-2"
12
+ variant="subtle"
13
+ class="mt-auto mb-3"
14
+ :ui="{ header: 'flex items-center gap-1.5 text-dimmed' }"
13
15
  >
14
16
  <div>
15
17
  <comment-author
@@ -20,6 +22,6 @@ const props = defineProps({
20
22
  {{ reply.content }}
21
23
  </p>
22
24
  </div>
23
- </div>
25
+ </UCard>
24
26
  </div>
25
27
  </template>
@@ -7,14 +7,16 @@
7
7
  <p class="text-xs">
8
8
  No comments available
9
9
  </p>
10
- <div class="rounded border p-3 mt-2 mb-2">
11
- <div class="flex gap-2 mb-3 items-center">
12
- <span><USkeleton class="h-4 w-5 rounded-full" /></span><USkeleton class="h-4" />
13
- </div>
10
+ <UCard
11
+ variant="subtle"
12
+ class="mt-auto"
13
+ :ui="{ header: 'flex items-center gap-1.5 text-dimmed' }"
14
+ >
15
+ <span><USkeleton class="h-4 w-5 rounded-full" /></span><USkeleton class="h-4" />
14
16
  <div class="mt-3">
15
17
  <USkeleton class="h-4" />
16
18
  </div>
17
- </div>
19
+ </UCard>
18
20
  </div>
19
21
  </template>
20
22
 
@@ -77,9 +77,13 @@ function useNuxstr() {
77
77
  async function fetchProfile(pubkey) {
78
78
  try {
79
79
  const ndk = initializeNDK();
80
- const user = ndk.getUser({ pubkey });
81
- const profile = await user.fetchProfile();
82
- return mapProfile(profile);
80
+ const user = await ndk.fetchUser(pubkey);
81
+ if (user !== null) {
82
+ const profile = await user?.fetchProfile();
83
+ if (!profile) return void 0;
84
+ return mapProfile(profile);
85
+ }
86
+ return void 0;
83
87
  } catch (error) {
84
88
  console.error("Failed to fetch profile for", pubkey, error);
85
89
  return void 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@threenine/nuxstr-comments",
3
- "version": "1.5.3",
3
+ "version": "1.5.4",
4
4
  "description": "Nuxt module to enable Nostr Comments on Nuxt 4 based websites",
5
5
  "repository": "threenine/nuxstr-comments",
6
6
  "license": "MIT",
@@ -24,8 +24,7 @@
24
24
  ],
25
25
  "dependencies": {
26
26
  "@nostr-dev-kit/ndk": "^2.18.1",
27
- "defu": "^6.1.4",
28
- "marked": "^16.2.1"
27
+ "defu": "^6.1.4"
29
28
  },
30
29
  "devDependencies": {
31
30
  "@nuxt/devtools": "^2.6.2",
@@ -36,7 +35,7 @@
36
35
  "@nuxt/schema": "^4.2.1",
37
36
  "@nuxt/scripts": "0.11.10",
38
37
  "@nuxt/test-utils": "^3.19.2",
39
- "@nuxt/ui": "^4.2.1",
38
+ "@nuxt/ui": "^4.3.0",
40
39
  "@testing-library/jest-dom": "^6.8.0",
41
40
  "@testing-library/vue": "^8.1.0",
42
41
  "@types/node": "latest",