feat(services): add centralized writingsController for kind 30023

This commit is contained in:
Gigi
2025-10-18 23:43:16 +02:00
parent 8619cecaf3
commit 3149e5b824
2 changed files with 291 additions and 3 deletions

View File

@@ -11,6 +11,7 @@ import { Highlight } from '../types/highlights'
import { HighlightItem } from './HighlightItem'
import { fetchHighlights } from '../services/highlightService'
import { highlightsController } from '../services/highlightsController'
import { writingsController } from '../services/writingsController'
import { fetchAllReads, ReadItem } from '../services/readsService'
import { fetchLinks } from '../services/linksService'
import { BlogPostPreview, fetchBlogPostsFromAuthors } from '../services/exploreService'
@@ -81,6 +82,10 @@ const Me: React.FC<MeProps> = ({
const [myHighlights, setMyHighlights] = useState<Highlight[]>([])
const [myHighlightsLoading, setMyHighlightsLoading] = useState(false)
// Get myWritings directly from controller
const [myWritings, setMyWritings] = useState<BlogPostPreview[]>([])
const [myWritingsLoading, setMyWritingsLoading] = useState(false)
// Load cached data from event store for OTHER profiles (not own)
const cachedHighlights = useStoreTimeline(
eventStore,
@@ -138,6 +143,20 @@ const Me: React.FC<MeProps> = ({
}
}, [])
// Subscribe to writings controller
useEffect(() => {
// Get initial state immediately
setMyWritings(writingsController.getWritings())
// Subscribe to updates
const unsubWritings = writingsController.onWritings(setMyWritings)
const unsubLoading = writingsController.onLoading(setMyWritingsLoading)
return () => {
unsubWritings()
unsubLoading()
}
}, [])
// Update local state when prop changes
useEffect(() => {
if (propActiveTab) {
@@ -204,8 +223,20 @@ const Me: React.FC<MeProps> = ({
try {
if (!hasBeenLoaded) setLoading(true)
// Seed with cached writings first
if (!isOwnProfile && cachedWritings.length > 0) {
// For own profile, use centralized controller
if (isOwnProfile) {
await writingsController.start({
relayPool,
eventStore,
pubkey: viewingPubkey,
force: refreshTrigger > 0
})
setLoadedTabs(prev => new Set(prev).add('writings'))
return
}
// For other profiles, seed with cached writings first
if (cachedWritings.length > 0) {
setWritings(cachedWritings.sort((a, b) => {
const timeA = a.published || a.event.created_at
const timeB = b.published || b.event.created_at
@@ -213,7 +244,7 @@ const Me: React.FC<MeProps> = ({
}))
}
// Fetch fresh writings
// Fetch fresh writings for other profiles
const userWritings = await fetchBlogPostsFromAuthors(relayPool, [viewingPubkey], RELAYS)
setWritings(userWritings)
setLoadedTabs(prev => new Set(prev).add('writings'))
@@ -375,6 +406,13 @@ const Me: React.FC<MeProps> = ({
}
}, [isOwnProfile, myHighlights])
// Sync myWritings from controller when viewing own profile
useEffect(() => {
if (isOwnProfile) {
setWritings(myWritings)
}
}, [isOwnProfile, myWritings])
// Pull-to-refresh - reload active tab without clearing state
const { isRefreshing, pullPosition } = usePullToRefresh({
onRefresh: () => {