diff --git a/src/pages/blog/loader.ts b/src/pages/blog/loader.ts
index aadddb0..27325be 100644
--- a/src/pages/blog/loader.ts
+++ b/src/pages/blog/loader.ts
@@ -1,8 +1,7 @@
-import { filterForEventsTaggingId, NDKFilter } from '@nostr-dev-kit/ndk'
+import { NDKFilter } from '@nostr-dev-kit/ndk'
import { NDKContextType } from 'contexts/NDKContext'
import { kinds, nip19 } from 'nostr-tools'
import { LoaderFunctionArgs, redirect } from 'react-router-dom'
-import { toast } from 'react-toastify'
import { appRoutes } from 'routes'
import { store } from 'store'
import { BlogPageLoaderResult, FilterOptions, NSFWFilter } from 'types'
@@ -16,28 +15,43 @@ import { extractBlogCardDetails, extractBlogDetails } from 'utils/blog'
export const blogRouteLoader =
(ndkContext: NDKContextType) =>
- async ({ params }: LoaderFunctionArgs) => {
+ async ({ params, request }: LoaderFunctionArgs) => {
const { naddr } = params
if (!naddr) {
log(true, LogType.Error, 'Required naddr.')
return redirect(appRoutes.blogs)
}
- // Decode author from naddr
- const decoded = nip19.decode<'naddr'>(naddr as `naddr1${string}`)
- const { pubkey } = decoded.data
+ // Decode author and identifier from naddr
+ let pubkey: string | undefined
+ let identifier: string | undefined
+ try {
+ const decoded = nip19.decode<'naddr'>(naddr as `naddr1${string}`)
+ pubkey = decoded.data.pubkey
+ identifier = decoded.data.identifier
+ } catch (error) {
+ log(true, LogType.Error, `Failed to decode naddr: ${naddr}`, error)
+ throw new Error('Failed to fetch the blog. The address might be wrong')
+ }
+
+ const userState = store.getState().user
+ const loggedInUserPubkey = userState?.user?.pubkey as string | undefined
+
+ // Check if editing and the user is the original author
+ // Redirect if NOT
+ const url = new URL(request.url)
+ const isEditMode = url.pathname.endsWith('/edit')
+ if (isEditMode && loggedInUserPubkey !== pubkey) {
+ return redirect(appRoutes.blogs)
+ }
try {
- // Get the filter with #a from naddr for the main blog content
- const filter = filterForEventsTaggingId(naddr)
- if (!filter) {
- log(true, LogType.Error, 'Unable to create filter from blog naddr.')
- return redirect(appRoutes.blogs)
+ // Set the filter for the main blog content
+ const filter = {
+ kinds: [kinds.LongFormArticle],
+ authors: [pubkey],
+ '#d': [identifier]
}
- // Update kinds to make sure we fetch correct event kind
- filter.kinds = [kinds.LongFormArticle]
-
- const userState = store.getState().user
// Get the blog filter options for latest blogs
const filterOptions = JSON.parse(
@@ -68,7 +82,7 @@ export const blogRouteLoader =
const settled = await Promise.allSettled([
ndkContext.fetchEvent(filter),
ndkContext.fetchEvents(latestModsFilter),
- ndkContext.getMuteLists(userState?.user?.pubkey as string),
+ ndkContext.getMuteLists(loggedInUserPubkey), // Pass pubkey for logged-in users
ndkContext.getNSFWList()
])
@@ -93,6 +107,12 @@ export const blogRouteLoader =
)
}
+ // Throw an error if we are missing the main blog result
+ // Handle it with the react-router's errorComponent
+ if (!result.blog) {
+ throw new Error('We are unable to find the blog on the relays')
+ }
+
// Check the lateast blog events
const fetchEventsResult = settled[1]
if (fetchEventsResult.status === 'fulfilled' && fetchEventsResult.value) {
@@ -165,13 +185,11 @@ export const blogRouteLoader =
return result
} catch (error) {
- log(
- true,
- LogType.Error,
- 'An error occurred in fetching blog details from relays',
- error
- )
- toast.error('An error occurred in fetching blog details from relays')
- return redirect(appRoutes.blogs)
+ let message = 'An error occurred in fetching blog details from relays'
+ log(true, LogType.Error, message, error)
+ if (error instanceof Error) {
+ message = error.message
+ throw new Error(message)
+ }
}
}
diff --git a/src/routes/index.tsx b/src/routes/index.tsx
index 5c14fd0..aec86c6 100644
--- a/src/routes/index.tsx
+++ b/src/routes/index.tsx
@@ -103,13 +103,15 @@ export const routerWithNdkContext = (context: NDKContextType) =>
path: appRoutes.blog,
element: ,
loader: blogRouteLoader(context),
- action: blogRouteAction(context)
+ action: blogRouteAction(context),
+ errorElement:
},
{
path: appRoutes.blogEdit,
element: ,
loader: blogRouteLoader(context),
- action: writeRouteAction(context)
+ action: writeRouteAction(context),
+ errorElement:
},
{
path: appRoutes.blogReport_actionOnly,