diff --git a/src/components/Note/DiscussionContent/index.tsx b/src/components/Note/DiscussionContent/index.tsx
new file mode 100644
index 0000000..c052c9f
--- /dev/null
+++ b/src/components/Note/DiscussionContent/index.tsx
@@ -0,0 +1,47 @@
+import Markdown from 'react-markdown'
+import remarkGfm from 'remark-gfm'
+import { Event } from 'nostr-tools'
+import { useMemo } from 'react'
+import NostrNode from '../LongFormArticle/NostrNode'
+import { remarkNostr } from '../LongFormArticle/remarkNostr'
+import { Components } from '../LongFormArticle/types'
+
+export default function DiscussionContent({
+ event,
+ className
+}: {
+ event: Event
+ className?: string
+}) {
+ const components = useMemo(
+ () =>
+ ({
+ nostr: (props) => (
+
+ ),
+ }) as Components,
+ []
+ )
+
+ return (
+
+ {
+ if (url.startsWith('nostr:')) {
+ return url.slice(6) // Remove 'nostr:' prefix for rendering
+ }
+ return url
+ }}
+ components={components}
+ >
+ {event.content}
+
+
+ )
+}
diff --git a/src/components/Note/index.tsx b/src/components/Note/index.tsx
index 30148ea..126d414 100644
--- a/src/components/Note/index.tsx
+++ b/src/components/Note/index.tsx
@@ -19,6 +19,7 @@ import UserAvatar from '../UserAvatar'
import Username from '../Username'
import { MessageSquare } from 'lucide-react'
import CommunityDefinition from './CommunityDefinition'
+import DiscussionContent from './DiscussionContent'
import GroupMetadata from './GroupMetadata'
import Highlight from './Highlight'
import IValue from './IValue'
@@ -97,7 +98,7 @@ export default function Note({
content = (
<>
{title}
-
+
>
)
} else if (event.kind === ExtendedKind.POLL) {
diff --git a/src/pages/primary/DiscussionsPage/CreateThreadDialog.tsx b/src/pages/primary/DiscussionsPage/CreateThreadDialog.tsx
index a22baff..ef2ceb5 100644
--- a/src/pages/primary/DiscussionsPage/CreateThreadDialog.tsx
+++ b/src/pages/primary/DiscussionsPage/CreateThreadDialog.tsx
@@ -12,6 +12,7 @@ import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useNostr } from '@/providers/NostrProvider'
import { TDraftEvent } from '@/types'
+import { NostrEvent } from 'nostr-tools'
import { prefixNostrAddresses } from '@/lib/nostr-address'
import { showPublishingError } from '@/lib/publishing-feedback'
import dayjs from 'dayjs'
@@ -41,7 +42,7 @@ interface CreateThreadDialogProps {
availableRelays: string[]
selectedRelay?: string | null
onClose: () => void
- onThreadCreated: () => void
+ onThreadCreated: (publishedEvent?: NostrEvent) => void
}
export const DISCUSSION_TOPICS = [
@@ -206,7 +207,7 @@ export default function CreateThreadDialog({
if (publishedEvent) {
- onThreadCreated()
+ onThreadCreated(publishedEvent)
onClose()
} else {
throw new Error(t('Failed to publish thread'))
diff --git a/src/pages/primary/DiscussionsPage/index.tsx b/src/pages/primary/DiscussionsPage/index.tsx
index bb5a943..9901aab 100644
--- a/src/pages/primary/DiscussionsPage/index.tsx
+++ b/src/pages/primary/DiscussionsPage/index.tsx
@@ -18,6 +18,7 @@ import TopicSubscribeButton from '@/components/TopicSubscribeButton'
import { NostrEvent } from 'nostr-tools'
import client from '@/services/client.service'
import noteStatsService from '@/services/note-stats.service'
+import storage from '@/services/local-storage.service'
import { useSecondaryPage } from '@/PageManager'
import { toNote } from '@/lib/link'
import { kinds } from 'nostr-tools'
@@ -60,20 +61,56 @@ const DiscussionsPage = forwardRef((_, ref) => {
[pubkey, favoriteRelays]
)
- // Memoize relay URLs with deduplication
- const relayUrls = useMemo(() => {
- if (selectedRelay) {
- // Check if it's a relay set
- const relaySet = relaySets.find(set => set.id === selectedRelay)
- if (relaySet) {
- return relaySet.relayUrls
+ // State for relay URLs
+ const [relayUrls, setRelayUrls] = useState([])
+
+ // Update relay URLs when dependencies change
+ useEffect(() => {
+ const updateRelayUrls = async () => {
+ if (selectedRelay) {
+ // Check if it's a relay set
+ const relaySet = relaySets.find(set => set.id === selectedRelay)
+ if (relaySet) {
+ setRelayUrls(relaySet.relayUrls)
+ return
+ }
+ // It's an individual relay
+ setRelayUrls([selectedRelay])
+ return
}
- // It's an individual relay
- return [selectedRelay]
+
+ // For "All Relays", include user's write relays and stored relay sets too
+ let userWriteRelays: string[] = []
+ let storedRelaySetRelays: string[] = []
+
+ if (pubkey) {
+ try {
+ // Get user's write relays
+ const relayList = await client.fetchRelayList(pubkey)
+ userWriteRelays = relayList?.write || []
+
+ // Get relays from stored relay sets (additional safety check)
+ // Note: favoriteRelays should already include these, but let's be thorough
+ const storedRelaySets = storage.getRelaySets()
+ storedRelaySetRelays = storedRelaySets.flatMap(set => set.relayUrls)
+ } catch (error) {
+ console.warn('Failed to fetch user relay list:', error)
+ }
+ }
+
+ // Deduplicate and combine all relays: favorite relays, user write relays, stored relay sets, and fast read relays
+ const allRelays = Array.from(new Set([
+ ...availableRelays,
+ ...userWriteRelays,
+ ...storedRelaySetRelays,
+ ...FAST_READ_RELAY_URLS
+ ]))
+
+ setRelayUrls(allRelays)
}
- // Deduplicate and combine relays
- return Array.from(new Set([...availableRelays, ...FAST_READ_RELAY_URLS]))
- }, [selectedRelay, availableRelays, relaySets])
+
+ updateRelayUrls()
+ }, [selectedRelay, availableRelays, relaySets, pubkey, favoriteRelays])
// Available topic IDs for matching
const availableTopicIds = useMemo(() =>
@@ -451,9 +488,29 @@ const DiscussionsPage = forwardRef((_, ref) => {
setShowCreateThread(true)
}
- const handleThreadCreated = () => {
+ const handleThreadCreated = (publishedEvent?: NostrEvent) => {
setShowCreateThread(false)
- fetchAllThreads() // Refresh all threads
+
+ if (publishedEvent) {
+ // Optimistically add the new thread to the local state
+ setAllThreads(prev => {
+ // Check if the thread is already in the list (avoid duplicates)
+ if (prev.some(thread => thread.id === publishedEvent.id)) {
+ return prev
+ }
+
+ // Add relay source info
+ const eventHints = client.getEventHints(publishedEvent.id)
+ const relaySource = eventHints.length > 0 ? eventHints[0] : 'unknown'
+ const newThread = { ...publishedEvent, _relaySource: relaySource }
+
+ // Add the new thread at the beginning (newest first)
+ return [newThread, ...prev]
+ })
+ } else {
+ // Fallback: refresh all threads if no published event provided
+ fetchAllThreads()
+ }
}
return (
diff --git a/src/services/client.service.ts b/src/services/client.service.ts
index ced50ad..da3cf06 100644
--- a/src/services/client.service.ts
+++ b/src/services/client.service.ts
@@ -1768,8 +1768,9 @@ class ClientService extends EventTarget {
}
})
- // Limit to 3 relays to prevent "too many concurrent REQs" errors
- return validRelays.slice(0, 3)
+ // Limit to 8 relays to prevent "too many concurrent REQs" errors
+ // Increased from 3 to 8 for discussions to include more relay sources
+ return validRelays.slice(0, 8)
}
// ================= Utils =================