feat(feed): add feed outlet, note action and types
This commit is contained in:
parent
eb27eabcc6
commit
27cd22f47b
85
src/pages/feed/action.ts
Normal file
85
src/pages/feed/action.ts
Normal file
@ -0,0 +1,85 @@
|
||||
import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk'
|
||||
import { NDKContextType } from 'contexts/NDKContext'
|
||||
import { ActionFunctionArgs, redirect } from 'react-router-dom'
|
||||
import { toast } from 'react-toastify'
|
||||
import { getFeedNotePageRoute } from 'routes'
|
||||
import { store } from 'store'
|
||||
import { NoteSubmitForm, NoteSubmitFormErrors } from 'types'
|
||||
import { log, LogType, now } from 'utils'
|
||||
|
||||
export const feedPostRouteAction =
|
||||
(ndkContext: NDKContextType) =>
|
||||
async ({ request }: ActionFunctionArgs) => {
|
||||
const userState = store.getState().user
|
||||
let hexPubkey: string
|
||||
if (userState.auth && userState.user?.pubkey) {
|
||||
hexPubkey = userState.user.pubkey as string
|
||||
} else {
|
||||
try {
|
||||
hexPubkey = (await window.nostr?.getPublicKey()) as string
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
log(true, LogType.Error, 'Failed to get public key.', error)
|
||||
}
|
||||
|
||||
toast.error('Failed to get public key.')
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
if (!hexPubkey) {
|
||||
toast.error('Could not get pubkey')
|
||||
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: [],
|
||||
pubkey: hexPubkey
|
||||
})
|
||||
|
||||
try {
|
||||
await ndkEvent.generateTags()
|
||||
|
||||
if (formSubmit.nsfw) ndkEvent.tags.push(['L', 'content-warning'])
|
||||
|
||||
ndkEvent.tags.push(['L', 'source'])
|
||||
ndkEvent.tags.push(['l', window.location.host, 'source'])
|
||||
ndkEvent.tags.push(['client', 'DEG Mods'])
|
||||
|
||||
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')
|
||||
return redirect(getFeedNotePageRoute(note1))
|
||||
}
|
||||
} catch (error) {
|
||||
log(true, LogType.Error, 'Failed to publish note', error)
|
||||
toast.error('Failed to publish note')
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const validateFormData = (formSubmit: NoteSubmitForm): NoteSubmitFormErrors => {
|
||||
const errors: NoteSubmitFormErrors = {}
|
||||
|
||||
if (!formSubmit.content.trim()) {
|
||||
errors.content = 'Content is required'
|
||||
}
|
||||
|
||||
return errors
|
||||
}
|
@ -4,9 +4,12 @@ import { FeedTabBlogs } from './FeedTabBlogs'
|
||||
import { FeedTabMods } from './FeedTabMods'
|
||||
import { FeedTabPosts } from './FeedTabPosts'
|
||||
import { FeedFilter } from 'components/Filters/FeedFilter'
|
||||
import { Outlet, useParams } from 'react-router-dom'
|
||||
|
||||
export const FeedPage = () => {
|
||||
const [tab, setTab] = useState(0)
|
||||
const { note } = useParams()
|
||||
// Open posts tab if note is present
|
||||
const [tab, setTab] = useState(note ? 2 : 0)
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -17,6 +20,8 @@ export const FeedPage = () => {
|
||||
{tab === 0 && <FeedTabMods />}
|
||||
{tab === 1 && <FeedTabBlogs />}
|
||||
{tab === 2 && <FeedTabPosts />}
|
||||
|
||||
<Outlet key={note} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import { BackupPage } from 'pages/backup'
|
||||
import { SupportersPage } from 'pages/supporters'
|
||||
import { commentsLoader } from 'loaders/comment'
|
||||
import { CommentsPopup } from 'components/comment/CommentsPopup'
|
||||
import { feedPostRouteAction } from 'pages/feed/action'
|
||||
|
||||
export const appRoutes = {
|
||||
home: '/',
|
||||
@ -56,6 +57,7 @@ export const appRoutes = {
|
||||
settingsAdmin: '/settings-admin',
|
||||
profile: '/profile/:nprofile?',
|
||||
feed: '/feed',
|
||||
note: '/feed/:note',
|
||||
notifications: '/notifications',
|
||||
backup: '/backup',
|
||||
supporters: '/supporters'
|
||||
@ -76,6 +78,9 @@ export const getBlogPageRoute = (eventId: string) =>
|
||||
export const getProfilePageRoute = (nprofile: string) =>
|
||||
appRoutes.profile.replace(':nprofile', nprofile)
|
||||
|
||||
export const getFeedNotePageRoute = (note: string) =>
|
||||
appRoutes.note.replace(':note', note)
|
||||
|
||||
export const routerWithNdkContext = (context: NDKContextType) =>
|
||||
createBrowserRouter([
|
||||
{
|
||||
@ -199,7 +204,15 @@ export const routerWithNdkContext = (context: NDKContextType) =>
|
||||
{
|
||||
path: appRoutes.feed,
|
||||
element: <FeedPage />,
|
||||
loader: feedPageLoader(context)
|
||||
loader: feedPageLoader(context),
|
||||
action: feedPostRouteAction(context),
|
||||
children: [
|
||||
{
|
||||
path: ':note',
|
||||
element: <CommentsPopup />,
|
||||
loader: commentsLoader(context)
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: appRoutes.notifications,
|
||||
|
@ -8,3 +8,4 @@ export * from './category'
|
||||
export * from './popup'
|
||||
export * from './errors'
|
||||
export * from './comments'
|
||||
export * from './note'
|
||||
|
6
src/types/note.ts
Normal file
6
src/types/note.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export interface NoteSubmitForm {
|
||||
content: string
|
||||
nsfw: boolean
|
||||
}
|
||||
|
||||
export interface NoteSubmitFormErrors extends Partial<NoteSubmitForm> {}
|
Loading…
x
Reference in New Issue
Block a user