diff --git a/src/app/channel/components/messages/item.tsx b/src/app/channel/components/messages/item.tsx index 39cc765a..55be8546 100644 --- a/src/app/channel/components/messages/item.tsx +++ b/src/app/channel/components/messages/item.tsx @@ -2,7 +2,7 @@ import MessageHideButton from '@lume/app/channel/components/messages/hideButton' import MessageMuteButton from '@lume/app/channel/components/messages/muteButton'; import MessageReplyButton from '@lume/app/channel/components/messages/replyButton'; import ChannelMessageUser from '@lume/app/channel/components/messages/user'; -import { noteParser } from '@lume/app/note/components/parser'; +import { noteParser } from '@lume/utils/parser'; import { useMemo } from 'react'; diff --git a/src/app/chat/components/messages/item.tsx b/src/app/chat/components/messages/item.tsx index f86f24f8..971538f9 100644 --- a/src/app/chat/components/messages/item.tsx +++ b/src/app/chat/components/messages/item.tsx @@ -1,8 +1,8 @@ import ChatMessageUser from '@lume/app/chat/components/messages/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 { useDecryptMessage } from '@lume/utils/hooks/useDecryptMessage'; +import { noteParser } from '@lume/utils/parser'; import { memo } from 'react'; diff --git a/src/app/index/pages/index.page.tsx b/src/app/index/pages/index.page.tsx index f2a021e9..cb1bdfa2 100644 --- a/src/app/index/pages/index.page.tsx +++ b/src/app/index/pages/index.page.tsx @@ -1,4 +1,3 @@ -import LumeIcon from '@lume/shared/icons/lume'; import { getActiveAccount } from '@lume/utils/storage'; import useSWR from 'swr'; @@ -21,41 +20,5 @@ export function Page() { navigate('/app/inital-data', { overwriteLastHistoryEntry: true }); } - return ( -
-
- {/* dragging area */} -
- {/* end dragging area */} -
-
- -
-

- Here's an interesting fact: -

-

- Bitcoin and Nostr can be used by anyone, and no one can stop you! -

-
-
-
- - - - -
-
-
-
- ); + return
; } diff --git a/src/app/note/components/base.tsx b/src/app/note/components/base.tsx index 48555b63..64d9b9bc 100644 --- a/src/app/note/components/base.tsx +++ b/src/app/note/components/base.tsx @@ -1,10 +1,8 @@ -import { ContentMarkdown } from '@lume/app/note/components/markdown'; +import { NoteContent } from '@lume/app/note/components/content'; import NoteMetadata from '@lume/app/note/components/metadata'; import { NoteParent } from '@lume/app/note/components/parent'; -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 { noteParser } from '@lume/utils/parser'; import { navigate } from 'vite-plugin-ssr/client/router'; @@ -25,19 +23,13 @@ export default function NoteBase({ event }: { event: any }) { onClick={(e) => openNote(e)} className="relative z-10 flex h-min min-h-min w-full select-text flex-col border-b border-zinc-800 px-3 py-5 hover:bg-black/20" > - {event.parent_id && event.parent_id !== event.event_id ? ( + {event.parent_id && event.parent_id !== event.event_id && ( - ) : ( - <> )}
- - {Array.isArray(content.images) && content.images.length ? : <>} - {Array.isArray(content.videos) && content.videos.length ? : <>} -
-
e.stopPropagation()} className="mt-5 pl-[52px]"> +
diff --git a/src/app/note/components/comment.tsx b/src/app/note/components/comment.tsx deleted file mode 100644 index 6a62e5d5..00000000 --- a/src/app/note/components/comment.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { NoteDefaultUser } from '@lume/app/note/components/user/default'; - -import { memo } from 'react'; - -export const NoteComment = memo(function NoteComment({ event }: { event: any }) { - return ( -
-
- -
-
-
- {event.content} -
-
-
-
e.stopPropagation()} className="mt-5 pl-[52px]">
-
-
- ); -}); diff --git a/src/app/note/components/content.tsx b/src/app/note/components/content.tsx new file mode 100644 index 00000000..5559de90 --- /dev/null +++ b/src/app/note/components/content.tsx @@ -0,0 +1,28 @@ +import ImagePreview from '@lume/app/note/components/preview/image'; +import VideoPreview from '@lume/app/note/components/preview/video'; +import { NoteQuote } from '@lume/app/note/components/quote'; +import { NoteMentionUser } from '@lume/app/note/components/user/mention'; + +import ReactMarkdown from 'react-markdown'; +import remarkGfm from 'remark-gfm'; + +export const NoteContent = ({ content }: { content: any }) => { + return ( + <> + , + h6: ({ ...props }) => , + em: ({ ...props }) => , + }} + > + {content.parsed} + + {Array.isArray(content.images) && content.images.length ? : <>} + {Array.isArray(content.videos) && content.videos.length ? : <>} + + ); +}; diff --git a/src/app/note/components/markdown.tsx b/src/app/note/components/markdown.tsx deleted file mode 100644 index aca27275..00000000 --- a/src/app/note/components/markdown.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { NoteQuote } from '@lume/app/note/components/quote'; -import { NoteMentionUser } from '@lume/app/note/components/user/mention'; - -import ReactMarkdown from 'react-markdown'; -import remarkGfm from 'remark-gfm'; - -export const ContentMarkdown = ({ content }: { content: any }) => { - return ( - , - h6: ({ ...props }) => , - em: ({ ...props }) => , - }} - > - {content} - - ); -}; diff --git a/src/app/note/components/metadata.tsx b/src/app/note/components/metadata.tsx index ea44b8a7..0b5e20c5 100644 --- a/src/app/note/components/metadata.tsx +++ b/src/app/note/components/metadata.tsx @@ -51,7 +51,7 @@ export default function NoteMetadata({ id, eventPubkey }: { id: string; eventPub }); return ( -
+
diff --git a/src/app/note/components/parent.tsx b/src/app/note/components/parent.tsx index 85ab2a55..a4f7d7c7 100644 --- a/src/app/note/components/parent.tsx +++ b/src/app/note/components/parent.tsx @@ -1,11 +1,9 @@ -import { ContentMarkdown } from '@lume/app/note/components/markdown'; +import { NoteContent } from '@lume/app/note/components/content'; 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'; +import { noteParser } from '@lume/utils/parser'; import { memo, useContext } from 'react'; import useSWRSubscription from 'swr/subscription'; @@ -72,12 +70,7 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) {
-
- - {Array.isArray(content.images) && content.images.length ? : <>} - {Array.isArray(content.videos) && content.videos.length ? : <>} -
-
e.stopPropagation()} className="mt-5 pl-[52px]"> +
diff --git a/src/app/note/components/preview/image.tsx b/src/app/note/components/preview/image.tsx index a736e3a2..47204a09 100644 --- a/src/app/note/components/preview/image.tsx +++ b/src/app/note/components/preview/image.tsx @@ -2,28 +2,15 @@ import { Image } from '@lume/shared/image'; export default function ImagePreview({ urls }: { urls: string[] }) { return ( -
- {urls.length === 1 ? ( -
- image -
- ) : ( - urls.map((url: string) => ( -
- image -
- )) - )} +
+
+ image +
); } diff --git a/src/app/note/components/preview/video.tsx b/src/app/note/components/preview/video.tsx index 3cdfc180..4bd0fc66 100644 --- a/src/app/note/components/preview/video.tsx +++ b/src/app/note/components/preview/video.tsx @@ -4,7 +4,7 @@ export default function VideoPreview({ urls }: { urls: string[] }) { return (
e.stopPropagation()} - className="relative mt-2 flex w-full flex-col overflow-hidden rounded-lg bg-zinc-950" + className="relative mt-3 flex w-full flex-col overflow-hidden rounded-lg bg-zinc-950" > diff --git a/src/app/note/components/quote.tsx b/src/app/note/components/quote.tsx index 6d1e1fe3..b9c9a744 100644 --- a/src/app/note/components/quote.tsx +++ b/src/app/note/components/quote.tsx @@ -1,10 +1,8 @@ -import { ContentMarkdown } from '@lume/app/note/components/markdown'; -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 { NoteContent } from '@lume/app/note/components/content'; import { NoteDefaultUser } from '@lume/app/note/components/user/default'; import { RelayContext } from '@lume/shared/relayProvider'; import { READONLY_RELAYS } from '@lume/stores/constants'; +import { noteParser } from '@lume/utils/parser'; import { memo, useContext } from 'react'; import useSWRSubscription from 'swr/subscription'; @@ -36,6 +34,8 @@ export const NoteQuote = memo(function NoteQuote({ id }: { id: string }) { }; }); + const content = !error && data ? noteParser(data) : null; + const openNote = (e) => { const selection = window.getSelection(); if (selection.toString().length === 0) { @@ -45,8 +45,6 @@ export const NoteQuote = memo(function NoteQuote({ id }: { id: string }) { } }; - const content = !error && data ? noteParser(data) : null; - return (
openNote(e)} @@ -59,9 +57,7 @@ export const NoteQuote = memo(function NoteQuote({ id }: { id: string }) {
- - {Array.isArray(content.images) && content.images.length ? : <>} - {Array.isArray(content.videos) && content.videos.length ? : <>} +
)} diff --git a/src/app/note/components/formReply.tsx b/src/app/note/components/replies/form.tsx similarity index 100% rename from src/app/note/components/formReply.tsx rename to src/app/note/components/replies/form.tsx diff --git a/src/app/note/components/replies/item.tsx b/src/app/note/components/replies/item.tsx new file mode 100644 index 00000000..56b02bc8 --- /dev/null +++ b/src/app/note/components/replies/item.tsx @@ -0,0 +1,18 @@ +import { NoteContent } from '@lume/app/note/components/content'; +import NoteReplyUser from '@lume/app/note/components/user/reply'; +import { noteParser } from '@lume/utils/parser'; + +export default function Reply({ data }: { data: any }) { + const content = noteParser(data); + + return ( +
+
+ +
+ +
+
+
+ ); +} diff --git a/src/app/note/components/replies.tsx b/src/app/note/components/replies/list.tsx similarity index 88% rename from src/app/note/components/replies.tsx rename to src/app/note/components/replies/list.tsx index 60375ed7..1e7b132d 100644 --- a/src/app/note/components/replies.tsx +++ b/src/app/note/components/replies/list.tsx @@ -1,5 +1,5 @@ -import NoteReplyForm from '@lume/app/note/components/formReply'; -import NoteReply from '@lume/app/note/components/reply'; +import NoteReplyForm from '@lume/app/note/components/replies/form'; +import Reply from '@lume/app/note/components/replies/item'; import { RelayContext } from '@lume/shared/relayProvider'; import { READONLY_RELAYS } from '@lume/stores/constants'; import { sortEvents } from '@lume/utils/transform'; @@ -7,7 +7,7 @@ import { sortEvents } from '@lume/utils/transform'; import { useContext } from 'react'; import useSWRSubscription from 'swr/subscription'; -export default function NoteReplies({ id }: { id: string }) { +export default function RepliesList({ id }: { id: string }) { const pool: any = useContext(RelayContext); const { data, error } = useSWRSubscription(id ? ['note-replies', id] : null, ([, key], { next }) => { @@ -53,7 +53,7 @@ export default function NoteReplies({ id }: { id: string }) {
) : ( sortEvents(data).map((event: any) => { - return ; + return ; }) )}
diff --git a/src/app/note/components/reply.tsx b/src/app/note/components/reply.tsx deleted file mode 100644 index 79e4a1aa..00000000 --- a/src/app/note/components/reply.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { noteParser } from '@lume/app/note/components//parser'; -import { ContentMarkdown } from '@lume/app/note/components/markdown'; -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 = noteParser(data); - - return ( -
-
- -
- - {Array.isArray(content.images) && content.images.length ? : <>} - {Array.isArray(content.videos) && content.videos.length ? : <>} -
-
-
- ); -} diff --git a/src/app/note/components/rootNote.tsx b/src/app/note/components/rootNote.tsx index 5ef3280f..1d13c396 100644 --- a/src/app/note/components/rootNote.tsx +++ b/src/app/note/components/rootNote.tsx @@ -1,11 +1,9 @@ -import { ContentMarkdown } from '@lume/app/note/components/markdown'; +import { NoteContent } from '@lume/app/note/components/content'; 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'; +import { noteParser } from '@lume/utils/parser'; import { memo, useContext } from 'react'; import useSWRSubscription from 'swr/subscription'; @@ -65,19 +63,7 @@ export const RootNote = memo(function RootNote({ id, fallback }: { id: string; f
openNote(e)} className="relative z-10 flex flex-col">
- - {Array.isArray(contentFallback.images) && contentFallback.images.length ? ( - - ) : ( - <> - )} - {Array.isArray(contentFallback.videos) && contentFallback.videos.length ? ( - - ) : ( - <> - )} -
-
e.stopPropagation()} className="mt-5 pl-[52px]"> +
@@ -113,11 +99,7 @@ export const RootNote = memo(function RootNote({ id, fallback }: { id: string; f
openNote(e)} className="relative z-10 flex flex-col">
- - {Array.isArray(content.images) && content.images.length ? : <>} - {Array.isArray(content.videos) && content.videos.length ? : <>} -
-
e.stopPropagation()} className="mt-5 pl-[52px]"> +
diff --git a/src/app/note/pages/index.page.tsx b/src/app/note/pages/index.page.tsx index 93092189..f68c003a 100644 --- a/src/app/note/pages/index.page.tsx +++ b/src/app/note/pages/index.page.tsx @@ -1,12 +1,12 @@ 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 RepliesList from '@lume/app/note/components/replies/list'; 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'; +import { noteParser } from '@lume/utils/parser'; import { useContext } from 'react'; import useSWRSubscription from 'swr/subscription'; @@ -94,7 +94,7 @@ export function Page() { )}
- +
); diff --git a/src/app/note/components/parser.tsx b/src/utils/parser.tsx similarity index 81% rename from src/app/note/components/parser.tsx rename to src/utils/parser.tsx index c306321d..c6279b7a 100644 --- a/src/app/note/components/parser.tsx +++ b/src/utils/parser.tsx @@ -6,9 +6,10 @@ const getURLs = new RegExp( ); export const noteParser = (event: Event) => { - const content: { original: string; parsed: any; images: string[]; videos: string[] } = { + const content: { original: string; parsed: any; notes: string[]; images: string[]; videos: string[] } = { original: event.content, parsed: event.content, + notes: [], images: [], videos: [], }; @@ -31,19 +32,21 @@ export const noteParser = (event: Event) => { } }); + // extract note mention + content.original.match(/^(nostr:)?(note1|nevent1).*$/gm)?.forEach((item) => { + content.notes.push(item); + // remove url from original content + content.parsed = content.parsed.toString().replace(item, ''); + }); + // map hashtag to em content.original.match(/#(\w+)(?!:\/\/)/gi)?.forEach((item) => { content.parsed = content.parsed.replace(item, `*${item}*`); }); - // map note mention to h6 - content.original.match(/^(nostr:)?(note1|nevent1).*$/gm)?.forEach((item) => { - content.parsed = content.parsed.replace(item, `###### ${item}`); - }); - - // map profile mention to h5 + // map profile mention to h6 (markdown) content.original.match(/^(nostr:)?(nprofile1|npub1).*$/gm)?.forEach((item) => { - content.parsed = content.parsed.replace(item, `##### ${item}`); + content.parsed = content.parsed.replace(item, `###### ${item}`); }); return content;