This repository has no description
0

Configure Feed

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

fix

+67 -14
+65 -12
app/src/app/api/bluesky/feed/route.ts
··· 15 15 text: string; 16 16 emoji: string; 17 17 created_at: string; 18 + handle?: string; // Optional handle field from the database 18 19 } 19 20 20 21 // Type for the processed entry for the client ··· 84 85 did, 85 86 text, 86 87 emoji, 87 - created_at 88 + created_at, 89 + handle 88 90 `) 89 91 .lt('created_at', cursorRecord.created_at) // Get entries older than cursor 90 92 .order('created_at', { ascending: false }) ··· 96 98 97 99 // Process and return older entries (skip caching) 98 100 const processedEntries = await Promise.all((entries || []).map(async (entry: FlushingRecord) => { 101 + // Get the DID 99 102 const authorDid = entry.did; 100 - const authorHandle = await resolveDidToHandle(authorDid); 103 + 104 + // First check if we have a valid handle in the database record 105 + // and it's not "unknown" 106 + let authorHandle: string; 107 + if (entry.handle && entry.handle !== 'unknown') { 108 + // Use the handle from the database 109 + authorHandle = entry.handle; 110 + console.log(`Using handle from database for ${authorDid}: ${authorHandle}`); 111 + 112 + // Store in cache for future use 113 + dbHandleCache.set(authorDid, authorHandle); 114 + } else if (dbHandleCache.has(authorDid)) { 115 + // Use cached handle from previous database entries 116 + authorHandle = dbHandleCache.get(authorDid)!; 117 + console.log(`Using cached DB handle for ${authorDid}: ${authorHandle}`); 118 + } else { 119 + // Resolve handle from DID 120 + authorHandle = await resolveDidToHandle(authorDid); 121 + console.log(`Resolved handle for ${authorDid}: ${authorHandle}`); 122 + } 101 123 102 124 if (containsBannedWords(entry.text)) { 103 125 return null; ··· 152 174 did, 153 175 text, 154 176 emoji, 155 - created_at 177 + created_at, 178 + handle 156 179 `) 157 180 .order('created_at', { ascending: false }) 158 181 .limit(MAX_ENTRIES); ··· 170 193 171 194 // Transform the data to match our client-side model 172 195 const processedEntries = await Promise.all((entries || []).map(async (entry: FlushingRecord) => { 173 - // Resolve handle from DID 196 + // Get the DID 174 197 const authorDid = entry.did; 175 - const authorHandle = await resolveDidToHandle(authorDid); 198 + 199 + // First check if we have a valid handle in the database record 200 + // and it's not "unknown" 201 + let authorHandle: string; 202 + if (entry.handle && entry.handle !== 'unknown') { 203 + // Use the handle from the database 204 + authorHandle = entry.handle; 205 + console.log(`Using handle from database for ${authorDid}: ${authorHandle}`); 206 + 207 + // Store in cache for future use 208 + dbHandleCache.set(authorDid, authorHandle); 209 + } else if (dbHandleCache.has(authorDid)) { 210 + // Use cached handle from previous database entries 211 + authorHandle = dbHandleCache.get(authorDid)!; 212 + console.log(`Using cached DB handle for ${authorDid}: ${authorHandle}`); 213 + } else { 214 + // Resolve handle from DID 215 + authorHandle = await resolveDidToHandle(authorDid); 216 + console.log(`Resolved handle for ${authorDid}: ${authorHandle}`); 217 + } 176 218 177 219 // Skip entries with banned content 178 220 if (containsBannedWords(entry.text)) { ··· 265 307 266 308 // DID resolution cache 267 309 const didResolutionCache = new Map<string, string>(); 310 + 311 + // Handle column cache - maps DID to handle stored in the database 312 + // This allows us to use existing handle values from the DB instead of resolving every time 313 + const dbHandleCache = new Map<string, string>(); 268 314 269 315 // Timeout promise to prevent hanging on API calls 270 316 function timeout(ms: number): Promise<never> { ··· 392 438 393 439 // If we get here, all resolution methods failed 394 440 console.log(`All resolution methods failed for ${did}, using shortened DID: ${shortDid}`); 441 + 442 + // Create a user-friendly version of the DID 443 + // Format: "user.{first6chars}" 444 + const userFriendlyDid = did.startsWith('did:plc:') ? 445 + `user.${did.substring(8, 14)}` : 446 + `user.${did.substring(0, 6)}`; 447 + 395 448 // Cache the fallback result too 396 - didResolutionCache.set(did, shortDid); 397 - return shortDid; 449 + didResolutionCache.set(did, userFriendlyDid); 450 + return userFriendlyDid; 398 451 } catch (error) { 399 452 console.error(`Failed to resolve handle for DID ${did}:`, error); 400 - // Last resort fallback is the shortened DID 401 - const shortDid = did.startsWith('did:plc:') ? 402 - `${did.substring(0, 13)}...` : 403 - `${did.substring(0, 10)}...`; 404 - return shortDid; 453 + // Last resort fallback is a user-friendly version of the DID 454 + const userFriendlyDid = did.startsWith('did:plc:') ? 455 + `user.${did.substring(8, 14)}` : 456 + `user.${did.substring(0, 6)}`; 457 + return userFriendlyDid; 405 458 } 406 459 }
+2 -2
app/src/app/page.tsx
··· 42 42 // Fetch the latest entries when the component mounts 43 43 fetchLatestEntries(true); // Force refresh on initial load 44 44 45 - // Set up periodic refresh every 60 seconds 45 + // Set up periodic refresh every 20 seconds 46 46 const refreshInterval = setInterval(() => { 47 47 console.log('Auto-refreshing feed...'); 48 48 fetchLatestEntries(true); 49 - }, 60000); 49 + }, 20000); 50 50 51 51 // Clean up interval on unmount 52 52 return () => clearInterval(refreshInterval);