diff --git a/src/App.tsx b/src/App.tsx index a1d9814e..ee0f1e95 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -20,7 +20,6 @@ import { RELAYS } from './config/relays' import { SkeletonThemeProvider } from './components/Skeletons' import { DebugBus } from './utils/debugBus' import { Bookmark } from './types/bookmarks' -import { Highlight } from './types/highlights' import { bookmarkController } from './services/bookmarkController' import { contactsController } from './services/contactsController' import { highlightsController } from './services/highlightsController' @@ -49,10 +48,6 @@ function AppRoutes({ const [contacts, setContacts] = useState>(new Set()) const [contactsLoading, setContactsLoading] = useState(false) - // Centralized highlights state (fed by controller) - const [highlights, setHighlights] = useState([]) - const [highlightsLoading, setHighlightsLoading] = useState(false) - // Subscribe to bookmark controller useEffect(() => { console.log('[bookmark] 🎧 Subscribing to bookmark controller') @@ -91,24 +86,6 @@ function AppRoutes({ } }, []) - // Subscribe to highlights controller - useEffect(() => { - console.log('[highlights] 🎧 Subscribing to highlights controller') - const unsubHighlights = highlightsController.onHighlights((highlights) => { - console.log('[highlights] 📥 Received highlights:', highlights.length) - setHighlights(highlights) - }) - const unsubLoading = highlightsController.onLoading((loading) => { - console.log('[highlights] 📥 Loading state:', loading) - setHighlightsLoading(loading) - }) - - return () => { - console.log('[highlights] 🔇 Unsubscribing from highlights controller') - unsubHighlights() - unsubLoading() - } - }, []) // Auto-load bookmarks, contacts, and highlights when account is ready (on login or page mount) useEffect(() => { @@ -127,13 +104,13 @@ function AppRoutes({ contactsController.start({ relayPool, pubkey }) } - // Load highlights - if (pubkey && eventStore && highlights.length === 0 && !highlightsLoading) { + // Load highlights (controller manages its own state) + if (pubkey && eventStore && !highlightsController.isLoadedFor(pubkey)) { console.log('[highlights] 🚀 Auto-loading highlights on mount/login') highlightsController.start({ relayPool, eventStore, pubkey }) } } - }, [activeAccount, relayPool, eventStore, bookmarks.length, bookmarksLoading, contacts.size, contactsLoading, highlights.length, highlightsLoading, accountManager]) + }, [activeAccount, relayPool, eventStore, bookmarks.length, bookmarksLoading, contacts.size, contactsLoading, accountManager]) // Manual refresh (for sidebar button) const handleRefreshBookmarks = useCallback(async () => { @@ -165,8 +142,6 @@ function AppRoutes({ bookmarks={bookmarks} bookmarksLoading={bookmarksLoading} onRefreshBookmarks={handleRefreshBookmarks} - myHighlights={highlights} - myHighlightsLoading={highlightsLoading} /> } /> @@ -179,8 +154,6 @@ function AppRoutes({ bookmarks={bookmarks} bookmarksLoading={bookmarksLoading} onRefreshBookmarks={handleRefreshBookmarks} - myHighlights={highlights} - myHighlightsLoading={highlightsLoading} /> } /> @@ -193,8 +166,6 @@ function AppRoutes({ bookmarks={bookmarks} bookmarksLoading={bookmarksLoading} onRefreshBookmarks={handleRefreshBookmarks} - myHighlights={highlights} - myHighlightsLoading={highlightsLoading} /> } /> @@ -207,8 +178,6 @@ function AppRoutes({ bookmarks={bookmarks} bookmarksLoading={bookmarksLoading} onRefreshBookmarks={handleRefreshBookmarks} - myHighlights={highlights} - myHighlightsLoading={highlightsLoading} /> } /> @@ -221,8 +190,6 @@ function AppRoutes({ bookmarks={bookmarks} bookmarksLoading={bookmarksLoading} onRefreshBookmarks={handleRefreshBookmarks} - myHighlights={highlights} - myHighlightsLoading={highlightsLoading} /> } /> @@ -235,8 +202,6 @@ function AppRoutes({ bookmarks={bookmarks} bookmarksLoading={bookmarksLoading} onRefreshBookmarks={handleRefreshBookmarks} - myHighlights={highlights} - myHighlightsLoading={highlightsLoading} /> } /> @@ -253,8 +218,6 @@ function AppRoutes({ bookmarks={bookmarks} bookmarksLoading={bookmarksLoading} onRefreshBookmarks={handleRefreshBookmarks} - myHighlights={highlights} - myHighlightsLoading={highlightsLoading} /> } /> @@ -267,8 +230,6 @@ function AppRoutes({ bookmarks={bookmarks} bookmarksLoading={bookmarksLoading} onRefreshBookmarks={handleRefreshBookmarks} - myHighlights={highlights} - myHighlightsLoading={highlightsLoading} /> } /> @@ -281,8 +242,6 @@ function AppRoutes({ bookmarks={bookmarks} bookmarksLoading={bookmarksLoading} onRefreshBookmarks={handleRefreshBookmarks} - myHighlights={highlights} - myHighlightsLoading={highlightsLoading} /> } /> @@ -295,8 +254,6 @@ function AppRoutes({ bookmarks={bookmarks} bookmarksLoading={bookmarksLoading} onRefreshBookmarks={handleRefreshBookmarks} - myHighlights={highlights} - myHighlightsLoading={highlightsLoading} /> } /> @@ -309,8 +266,6 @@ function AppRoutes({ bookmarks={bookmarks} bookmarksLoading={bookmarksLoading} onRefreshBookmarks={handleRefreshBookmarks} - myHighlights={highlights} - myHighlightsLoading={highlightsLoading} /> } /> @@ -323,8 +278,6 @@ function AppRoutes({ bookmarks={bookmarks} bookmarksLoading={bookmarksLoading} onRefreshBookmarks={handleRefreshBookmarks} - myHighlights={highlights} - myHighlightsLoading={highlightsLoading} /> } /> @@ -337,8 +290,6 @@ function AppRoutes({ bookmarks={bookmarks} bookmarksLoading={bookmarksLoading} onRefreshBookmarks={handleRefreshBookmarks} - myHighlights={highlights} - myHighlightsLoading={highlightsLoading} /> } /> @@ -351,8 +302,6 @@ function AppRoutes({ bookmarks={bookmarks} bookmarksLoading={bookmarksLoading} onRefreshBookmarks={handleRefreshBookmarks} - myHighlights={highlights} - myHighlightsLoading={highlightsLoading} /> } /> diff --git a/src/components/Bookmarks.tsx b/src/components/Bookmarks.tsx index 02b9a40a..3365c1bc 100644 --- a/src/components/Bookmarks.tsx +++ b/src/components/Bookmarks.tsx @@ -14,7 +14,6 @@ import { useBookmarksUI } from '../hooks/useBookmarksUI' import { useRelayStatus } from '../hooks/useRelayStatus' import { useOfflineSync } from '../hooks/useOfflineSync' import { Bookmark } from '../types/bookmarks' -import { Highlight } from '../types/highlights' import ThreePaneLayout from './ThreePaneLayout' import Explore from './Explore' import Me from './Me' @@ -29,8 +28,6 @@ interface BookmarksProps { bookmarks: Bookmark[] bookmarksLoading: boolean onRefreshBookmarks: () => Promise - myHighlights: Highlight[] - myHighlightsLoading: boolean } const Bookmarks: React.FC = ({ @@ -38,9 +35,7 @@ const Bookmarks: React.FC = ({ onLogout, bookmarks, bookmarksLoading, - onRefreshBookmarks, - myHighlights, - myHighlightsLoading + onRefreshBookmarks }) => { const { naddr, npub } = useParams<{ naddr?: string; npub?: string }>() const location = useLocation() @@ -327,10 +322,10 @@ const Bookmarks: React.FC = ({ onCreateHighlight={handleCreateHighlight} hasActiveAccount={!!(activeAccount && relayPool)} explore={showExplore ? ( - relayPool ? : null + relayPool ? : null ) : undefined} me={showMe ? ( - relayPool ? : null + relayPool ? : null ) : undefined} profile={showProfile && profilePubkey ? ( relayPool ? : null diff --git a/src/components/Explore.tsx b/src/components/Explore.tsx index 0d6bad68..179af750 100644 --- a/src/components/Explore.tsx +++ b/src/components/Explore.tsx @@ -13,6 +13,7 @@ import { fetchBlogPostsFromAuthors, BlogPostPreview } from '../services/exploreS import { fetchHighlightsFromAuthors } from '../services/highlightService' import { fetchProfiles } from '../services/profileService' import { fetchNostrverseBlogPosts, fetchNostrverseHighlights } from '../services/nostrverseService' +import { highlightsController } from '../services/highlightsController' import { Highlight } from '../types/highlights' import { UserSettings } from '../services/settingsService' import BlogPostCard from './BlogPostCard' @@ -28,13 +29,11 @@ interface ExploreProps { eventStore: IEventStore settings?: UserSettings activeTab?: TabType - myHighlights?: Highlight[] // From highlightsController in App.tsx - myHighlightsLoading?: boolean // Loading state from highlightsController } type TabType = 'writings' | 'highlights' -const Explore: React.FC = ({ relayPool, eventStore, settings, activeTab: propActiveTab, myHighlights = [], myHighlightsLoading = false }) => { +const Explore: React.FC = ({ relayPool, eventStore, settings, activeTab: propActiveTab }) => { const activeAccount = Hooks.useActiveAccount() const navigate = useNavigate() const [activeTab, setActiveTab] = useState(propActiveTab || 'highlights') @@ -44,6 +43,10 @@ const Explore: React.FC = ({ relayPool, eventStore, settings, acti const [loading, setLoading] = useState(true) const [refreshTrigger, setRefreshTrigger] = useState(0) + // Get myHighlights directly from controller + const [myHighlights, setMyHighlights] = useState([]) + const [myHighlightsLoading, setMyHighlightsLoading] = useState(false) + // Visibility filters (defaults from settings, or friends only) const [visibility, setVisibility] = useState({ nostrverse: settings?.defaultHighlightVisibilityNostrverse ?? false, @@ -51,6 +54,16 @@ const Explore: React.FC = ({ relayPool, eventStore, settings, acti mine: settings?.defaultHighlightVisibilityMine ?? false }) + // Subscribe to highlights controller + useEffect(() => { + const unsubHighlights = highlightsController.onHighlights(setMyHighlights) + const unsubLoading = highlightsController.onLoading(setMyHighlightsLoading) + return () => { + unsubHighlights() + unsubLoading() + } + }, []) + // Update local state when prop changes useEffect(() => { if (propActiveTab) { diff --git a/src/components/Me.tsx b/src/components/Me.tsx index 948dda5b..6de6f949 100644 --- a/src/components/Me.tsx +++ b/src/components/Me.tsx @@ -9,6 +9,7 @@ import { useNavigate, useParams } from 'react-router-dom' import { Highlight } from '../types/highlights' import { HighlightItem } from './HighlightItem' import { fetchHighlights } from '../services/highlightService' +import { highlightsController } from '../services/highlightsController' import { fetchAllReads, ReadItem } from '../services/readsService' import { fetchLinks } from '../services/linksService' import { BlogPostPreview, fetchBlogPostsFromAuthors } from '../services/exploreService' @@ -38,8 +39,6 @@ interface MeProps { pubkey?: string // Optional pubkey for viewing other users' profiles bookmarks: Bookmark[] // From centralized App.tsx state bookmarksLoading?: boolean // From centralized App.tsx state (reserved for future use) - myHighlights?: Highlight[] // From highlightsController (for own profile) - myHighlightsLoading?: boolean // Loading state from highlightsController } type TabType = 'highlights' | 'reading-list' | 'reads' | 'links' | 'writings' @@ -51,9 +50,7 @@ const Me: React.FC = ({ relayPool, activeTab: propActiveTab, pubkey: propPubkey, - bookmarks, - myHighlights = [], - myHighlightsLoading = false + bookmarks }) => { const activeAccount = Hooks.useActiveAccount() const navigate = useNavigate() @@ -71,6 +68,10 @@ const Me: React.FC = ({ const [writings, setWritings] = useState([]) const [loading, setLoading] = useState(true) const [loadedTabs, setLoadedTabs] = useState>(new Set()) + + // Get myHighlights directly from controller + const [myHighlights, setMyHighlights] = useState([]) + const [myHighlightsLoading, setMyHighlightsLoading] = useState(false) const [viewMode, setViewMode] = useState('cards') const [refreshTrigger, setRefreshTrigger] = useState(0) const [bookmarkFilter, setBookmarkFilter] = useState('all') @@ -91,6 +92,16 @@ const Me: React.FC = ({ : 'all' const [readingProgressFilter, setReadingProgressFilter] = useState(initialFilter) + // Subscribe to highlights controller + useEffect(() => { + const unsubHighlights = highlightsController.onHighlights(setMyHighlights) + const unsubLoading = highlightsController.onLoading(setMyHighlightsLoading) + return () => { + unsubHighlights() + unsubLoading() + } + }, []) + // Update local state when prop changes useEffect(() => { if (propActiveTab) {