diff --git a/packages/app/src/components/diff-viewer.tsx b/packages/app/src/components/diff-viewer.tsx index cda3382a0..a2953f323 100644 --- a/packages/app/src/components/diff-viewer.tsx +++ b/packages/app/src/components/diff-viewer.tsx @@ -31,6 +31,20 @@ export function DiffViewer({ [], ); + const outerScrollStyle = React.useMemo( + () => [ + styles.verticalScroll, + maxHeight !== undefined && { maxHeight }, + fillAvailableHeight && styles.fillHeight, + webScrollbarStyle, + ], + [maxHeight, fillAvailableHeight, webScrollbarStyle], + ); + const linesContainerStyle = React.useMemo( + () => [styles.linesContainer, scrollViewWidth > 0 && { minWidth: scrollViewWidth }], + [scrollViewWidth], + ); + if (!diffLines.length) { return ( @@ -41,12 +55,7 @@ export function DiffViewer({ return ( - 0 && { minWidth: scrollViewWidth }]}> + {diffLines.map((line, index) => ( { + try { + const stats = await stat(fullPath); + return stats.isFile(); + } catch { + return false; + } +} + +async function isExistingDirectory(fullPath: string): Promise { + try { + const stats = await stat(fullPath); + return stats.isDirectory(); + } catch { + return false; + } +} + async function findIconInDir(dir: string, patterns: string[]): Promise { let entries: string[]; try { @@ -204,16 +222,12 @@ async function findIconInDir(dir: string, patterns: string[]): Promise, + remainingDepth: number, +): Promise { + for (const priorityDir of PRIORITY_DIRS) { + const priorityPath = join(basePath, priorityDir); + if (!(await isExistingDirectory(priorityPath))) { + continue; + } + const result = await searchDirRecursively( + priorityPath, + ICON_PATTERNS, + ignoredDirsSet, + remainingDepth, + ); + if (result) { + return result; + } + } + return null; +} + async function searchDirRecursively( dir: string, patterns: string[], @@ -252,22 +289,18 @@ async function searchDirRecursively( } const fullPath = join(dir, entry); - try { - const stats = await stat(fullPath); - if (stats.isDirectory()) { - const result = await searchDirRecursively( - fullPath, - patterns, - ignoredDirs, - maxDepth, - currentDepth + 1, - ); - if (result) { - return result; - } - } - } catch { - // Directory may be inaccessible, continue + if (!(await isExistingDirectory(fullPath))) { + continue; + } + const result = await searchDirRecursively( + fullPath, + patterns, + ignoredDirs, + maxDepth, + currentDepth + 1, + ); + if (result) { + return result; } } @@ -289,24 +322,9 @@ export async function findProjectIcon( const ignoredDirsSet = new Set(IGNORED_DIRS); // First search priority directories - for (const priorityDir of PRIORITY_DIRS) { - const priorityPath = join(projectDir, priorityDir); - try { - const stats = await stat(priorityPath); - if (stats.isDirectory()) { - const result = await searchDirRecursively( - priorityPath, - ICON_PATTERNS, - ignoredDirsSet, - maxDepth - 1, - ); - if (result) { - return result; - } - } - } catch { - // Directory doesn't exist, continue - } + const priorityResult = await searchPriorityDirs(projectDir, ignoredDirsSet, maxDepth - 1); + if (priorityResult) { + return priorityResult; } // Then search monorepo package directories (packages/*, apps/*) @@ -321,32 +339,17 @@ export async function findProjectIcon( for (const packageName of packageEntries) { const packagePath = join(monoPath, packageName); - try { - const packageStats = await stat(packagePath); - if (!packageStats.isDirectory()) continue; - } catch { + if (!(await isExistingDirectory(packagePath))) { continue; } - // Search priority dirs within the package - for (const priorityDir of PRIORITY_DIRS) { - const priorityPath = join(packagePath, priorityDir); - try { - const priorityStats = await stat(priorityPath); - if (priorityStats.isDirectory()) { - const result = await searchDirRecursively( - priorityPath, - ICON_PATTERNS, - ignoredDirsSet, - maxDepth - 1, - ); - if (result) { - return result; - } - } - } catch { - // Directory doesn't exist, continue - } + const packagePriorityResult = await searchPriorityDirs( + packagePath, + ignoredDirsSet, + maxDepth - 1, + ); + if (packagePriorityResult) { + return packagePriorityResult; } // Search package root @@ -385,31 +388,29 @@ async function findDirRecursively( } // Don't recurse further from root - we already searched priority dirs - if (currentDepth > 0) { - let entries: string[]; - try { - entries = await readdir(dir); - } catch { - return null; + if (currentDepth === 0) { + return null; + } + + let entries: string[]; + try { + entries = await readdir(dir); + } catch { + return null; + } + + for (const entry of entries) { + if (ignoredDirsSet.has(entry) || priorityDirsSet.has(entry)) { + continue; } - for (const entry of entries) { - if (ignoredDirsSet.has(entry) || priorityDirsSet.has(entry)) { - continue; - } - - const fullPath = join(dir, entry); - try { - const stats = await stat(fullPath); - if (stats.isDirectory()) { - const result = await findDirRecursively(fullPath, maxDepth, currentDepth + 1); - if (result) { - return result; - } - } - } catch { - // Continue - } + const fullPath = join(dir, entry); + if (!(await isExistingDirectory(fullPath))) { + continue; + } + const result = await findDirRecursively(fullPath, maxDepth, currentDepth + 1); + if (result) { + return result; } }