add naddr support to search results navigation

This commit is contained in:
austinkelsay 2025-04-27 14:48:52 -05:00
parent 1e380b8dc0
commit dd58859dd1
No known key found for this signature in database
GPG Key ID: 5A763922E5BA08EE
3 changed files with 80 additions and 3 deletions

View File

@ -8,6 +8,7 @@ import GenericButton from '@/components/buttons/GenericButton';
import useWindowWidth from '@/hooks/useWindowWidth';
import { BookOpen } from 'lucide-react';
import { highlightText, getTextWithMatchContext } from '@/utils/text';
import { generateNaddr } from '@/utils/nostr';
const ContentDropdownItem = ({ content, onSelect }) => {
const { returnImageProxy } = useImageProxy();
@ -16,11 +17,39 @@ const ContentDropdownItem = ({ content, onSelect }) => {
// Get match information if available
const matches = content?._matches || {};
// Handle content selection with naddress
const handleSelect = () => {
// Create a copy of the content object with naddress information
const contentWithNaddr = { ...content };
// If content has pubkey, kind, and identifier (d tag), generate naddr
if (content.pubkey && content.kind && (content.d || content.identifier)) {
// Use the appropriate identifier (d tag value)
const identifier = content.d || content.identifier;
// Generate naddress
contentWithNaddr.naddress = generateNaddr(
content.pubkey,
content.kind,
identifier
);
// Log success or failure
if (contentWithNaddr.naddress) {
console.log(`Generated naddress for ${content.type || 'content'}: ${contentWithNaddr.naddress}`);
} else {
console.warn('Failed to generate naddress:', { pubkey: content.pubkey, kind: content.kind, identifier });
}
}
onSelect(contentWithNaddr);
};
return (
<div
className="group px-6 py-5 border-b border-gray-700/50 cursor-pointer hover:bg-gray-800/30 transition-colors duration-200"
onClick={() => onSelect(content)}
onClick={handleSelect}
>
<div className={`flex ${isMobile ? 'flex-col' : 'flex-row'} gap-5`}>
<div
@ -107,7 +136,7 @@ const ContentDropdownItem = ({ content, onSelect }) => {
iconPos="right"
onClick={e => {
e.stopPropagation();
onSelect(content);
handleSelect();
}}
className="items-center py-1 shadow-sm hover:shadow-md transition-shadow duration-200"
/>

View File

@ -133,8 +133,18 @@ const SearchBar = ({ isMobileSearch, isDesktopNav, onCloseSearch }) => {
const handleContentSelect = content => {
if (selectedSearchOption.code === 'content') {
if (content?.type === 'course') {
router.push(`/course/${content?.d || content?.id}`);
if (content?.naddress) {
// Use naddress for course if available
router.push(`/course/${content.naddress}`);
} else {
// Fallback to d or id
router.push(`/course/${content?.d || content?.id}`);
}
} else if (content?.naddress) {
// Use naddress for other content if available
router.push(`/details/${content.naddress}`);
} else {
// Fallback to ID if naddress is not available
router.push(`/details/${content.id}`);
}
} else if (selectedSearchOption.code === 'community') {

View File

@ -221,6 +221,44 @@ export const hexToNpub = hex => {
return nip19.npubEncode(hex);
};
/**
* Generates a Nostr address (naddr) from event details
*
* @param {string} pubkey - The public key of the content creator
* @param {number} kind - The event kind
* @param {string} identifier - The 'd' tag value
* @param {Array} relays - Optional array of relay URLs
* @returns {string} - The naddr string
*/
export const generateNaddr = (pubkey, kind, identifier, relays = []) => {
try {
// Convert npub to hex if needed
let hexPubkey = pubkey;
if (pubkey.startsWith('npub')) {
try {
const { data } = nip19.decode(pubkey);
hexPubkey = data;
} catch (e) {
console.error('Error decoding npub:', e);
}
}
// Create the address data
const addressData = {
pubkey: hexPubkey,
kind: parseInt(kind),
identifier,
relays
};
// Generate and return the naddr
return nip19.naddrEncode(addressData);
} catch (error) {
console.error('Error generating naddr:', error);
return null;
}
};
export function validateEvent(event) {
if (typeof event.kind !== 'number') return 'Invalid kind';
if (typeof event.content !== 'string') return 'Invalid content';