| 361 | }>({}); |
| 362 | |
| 363 | const fetchFileContent = async (filePath: string) => { |
| 364 | setFileContentLoading(true); |
| 365 | |
| 366 | // Use AbortController to handle timeouts |
| 367 | const controller = new AbortController(); |
| 368 | const timeoutId = setTimeout(() => controller.abort(), 20000); // 20 second timeout |
| 369 | |
| 370 | try { |
| 371 | // Check if we already have cached content for this file |
| 372 | const cacheKey = `${repoFullName}:${filePath}`; |
| 373 | if (cachedFileContentsRef.current[cacheKey]) { |
| 374 | console.log('Using cached file content for:', filePath); |
| 375 | return cachedFileContentsRef.current[cacheKey]; |
| 376 | } |
| 377 | |
| 378 | console.log('Fetching file content for:', filePath); |
| 379 | // Use the correct parameter format for our API |
| 380 | const response = await fetch( |
| 381 | `/api/get-file-content?repo=${encodeURIComponent(repoFullName)}&path=${encodeURIComponent(filePath)}`, |
| 382 | { signal: controller.signal } |
| 383 | ); |
| 384 | |
| 385 | if (!response.ok) { |
| 386 | console.error('API response not OK:', response.status); |
| 387 | throw new Error(`Failed to fetch file content: ${response.status}`); |
| 388 | } |
| 389 | |
| 390 | const data = await response.json(); |
| 391 | console.log('File content response:', { path: data.path, contentLength: data.content?.length || 0 }); |
| 392 | |
| 393 | // Cache the file content |
| 394 | if (data.content) { |
| 395 | cachedFileContentsRef.current[cacheKey] = data.content; |
| 396 | } else { |
| 397 | console.warn('No content returned from API for:', filePath); |
| 398 | } |
| 399 | |
| 400 | return data.content; |
| 401 | } catch (err) { |
| 402 | console.error('Error fetching file content:', err); |
| 403 | if (typeof err === 'object' && err !== null && 'name' in err && (err as { name?: string }).name === 'AbortError') { |
| 404 | console.warn('File content request timed out for:', filePath); |
| 405 | } |
| 406 | return null; |
| 407 | } finally { |
| 408 | clearTimeout(timeoutId); |
| 409 | setFileContentLoading(false); |
| 410 | } |
| 411 | }; |
| 412 | |
| 413 | const handleFileClick = async (file: KeyFile) => { |
| 414 | setSelectedFile(file); |