@@ -13,7 +10,7 @@ export const NoteComment = memo(function NoteComment({ event }: { event: any })
- {content}
+ {event.content}
diff --git a/src/app/note/components/form.tsx b/src/app/note/components/formReply.tsx
similarity index 100%
rename from src/app/note/components/form.tsx
rename to src/app/note/components/formReply.tsx
diff --git a/src/app/newsfeed/components/note/metadata.tsx b/src/app/note/components/metadata.tsx
similarity index 89%
rename from src/app/newsfeed/components/note/metadata.tsx
rename to src/app/note/components/metadata.tsx
index 4d84a9cf..ea44b8a7 100644
--- a/src/app/newsfeed/components/note/metadata.tsx
+++ b/src/app/note/components/metadata.tsx
@@ -1,6 +1,6 @@
-import NoteLike from '@lume/app/newsfeed/components/metadata/like';
-import NoteReply from '@lume/app/newsfeed/components/metadata/reply';
-import NoteRepost from '@lume/app/newsfeed/components/metadata/repost';
+import NoteLike from '@lume/app/note/components/metadata/like';
+import NoteReply from '@lume/app/note/components/metadata/reply';
+import NoteRepost from '@lume/app/note/components/metadata/repost';
import ZapIcon from '@lume/shared/icons/zap';
import { RelayContext } from '@lume/shared/relayProvider';
import { READONLY_RELAYS } from '@lume/stores/constants';
diff --git a/src/app/newsfeed/components/metadata/like.tsx b/src/app/note/components/metadata/like.tsx
similarity index 100%
rename from src/app/newsfeed/components/metadata/like.tsx
rename to src/app/note/components/metadata/like.tsx
diff --git a/src/app/newsfeed/components/metadata/reply.tsx b/src/app/note/components/metadata/reply.tsx
similarity index 100%
rename from src/app/newsfeed/components/metadata/reply.tsx
rename to src/app/note/components/metadata/reply.tsx
diff --git a/src/app/newsfeed/components/metadata/repost.tsx b/src/app/note/components/metadata/repost.tsx
similarity index 100%
rename from src/app/newsfeed/components/metadata/repost.tsx
rename to src/app/note/components/metadata/repost.tsx
diff --git a/src/app/newsfeed/components/note/parent.tsx b/src/app/note/components/parent.tsx
similarity index 95%
rename from src/app/newsfeed/components/note/parent.tsx
rename to src/app/note/components/parent.tsx
index c37d46fe..e8718c0a 100644
--- a/src/app/newsfeed/components/note/parent.tsx
+++ b/src/app/note/components/parent.tsx
@@ -1,8 +1,8 @@
-import NoteMetadata from '@lume/app/newsfeed/components/note/metadata';
-import { NoteDefaultUser } from '@lume/app/newsfeed/components/user/default';
+import NoteMetadata from '@lume/app/note/components/metadata';
import { noteParser } from '@lume/app/note/components/parser';
import ImagePreview from '@lume/app/note/components/preview/image';
import VideoPreview from '@lume/app/note/components/preview/video';
+import { NoteDefaultUser } from '@lume/app/note/components/user/default';
import { RelayContext } from '@lume/shared/relayProvider';
import { READONLY_RELAYS } from '@lume/stores/constants';
diff --git a/src/app/note/components/parser.tsx b/src/app/note/components/parser.tsx
index 09df7ed0..cae72011 100644
--- a/src/app/note/components/parser.tsx
+++ b/src/app/note/components/parser.tsx
@@ -1,55 +1,66 @@
+import { NoteQuote } from '@lume/app/note/components/quote';
+import { NoteMentionUser } from '@lume/app/note/components/user/mention';
+
import { Event, parseReferences } from 'nostr-tools';
+import reactStringReplace from 'react-string-replace';
const getURLs = new RegExp(
- '(^|[ \t\r\n])((ftp|http|https|gopher|mailto|news|nntp|telnet|wais|file|prospero|aim|webcal):(([A-Za-z0-9$_.+!*(),;/?:@&~=-])|%[A-Fa-f0-9]{2}){2,}(#([a-zA-Z0-9][a-zA-Z0-9$_.+!*(),;/?:@&~=%-]*))?([A-Za-z0-9$_+!*();/?:~-]))',
- 'g'
+ '(^|[ \t\r\n])((ftp|http|https|gopher|mailto|news|nntp|telnet|wais|file|prospero|aim|webcal|wss|ws):(([A-Za-z0-9$_.+!*(),;/?:@&~=-])|%[A-Fa-f0-9]{2}){2,}(#([a-zA-Z0-9][a-zA-Z0-9$_.+!*(),;/?:@&~=%-]*))?([A-Za-z0-9$_+!*();/?:~-]))',
+ 'gmi'
);
export const noteParser = (event: Event) => {
const references = parseReferences(event);
- const content = { original: event.content, parsed: event.content, images: [], videos: [], others: [] };
-
- // remove extra whitespace
- content.parsed = content.parsed.replace(/\s+/g, ' ').trim();
+ const content: { original: string; parsed: any; images: string[]; videos: string[] } = {
+ original: event.content,
+ parsed: event.content,
+ images: [],
+ videos: [],
+ };
// handle media
- content.original.match(getURLs)?.forEach((url) => {
- if (url.match(/\.(jpg|jpeg|gif|png|webp|avif)$/im)) {
+ content.original.match(getURLs)?.forEach((item) => {
+ // make sure url is trimmed
+ const url = item.trim();
+
+ if (url.match(/\.(jpg|jpeg|gif|png|webp|avif)$/gim)) {
// image url
- content.images.push(url.trim());
+ content.images.push(url);
// remove url from original content
content.parsed = content.parsed.replace(url, '');
- } else if (url.match(/(http:|https:)?(\/\/)?(www\.)?(youtube.com|youtu.be)\/(watch|embed)?(\?v=|\/)?(\S+)?/)) {
- // youtube
- content.videos.push(url.trim());
- // remove url from original content
- content.parsed = content.parsed.replace(url, '');
- } else if (url.match(/\.(mp4|webm|mov)$/im)) {
+ } else if (url.match(/\.(mp4|webm|mov)$/i)) {
// video
- content.videos.push(url.trim());
+ content.videos.push(url);
// remove url from original content
content.parsed = content.parsed.replace(url, '');
- } else {
- content.others.push(url.trim());
}
});
+ // handle hashtag
+ content.parsed = reactStringReplace(content.parsed, /#(\w+)/g, (match, i) => (
+
+ #{match}
+
+ ));
+
// handle note references
references?.forEach((reference) => {
if (reference?.profile) {
- content.parsed = content.parsed.replace(
- reference.text,
- `
`
- );
+ content.parsed = reactStringReplace(content.parsed, reference.text, () => {
+ return
;
+ });
}
if (reference?.event) {
- content.parsed = content.parsed.replace(reference.text, `
;`);
+ content.parsed = reactStringReplace(content.parsed, reference.text, () => {
+ return
;
+ });
}
- if (reference?.address) {
- content.parsed = content.parsed.replace(
- reference.text,
- `
${reference.address}>`
- );
+ });
+
+ // make sure no unnessary spaces are left
+ content.parsed.forEach((item: string, index: string) => {
+ if (typeof item === 'string') {
+ content.parsed[index] = item.replace(/^\x20+|\x20+$/gm, '');
}
});
diff --git a/src/app/newsfeed/components/note/placeholder.tsx b/src/app/note/components/placeholder.tsx
similarity index 100%
rename from src/app/newsfeed/components/note/placeholder.tsx
rename to src/app/note/components/placeholder.tsx
diff --git a/src/app/newsfeed/components/note/quote.tsx b/src/app/note/components/quote.tsx
similarity index 96%
rename from src/app/newsfeed/components/note/quote.tsx
rename to src/app/note/components/quote.tsx
index 8b728ffb..ebf5ea39 100644
--- a/src/app/newsfeed/components/note/quote.tsx
+++ b/src/app/note/components/quote.tsx
@@ -1,7 +1,7 @@
-import { NoteDefaultUser } from '@lume/app/newsfeed/components/user/default';
import { noteParser } from '@lume/app/note/components/parser';
import ImagePreview from '@lume/app/note/components/preview/image';
import VideoPreview from '@lume/app/note/components/preview/video';
+import { NoteDefaultUser } from '@lume/app/note/components/user/default';
import { RelayContext } from '@lume/shared/relayProvider';
import { READONLY_RELAYS } from '@lume/stores/constants';
diff --git a/src/app/newsfeed/components/note/quoteRepost.tsx b/src/app/note/components/quoteRepost.tsx
similarity index 82%
rename from src/app/newsfeed/components/note/quoteRepost.tsx
rename to src/app/note/components/quoteRepost.tsx
index 80b5eb6e..9250f059 100644
--- a/src/app/newsfeed/components/note/quoteRepost.tsx
+++ b/src/app/note/components/quoteRepost.tsx
@@ -1,5 +1,5 @@
-import { RootNote } from '@lume/app/newsfeed/components/note/rootNote';
-import { NoteRepostUser } from '@lume/app/newsfeed/components/user/repost';
+import { RootNote } from '@lume/app/note/components/rootNote';
+import { NoteRepostUser } from '@lume/app/note/components/user/repost';
import { getQuoteID } from '@lume/utils/transform';
import { memo } from 'react';
diff --git a/src/app/note/components/replies.tsx b/src/app/note/components/replies.tsx
index 3d4cb94c..60375ed7 100644
--- a/src/app/note/components/replies.tsx
+++ b/src/app/note/components/replies.tsx
@@ -1,4 +1,4 @@
-import NoteReplyForm from '@lume/app/note/components/form';
+import NoteReplyForm from '@lume/app/note/components/formReply';
import NoteReply from '@lume/app/note/components/reply';
import { RelayContext } from '@lume/shared/relayProvider';
import { READONLY_RELAYS } from '@lume/stores/constants';
diff --git a/src/app/note/components/reply.tsx b/src/app/note/components/reply.tsx
index f0809a95..b8e6be08 100644
--- a/src/app/note/components/reply.tsx
+++ b/src/app/note/components/reply.tsx
@@ -1,16 +1,19 @@
-import { contentParser } from '@lume/app/newsfeed/components/contentParser';
-
-import NoteReplyUser from './user';
+import { noteParser } from '@lume/app/note/components//parser';
+import ImagePreview from '@lume/app/note/components/preview/image';
+import VideoPreview from '@lume/app/note/components/preview/video';
+import NoteReplyUser from '@lume/app/note/components/user/reply';
export default function NoteReply({ data }: { data: any }) {
- const content = contentParser(data.content, data.tags);
+ const content = noteParser(data);
return (
-
{content}
+
{content.parsed}
+ {Array.isArray(content.images) && content.images.length ?
: <>>}
+ {Array.isArray(content.videos) && content.videos.length ?
: <>>}
diff --git a/src/app/newsfeed/components/note/rootNote.tsx b/src/app/note/components/rootNote.tsx
similarity index 95%
rename from src/app/newsfeed/components/note/rootNote.tsx
rename to src/app/note/components/rootNote.tsx
index 09cc6bd0..05dd642d 100644
--- a/src/app/newsfeed/components/note/rootNote.tsx
+++ b/src/app/note/components/rootNote.tsx
@@ -1,8 +1,8 @@
-import NoteMetadata from '@lume/app/newsfeed/components/note/metadata';
-import { NoteDefaultUser } from '@lume/app/newsfeed/components/user/default';
+import NoteMetadata from '@lume/app/note/components/metadata';
import { noteParser } from '@lume/app/note/components/parser';
import ImagePreview from '@lume/app/note/components/preview/image';
import VideoPreview from '@lume/app/note/components/preview/video';
+import { NoteDefaultUser } from '@lume/app/note/components/user/default';
import { RelayContext } from '@lume/shared/relayProvider';
import { READONLY_RELAYS } from '@lume/stores/constants';
@@ -46,7 +46,7 @@ export const RootNote = memo(function RootNote({ id, fallback }: { id: string; f
}
};
- const content = !error && data ? noteParser(parseFallback) : null;
+ const content = !error && data ? noteParser(data) : null;
if (parseFallback) {
const contentFallback = noteParser(parseFallback);
diff --git a/src/app/newsfeed/components/user/default.tsx b/src/app/note/components/user/default.tsx
similarity index 97%
rename from src/app/newsfeed/components/user/default.tsx
rename to src/app/note/components/user/default.tsx
index 96a177fc..520e39ae 100644
--- a/src/app/newsfeed/components/user/default.tsx
+++ b/src/app/note/components/user/default.tsx
@@ -14,7 +14,7 @@ export const NoteDefaultUser = ({ pubkey, time }: { pubkey: string; time: number
{isError || isLoading ? (
<>
-
+
diff --git a/src/app/newsfeed/components/user/mention.tsx b/src/app/note/components/user/mention.tsx
similarity index 100%
rename from src/app/newsfeed/components/user/mention.tsx
rename to src/app/note/components/user/mention.tsx
diff --git a/src/app/note/components/user.tsx b/src/app/note/components/user/reply.tsx
similarity index 100%
rename from src/app/note/components/user.tsx
rename to src/app/note/components/user/reply.tsx
diff --git a/src/app/newsfeed/components/user/repost.tsx b/src/app/note/components/user/repost.tsx
similarity index 97%
rename from src/app/newsfeed/components/user/repost.tsx
rename to src/app/note/components/user/repost.tsx
index af72675b..8549af48 100644
--- a/src/app/newsfeed/components/user/repost.tsx
+++ b/src/app/note/components/user/repost.tsx
@@ -14,7 +14,7 @@ export const NoteRepostUser = ({ pubkey, time }: { pubkey: string; time: number
{isError || isLoading ? (
<>
-
+
diff --git a/src/app/note/pages/index.page.tsx b/src/app/note/pages/index.page.tsx
index 5be6ae95..93092189 100644
--- a/src/app/note/pages/index.page.tsx
+++ b/src/app/note/pages/index.page.tsx
@@ -1,7 +1,9 @@
-import { contentParser } from '@lume/app/newsfeed/components/contentParser';
-import NoteMetadata from '@lume/app/newsfeed/components/note/metadata';
-import { NoteDefaultUser } from '@lume/app/newsfeed/components/user/default';
+import NoteMetadata from '@lume/app/note/components/metadata';
+import { noteParser } from '@lume/app/note/components/parser';
+import ImagePreview from '@lume/app/note/components/preview/image';
+import VideoPreview from '@lume/app/note/components/preview/video';
import NoteReplies from '@lume/app/note/components/replies';
+import { NoteDefaultUser } from '@lume/app/note/components/user/default';
import { RelayContext } from '@lume/shared/relayProvider';
import { READONLY_RELAYS } from '@lume/stores/constants';
import { usePageContext } from '@lume/utils/hooks/usePageContext';
@@ -35,6 +37,8 @@ export function Page() {
};
});
+ const content = !error && data ? noteParser(data) : null;
+
return (
@@ -69,8 +73,18 @@ export function Page() {
- {contentParser(data.content, data.tags)}
+ {content ? content.parsed : ''}
+ {Array.isArray(content.images) && content.images.length ? (
+
+ ) : (
+ <>>
+ )}
+ {Array.isArray(content.videos) && content.videos.length ? (
+
+ ) : (
+ <>>
+ )}
e.stopPropagation()} className="mt-5 border-t border-zinc-800 px-5 py-5">