update note parser
This commit is contained in:
@@ -1,15 +1,16 @@
|
|||||||
import CancelIcon from '@lume/shared/icons/cancel';
|
import CancelIcon from '@lume/shared/icons/cancel';
|
||||||
import PlusIcon from '@lume/shared/icons/plus';
|
import PlusIcon from '@lume/shared/icons/plus';
|
||||||
import { getNoteAuthors } from '@lume/utils/storage';
|
|
||||||
|
|
||||||
|
//import { getNoteAuthors } from '@lume/utils/storage';
|
||||||
import { Dialog, Transition } from '@headlessui/react';
|
import { Dialog, Transition } from '@headlessui/react';
|
||||||
import { Fragment, useState } from 'react';
|
import { Fragment, useState } from 'react';
|
||||||
import useSWR from 'swr';
|
|
||||||
|
|
||||||
const fetcher = () => getNoteAuthors();
|
//import useSWR from 'swr';
|
||||||
|
|
||||||
|
//const fetcher = () => getNoteAuthors();
|
||||||
|
|
||||||
export const CreateViewModal = () => {
|
export const CreateViewModal = () => {
|
||||||
const { data, error }: any = useSWR('authors', fetcher);
|
//const { data, error }: any = useSWR('authors', fetcher);
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
const closeModal = () => {
|
const closeModal = () => {
|
||||||
@@ -80,10 +81,7 @@ export const CreateViewModal = () => {
|
|||||||
</Dialog.Description>
|
</Dialog.Description>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex h-full w-full flex-col overflow-y-auto pb-5 pt-3">
|
<div className="flex h-full w-full flex-col overflow-y-auto pb-5 pt-3"></div>
|
||||||
{error && <>failed to fetch</>}
|
|
||||||
{!data ? <>loading...</> : data.map((author) => <div key={author.id}>{author.pubkey}</div>)}
|
|
||||||
</div>
|
|
||||||
</Dialog.Panel>
|
</Dialog.Panel>
|
||||||
</Transition.Child>
|
</Transition.Child>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import ImagePreview from '@lume/app/note/components/preview/image';
|
import ImagePreview from '@lume/app/note/components/preview/image';
|
||||||
import VideoPreview from '@lume/app/note/components/preview/video';
|
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 { NoteMentionUser } from '@lume/app/note/components/user/mention';
|
||||||
|
|
||||||
import ReactMarkdown from 'react-markdown';
|
import ReactMarkdown from 'react-markdown';
|
||||||
@@ -14,9 +13,7 @@ export const NoteContent = ({ content }: { content: any }) => {
|
|||||||
linkTarget="_blank"
|
linkTarget="_blank"
|
||||||
className="prose prose-zinc max-w-none select-text break-words dark:prose-invert prose-p:text-[15px] prose-p:leading-tight prose-a:text-[15px] prose-a:leading-tight prose-a:text-fuchsia-500 prose-a:no-underline hover:prose-a:text-fuchsia-600 hover:prose-a:underline prose-ol:mb-1 prose-ul:mb-1 prose-li:text-[15px] prose-li:leading-tight"
|
className="prose prose-zinc max-w-none select-text break-words dark:prose-invert prose-p:text-[15px] prose-p:leading-tight prose-a:text-[15px] prose-a:leading-tight prose-a:text-fuchsia-500 prose-a:no-underline hover:prose-a:text-fuchsia-600 hover:prose-a:underline prose-ol:mb-1 prose-ul:mb-1 prose-li:text-[15px] prose-li:leading-tight"
|
||||||
components={{
|
components={{
|
||||||
h5: ({ ...props }) => <NoteMentionUser pubkey={props.content} />,
|
em: ({ ...props }) => <NoteMentionUser {...props} />,
|
||||||
h6: ({ ...props }) => <NoteQuote id={props.content} />,
|
|
||||||
em: ({ ...props }) => <span className="text-fuchsia-500 hover:text-fuchsia-600" {...props} />,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{content.parsed}
|
{content.parsed}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { useProfile } from '@lume/utils/hooks/useProfile';
|
import { useProfile } from '@lume/utils/hooks/useProfile';
|
||||||
import { shortenKey } from '@lume/utils/shortenKey';
|
import { shortenKey } from '@lume/utils/shortenKey';
|
||||||
|
|
||||||
export const NoteMentionUser = ({ pubkey }: { pubkey: string }) => {
|
export const NoteMentionUser = (props: { children: any[] }) => {
|
||||||
|
const pubkey = props.children[0];
|
||||||
const { user } = useProfile(pubkey);
|
const { user } = useProfile(pubkey);
|
||||||
|
|
||||||
return <span className="cursor-pointer text-fuchsia-500">@{user?.username || user?.name || shortenKey(pubkey)}</span>;
|
return <span className="cursor-pointer text-fuchsia-500">@{user?.username || user?.name || shortenKey(pubkey)}</span>;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Event } from 'nostr-tools';
|
import { Event, parseReferences } from 'nostr-tools';
|
||||||
|
|
||||||
const getURLs = new RegExp(
|
const getURLs = new RegExp(
|
||||||
'(^|[ \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$_+!*();/?:~-]))',
|
'(^|[ \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$_+!*();/?:~-]))',
|
||||||
@@ -6,6 +6,7 @@ const getURLs = new RegExp(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const noteParser = (event: Event) => {
|
export const noteParser = (event: Event) => {
|
||||||
|
const references = parseReferences(event);
|
||||||
const content: { original: string; parsed: any; notes: string[]; images: string[]; videos: string[] } = {
|
const content: { original: string; parsed: any; notes: string[]; images: string[]; videos: string[] } = {
|
||||||
original: event.content,
|
original: event.content,
|
||||||
parsed: event.content,
|
parsed: event.content,
|
||||||
@@ -23,30 +24,33 @@ export const noteParser = (event: Event) => {
|
|||||||
// image url
|
// image url
|
||||||
content.images.push(url);
|
content.images.push(url);
|
||||||
// remove url from original content
|
// remove url from original content
|
||||||
content.parsed = content.parsed.toString().replace(url, '');
|
content.parsed = content.parsed.replace(url, '');
|
||||||
} else if (url.match(/\.(mp4|webm|mov)$/i)) {
|
} else if (url.match(/\.(mp4|webm|mov)$/i)) {
|
||||||
// video
|
// video
|
||||||
content.videos.push(url);
|
content.videos.push(url);
|
||||||
// remove url from original content
|
// remove url from original content
|
||||||
content.parsed = content.parsed.toString().replace(url, '');
|
content.parsed = content.parsed.replace(url, '');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 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
|
// map hashtag to em
|
||||||
content.original.match(/#(\w+)(?!:\/\/)/gi)?.forEach((item) => {
|
content.original.match(/#(\w+)(?!:\/\/)/gi)?.forEach((item) => {
|
||||||
content.parsed = content.parsed.replace(item, `*${item}*`);
|
content.parsed = content.parsed.replace(item, `[${item}](https://snort.social/search/#${item})`);
|
||||||
});
|
});
|
||||||
|
|
||||||
// map profile mention to h6 (markdown)
|
// handle nostr mention
|
||||||
content.original.match(/^(nostr:)?(nprofile1|npub1).*$/gm)?.forEach((item) => {
|
references.forEach((item) => {
|
||||||
content.parsed = content.parsed.replace(item, `###### ${item}`);
|
const profile = item.profile;
|
||||||
|
const event = item.event;
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
content.notes.push(event.id);
|
||||||
|
content.parsed = content.parsed.replace(item.text, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (profile) {
|
||||||
|
content.parsed = content.parsed.replace(item.text, `*${profile.pubkey}*`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
|
|||||||
Reference in New Issue
Block a user