2024-11-06 17:33:15 +01:00
|
|
|
import { NDKContextType } from 'contexts/NDKContext'
|
|
|
|
import { nip19 } from 'nostr-tools'
|
|
|
|
import { LoaderFunctionArgs, redirect } from 'react-router-dom'
|
|
|
|
import { appRoutes, getProfilePageRoute } from 'routes'
|
|
|
|
import { store } from 'store'
|
2024-11-07 17:33:59 +01:00
|
|
|
import { MuteLists, UserProfile } from 'types'
|
2024-11-06 17:33:15 +01:00
|
|
|
import { log, LogType } from 'utils'
|
|
|
|
|
|
|
|
export interface ProfilePageLoaderResult {
|
|
|
|
profile: UserProfile
|
|
|
|
isBlocked: boolean
|
|
|
|
isOwnProfile: boolean
|
2024-11-07 17:33:59 +01:00
|
|
|
muteLists: {
|
|
|
|
admin: MuteLists
|
|
|
|
user: MuteLists
|
|
|
|
}
|
|
|
|
nsfwList: string[]
|
2024-11-06 17:33:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
export const profileRouteLoader =
|
|
|
|
(ndkContext: NDKContextType) =>
|
|
|
|
async ({ params }: LoaderFunctionArgs) => {
|
|
|
|
// Try to decode nprofile parameter
|
|
|
|
const { nprofile } = params
|
|
|
|
let profilePubkey: string | undefined
|
|
|
|
try {
|
|
|
|
const value = nprofile
|
|
|
|
? nip19.decode(nprofile as `nprofile1${string}`)
|
|
|
|
: undefined
|
|
|
|
profilePubkey = value?.data.pubkey
|
|
|
|
} catch (error) {
|
|
|
|
// Silently ignore and redirect to home or logged in user
|
|
|
|
log(true, LogType.Error, 'Failed to decode nprofile.', error)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the current state
|
|
|
|
const userState = store.getState().user
|
|
|
|
|
2024-11-07 17:33:59 +01:00
|
|
|
// Check if current user is logged in
|
|
|
|
let userPubkey: string | undefined
|
|
|
|
if (userState.auth && userState.user?.pubkey) {
|
|
|
|
userPubkey = userState.user.pubkey as string
|
2024-11-06 17:33:15 +01:00
|
|
|
}
|
|
|
|
|
2024-11-07 17:33:59 +01:00
|
|
|
// Redirect if profile naddr is missing
|
|
|
|
// - home if user is not logged
|
|
|
|
let profileRoute = appRoutes.home
|
|
|
|
if (!profilePubkey && userPubkey) {
|
|
|
|
// - own profile
|
|
|
|
profileRoute = getProfilePageRoute(
|
|
|
|
nip19.nprofileEncode({
|
|
|
|
pubkey: userPubkey
|
|
|
|
})
|
|
|
|
)
|
|
|
|
}
|
2024-11-06 17:33:15 +01:00
|
|
|
if (!profilePubkey) return redirect(profileRoute)
|
|
|
|
|
2024-11-07 17:33:59 +01:00
|
|
|
// Empty result
|
2024-11-06 17:33:15 +01:00
|
|
|
const result: ProfilePageLoaderResult = {
|
|
|
|
profile: {},
|
|
|
|
isBlocked: false,
|
2024-11-07 17:33:59 +01:00
|
|
|
isOwnProfile: false,
|
|
|
|
muteLists: {
|
|
|
|
admin: {
|
|
|
|
authors: [],
|
|
|
|
replaceableEvents: []
|
|
|
|
},
|
|
|
|
user: {
|
|
|
|
authors: [],
|
|
|
|
replaceableEvents: []
|
|
|
|
}
|
|
|
|
},
|
|
|
|
nsfwList: []
|
2024-11-06 17:33:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check if user the user is logged in
|
|
|
|
if (userState.auth && userState.user?.pubkey) {
|
|
|
|
result.isOwnProfile = userState.user.pubkey === profilePubkey
|
2024-11-07 17:33:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const settled = await Promise.allSettled([
|
|
|
|
ndkContext.findMetadata(profilePubkey),
|
|
|
|
ndkContext.getMuteLists(userPubkey),
|
|
|
|
ndkContext.getNSFWList()
|
|
|
|
])
|
|
|
|
|
|
|
|
// Check the profile event result
|
|
|
|
const profileEventResult = settled[0]
|
|
|
|
if (profileEventResult.status === 'fulfilled' && profileEventResult.value) {
|
|
|
|
result.profile = profileEventResult.value
|
|
|
|
} else if (profileEventResult.status === 'rejected') {
|
|
|
|
log(
|
|
|
|
true,
|
|
|
|
LogType.Error,
|
|
|
|
'Failed to fetch profile.',
|
|
|
|
profileEventResult.reason
|
|
|
|
)
|
|
|
|
}
|
2024-11-06 17:33:15 +01:00
|
|
|
|
2024-11-07 17:33:59 +01:00
|
|
|
// Check the profile event result
|
|
|
|
const muteListResult = settled[1]
|
|
|
|
if (muteListResult.status === 'fulfilled' && muteListResult.value) {
|
|
|
|
result.muteLists = muteListResult.value
|
2024-11-06 17:33:15 +01:00
|
|
|
|
|
|
|
// Check if user has blocked this profile
|
2024-11-07 17:33:59 +01:00
|
|
|
result.isBlocked = result.muteLists.user.authors.includes(profilePubkey)
|
|
|
|
} else if (muteListResult.status === 'rejected') {
|
|
|
|
log(
|
|
|
|
true,
|
|
|
|
LogType.Error,
|
|
|
|
'Failed to fetch mutelist.',
|
|
|
|
muteListResult.reason
|
2024-11-06 17:33:15 +01:00
|
|
|
)
|
2024-11-07 17:33:59 +01:00
|
|
|
}
|
2024-11-06 17:33:15 +01:00
|
|
|
|
2024-11-07 17:33:59 +01:00
|
|
|
// Check the profile event result
|
|
|
|
const nsfwListResult = settled[2]
|
|
|
|
if (nsfwListResult.status === 'fulfilled' && nsfwListResult.value) {
|
|
|
|
result.nsfwList = nsfwListResult.value
|
|
|
|
} else if (nsfwListResult.status === 'rejected') {
|
|
|
|
log(
|
|
|
|
true,
|
|
|
|
LogType.Error,
|
|
|
|
'Failed to fetch mutelist.',
|
|
|
|
nsfwListResult.reason
|
|
|
|
)
|
2024-11-06 17:33:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|