feat(notes): finalize repost action

This commit is contained in:
en 2025-02-19 21:22:56 +01:00
parent f73a4277b3
commit 9c153e4a18
4 changed files with 108 additions and 36 deletions

View File

@ -18,7 +18,7 @@ import {
import { useComments } from 'hooks/useComments' import { useComments } from 'hooks/useComments'
import { nip19 } from 'nostr-tools' import { nip19 } from 'nostr-tools'
import { useState } from 'react' import { useState } from 'react'
import { Link } from 'react-router-dom' import { Link, useSubmit } from 'react-router-dom'
import { appRoutes, getProfilePageRoute } from 'routes' import { appRoutes, getProfilePageRoute } from 'routes'
import { FeedPostsFilter, NSFWFilter, UserProfile } from 'types' import { FeedPostsFilter, NSFWFilter, UserProfile } from 'types'
import { DEFAULT_FILTER_OPTIONS, hexToNpub, log, LogType } from 'utils' import { DEFAULT_FILTER_OPTIONS, hexToNpub, log, LogType } from 'utils'
@ -32,6 +32,7 @@ interface NoteProps {
export const Note = ({ ndkEvent }: NoteProps) => { export const Note = ({ ndkEvent }: NoteProps) => {
const { ndk } = useNDKContext() const { ndk } = useNDKContext()
const submit = useSubmit()
const userState = useAppSelector((state) => state.user) const userState = useAppSelector((state) => state.user)
const userPubkey = userState.user?.pubkey as string | undefined const userPubkey = userState.user?.pubkey as string | undefined
const [eventProfile, setEventProfile] = useState<UserProfile>() const [eventProfile, setEventProfile] = useState<UserProfile>()
@ -172,7 +173,18 @@ export const Note = ({ ndkEvent }: NoteProps) => {
if (!confirm) return if (!confirm) return
const repostNdkEvent = await ndkEvent.repost(false) const repostNdkEvent = await ndkEvent.repost(false)
await repostNdkEvent.sign() const rawEvent = repostNdkEvent.rawEvent()
submit(
JSON.stringify({
intent: 'repost',
note1: ndkEvent.encode(),
data: rawEvent
}),
{
method: 'post',
encType: 'application/json'
}
)
} }
// Is this user's repost? // Is this user's repost?

View File

@ -55,8 +55,11 @@ export const NoteSubmit = ({
const handleFormSubmit = async (event: React.FormEvent<HTMLFormElement>) => { const handleFormSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault() event.preventDefault()
const formSubmit = { const formSubmit = {
content, intent: 'submit',
nsfw data: {
content,
nsfw
}
} }
// Reset form // Reset form

View File

@ -1,10 +1,10 @@
import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk' import NDK, { NDKEvent, NDKKind, NostrEvent } from '@nostr-dev-kit/ndk'
import { NDKContextType } from 'contexts/NDKContext' import { NDKContextType } from 'contexts/NDKContext'
import { ActionFunctionArgs, redirect } from 'react-router-dom' import { ActionFunctionArgs, redirect } from 'react-router-dom'
import { toast } from 'react-toastify' import { toast } from 'react-toastify'
import { getFeedNotePageRoute } from 'routes' import { getFeedNotePageRoute } from 'routes'
import { store } from 'store' import { store } from 'store'
import { NoteSubmitForm, NoteSubmitFormErrors } from 'types' import { NoteAction, NoteSubmitForm, NoteSubmitFormErrors } from 'types'
import { import {
log, log,
LogType, LogType,
@ -38,38 +38,25 @@ export const feedPostRouteAction =
return null return null
} }
const formSubmit = (await request.json()) as NoteSubmitForm
const formErrors = validateFormData(formSubmit)
if (Object.keys(formErrors).length) return formErrors
const content = decodeURIComponent(formSubmit.content!)
const currentTimeStamp = now()
const ndkEvent = new NDKEvent(ndkContext.ndk, {
kind: NDKKind.Text,
created_at: currentTimeStamp,
content: content,
tags: [
['L', 'source'],
['l', window.location.host, 'source']
],
pubkey: hexPubkey
})
try { try {
if (formSubmit.nsfw) ndkEvent.tags.push(['L', 'content-warning']) const action = (await request.json()) as NoteAction
switch (action.intent) {
case 'submit':
return await handleActionSubmit(
ndkContext.ndk,
action.data,
hexPubkey
)
await ndkEvent.sign() case 'repost':
const note1 = ndkEvent.encode() return await handleActionRepost(
const publishedOnRelays = await ndkEvent.publish() ndkContext.ndk,
if (publishedOnRelays.size === 0) { action.data,
toast.error('Failed to publish note on any relay') action.note1
return null )
} else {
toast.success('Note published successfully') default:
removeLocalStorageItem(NOTE_DRAFT_CACHE_KEY) throw new Error('Unsupported feed action. Intent missing.')
return redirect(getFeedNotePageRoute(note1))
} }
} catch (error) { } catch (error) {
log(true, LogType.Error, 'Failed to publish note', error) log(true, LogType.Error, 'Failed to publish note', error)
@ -87,3 +74,60 @@ const validateFormData = (formSubmit: NoteSubmitForm): NoteSubmitFormErrors => {
return errors return errors
} }
async function handleActionSubmit(
ndk: NDK,
data: NoteSubmitForm,
pubkey: string
) {
const formErrors = validateFormData(data)
if (Object.keys(formErrors).length) return formErrors
const content = decodeURIComponent(data.content!)
const currentTimeStamp = now()
const ndkEvent = new NDKEvent(ndk, {
kind: NDKKind.Text,
created_at: currentTimeStamp,
content: content,
tags: [
['L', 'source'],
['l', window.location.host, 'source']
],
pubkey
})
try {
if (data.nsfw) ndkEvent.tags.push(['L', 'content-warning'])
await ndkEvent.sign()
const note1 = ndkEvent.encode()
const publishedOnRelays = await ndkEvent.publish()
if (publishedOnRelays.size === 0) {
toast.error('Failed to publish note on any relay')
return null
} else {
toast.success('Note published successfully')
removeLocalStorageItem(NOTE_DRAFT_CACHE_KEY)
return redirect(getFeedNotePageRoute(note1))
}
} catch (error) {
log(true, LogType.Error, 'Failed to publish note', error)
toast.error('Failed to publish note')
return null
}
}
async function handleActionRepost(ndk: NDK, data: NostrEvent, note1: string) {
const ndkEvent = new NDKEvent(ndk, data)
await ndkEvent.sign()
const publishedOnRelays = await ndkEvent.publish()
if (publishedOnRelays.size === 0) {
toast.error('Failed to publish note on any relay')
return null
} else {
toast.success('Note published successfully')
return redirect(getFeedNotePageRoute(note1))
}
}

View File

@ -1,6 +1,19 @@
import { NostrEvent } from '@nostr-dev-kit/ndk'
export interface NoteSubmitForm { export interface NoteSubmitForm {
content: string content: string
nsfw: boolean nsfw: boolean
} }
export interface NoteSubmitFormErrors extends Partial<NoteSubmitForm> {} export interface NoteSubmitFormErrors extends Partial<NoteSubmitForm> {}
export type NoteAction =
| {
intent: 'submit'
data: NoteSubmitForm
}
| {
intent: 'repost'
note1: string
data: NostrEvent
}