From f3b2498b5cbbd05c81a63bab216af0a4766d65de Mon Sep 17 00:00:00 2001 From: Jinjing <6427696+AmethystLiang@users.noreply.github.com> Date: Thu, 6 Aug 2026 18:40:20 -0700 Subject: [PATCH] feat(diff): HTML preview + always-visible open actions in View all Expose Open Preview to the Side for HTML sections in combined diffs when the working-tree file still exists, and keep the open-file external-link icon visible without hover. Split DiffSectionItem props/lifecycle helpers to stay under the max-lines limit. --- .../components/editor/CombinedDiffViewer.tsx | 34 +++++++ .../components/editor/DiffSectionHeader.tsx | 27 ++++- .../src/components/editor/DiffSectionItem.tsx | 98 ++++--------------- .../editor/diff-section-item-props.ts | 38 +++++++ .../editor/diff-section-preview.test.ts | 54 ++++++++++ .../components/editor/diff-section-preview.ts | 19 ++++ .../use-diff-section-model-lifecycle.ts | 39 ++++++++ 7 files changed, 228 insertions(+), 81 deletions(-) create mode 100644 src/renderer/src/components/editor/diff-section-item-props.ts create mode 100644 src/renderer/src/components/editor/diff-section-preview.test.ts create mode 100644 src/renderer/src/components/editor/diff-section-preview.ts create mode 100644 src/renderer/src/components/editor/use-diff-section-model-lifecycle.ts diff --git a/src/renderer/src/components/editor/CombinedDiffViewer.tsx b/src/renderer/src/components/editor/CombinedDiffViewer.tsx index 2c53bd87285..653130200f3 100644 --- a/src/renderer/src/components/editor/CombinedDiffViewer.tsx +++ b/src/renderer/src/components/editor/CombinedDiffViewer.tsx @@ -13,6 +13,8 @@ import { getVirtualizedScrollAnchorForOffset } from '@/hooks/virtualized-scroll- import { createProgrammaticScrollMarks } from '@/hooks/programmatic-scroll-marks' import { joinPath } from '@/lib/path' import { detectLanguage } from '@/lib/language-detect' +import { openFilePreviewToSide } from '@/lib/file-preview' +import { canOpenDiffSectionPreviewToSide } from './diff-section-preview' import { setWithLRU } from '@/lib/scroll-cache' import { getCombinedDiffSectionConnectionId } from './combined-diff-section-connection' import { findWorktreeById } from '@/store/slices/worktree-helpers' @@ -1284,6 +1286,29 @@ export default function CombinedDiffViewer({ ] ) + // Why: match single-file HTML diffs — preview the on-disk working tree file + // beside the combined view when the section is still present on disk. + const openSectionPreview = useCallback( + (section: DiffSection) => { + if ( + !canOpenDiffSectionPreviewToSide({ + path: section.path, + status: section.status, + isCommitSurface: isCommitMode + }) + ) { + return + } + openFilePreviewToSide({ + language: detectLanguage(section.path), + filePath: joinPath(file.filePath, section.path), + worktreeId: file.worktreeId, + sourceGroupId: activeGroupId ?? null + }) + }, + [activeGroupId, file.filePath, file.worktreeId, isCommitMode] + ) + const handleSectionSave = useCallback( async (index: number) => { const section = sections[index] @@ -2024,6 +2049,15 @@ export default function CombinedDiffViewer({ openSectionTitle={ isAllMode || isBranchMode || isCommitMode ? 'Open diff' : 'Open in editor' } + onOpenPreview={ + canOpenDiffSectionPreviewToSide({ + path: section.path, + status: section.status, + isCommitSurface: isCommitMode + }) + ? (previewSection) => openSectionPreview(previewSection) + : undefined + } setSectionHeights={setSectionHeights} setSections={setSections} modifiedEditorsRef={modifiedEditorsRef} diff --git a/src/renderer/src/components/editor/DiffSectionHeader.tsx b/src/renderer/src/components/editor/DiffSectionHeader.tsx index 8df224e7c9d..e26d993baff 100644 --- a/src/renderer/src/components/editor/DiffSectionHeader.tsx +++ b/src/renderer/src/components/editor/DiffSectionHeader.tsx @@ -1,4 +1,4 @@ -import { ChevronDown, ChevronRight, ExternalLink } from 'lucide-react' +import { ChevronDown, ChevronRight, ExternalLink, Eye } from 'lucide-react' import type { MouseEvent, ReactElement, ReactNode } from 'react' import { translate } from '@/i18n/i18n' @@ -11,6 +11,7 @@ export function DiffSectionHeader({ onToggle, onOpenSection, openSectionTitle, + onOpenPreview, trailingContent }: { path: string @@ -21,6 +22,7 @@ export function DiffSectionHeader({ onToggle: () => void onOpenSection: (event: MouseEvent) => void openSectionTitle: string + onOpenPreview?: (event: MouseEvent) => void trailingContent?: ReactNode }): ReactElement { return ( @@ -71,8 +73,29 @@ export function DiffSectionHeader({
{trailingContent} + {onOpenPreview != null && ( + + )}