This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

yay

+70 -43
+69 -43
src/components/Verifier/Verifier.js
··· 11 11 'theathletic.bsky.social' 12 12 ]; 13 13 14 - // Helper function to fetch all paginated results using a specific agent instance 15 - async function fetchAllPaginated(agentInstance, apiMethod, initialParams) { 14 + // Helper function modified to handle direct fetch or agent calls 15 + // Now accepts an optional 'useDirectFetch' flag and the direct URL if needed 16 + async function fetchAllPaginated(agentInstance, apiMethod, initialParams, useDirectFetch = false, directUrl = null) { 16 17 let results = []; 17 18 let cursor = initialParams.cursor; 18 - const params = { ...initialParams }; 19 - // Attempt to log the intended operation more reliably 20 - const operationName = apiMethod.name.includes('bound ') ? apiMethod.name.split('bound ')[1].trim() : apiMethod.name; 21 - console.log(`fetchAllPaginated: Starting ${operationName} with params:`, initialParams); 19 + const params = { ...initialParams }; // Copy initial params 20 + // Determine operation name 21 + const operationName = apiMethod ? (apiMethod.name.includes('bound ') ? apiMethod.name.split('bound ')[1].trim() : apiMethod.name) : (directUrl || 'directFetch'); 22 + console.log(`fetchAllPaginated: Starting ${operationName} with initialParams:`, initialParams); 23 + 24 + let currentUrl = directUrl; // Use direct URL if provided 22 25 23 26 do { 24 27 try { 25 - if (cursor) { 26 - params.cursor = cursor; 27 - } 28 - // Call the method. Assumes namespaced methods return { data: { records: [], cursor: '...' } } 29 - // or similar structure where records are in an array under `data`. 30 - const response = await apiMethod(params); 31 - 32 - // Check if response and response.data exist 33 - if (!response || !response.data) { 34 - console.warn(`fetchAllPaginated: Invalid response structure for ${operationName}`, response); 35 - break; // Stop pagination if structure is unexpected 36 - } 37 - 38 - // Find the key containing the array of results (e.g., 'records', 'follows', 'followers', 'actors') 39 - const listKey = Object.keys(response.data).find(key => Array.isArray(response.data[key])); 40 - 41 - if (listKey && response.data[listKey]) { 42 - results = results.concat(response.data[listKey]); 28 + let responseData; 29 + if (useDirectFetch && currentUrl) { 30 + // Handle pagination for direct fetch 31 + const url = new URL(currentUrl); 32 + if (cursor) { 33 + url.searchParams.set('cursor', cursor); 34 + } 35 + // Add other params like limit (ensure initialParams doesn't duplicate) 36 + Object.entries(params).forEach(([key, value]) => { 37 + if (key !== 'cursor' && !url.searchParams.has(key)) { 38 + url.searchParams.set(key, value); 39 + } 40 + }); 41 + // console.log(`fetchAllPaginated: Direct fetch URL: ${url.toString()}`); 42 + const response = await fetch(url.toString()); 43 + if (!response.ok) throw new Error(`HTTP error ${response.status}`); 44 + responseData = await response.json(); 45 + } else if (apiMethod) { 46 + // Use agent method 47 + if (cursor) { 48 + params.cursor = cursor; 49 + } 50 + const response = await apiMethod(params); 51 + if (!response || !response.data) { 52 + console.warn(`fetchAllPaginated: Invalid agent response for ${operationName}`, response); 53 + break; 54 + } 55 + responseData = response.data; 43 56 } else { 44 - console.warn(`fetchAllPaginated: Could not find results array key in response.data for ${operationName}`, response.data); 57 + console.error("fetchAllPaginated: Called without agent method or direct URL"); 58 + break; 45 59 } 46 60 47 - cursor = response.data.cursor; 48 - // console.log(`fetchAllPaginated: Fetched page for ${operationName}, got ${response.data[listKey]?.length || 0} items, cursor: ${cursor}`); 61 + // Find results array 62 + const listKey = Object.keys(responseData).find(key => Array.isArray(responseData[key])); 63 + if (listKey && responseData[listKey]) { 64 + results = results.concat(responseData[listKey]); 65 + } 66 + cursor = responseData.cursor; 49 67 50 68 } catch (error) { 51 69 console.error(`Error during paginated fetch for ${operationName}:`, error); 52 - cursor = undefined; // Stop pagination on error 70 + cursor = undefined; 53 71 } 54 72 } while (cursor); 55 73 ··· 268 286 setNetworkVerifications({ mutualsVerifiedMe: [], followsVerifiedMe: [], mutualsVerifiedAnyone: 0, followsVerifiedAnyone: 0, fetchedMutualsCount: 0, fetchedFollowsCount: 0 }); 269 287 setNetworkStatusMessage("Fetching network lists (mutuals, follows)..."); 270 288 271 - const publicAgent = new Agent({ service: 'https://public.api.bsky.app' }); 289 + try { 290 + console.log("checkNetworkVerifications: Fetching follows (public) and mutuals (authenticated)..."); 272 291 273 - try { 274 - console.log("checkNetworkVerifications: Fetching follows and mutuals..."); 275 - // Ensure correct agent and bound namespaced methods are used 292 + // *** Fetch follows using direct fetch *** 293 + const followsUrl = `https://public.api.bsky.app/xrpc/app.bsky.graph.getFollows`; 294 + const followsParams = { actor: session.did, limit: 100 }; 295 + 296 + // *** Fetch known followers using authenticated agent *** 297 + const knownFollowersMethod = agent.api.app.bsky.graph.getKnownFollowers.bind(agent.api.app.bsky.graph); 298 + const knownFollowersParams = { actor: session.did, limit: 100 }; 299 + 276 300 const [follows, mutuals] = await Promise.all([ 277 - fetchAllPaginated(publicAgent, publicAgent.api.app.bsky.graph.getFollows.bind(publicAgent.api.app.bsky.graph), { actor: session.did, limit: 100 }), 278 - fetchAllPaginated(agent, agent.api.app.bsky.graph.getKnownFollowers.bind(agent.api.app.bsky.graph), { actor: session.did, limit: 100 }) 301 + fetchAllPaginated(null, null, followsParams, true, followsUrl), 302 + fetchAllPaginated(agent, knownFollowersMethod, knownFollowersParams) 279 303 ]); 280 304 281 305 console.log(`checkNetworkVerifications: Fetched ${follows.length} follows, ${mutuals.length} mutuals.`); ··· 315 339 return null; 316 340 } 317 341 318 - // Create a temporary agent specifically for this user's PDS 319 - const tempUserAgent = new Agent({ service: pdsEndpoint }); 320 342 let foundVerificationForMe = null; 321 343 let hasVerifiedAnyone = false; 322 344 323 345 try { 324 - // Use fetchAllPaginated to handle listing records from the specific PDS 346 + // *** Use fetchAllPaginated with direct fetch for listRecords *** 347 + const listRecordsUrl = `${pdsEndpoint}/xrpc/com.atproto.repo.listRecords`; 348 + const listRecordsParams = { repo: did, collection: 'app.bsky.graph.verification', limit: 100 }; 349 + 325 350 const verificationRecords = await fetchAllPaginated( 326 - tempUserAgent, 327 - tempUserAgent.api.com.atproto.repo.listRecords.bind(tempUserAgent.api.com.atproto.repo), // Bind namespaced method 328 - { repo: did, collection: 'app.bsky.graph.verification', limit: 100 } 351 + null, 352 + null, 353 + listRecordsParams, 354 + true, // Use direct fetch 355 + listRecordsUrl 329 356 ); 330 357 331 358 if (verificationRecords.length > 0) { ··· 337 364 } 338 365 } 339 366 } catch (err) { 340 - // fetchAllPaginated already logs errors, just skip this user on error 341 - console.warn(`Error processing records for ${profile.handle || did} on ${pdsEndpoint}`); 367 + console.warn(`Error processing records for ${profile?.handle || did} on ${pdsEndpoint}:`, err); 342 368 } 343 369 344 370 // Return data for aggregation ··· 387 413 setIsLoadingNetwork(false); 388 414 setNetworkChecked(true); 389 415 } 390 - }, [agent, session, userInfo]); // Keep dependencies 416 + }, [agent, session, userInfo]); 391 417 392 418 useEffect(() => { 393 419 if (agent) {
+1
src/contexts/AuthContext.js
··· 46 46 const oauthClient = new BrowserOAuthClient({ 47 47 clientMetadata: clientMetadata, 48 48 handleResolver: 'https://bsky.social', // Use Bluesky's resolver or your own 49 + scope: 'atproto transition:generic' 49 50 }); 50 51 51 52 setClient(oauthClient); // Store the client instance