Browse Source

feat: automatically add nostr: prefix to nip19 stuff

imwald
codytseng 1 year ago
parent
commit
eb15544195
  1. 22
      src/components/PostEditor/NormalPostContent.tsx
  2. 18
      src/components/PostEditor/PicturePostContent.tsx
  3. 6
      src/components/PostEditor/utils.ts
  4. 21
      src/services/post-content-cache.service.ts

22
src/components/PostEditor/NormalPostContent.tsx

@ -13,6 +13,7 @@ import PostOptions from './PostOptions' @@ -13,6 +13,7 @@ import PostOptions from './PostOptions'
import Preview from './Preview'
import SendOnlyToSwitch from './SendOnlyToSwitch'
import Uploader from './Uploader'
import { preprocessContent } from './utils'
export default function NormalPostContent({
defaultContent = '',
@ -27,6 +28,7 @@ export default function NormalPostContent({ @@ -27,6 +28,7 @@ export default function NormalPostContent({
const { toast } = useToast()
const { publish, checkLogin } = useNostr()
const [content, setContent] = useState('')
const [processedContent, setProcessedContent] = useState('')
const [pictureInfos, setPictureInfos] = useState<{ url: string; tags: string[][] }[]>([])
const [posting, setPosting] = useState(false)
const [showMoreOptions, setShowMoreOptions] = useState(false)
@ -39,9 +41,10 @@ export default function NormalPostContent({ @@ -39,9 +41,10 @@ export default function NormalPostContent({
const canPost = !!content && !posting
useEffect(() => {
const cachedContent = postContentCache.getNormalPostCache({ defaultContent, parentEvent })
if (cachedContent) {
setContent(cachedContent)
const cached = postContentCache.getNormalPostCache({ defaultContent, parentEvent })
if (cached) {
setContent(cached.content || '')
setPictureInfos(cached.pictureInfos || [])
}
if (defaultContent) {
setCursorOffset(defaultContent.length)
@ -52,9 +55,10 @@ export default function NormalPostContent({ @@ -52,9 +55,10 @@ export default function NormalPostContent({
}, [defaultContent, parentEvent])
useEffect(() => {
setProcessedContent(preprocessContent(content))
if (!initializedRef.current) return
postContentCache.setNormalPostCache({ defaultContent, parentEvent }, content)
}, [content])
postContentCache.setNormalPostCache({ defaultContent, parentEvent }, content, pictureInfos)
}, [content, pictureInfos])
const post = async (e: React.MouseEvent) => {
e.stopPropagation()
@ -68,11 +72,11 @@ export default function NormalPostContent({ @@ -68,11 +72,11 @@ export default function NormalPostContent({
try {
const draftEvent =
parentEvent && parentEvent.kind !== kinds.ShortTextNote
? await createCommentDraftEvent(content, parentEvent, pictureInfos, mentions, {
? await createCommentDraftEvent(processedContent, parentEvent, pictureInfos, mentions, {
addClientTag,
protectedEvent: !!specifiedRelayUrls
})
: await createShortTextNoteDraftEvent(content, pictureInfos, mentions, {
: await createShortTextNoteDraftEvent(processedContent, pictureInfos, mentions, {
parentEvent,
addClientTag,
protectedEvent: !!specifiedRelayUrls
@ -117,7 +121,7 @@ export default function NormalPostContent({ @@ -117,7 +121,7 @@ export default function NormalPostContent({
placeholder={t('Write something...')}
cursorOffset={cursorOffset}
/>
{content && <Preview content={content} />}
{processedContent && <Preview content={processedContent} />}
<SendOnlyToSwitch
parentEvent={parentEvent}
specifiedRelayUrls={specifiedRelayUrls}
@ -150,7 +154,7 @@ export default function NormalPostContent({ @@ -150,7 +154,7 @@ export default function NormalPostContent({
</div>
<div className="flex gap-2 items-center">
<Mentions
content={content}
content={processedContent}
parentEvent={parentEvent}
mentions={mentions}
setMentions={setMentions}

18
src/components/PostEditor/PicturePostContent.tsx

@ -13,12 +13,14 @@ import Mentions from './Mentions' @@ -13,12 +13,14 @@ import Mentions from './Mentions'
import PostOptions from './PostOptions'
import SendOnlyToSwitch from './SendOnlyToSwitch'
import Uploader from './Uploader'
import { preprocessContent } from './utils'
export default function PicturePostContent({ close }: { close: () => void }) {
const { t } = useTranslation()
const { toast } = useToast()
const { publish, checkLogin } = useNostr()
const [content, setContent] = useState('')
const [processedContent, setProcessedContent] = useState('')
const [pictureInfos, setPictureInfos] = useState<{ url: string; tags: string[][] }[]>([])
const [posting, setPosting] = useState(false)
const [showMoreOptions, setShowMoreOptions] = useState(false)
@ -38,6 +40,7 @@ export default function PicturePostContent({ close }: { close: () => void }) { @@ -38,6 +40,7 @@ export default function PicturePostContent({ close }: { close: () => void }) {
}, [])
useEffect(() => {
setProcessedContent(preprocessContent(content))
if (!initializedRef.current) return
postContentCache.setPicturePostCache(content, pictureInfos)
}, [content, pictureInfos])
@ -55,10 +58,15 @@ export default function PicturePostContent({ close }: { close: () => void }) { @@ -55,10 +58,15 @@ export default function PicturePostContent({ close }: { close: () => void }) {
if (!pictureInfos.length) {
throw new Error(t('Picture note requires images'))
}
const draftEvent = await createPictureNoteDraftEvent(content, pictureInfos, mentions, {
addClientTag,
protectedEvent: !!specifiedRelayUrls
})
const draftEvent = await createPictureNoteDraftEvent(
processedContent,
pictureInfos,
mentions,
{
addClientTag,
protectedEvent: !!specifiedRelayUrls
}
)
await publish(draftEvent, { specifiedRelayUrls })
setContent('')
setPictureInfos([])
@ -117,7 +125,7 @@ export default function PicturePostContent({ close }: { close: () => void }) { @@ -117,7 +125,7 @@ export default function PicturePostContent({ close }: { close: () => void }) {
<ChevronDown className={`transition-transform ${showMoreOptions ? 'rotate-180' : ''}`} />
</Button>
<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">
<Button
variant="secondary"

6
src/components/PostEditor/utils.ts

@ -0,0 +1,6 @@ @@ -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}`
})
}

21
src/services/post-content-cache.service.ts

@ -3,7 +3,13 @@ import { Event } from 'nostr-tools' @@ -3,7 +3,13 @@ import { Event } from 'nostr-tools'
class 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: {
content: string
pictureInfos: { url: string; tags: string[][] }[]
@ -21,15 +27,22 @@ class PostContentCacheService { @@ -21,15 +27,22 @@ class PostContentCacheService {
parentEvent
}: { defaultContent?: string; parentEvent?: Event } = {}) {
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(
{ 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() {

Loading…
Cancel
Save