feat: automatically add nostr: prefix to nip19 stuff
This commit is contained in:
@@ -13,6 +13,7 @@ import PostOptions from './PostOptions'
|
|||||||
import Preview from './Preview'
|
import Preview from './Preview'
|
||||||
import SendOnlyToSwitch from './SendOnlyToSwitch'
|
import SendOnlyToSwitch from './SendOnlyToSwitch'
|
||||||
import Uploader from './Uploader'
|
import Uploader from './Uploader'
|
||||||
|
import { preprocessContent } from './utils'
|
||||||
|
|
||||||
export default function NormalPostContent({
|
export default function NormalPostContent({
|
||||||
defaultContent = '',
|
defaultContent = '',
|
||||||
@@ -27,6 +28,7 @@ export default function NormalPostContent({
|
|||||||
const { toast } = useToast()
|
const { toast } = useToast()
|
||||||
const { publish, checkLogin } = useNostr()
|
const { publish, checkLogin } = useNostr()
|
||||||
const [content, setContent] = useState('')
|
const [content, setContent] = useState('')
|
||||||
|
const [processedContent, setProcessedContent] = useState('')
|
||||||
const [pictureInfos, setPictureInfos] = useState<{ url: string; tags: string[][] }[]>([])
|
const [pictureInfos, setPictureInfos] = useState<{ url: string; tags: string[][] }[]>([])
|
||||||
const [posting, setPosting] = useState(false)
|
const [posting, setPosting] = useState(false)
|
||||||
const [showMoreOptions, setShowMoreOptions] = useState(false)
|
const [showMoreOptions, setShowMoreOptions] = useState(false)
|
||||||
@@ -39,9 +41,10 @@ export default function NormalPostContent({
|
|||||||
const canPost = !!content && !posting
|
const canPost = !!content && !posting
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const cachedContent = postContentCache.getNormalPostCache({ defaultContent, parentEvent })
|
const cached = postContentCache.getNormalPostCache({ defaultContent, parentEvent })
|
||||||
if (cachedContent) {
|
if (cached) {
|
||||||
setContent(cachedContent)
|
setContent(cached.content || '')
|
||||||
|
setPictureInfos(cached.pictureInfos || [])
|
||||||
}
|
}
|
||||||
if (defaultContent) {
|
if (defaultContent) {
|
||||||
setCursorOffset(defaultContent.length)
|
setCursorOffset(defaultContent.length)
|
||||||
@@ -52,9 +55,10 @@ export default function NormalPostContent({
|
|||||||
}, [defaultContent, parentEvent])
|
}, [defaultContent, parentEvent])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setProcessedContent(preprocessContent(content))
|
||||||
if (!initializedRef.current) return
|
if (!initializedRef.current) return
|
||||||
postContentCache.setNormalPostCache({ defaultContent, parentEvent }, content)
|
postContentCache.setNormalPostCache({ defaultContent, parentEvent }, content, pictureInfos)
|
||||||
}, [content])
|
}, [content, pictureInfos])
|
||||||
|
|
||||||
const post = async (e: React.MouseEvent) => {
|
const post = async (e: React.MouseEvent) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
@@ -68,11 +72,11 @@ export default function NormalPostContent({
|
|||||||
try {
|
try {
|
||||||
const draftEvent =
|
const draftEvent =
|
||||||
parentEvent && parentEvent.kind !== kinds.ShortTextNote
|
parentEvent && parentEvent.kind !== kinds.ShortTextNote
|
||||||
? await createCommentDraftEvent(content, parentEvent, pictureInfos, mentions, {
|
? await createCommentDraftEvent(processedContent, parentEvent, pictureInfos, mentions, {
|
||||||
addClientTag,
|
addClientTag,
|
||||||
protectedEvent: !!specifiedRelayUrls
|
protectedEvent: !!specifiedRelayUrls
|
||||||
})
|
})
|
||||||
: await createShortTextNoteDraftEvent(content, pictureInfos, mentions, {
|
: await createShortTextNoteDraftEvent(processedContent, pictureInfos, mentions, {
|
||||||
parentEvent,
|
parentEvent,
|
||||||
addClientTag,
|
addClientTag,
|
||||||
protectedEvent: !!specifiedRelayUrls
|
protectedEvent: !!specifiedRelayUrls
|
||||||
@@ -117,7 +121,7 @@ export default function NormalPostContent({
|
|||||||
placeholder={t('Write something...')}
|
placeholder={t('Write something...')}
|
||||||
cursorOffset={cursorOffset}
|
cursorOffset={cursorOffset}
|
||||||
/>
|
/>
|
||||||
{content && <Preview content={content} />}
|
{processedContent && <Preview content={processedContent} />}
|
||||||
<SendOnlyToSwitch
|
<SendOnlyToSwitch
|
||||||
parentEvent={parentEvent}
|
parentEvent={parentEvent}
|
||||||
specifiedRelayUrls={specifiedRelayUrls}
|
specifiedRelayUrls={specifiedRelayUrls}
|
||||||
@@ -150,7 +154,7 @@ export default function NormalPostContent({
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex gap-2 items-center">
|
<div className="flex gap-2 items-center">
|
||||||
<Mentions
|
<Mentions
|
||||||
content={content}
|
content={processedContent}
|
||||||
parentEvent={parentEvent}
|
parentEvent={parentEvent}
|
||||||
mentions={mentions}
|
mentions={mentions}
|
||||||
setMentions={setMentions}
|
setMentions={setMentions}
|
||||||
|
|||||||
@@ -13,12 +13,14 @@ import Mentions from './Mentions'
|
|||||||
import PostOptions from './PostOptions'
|
import PostOptions from './PostOptions'
|
||||||
import SendOnlyToSwitch from './SendOnlyToSwitch'
|
import SendOnlyToSwitch from './SendOnlyToSwitch'
|
||||||
import Uploader from './Uploader'
|
import Uploader from './Uploader'
|
||||||
|
import { preprocessContent } from './utils'
|
||||||
|
|
||||||
export default function PicturePostContent({ close }: { close: () => void }) {
|
export default function PicturePostContent({ close }: { close: () => void }) {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { toast } = useToast()
|
const { toast } = useToast()
|
||||||
const { publish, checkLogin } = useNostr()
|
const { publish, checkLogin } = useNostr()
|
||||||
const [content, setContent] = useState('')
|
const [content, setContent] = useState('')
|
||||||
|
const [processedContent, setProcessedContent] = useState('')
|
||||||
const [pictureInfos, setPictureInfos] = useState<{ url: string; tags: string[][] }[]>([])
|
const [pictureInfos, setPictureInfos] = useState<{ url: string; tags: string[][] }[]>([])
|
||||||
const [posting, setPosting] = useState(false)
|
const [posting, setPosting] = useState(false)
|
||||||
const [showMoreOptions, setShowMoreOptions] = useState(false)
|
const [showMoreOptions, setShowMoreOptions] = useState(false)
|
||||||
@@ -38,6 +40,7 @@ export default function PicturePostContent({ close }: { close: () => void }) {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setProcessedContent(preprocessContent(content))
|
||||||
if (!initializedRef.current) return
|
if (!initializedRef.current) return
|
||||||
postContentCache.setPicturePostCache(content, pictureInfos)
|
postContentCache.setPicturePostCache(content, pictureInfos)
|
||||||
}, [content, pictureInfos])
|
}, [content, pictureInfos])
|
||||||
@@ -55,10 +58,15 @@ export default function PicturePostContent({ close }: { close: () => void }) {
|
|||||||
if (!pictureInfos.length) {
|
if (!pictureInfos.length) {
|
||||||
throw new Error(t('Picture note requires images'))
|
throw new Error(t('Picture note requires images'))
|
||||||
}
|
}
|
||||||
const draftEvent = await createPictureNoteDraftEvent(content, pictureInfos, mentions, {
|
const draftEvent = await createPictureNoteDraftEvent(
|
||||||
addClientTag,
|
processedContent,
|
||||||
protectedEvent: !!specifiedRelayUrls
|
pictureInfos,
|
||||||
})
|
mentions,
|
||||||
|
{
|
||||||
|
addClientTag,
|
||||||
|
protectedEvent: !!specifiedRelayUrls
|
||||||
|
}
|
||||||
|
)
|
||||||
await publish(draftEvent, { specifiedRelayUrls })
|
await publish(draftEvent, { specifiedRelayUrls })
|
||||||
setContent('')
|
setContent('')
|
||||||
setPictureInfos([])
|
setPictureInfos([])
|
||||||
@@ -117,7 +125,7 @@ export default function PicturePostContent({ close }: { close: () => void }) {
|
|||||||
<ChevronDown className={`transition-transform ${showMoreOptions ? 'rotate-180' : ''}`} />
|
<ChevronDown className={`transition-transform ${showMoreOptions ? 'rotate-180' : ''}`} />
|
||||||
</Button>
|
</Button>
|
||||||
<div className="flex gap-2 items-center">
|
<div className="flex gap-2 items-center">
|
||||||
<Mentions content={content} mentions={mentions} setMentions={setMentions} />
|
<Mentions content={processedContent} mentions={mentions} setMentions={setMentions} />
|
||||||
<div className="flex gap-2 items-center max-sm:hidden">
|
<div className="flex gap-2 items-center max-sm:hidden">
|
||||||
<Button
|
<Button
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
|
|||||||
6
src/components/PostEditor/utils.ts
Normal file
6
src/components/PostEditor/utils.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export function preprocessContent(content: string) {
|
||||||
|
const regex = /(?<=^|\s)(nevent|naddr|nprofile|npub)[a-zA-Z0-9]+/g
|
||||||
|
return content.replace(regex, (match) => {
|
||||||
|
return `nostr:${match}`
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -3,7 +3,13 @@ import { Event } from 'nostr-tools'
|
|||||||
class PostContentCacheService {
|
class PostContentCacheService {
|
||||||
static instance: PostContentCacheService
|
static instance: PostContentCacheService
|
||||||
|
|
||||||
private normalPostCache: Map<string, string> = new Map()
|
private normalPostCache: Map<
|
||||||
|
string,
|
||||||
|
{
|
||||||
|
content: string
|
||||||
|
pictureInfos: { url: string; tags: string[][] }[]
|
||||||
|
}
|
||||||
|
> = new Map()
|
||||||
private picturePostCache: {
|
private picturePostCache: {
|
||||||
content: string
|
content: string
|
||||||
pictureInfos: { url: string; tags: string[][] }[]
|
pictureInfos: { url: string; tags: string[][] }[]
|
||||||
@@ -21,15 +27,22 @@ class PostContentCacheService {
|
|||||||
parentEvent
|
parentEvent
|
||||||
}: { defaultContent?: string; parentEvent?: Event } = {}) {
|
}: { defaultContent?: string; parentEvent?: Event } = {}) {
|
||||||
return (
|
return (
|
||||||
this.normalPostCache.get(this.generateCacheKey(defaultContent, parentEvent)) ?? defaultContent
|
this.normalPostCache.get(this.generateCacheKey(defaultContent, parentEvent)) ?? {
|
||||||
|
content: defaultContent,
|
||||||
|
pictureInfos: [] as { url: string; tags: string[][] }[]
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
setNormalPostCache(
|
setNormalPostCache(
|
||||||
{ defaultContent, parentEvent }: { defaultContent?: string; parentEvent?: Event },
|
{ defaultContent, parentEvent }: { defaultContent?: string; parentEvent?: Event },
|
||||||
content: string
|
content: string,
|
||||||
|
pictureInfos: { url: string; tags: string[][] }[]
|
||||||
) {
|
) {
|
||||||
this.normalPostCache.set(this.generateCacheKey(defaultContent, parentEvent), content)
|
this.normalPostCache.set(this.generateCacheKey(defaultContent, parentEvent), {
|
||||||
|
content,
|
||||||
|
pictureInfos
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getPicturePostCache() {
|
getPicturePostCache() {
|
||||||
|
|||||||
Reference in New Issue
Block a user