refactor: centralize event ID extraction logic in getEventId

This commit is contained in:
austinkelsay 2025-07-02 16:37:28 -05:00
parent 2cdfe25049
commit c5a2cedad3
No known key found for this signature in database
GPG Key ID: 5A763922E5BA08EE
4 changed files with 142 additions and 141 deletions

View File

@ -5,7 +5,7 @@
* system is unavailable, helping users understand the current state.
*
* @param {Object} props - Component props
* @param {string} props.mode - Current mode ('loading', 'error', 'fallback', 'no-channel')
* @param {string} props.mode - Current mode ('loading', 'error', 'no-channel')
* @param {string} props.error - Error message if applicable
* @param {Function} props.onRetry - Optional retry function
* @param {boolean} props.canCreateChannel - Whether user can create channels

View File

@ -11,6 +11,7 @@ import { useCommunityNotes } from '@/hooks/nostr/useCommunityNotes';
import { useNip28Channel } from '@/hooks/nostr/useNip28Channel';
import CommunityMessage from '@/components/feeds/messages/CommunityMessage';
import ChannelEmptyState from './ChannelEmptyState';
import { useToast } from '@/hooks/useToast';
const NostrFeed = ({ searchQuery }) => {
const { communityNotes, isLoading, error, hasChannel } = useCommunityNotes();
@ -26,6 +27,7 @@ const NostrFeed = ({ searchQuery }) => {
const [authorData, setAuthorData] = useState({});
const windowWidth = useWindowWidth();
const { showToast } = useToast();
/**
* Handle admin channel creation
@ -36,6 +38,11 @@ const NostrFeed = ({ searchQuery }) => {
// Channel creation will trigger a refresh automatically
} catch (error) {
console.error('Failed to create channel:', error);
showToast(
'error',
'Channel Creation Failed',
error?.message || 'An unexpected error occurred while creating the channel.'
);
}
};

View File

@ -29,7 +29,9 @@ export function useIsAdmin() {
try {
const user = await ndk.signer.user();
if (user?.pubkey) {
isNostrAdmin = appConfig.nip28.adminPubkeys.includes(user.pubkey);
const adminPubkeys = appConfig.nip28?.adminPubkeys;
if (Array.isArray(adminPubkeys))
isNostrAdmin = adminPubkeys.includes(user.pubkey);
}
} catch (err) {
console.warn('Could not get Nostr user for admin check:', err);

View File

@ -289,7 +289,136 @@ export const parseChannelEvent = event => {
console.log('Parsing channel event:', event);
// Try to get ID from the actual event data
// Use centralized event ID extraction logic
const eventId = getEventId(event);
const eventData = {
id: eventId,
pubkey: event.pubkey || '',
content: event.content || '',
kind: event.kind || 40,
created_at: event.created_at || 0,
type: 'channel',
metadata: null,
tags: event.tags || []
};
// Parse channel metadata from content
try {
if (eventData.content) {
eventData.metadata = JSON.parse(eventData.content);
}
} catch (err) {
console.warn('Error parsing channel metadata:', err);
eventData.metadata = {};
}
// Extract additional data from tags
event.tags.forEach(tag => {
switch (tag[0]) {
case 't':
if (!eventData.topics) eventData.topics = [];
eventData.topics.push(tag[1]);
break;
case 'r':
if (!eventData.relays) eventData.relays = [];
eventData.relays.push(tag[1]);
break;
default:
break;
}
});
return eventData;
};
/**
* Parse NIP-28 Channel Metadata Event (kind 41)
*
* @param {Object} event - The NDK event object
* @returns {Object} - Parsed channel metadata
*/
export const parseChannelMetadataEvent = event => {
const eventData = {
id: getEventId(event),
pubkey: event.pubkey || '',
content: event.content || '',
kind: event.kind || 41,
created_at: event.created_at || 0,
type: 'channel-metadata',
channelId: null,
metadata: null,
tags: event.tags || []
};
// Find channel reference
event.tags.forEach(tag => {
if (tag[0] === 'e' && tag[3] === 'root') {
eventData.channelId = tag[1];
}
});
// Parse metadata from content
try {
if (eventData.content) {
eventData.metadata = JSON.parse(eventData.content);
}
} catch (err) {
console.warn('Error parsing channel metadata:', err);
eventData.metadata = {};
}
return eventData;
};
/**
* Parse NIP-28 Channel Message Event (kind 42)
*
* @param {Object} event - The NDK event object
* @returns {Object} - Parsed channel message
*/
export const parseChannelMessageEvent = event => {
const eventData = {
id: getEventId(event),
pubkey: event.pubkey || '',
content: event.content || '',
kind: event.kind || 42,
created_at: event.created_at || 0,
type: 'channel-message',
channelId: null,
replyTo: null,
mentions: [],
tags: event.tags || []
};
// Parse NIP-10 threading and channel references
event.tags.forEach(tag => {
switch (tag[0]) {
case 'e':
if (tag[3] === 'root') {
eventData.channelId = tag[1];
} else if (tag[3] === 'reply') {
eventData.replyTo = tag[1];
}
break;
case 'p':
eventData.mentions.push(tag[1]);
break;
default:
break;
}
});
return eventData;
};
/**
* Generate a proper event ID from NDK event with comprehensive fallback logic
*
* @param {Object} event - The NDK event object
* @returns {string} - The event ID
*/
export const getEventId = event => {
let eventId = '';
// First try the direct properties
@ -373,143 +502,6 @@ export const parseChannelEvent = event => {
eventId = `temp_${event.pubkey.slice(0, 8)}_${event.created_at}`;
}
}
const eventData = {
id: eventId,
pubkey: event.pubkey || '',
content: event.content || '',
kind: event.kind || 40,
created_at: event.created_at || 0,
type: 'channel',
metadata: null,
tags: event.tags || []
};
// Parse channel metadata from content
try {
if (eventData.content) {
eventData.metadata = JSON.parse(eventData.content);
}
} catch (err) {
console.warn('Error parsing channel metadata:', err);
eventData.metadata = {};
}
// Extract additional data from tags
event.tags.forEach(tag => {
switch (tag[0]) {
case 't':
if (!eventData.topics) eventData.topics = [];
eventData.topics.push(tag[1]);
break;
case 'r':
if (!eventData.relays) eventData.relays = [];
eventData.relays.push(tag[1]);
break;
default:
break;
}
});
return eventData;
};
/**
* Parse NIP-28 Channel Metadata Event (kind 41)
*
* @param {Object} event - The NDK event object
* @returns {Object} - Parsed channel metadata
*/
export const parseChannelMetadataEvent = event => {
const eventData = {
id: event.id || event.eventId || event.tagId() || '',
pubkey: event.pubkey || '',
content: event.content || '',
kind: event.kind || 41,
created_at: event.created_at || 0,
type: 'channel-metadata',
channelId: null,
metadata: null,
tags: event.tags || []
};
// Find channel reference
event.tags.forEach(tag => {
if (tag[0] === 'e' && tag[3] === 'root') {
eventData.channelId = tag[1];
}
});
// Parse metadata from content
try {
if (eventData.content) {
eventData.metadata = JSON.parse(eventData.content);
}
} catch (err) {
console.warn('Error parsing channel metadata:', err);
eventData.metadata = {};
}
return eventData;
};
/**
* Parse NIP-28 Channel Message Event (kind 42)
*
* @param {Object} event - The NDK event object
* @returns {Object} - Parsed channel message
*/
export const parseChannelMessageEvent = event => {
const eventData = {
id: event.id || event.eventId || event.tagId() || '',
pubkey: event.pubkey || '',
content: event.content || '',
kind: event.kind || 42,
created_at: event.created_at || 0,
type: 'channel-message',
channelId: null,
replyTo: null,
mentions: [],
tags: event.tags || []
};
// Parse NIP-10 threading and channel references
event.tags.forEach(tag => {
switch (tag[0]) {
case 'e':
if (tag[3] === 'root') {
eventData.channelId = tag[1];
} else if (tag[3] === 'reply') {
eventData.replyTo = tag[1];
}
break;
case 'p':
eventData.mentions.push(tag[1]);
break;
default:
break;
}
});
return eventData;
};
/**
* Generate a proper event ID from NDK event
*
* @param {Object} event - The NDK event object
* @returns {string} - The event ID
*/
export const getEventId = event => {
// Try different methods to get the ID
if (event.id && event.id !== '') return event.id;
if (event.eventId && event.eventId !== '') return event.eventId;
if (typeof event.tagId === 'function') {
const tagId = event.tagId();
if (tagId && tagId !== '') return tagId;
}
// If no ID available, generate one or return null
console.warn('No event ID found for event:', event);
return null;
return eventId || null;
};