From 4d18c84243e2cd631cb4fe00a2c6f3a482f514e8 Mon Sep 17 00:00:00 2001 From: Gigi Date: Sat, 15 Nov 2025 20:26:37 +0000 Subject: [PATCH] feat: improve relay hint selection to exclude non-content relays - Add NON_CONTENT_RELAYS list and isContentRelay helper to classify relays - Update ContentPanel to filter out non-content relays (e.g., relay.nsec.app) from naddr hints - Update HighlightItem to prefer publishedRelays/seenOnRelays and filter using isContentRelay - Ensures relay.nsec.app and other auth/utility relays are never suggested as content hints --- src/components/ContentPanel.tsx | 9 ++++++--- src/components/HighlightItem.tsx | 21 +++++++++++++++++---- src/config/relays.ts | 17 +++++++++++++++++ 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/components/ContentPanel.tsx b/src/components/ContentPanel.tsx index 3bbc45b8..61017d0d 100644 --- a/src/components/ContentPanel.tsx +++ b/src/components/ContentPanel.tsx @@ -12,6 +12,8 @@ import { nip19 } from 'nostr-tools' import { getNostrUrl, getSearchUrl } from '../config/nostrGateways' import { RelayPool } from 'applesauce-relay' import { getActiveRelayUrls } from '../services/relayManager' +import { isContentRelay } from '../config/relays' +import { isLocalRelay } from '../utils/helpers' import { IAccount } from 'applesauce-accounts' import { NostrEvent } from 'nostr-tools' import { Highlight } from '../types/highlights' @@ -432,9 +434,10 @@ const ContentPanel: React.FC = ({ const dTag = currentArticle.tags.find(t => t[0] === 'd')?.[1] || '' const activeRelays = relayPool ? getActiveRelayUrls(relayPool) : [] - const relayHints = activeRelays.filter(r => - !r.includes('localhost') && !r.includes('127.0.0.1') - ).slice(0, 3) + const relayHints = activeRelays + .filter(url => !isLocalRelay(url)) + .filter(url => isContentRelay(url)) + .slice(0, 3) const naddr = nip19.naddrEncode({ kind: 30023, diff --git a/src/components/HighlightItem.tsx b/src/components/HighlightItem.tsx index 90d4e9e5..eaf1e4e5 100644 --- a/src/components/HighlightItem.tsx +++ b/src/components/HighlightItem.tsx @@ -10,6 +10,7 @@ import { Hooks } from 'applesauce-react' import { onSyncStateChange, isEventSyncing, isEventOfflineCreated } from '../services/offlineSyncService' import { areAllRelaysLocal, isLocalRelay } from '../utils/helpers' import { getActiveRelayUrls } from '../services/relayManager' +import { isContentRelay } from '../config/relays' import { nip19 } from 'nostr-tools' import { formatDateCompact } from '../utils/bookmarkUtils' import { createDeletionRequest } from '../services/deletionService' @@ -224,11 +225,23 @@ export const HighlightItem: React.FC = ({ const getHighlightLinks = () => { // Encode the highlight event itself (kind 9802) as a nevent - // Get non-local relays for the hint + // Prefer relays we actually published to or saw the event on + const publishedRelays = highlight.publishedRelays || [] + const seenOnRelays = highlight.seenOnRelays || [] + + // Use published relays if available, else seen relays, else fall back to active relays + const baseRelays = publishedRelays.length > 0 + ? publishedRelays + : (seenOnRelays.length > 0 ? seenOnRelays : []) + const activeRelays = relayPool ? getActiveRelayUrls(relayPool) : [] - const relayHints = activeRelays.filter(r => - !r.includes('localhost') && !r.includes('127.0.0.1') - ).slice(0, 3) // Include up to 3 relay hints + const candidates = baseRelays.length > 0 ? baseRelays : activeRelays + + // Filter to content-capable remote relays + const relayHints = candidates + .filter(url => !isLocalRelay(url)) + .filter(url => isContentRelay(url)) + .slice(0, 3) // Include up to 3 relay hints const nevent = nip19.neventEncode({ id: highlight.id, diff --git a/src/config/relays.ts b/src/config/relays.ts index a09165fa..6abc96cf 100644 --- a/src/config/relays.ts +++ b/src/config/relays.ts @@ -19,3 +19,20 @@ export const RELAYS = [ 'wss://proxy.nostr-relay.app/5d0d38afc49c4b84ca0da951a336affa18438efed302aeedfa92eb8b0d3fcb87', ] +/** + * Relays that should NOT be used as content hints (auth/signer, etc.) + * These relays are fine for connection and other purposes, but shouldn't + * be suggested as places where posts/highlights are likely to be found. + */ +export const NON_CONTENT_RELAYS = [ + 'wss://relay.nsec.app', +] + +/** + * Check if a relay URL is suitable for use as a content hint + * Returns true for remote relays that are reasonable for posts/highlights + */ +export function isContentRelay(url: string): boolean { + return !NON_CONTENT_RELAYS.includes(url) +} +