- {Object.entries(groupedThreads).length === 0 && (
-
- Debug: No grouped threads found. groupedThreads keys: {Object.keys(groupedThreads).join(', ')}
-
- )}
{Object.entries(groupedThreads).map(([topicId, topicThreads]) => {
const topicInfo = DISCUSSION_TOPICS.find(t => t.id === topicId)
if (!topicInfo || topicThreads.length === 0) return null
@@ -880,18 +873,6 @@ const DiscussionsPage = forwardRef((_, ref) => {
? ['readings'] // Always include readings for literature threads
: getDynamicSubtopics(topicAnalysis.get(categorizedTopic), 3)
- // Debug logging
- if (thread.content.includes('readin')) {
- console.log('DEBUG DiscussionsPage ThreadCard props:', {
- threadId: thread.id,
- content: thread.content.substring(0, 50),
- allTopics: extractAllTopics(thread),
- categorizedTopic,
- threadSubtopics,
- availableTopicIds,
- topicAnalysisForCategorizedTopic: topicAnalysis.get(categorizedTopic)
- })
- }
return (
(null)
const [openLoginDialog, setOpenLoginDialog] = useState(false)
const [profile, setProfile] = useState(null)
+
+ // Cleanup on page unload to prevent extension UI issues
+ useEffect(() => {
+ const handleBeforeUnload = () => {
+ // Try to clean up any pending operations
+ if (signer && 'disconnect' in signer) {
+ try {
+ (signer as any).disconnect()
+ } catch (error) {
+ console.warn('Failed to disconnect signer:', error)
+ }
+ }
+ }
+
+ const handleUnload = () => {
+ // Additional cleanup for extensions that might leave UI elements
+ try {
+ // Clear any pending timeouts or intervals
+ if (window.nostr && typeof window.nostr === 'object') {
+ // Some extensions might have cleanup methods
+ if ('cleanup' in window.nostr && typeof window.nostr.cleanup === 'function') {
+ window.nostr.cleanup()
+ }
+ }
+ } catch (error) {
+ console.warn('Extension cleanup failed:', error)
+ }
+ }
+
+ window.addEventListener('beforeunload', handleBeforeUnload)
+ window.addEventListener('unload', handleUnload)
+
+ return () => {
+ window.removeEventListener('beforeunload', handleBeforeUnload)
+ window.removeEventListener('unload', handleUnload)
+ }
+ }, [signer])
const [profileEvent, setProfileEvent] = useState(null)
const [relayList, setRelayList] = useState(null)
const [followListEvent, setFollowListEvent] = useState(null)
@@ -604,7 +641,23 @@ export function NostrProvider({ children }: { children: React.ReactNode }) {
}
const signEvent = async (draftEvent: TDraftEvent) => {
- const event = await signer?.signEvent(draftEvent)
+ // Add timeout to prevent hanging
+ const signEventWithTimeout = new Promise(async (resolve, reject) => {
+ const timeout = setTimeout(() => {
+ reject(new Error('Signing request timed out. Your Nostr extension may be waiting for authorization. Try closing this tab and restarting your browser to surface any pending authorization requests from your extension.'))
+ }, 30000) // 30 second timeout
+
+ try {
+ const event = await signer?.signEvent(draftEvent)
+ clearTimeout(timeout)
+ resolve(event)
+ } catch (error) {
+ clearTimeout(timeout)
+ reject(error)
+ }
+ })
+
+ const event = await signEventWithTimeout as VerifiedEvent
if (!event) {
throw new Error('sign event failed')
}
diff --git a/src/services/client.service.ts b/src/services/client.service.ts
index da3cf06..1b95451 100644
--- a/src/services/client.service.ts
+++ b/src/services/client.service.ts
@@ -142,12 +142,9 @@ class ClientService extends EventTarget {
// Use current user's relay list
const relayList = this.pubkey ? await this.fetchRelayList(this.pubkey) : { write: [], read: [] }
- console.log('DEBUG: User relay list write URLs:', relayList?.write)
const senderWriteRelays = relayList?.write.slice(0, 6) ?? []
- console.log('DEBUG: Selected sender write relays:', senderWriteRelays)
const recipientReadRelays = Array.from(new Set(_additionalRelayUrls))
relays = senderWriteRelays.concat(recipientReadRelays)
- console.log('DEBUG: Final relay URLs before optimization:', relays)
}
if (!relays.length) {
@@ -241,7 +238,6 @@ class ClientService extends EventTarget {
totalCount: number
}> {
const uniqueRelayUrls = this.optimizeRelaySelection(Array.from(new Set(relayUrls)))
- console.log('DEBUG: uniqueRelayUrls after optimization:', uniqueRelayUrls)
const relayStatuses: Array<{
url: string
@@ -272,7 +268,6 @@ class ClientService extends EventTarget {
this.emitNewEvent(event)
}
resolved = true
- console.log('DEBUG: Publishing completed. relayStatuses:', relayStatuses)
resolve({
success: isSuccess,
relayStatuses,
@@ -285,7 +280,6 @@ class ClientService extends EventTarget {
// Handle case where no relays succeed
if (finishedCount >= uniqueRelayUrls.length && !resolved && successCount === 0) {
resolved = true
- console.log('DEBUG: All relays failed. relayStatuses:', relayStatuses)
const aggregateError = new AggregateError(
errors.map(
({ url, error }) => {
@@ -328,17 +322,14 @@ class ClientService extends EventTarget {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const that = this
- console.log('DEBUG: Attempting to publish to relay:', url)
- try {
+ try {
// Throttle requests to prevent "too many concurrent REQs" errors
await this.throttleRequest(url)
const relay = await this.pool.ensureRelay(url)
relay.publishTimeout = 8_000 // 8s
- console.log('DEBUG: Publishing to relay:', url)
await relay.publish(event)
- console.log('DEBUG: Successfully published to relay:', url)
this.trackEventSeenOn(event.id, relay)
this.recordSuccess(url)
successCount++
@@ -351,7 +342,6 @@ class ClientService extends EventTarget {
checkCompletion()
} catch (error) {
- console.log('DEBUG: Failed to publish to relay:', url, 'Error:', error)
let errorMessage = 'Unknown error'
if (error instanceof Error) {
errorMessage = error.message || 'Empty error message'
@@ -387,16 +377,12 @@ class ClientService extends EventTarget {
error.message.startsWith('auth-required') &&
!!that.signer
) {
- console.log('DEBUG: Attempting authentication for relay:', url)
try {
// Throttle auth requests too
await this.throttleRequest(url)
const relay = await this.pool.ensureRelay(url)
- // Attempt auth with proper timeout handling
- console.log('DEBUG: Starting auth for relay:', url)
-
const authPromise = relay.auth((authEvt: EventTemplate) => {
// Ensure the auth event has the correct pubkey
const authEventWithPubkey = { ...authEvt, pubkey: that.pubkey }
@@ -408,10 +394,8 @@ class ClientService extends EventTarget {
})
await Promise.race([authPromise, authTimeoutPromise])
- console.log('DEBUG: Auth successful for relay:', url)
await relay.publish(event)
- console.log('DEBUG: Publish successful for relay:', url)
this.trackEventSeenOn(event.id, relay)
this.recordSuccess(url)
successCount++
@@ -425,7 +409,6 @@ class ClientService extends EventTarget {
checkCompletion()
} catch (authError) {
- console.log('DEBUG: Auth failed for relay:', url, 'Error:', authError)
let authErrorMessage = 'Unknown auth error'
if (authError instanceof Error) {
authErrorMessage = authError.message || 'Empty auth error message'