fix: timeline

Changed files
+101 -28
src
lib
+101 -28
src/lib/hooks/useTimeline.tsx
··· 23 23 } 24 24 25 25 export function useFetchTimeline() { 26 - const { agent } = useAuth(); 26 + const { agent, session } = useAuth(); 27 27 const { 28 28 timeline, 29 29 appendTimeline, ··· 38 38 const pendingFeedRequests = useRef<Set<string>>(new Set()); 39 39 // Use a ref to track the latest agent value 40 40 const agentRef = useRef(agent); 41 + const sessionRef = useRef(session); 41 42 // Track processing state to avoid loops 42 43 const isProcessingRequests = useRef(false); 43 44 const processingRetries = useRef(0); 45 + const authenticationRetries = useRef(0); 46 + const [forceRetry, setForceRetry] = useState(0); 44 47 45 - // Update the ref when agent changes 48 + // Update the refs when agent or session changes 46 49 useEffect(() => { 47 50 agentRef.current = agent; 48 - }, [agent]); 51 + sessionRef.current = session; 52 + 53 + // If session exists but agent doesn't have session, trigger a retry 54 + if (session && agent && !agent.did) { 55 + console.log( 56 + "Session exists but agent doesn't have it attached yet, scheduling retry" 57 + ); 58 + const retryTimeout = setTimeout(() => { 59 + setForceRetry((prev) => prev + 1); 60 + }, 500); 61 + return () => clearTimeout(retryTimeout); 62 + } 63 + }, [agent, session]); 64 + 65 + const isAuthenticated = useCallback(() => { 66 + // Check both ways: either agent has session or we have separate session 67 + return ( 68 + (agentRef.current && agentRef.current.did) || 69 + (agentRef.current && sessionRef.current) 70 + ); 71 + }, []); 49 72 50 73 const fetchFeed = useCallback( 51 74 async (feed?: string | undefined) => { ··· 54 77 // Use the latest agent from the ref 55 78 const currentAgent = agentRef.current; 56 79 57 - // If not ready, queue the request for later 58 - if (!currentAgent) { 80 + // Enhanced authentication check 81 + const authenticated = isAuthenticated(); 82 + 83 + // If not ready or not authenticated, queue the request for later 84 + if (!currentAgent || !authenticated) { 59 85 console.log( 60 - "Agent not available, queuing feed request for later:", 61 - feed || "main" 86 + `Agent not available or not authenticated, queuing feed request for later: ${ 87 + feed || "main" 88 + }`, 89 + `Agent: ${!!currentAgent}, Auth: ${authenticated}` 62 90 ); 63 91 pendingFeedRequests.current.add(feed || "main"); 64 92 return; ··· 132 160 appendTimeline, 133 161 setTimelineLoading, 134 162 setCustomFeedLoading, 163 + isAuthenticated, 135 164 ] 136 165 ); 137 166 ··· 143 172 return; 144 173 } 145 174 146 - // If agent isn't ready, try again later 147 - if (!agentRef.current) { 175 + // Enhanced authentication check 176 + const authenticated = isAuthenticated(); 177 + 178 + // If agent isn't ready or not authenticated, try again later 179 + if (!agentRef.current || !authenticated) { 148 180 if (processingRetries.current < 5) { 149 181 processingRetries.current++; 150 182 console.log( 151 - `Agent not ready for processing, will retry (${processingRetries.current}/5)` 183 + `Agent not ready or not authenticated for processing, will retry (${processingRetries.current}/5)`, 184 + `Agent: ${!!agentRef.current}, Auth: ${authenticated}` 152 185 ); 153 186 setTimeout(() => processPendingRequests(), 1000); 154 187 } else { ··· 178 211 } finally { 179 212 isProcessingRequests.current = false; 180 213 } 181 - }, [fetchFeed]); 214 + }, [fetchFeed, isAuthenticated]); 215 + 216 + // Try to load feeds even if there are authentication issues 217 + useEffect(() => { 218 + if (authenticationRetries.current >= 3) return; 219 + 220 + if (agent && session && !isReady) { 221 + console.log( 222 + "Attempting to force feed load despite authentication issues" 223 + ); 224 + authenticationRetries.current++; 225 + 226 + setTimeout(() => { 227 + setIsReady(true); 228 + processPendingRequests(); 229 + }, 1000 * authenticationRetries.current); 230 + } 231 + }, [agent, session, isReady, processPendingRequests, forceRetry]); 182 232 183 - // Effect to initialize feed once agent is available 233 + // Effect to initialize feed once agent is available and authenticated 184 234 useEffect(() => { 185 235 if (!agent) { 186 236 console.log("Waiting for agent to become available"); 187 237 return; 188 238 } 189 239 190 - console.log("Agent detected, setting ready state"); 240 + // Enhanced authentication check 241 + const authenticated = isAuthenticated(); 242 + 243 + if (!authenticated) { 244 + console.log( 245 + `Agent available but not authenticated, waiting for session. Session ref: ${!!sessionRef.current}` 246 + ); 247 + return; 248 + } 249 + 250 + console.log("Authenticated agent detected, setting ready state"); 191 251 setIsReady(true); 192 252 193 253 // Give a small delay for agent to fully initialize ··· 200 260 201 261 const loadMinimum = async () => { 202 262 setIsInitialized(true); 203 - console.log("Agent available, loading initial feed"); 263 + console.log("Authenticated agent available, loading initial feed"); 204 264 205 - // Process any pending requests first 206 - await processPendingRequests(); 265 + try { 266 + // Process any pending requests first 267 + await processPendingRequests(); 207 268 208 - // Then load the minimum required images 209 - let attempts = 0; 210 - while ( 211 - timeline.posts.flatMap( 212 - (p) => (p.post.embed as AppBskyEmbedImages.View)?.images || [] 213 - ).length < 30 && 214 - attempts < 3 215 - ) { 216 - await fetchFeed(); 217 - attempts++; 218 - if (!timeline.cursor) break; 269 + // Then load the minimum required images 270 + let attempts = 0; 271 + while ( 272 + timeline.posts.flatMap( 273 + (p) => (p.post.embed as AppBskyEmbedImages.View)?.images || [] 274 + ).length < 30 && 275 + attempts < 3 276 + ) { 277 + await fetchFeed(); 278 + attempts++; 279 + if (!timeline.cursor) break; 280 + } 281 + } catch (err) { 282 + console.error("Error during initial feed loading:", err); 219 283 } 220 284 }; 221 285 222 286 loadMinimum(); 223 287 }, 500); // Small delay to ensure agent is fully initialized 224 - }, [agent, isInitialized, processPendingRequests, fetchFeed, timeline.posts]); 288 + }, [ 289 + agent, 290 + agent?.did, 291 + isInitialized, 292 + processPendingRequests, 293 + fetchFeed, 294 + timeline.posts, 295 + isAuthenticated, 296 + forceRetry, 297 + ]); 225 298 226 299 return { fetchFeed, isReady }; 227 300 }