diff --git a/src/renderer/src/components/pull-request-page/checks/details-list-keys.ts b/src/renderer/src/components/pull-request-page/checks/details-list-keys.ts index 068d6a9c077..66f10c98689 100644 --- a/src/renderer/src/components/pull-request-page/checks/details-list-keys.ts +++ b/src/renderer/src/components/pull-request-page/checks/details-list-keys.ts @@ -13,6 +13,7 @@ export function assignUniqueListKeys( const base = contentKey(item) const seen = occurrences.get(base) ?? 0 occurrences.set(base, seen + 1) - return { item, key: seen === 0 ? base : `${base}#${seen}` } + // JSON-encoded pair, not `base#seen`: a separator suffix would collide with a real content key. + return { item, key: JSON.stringify([base, seen]) } }) } diff --git a/src/renderer/src/components/pull-request-page/files/combined-diff-viewer.tsx b/src/renderer/src/components/pull-request-page/files/combined-diff-viewer.tsx index 7e7c2920136..8a50aabcf26 100644 --- a/src/renderer/src/components/pull-request-page/files/combined-diff-viewer.tsx +++ b/src/renderer/src/components/pull-request-page/files/combined-diff-viewer.tsx @@ -27,6 +27,7 @@ import { type PRFilesCombinedDiffViewerProps } from '@/components/github/pr-file-diff-mapping' import { githubRepoIdentityKey } from '../../../../../shared/github/repository-identity-key' +import { LOCAL_EXECUTION_HOST_ID } from '../../../../../shared/execution-host' import { prFilesDiffScrollTopCache, prFilesDiffViewStateCache } from '../cache/files-diff-view' import { PRFilesDiffToolbar } from './toolbar' import { addPullRequestLineComment } from './line-comment' @@ -80,27 +81,35 @@ export function PRFilesCombinedDiffViewer({ () => buildInlineReviewComments(comments, repoId, prNumber), [comments, prNumber, repoId] ) + // Why: section contents are fetched through sourceContext, so local and remote hosts must not share cache entries. + const sourceScope = sourceContext?.hostId ?? LOCAL_EXECUTION_HOST_ID const entrySignature = useMemo( () => JSON.stringify({ repoId, prNumber, prRepo: prRepo ? githubRepoIdentityKey(prRepo) : null, + sourceScope, headSha: headSha ?? null, baseSha: baseSha ?? null, files: diffEntrySignature }), - [baseSha, diffEntrySignature, headSha, prNumber, prRepo, repoId] + [baseSha, diffEntrySignature, headSha, prNumber, prRepo, repoId, sourceScope] ) const viewStateKey = useMemo( - () => [repoId || repoPath, prNumber, prRepo ? githubRepoIdentityKey(prRepo) : ''].join('\0'), - [prNumber, prRepo, repoId, repoPath] + () => + [repoId || repoPath, prNumber, prRepo ? githubRepoIdentityKey(prRepo) : '', sourceScope].join( + '\0' + ), + [prNumber, prRepo, repoId, repoPath, sourceScope] ) const [sections, setSections] = useState([]) const [sideBySide, setSideBySide] = useState(false) const [fileTreeCollapsed, setFileTreeCollapsed] = useState(false) const [sectionHeights, setSectionHeights] = useState>({}) const [activeTreeSectionKey, setActiveTreeSectionKey] = useState(null) + // Why: short virtualizer-key token; entrySignature serializes every file and would be copied into every item key. + const [entryRevision, setEntryRevision] = useState(0) const scrollContainerRef = useRef(null) const pendingRestoreScrollTopRef = useRef(null) const loadedIndicesRef = useRef>(new Set()) @@ -117,6 +126,7 @@ export function PRFilesCombinedDiffViewer({ useEffect(() => { // Why: bump generation so stale async diff loads from the previous view can't patch the restored sections. generationRef.current += 1 + setEntryRevision((revision) => revision + 1) const cached = prFilesDiffViewStateCache.get(viewStateKey) if (cached && cached.entrySignature === entrySignature) { const restoredSections = cached.sections @@ -210,8 +220,8 @@ export function PRFilesCombinedDiffViewer({ getItemKey: (index) => { const section = sections[index] return section - ? `${section.key}:${section.collapsed ? 'collapsed' : 'expanded'}:${entrySignature}` - : `${index}:${entrySignature}` + ? `${section.key}:${section.collapsed ? 'collapsed' : 'expanded'}:${entryRevision}` + : `${index}:${entryRevision}` } }) diff --git a/src/renderer/src/i18n/locales/es.json b/src/renderer/src/i18n/locales/es.json index 5c825005fb1..c3c6768dbd9 100644 --- a/src/renderer/src/i18n/locales/es.json +++ b/src/renderer/src/i18n/locales/es.json @@ -1538,7 +1538,7 @@ "dd5d9a4f17": "actualizado {{value0}}", "71a3c0f9d2": "Iniciar espacio de trabajo", "filesUnavailable": "Couldn't load changed files.", - "filesRetry": "Retry", + "filesRetry": "Reintentar", "77482513f8": "Cerrar", "2f5195c6a0": "Reabrir", "4b8ae7303f": "No se pudo cargar la diferencia.",