mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-04-11 13:20:37 +02:00
use global regexp for embeds
This commit is contained in:
parent
ce550f588c
commit
6752b80c0d
@ -4,7 +4,7 @@ import { DraftNostrEvent, NostrEvent } from "../../types/nostr-event";
|
||||
|
||||
export function embedEmoji(content: EmbedableContent, note: NostrEvent | DraftNostrEvent) {
|
||||
return embedJSX(content, {
|
||||
regexp: /:([a-zA-Z0-9_]+):/i,
|
||||
regexp: /:([a-zA-Z0-9_]+):/gi,
|
||||
render: (match) => {
|
||||
const emojiTag = note.tags.find(
|
||||
(tag) => tag[0] === "emoji" && tag[1].toLowerCase() === match[1].toLowerCase() && tag[2]
|
||||
|
@ -4,7 +4,7 @@ import { InlineInvoiceCard } from "../inline-invoice-card";
|
||||
export function embedLightningInvoice(content: EmbedableContent) {
|
||||
return embedJSX(content, {
|
||||
name: "Lightning Invoice",
|
||||
regexp: /(lightning:)?(LNBC[A-Za-z0-9]+)/im,
|
||||
regexp: /(lightning:)?(LNBC[A-Za-z0-9]+)/gim,
|
||||
render: (match) => <InlineInvoiceCard paymentRequest={match[2]} />,
|
||||
});
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ export function embedNostrLinks(content: EmbedableContent) {
|
||||
export function embedNostrMentions(content: EmbedableContent, event: NostrEvent | DraftNostrEvent) {
|
||||
return embedJSX(content, {
|
||||
name: "nostr-mention",
|
||||
regexp: /#\[(\d+)\]/,
|
||||
regexp: /#\[(\d+)\]/g,
|
||||
render: (match) => {
|
||||
const index = parseInt(match[1]);
|
||||
const tag = event?.tags[index];
|
||||
|
@ -20,24 +20,43 @@ export function embedJSX(content: EmbedableContent, embed: EmbedType): Embedable
|
||||
return content
|
||||
.map((subContent, i) => {
|
||||
if (typeof subContent === "string") {
|
||||
const match = subContent.match(embed.regexp);
|
||||
const matches = subContent.matchAll(embed.regexp);
|
||||
|
||||
if (match && match.index !== undefined) {
|
||||
const { start, end } = (embed.getLocation || defaultGetLocation)(match);
|
||||
const before = subContent.slice(0, start);
|
||||
const after = subContent.slice(end, subContent.length);
|
||||
let render = embed.render(match);
|
||||
if (matches) {
|
||||
const newContent: EmbedableContent = [];
|
||||
let cursor = 0;
|
||||
let str = subContent;
|
||||
for (const match of matches) {
|
||||
if (match.index !== undefined) {
|
||||
const { start, end } = (embed.getLocation || defaultGetLocation)(match);
|
||||
|
||||
if (render === null) return subContent;
|
||||
if (start < cursor) continue;
|
||||
|
||||
if (typeof render !== "string" && !render.props.key) {
|
||||
render = cloneElement(render, { key: match[0] });
|
||||
const before = str.slice(0, start - cursor);
|
||||
const after = str.slice(end - cursor, str.length);
|
||||
let render = embed.render(match);
|
||||
if (render === null) continue;
|
||||
|
||||
if (typeof render !== "string" && !render.props.key) {
|
||||
render = cloneElement(render, { key: embed.name + match[0] });
|
||||
}
|
||||
|
||||
newContent.push(before, render);
|
||||
|
||||
cursor = end;
|
||||
str = after;
|
||||
}
|
||||
}
|
||||
|
||||
const newContent: EmbedableContent = [];
|
||||
if (before.length > 0) newContent.push(...embedJSX([before], embed));
|
||||
newContent.push(render);
|
||||
if (after.length > 0) newContent.push(...embedJSX([after], embed));
|
||||
// if all matches failed just return the existing content
|
||||
if (newContent.length === 0) {
|
||||
return subContent;
|
||||
}
|
||||
|
||||
// add the remaining string to the content
|
||||
if (str.length > 0) {
|
||||
newContent.push(str);
|
||||
}
|
||||
|
||||
return newContent;
|
||||
}
|
||||
@ -53,7 +72,7 @@ export type LinkEmbedHandler = (link: URL) => JSX.Element | string | null;
|
||||
export function embedUrls(content: EmbedableContent, handlers: LinkEmbedHandler[]) {
|
||||
return embedJSX(content, {
|
||||
name: "embedUrls",
|
||||
regexp: /https?:\/\/([a-zA-Z0-9\.\-]+\.[a-zA-Z]+)([\p{Letter}\p{Number}&\.-\/\?=#\-@%\+_,:]*)/iu,
|
||||
regexp: /https?:\/\/([a-zA-Z0-9\.\-]+\.[a-zA-Z]+)([\p{Letter}\p{Number}&\.-\/\?=#\-@%\+_,:]*)/giu,
|
||||
render: (match) => {
|
||||
try {
|
||||
const url = new URL(match[0]);
|
||||
|
@ -2,5 +2,5 @@ export const mentionNpubOrNote = /(?:\s|^)(@|nostr:)?((npub1|note1)[qpzry9x8gf2t
|
||||
export const matchImageUrls =
|
||||
/https?:\/\/([\dA-z\.-]+\.[A-z\.]{2,12})((?:\/[\+~%\/\.\w\-_]*)?\.(?:svg|gif|png|jpg|jpeg|webp|avif))(\??(?:[\?#\-\+=&;%@\.\w_]*)#?(?:[\-\.\!\/\\\w]*))?/i;
|
||||
|
||||
export const matchNostrLink = /(nostr:|@)?((npub|note|nprofile|nevent)1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]{58,})/i;
|
||||
export const matchHashtag = /(^|[^\p{L}])#([\p{L}\p{N}]+)/iu;
|
||||
export const matchNostrLink = /(nostr:|@)?((npub|note|nprofile|nevent)1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]{58,})/gi;
|
||||
export const matchHashtag = /(^|[^\p{L}])#([\p{L}\p{N}]+)/giu;
|
||||
|
@ -27,7 +27,7 @@ export const ThreadPost = ({ post, initShowReplies, focusId }: ThreadItemProps)
|
||||
{showReplyForm.isOpen && (
|
||||
<ReplyForm item={post} onCancel={showReplyForm.onClose} onSubmitted={showReplyForm.onClose} />
|
||||
)}
|
||||
<ButtonGroup variant="ghost" size="sm" alignSelf="flex-start">
|
||||
<ButtonGroup variant="link" size="sm" alignSelf="flex-start">
|
||||
{!showReplyForm.isOpen && (
|
||||
<Button onClick={showReplyForm.onOpen} leftIcon={<ReplyIcon />}>
|
||||
Write relay
|
||||
|
@ -53,7 +53,7 @@ export const Metadata = ({ name, children }: { name: string } & PropsWithChildre
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
export function RelayMetadata({ url }: { url: string }) {
|
||||
export function RelayMetadata({ url, extended }: { url: string; extended?: boolean }) {
|
||||
const { info } = useRelayInfo(url);
|
||||
|
||||
return (
|
||||
@ -62,13 +62,17 @@ export function RelayMetadata({ url }: { url: string }) {
|
||||
{info?.pubkey && (
|
||||
<Flex gap="2" alignItems="center">
|
||||
<B>Owner:</B>
|
||||
<UserAvatar pubkey={info.pubkey} size="xs" />
|
||||
<UserAvatar pubkey={info.pubkey} size="xs" noProxy />
|
||||
<UserLink pubkey={info.pubkey} />
|
||||
<UserDnsIdentityIcon pubkey={info.pubkey} onlyIcon />
|
||||
</Flex>
|
||||
)}
|
||||
<Metadata name="Software">{info?.software}</Metadata>
|
||||
<Metadata name="Version">{info?.version}</Metadata>
|
||||
{extended && (
|
||||
<>
|
||||
<Metadata name="Software">{info?.software}</Metadata>
|
||||
<Metadata name="Version">{info?.version}</Metadata>
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ function RelayPage({ relay }: { relay: string }) {
|
||||
<RelayJoinAction url={relay} />
|
||||
</ButtonGroup>
|
||||
</Flex>
|
||||
<RelayMetadata url={relay} />
|
||||
<RelayMetadata url={relay} extended />
|
||||
{info?.supported_nips && <SupportedNIPs nips={info?.supported_nips} />}
|
||||
<Tabs display="flex" flexDirection="column" flexGrow="1" isLazy colorScheme="brand">
|
||||
<TabList overflowX="auto" overflowY="hidden" flexShrink={0}>
|
||||
|
Loading…
x
Reference in New Issue
Block a user