refactor: standardize applesauce helpers for npub/nprofile detection

Replace manual type checking and pubkey extraction with getPubkeyFromDecodeResult helper:
- Update getNostrUriLabel to use helper instead of manual npub/nprofile cases
- Update replaceNostrUrisInMarkdownWithProfileLabels to use helper
- Update addLoadingClassToProfileLinks to use helper
- Simplify NostrMentionLink by removing redundant type checks
- Update Bookmarks.tsx to use helper for profile pubkey extraction

This eliminates duplicate logic and ensures consistent handling of npub/nprofile
across the codebase using applesauce helpers.
This commit is contained in:
Gigi
2025-11-02 23:42:59 +01:00
parent 66de230f66
commit d4b78d9484
3 changed files with 27 additions and 39 deletions

View File

@@ -2,8 +2,11 @@ import React, { useMemo, useEffect, useRef } from 'react'
import { useParams, useLocation, useNavigate } from 'react-router-dom'
import { Hooks } from 'applesauce-react'
import { useEventStore } from 'applesauce-react/hooks'
import { Helpers } from 'applesauce-core'
import { RelayPool } from 'applesauce-relay'
import { nip19 } from 'nostr-tools'
const { getPubkeyFromDecodeResult } = Helpers
import { useSettings } from '../hooks/useSettings'
import { useArticleLoader } from '../hooks/useArticleLoader'
import { useExternalUrlLoader } from '../hooks/useExternalUrlLoader'
@@ -79,16 +82,12 @@ const Bookmarks: React.FC<BookmarksProps> = ({
// Extract tab from profile routes
const profileTab = location.pathname.endsWith('/writings') ? 'writings' : 'highlights'
// Decode npub or nprofile to pubkey for profile view
// Decode npub or nprofile to pubkey for profile view using applesauce helper
let profilePubkey: string | undefined
if (npub && showProfile) {
try {
const decoded = nip19.decode(npub)
if (decoded.type === 'npub') {
profilePubkey = decoded.data
} else if (decoded.type === 'nprofile') {
profilePubkey = decoded.data.pubkey
}
profilePubkey = getPubkeyFromDecodeResult(decoded)
} catch (err) {
console.error('Failed to decode npub/nprofile:', err)
}

View File

@@ -47,8 +47,8 @@ const NostrMentionLink: React.FC<NostrMentionLinkProps> = ({
}, [pubkey, eventStore])
// Show loading if profile doesn't exist and not in cache/store (for npub/nprofile)
const isLoading = !profile && pubkey && !isInCacheOrStore &&
decoded && (decoded.type === 'npub' || decoded.type === 'nprofile')
// pubkey will be undefined for non-profile types, so no need for explicit type check
const isLoading = !profile && pubkey && !isInCacheOrStore
// If decoding failed, show shortened identifier
if (!decoded) {
@@ -78,15 +78,12 @@ const NostrMentionLink: React.FC<NostrMentionLinkProps> = ({
}
// Render based on decoded type
// If we have a pubkey (from npub/nprofile), render profile link directly
if (pubkey) {
return renderProfileLink(pubkey)
}
switch (decoded.type) {
case 'npub': {
const pk = decoded.data
return renderProfileLink(pk)
}
case 'nprofile': {
const { pubkey: pk } = decoded.data
return renderProfileLink(pk)
}
case 'naddr': {
const { kind, pubkey: pk, identifier: addrIdentifier } = decoded.data
// Check if it's a blog post (kind:30023)

View File

@@ -2,7 +2,9 @@ import { decode, npubEncode, noteEncode } from 'nostr-tools/nip19'
import { getNostrUrl } from '../config/nostrGateways'
import { Tokens } from 'applesauce-content/helpers'
import { getContentPointers } from 'applesauce-factory/helpers'
import { encodeDecodeResult } from 'applesauce-core/helpers'
import { encodeDecodeResult, Helpers } from 'applesauce-core/helpers'
const { getPubkeyFromDecodeResult } = Helpers
/**
* Regular expression to match nostr: URIs and bare NIP-19 identifiers
@@ -85,17 +87,14 @@ export function getNostrUriLabel(encoded: string): string {
try {
const decoded = decode(encoded)
// Use applesauce helper to extract pubkey for npub/nprofile
const pubkey = getPubkeyFromDecodeResult(decoded)
if (pubkey) {
// Use shared fallback display function and add @ for label
return `@${getNpubFallbackDisplay(pubkey)}`
}
switch (decoded.type) {
case 'npub': {
// Use shared fallback display function and add @ for label
const pubkey = decoded.data
return `@${getNpubFallbackDisplay(pubkey)}`
}
case 'nprofile': {
// Use shared fallback display function and add @ for label
const pubkey = decoded.data.pubkey
return `@${getNpubFallbackDisplay(pubkey)}`
}
case 'note':
return `note:${encoded.slice(5, 12)}...`
case 'nevent': {
@@ -334,10 +333,9 @@ export function replaceNostrUrisInMarkdownWithProfileLabels(
return `[${title}](${link})`
}
// For npub/nprofile, extract pubkey and use it as the lookup key
if (decoded.type === 'npub' || decoded.type === 'nprofile') {
const pubkey = decoded.type === 'npub' ? decoded.data : decoded.data.pubkey
// For npub/nprofile, extract pubkey using applesauce helper
const pubkey = getPubkeyFromDecodeResult(decoded)
if (pubkey) {
// Check if we have a resolved profile name using pubkey as key
// Use the label if: 1) we have a label, AND 2) profile is not currently loading (false or undefined)
const isLoading = profileLoading.get(pubkey)
@@ -383,15 +381,9 @@ export function addLoadingClassToProfileLinks(
// Find all <a> tags with href starting with /p/ (profile links)
const result = html.replace(/<a\s+[^>]*?href="\/p\/([^"]+)"[^>]*?>/g, (match, npub: string) => {
try {
// Decode npub or nprofile to get pubkey
// Decode npub or nprofile to get pubkey using applesauce helper
const decoded: ReturnType<typeof decode> = decode(npub)
let pubkey: string | undefined
if (decoded.type === 'npub') {
pubkey = decoded.data
} else if (decoded.type === 'nprofile') {
pubkey = decoded.data.pubkey
}
const pubkey = getPubkeyFromDecodeResult(decoded)
if (pubkey) {
// Check if this profile is loading