Skip to content

Commit 852758c

Browse files
authored
fix(web): optimize diff display and enable text selection for code and log views (#1802)
* fix(web): optimize diff display and enable text selection for code and log views - Add ChangeTypes type definition to support file change type identification - Optimize FileDiff component to distinguish between pure rename and rename with modification prompt copy - Simplify parsedDiffs logic by removing EMPTY_DIFF_MARKER handling - Enable text selection functionality for code view and log view * fix(web): fix code text selection styling and diff parsing line break issues * fix(web): fix code text selection styling and diff parsing line break issues
1 parent 3079b4e commit 852758c

File tree

6 files changed

+102
-52
lines changed

6 files changed

+102
-52
lines changed

moon/apps/web/components/ClView/components/Checks/index.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,11 @@ const Checks = ({ cl }: { cl: number }) => {
209209
}
210210

211211
if (status === 'success' && logsMap[buildid] && eventSourcesRef.current[buildid]) {
212-
return <LazyLog extraLines={1} text={logsMap[buildid]} stream enableSearch caseInsensitive follow />
212+
return (
213+
<div className='h-full select-text [&_*]:select-text'>
214+
<LazyLog extraLines={1} text={logsMap[buildid]} stream enableSearch caseInsensitive follow />
215+
</div>
216+
)
213217
}
214218

215219
// Fallback: show select prompt

moon/apps/web/components/CodeView/BlobView/CodeContent.module.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,10 @@
6666
.bg-blame-10 {
6767
background-color: rgb(61, 19, 0);
6868
}
69+
70+
.codeContainer :global(*::selection),
71+
.blameContainer :global(*::selection),
72+
.previewContainer :global(*::selection) {
73+
background-color: #0969da;
74+
color: #fff;
75+
}

moon/apps/web/components/CodeView/BlobView/CodeContent.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -469,8 +469,8 @@ const CodeContent = ({
469469
<div className='flex flex-1 flex-col overflow-hidden'>
470470
<div style={{ flex: 1, overflow: 'auto' }}>
471471
<div
472-
className='rounded-b-lg border border-gray-200'
473-
style={{ minWidth: 'fit-content', backgroundColor: '#fff' }}
472+
className={`rounded-b-lg border border-gray-200 ${styles.codeContainer}`}
473+
style={{ minWidth: 'fit-content', backgroundColor: '#fff', userSelect: 'text' }}
474474
>
475475
{shikiTokens.map((line, index) => {
476476
return (
@@ -544,8 +544,8 @@ const CodeContent = ({
544544
<ContributionRecord contributors={blameData.data?.contributors} />
545545
<div style={{ flex: 1, overflow: 'auto' }}>
546546
<div
547-
className='rounded-b-lg border border-gray-200'
548-
style={{ minWidth: 'fit-content', backgroundColor: '#fff' }}
547+
className={`rounded-b-lg border border-gray-200 ${styles.blameContainer}`}
548+
style={{ minWidth: 'fit-content', backgroundColor: '#fff', userSelect: 'text' }}
549549
>
550550
{processedBlameBlocks.map((block, blockIndex) => {
551551
const isLastBlock = blockIndex === processedBlameBlocks.length - 1
@@ -654,7 +654,10 @@ const CodeContent = ({
654654
}
655655

656656
return (
657-
<div className='markdown-body overflow-auto rounded-b-lg border border-gray-200 p-8'>
657+
<div
658+
className={`markdown-body overflow-auto rounded-b-lg border border-gray-200 p-8 ${styles.previewContainer}`}
659+
style={{ userSelect: 'text' }}
660+
>
658661
<Markdown>{fileContent}</Markdown>
659662
</div>
660663
)

moon/apps/web/components/DiffView/FileDiff.tsx

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
2-
import { type FileDiffMetadata } from '@pierre/diffs'
2+
import { type ChangeTypes, type FileDiffMetadata } from '@pierre/diffs'
33
import { FileDiff as PierreFileDiff } from '@pierre/diffs/react'
44
import { Virtuoso } from 'react-virtuoso'
55

@@ -100,14 +100,35 @@ export default function FileDiff({
100100
setExpandedMap(Object.fromEntries(diffFiles.map((f) => [f.path, false])))
101101
}, [diffFiles])
102102

103+
const getChangeTypeMessage = (changeType: ChangeTypes | null): string | null => {
104+
switch (changeType) {
105+
case 'new':
106+
return 'This file was added.'
107+
case 'deleted':
108+
return 'This file was deleted.'
109+
case 'rename-pure':
110+
return 'This file was renamed.'
111+
case 'rename-changed':
112+
return 'This file was renamed and modified.'
113+
default:
114+
return null
115+
}
116+
}
117+
103118
const RenderDiffView = ({
104-
file,
105-
fileDiffMetadata
119+
fileDiffMetadata,
120+
changeType,
121+
isBinary,
122+
hasContent
106123
}: {
107-
file: { path: string; lang: string; diff: string }
108124
fileDiffMetadata: FileDiffMetadata | null
125+
changeType: ChangeTypes | null
126+
isBinary: boolean
127+
hasContent: boolean
109128
}) => {
110-
if (fileDiffMetadata) {
129+
const message = getChangeTypeMessage(changeType)
130+
131+
if (fileDiffMetadata && hasContent) {
111132
return (
112133
<PierreFileDiff
113134
fileDiff={fileDiffMetadata}
@@ -118,25 +139,44 @@ export default function FileDiff({
118139
overflow: 'wrap',
119140
disableFileHeader: true,
120141
unsafeCSS: `
121-
:host { overflow-x: hidden !important; }
122-
* { overflow-x: hidden !important; }
123-
::-webkit-scrollbar { display: none !important; }
124-
`
142+
:host { overflow-x: hidden !important; }
143+
* { overflow-x: hidden !important; }
144+
::-webkit-scrollbar { display: none !important; }
145+
code { padding: 0 !important; }
146+
`
125147
}}
126148
style={{ '--diffs-font-size': '14px' } as React.CSSProperties}
127149
/>
128150
)
129-
} else if (file.lang === 'binary') {
130-
return <div className='p-2 text-center'>Binary file</div>
131-
} else if (file.diff === 'EMPTY_DIFF_MARKER\n') {
132-
return <div className='p-2 text-center'>No change</div>
151+
}
152+
153+
if (isBinary) {
154+
return (
155+
<div className='p-4 text-center'>
156+
<div>Binary file</div>
157+
{message && <div className='mt-1 text-sm text-gray-600'>{message}</div>}
158+
</div>
159+
)
160+
}
161+
162+
if (message) {
163+
return (
164+
<div className='p-4 text-center'>
165+
<div>Load Diff</div>
166+
<div className='mt-1 text-sm text-gray-600'>{message}</div>
167+
</div>
168+
)
169+
}
170+
171+
if (!hasContent) {
172+
return <div className='p-4 text-center text-gray-500'>No content change</div>
133173
}
134174

135175
return null
136176
}
137177

138178
const DiffItemComponent = (index: number) => {
139-
const { file, fileDiffMetadata, stats } = parsedFiles[index]
179+
const { file, fileDiffMetadata, stats, changeType, isBinary, hasContent } = parsedFiles[index]
140180
const isExpanded = expandedMap[file.path]
141181

142182
return (
@@ -168,7 +208,14 @@ export default function FileDiff({
168208
</div>
169209

170210
<div className='copyable-text'>
171-
{isExpanded && <RenderDiffView file={file} fileDiffMetadata={fileDiffMetadata} />}
211+
{isExpanded && (
212+
<RenderDiffView
213+
fileDiffMetadata={fileDiffMetadata}
214+
changeType={changeType}
215+
isBinary={isBinary}
216+
hasContent={hasContent}
217+
/>
218+
)}
172219
</div>
173220
</div>
174221
)
Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { parsePatchFiles, type FileDiffMetadata } from '@pierre/diffs'
1+
import { parsePatchFiles, type ChangeTypes, type FileDiffMetadata } from '@pierre/diffs'
22

33
import { getLanguageForFile } from '@/utils/shikiLanguageFallback'
44

@@ -11,29 +11,17 @@ export interface ParsedFile {
1111
file: { path: string; lang: string; diff: string }
1212
fileDiffMetadata: FileDiffMetadata | null
1313
stats: { additions: number; deletions: number }
14+
changeType: ChangeTypes | null
15+
isBinary: boolean
16+
hasContent: boolean
1417
}
1518

1619
export function parsedDiffs(diffText: DiffItem[]): { path: string; lang: string; diff: string }[] {
1720
if (diffText.length < 1) return []
1821

1922
return diffText.map((block) => {
2023
const isBinary = /Binary files.*differ/.test(block.data)
21-
22-
let diff = block.data
23-
24-
if (isBinary) {
25-
/* empty */
26-
} else {
27-
const isEmptyDiff = !block.data.includes('@@')
28-
29-
if (isEmptyDiff) {
30-
diff = 'EMPTY_DIFF_MARKER'
31-
}
32-
}
33-
34-
if (!diff.endsWith('\n')) {
35-
diff += '\n'
36-
}
24+
const diff = block.data.endsWith('\n') ? block.data : block.data + '\n'
3725

3826
return {
3927
path: block.path,
@@ -45,31 +33,29 @@ export function parsedDiffs(diffText: DiffItem[]): { path: string; lang: string;
4533

4634
export function generateParsedFiles(diffFiles: { path: string; lang: string; diff: string }[]): ParsedFile[] {
4735
return diffFiles.map((file) => {
48-
if (file.lang === 'binary' || file.diff === 'EMPTY_DIFF_MARKER\n') {
49-
return {
50-
file,
51-
fileDiffMetadata: null,
52-
stats: { additions: 0, deletions: 0 }
53-
}
54-
}
55-
5636
let fileDiffMetadata: FileDiffMetadata | null = null
5737
let additions = 0
5838
let deletions = 0
39+
let changeType: ChangeTypes | null = null
40+
const isBinary = file.lang === 'binary'
41+
let hasContent = false
5942

6043
try {
6144
const patches = parsePatchFiles(file.diff)
6245

6346
if (patches.length > 0 && patches[0].files.length > 0) {
64-
fileDiffMetadata = patches[0].files[0]
47+
const parsed = patches[0].files[0]
6548

66-
if (!fileDiffMetadata.name && file.path) {
67-
fileDiffMetadata = { ...fileDiffMetadata, name: file.path }
68-
}
49+
changeType = parsed.type || null
50+
hasContent = parsed.hunks.length > 0
6951

7052
const safeLang = getLanguageForFile(file.path)
7153

72-
fileDiffMetadata = { ...fileDiffMetadata, lang: safeLang as any }
54+
fileDiffMetadata = {
55+
...parsed,
56+
name: parsed.name || file.path,
57+
lang: safeLang as any
58+
}
7359
}
7460

7561
if (fileDiffMetadata) {
@@ -83,6 +69,6 @@ export function generateParsedFiles(diffFiles: { path: string; lang: string; dif
8369
console.error('error parsing diff:', e)
8470
}
8571

86-
return { file, fileDiffMetadata, stats: { additions, deletions } }
72+
return { file, fileDiffMetadata, stats: { additions, deletions }, changeType, isBinary, hasContent }
8773
})
8874
}

moon/apps/web/types/pierre-diffs.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
declare module '@pierre/diffs' {
2+
export type ChangeTypes = 'change' | 'rename-pure' | 'rename-changed' | 'new' | 'deleted'
3+
24
export interface FileDiffHunk {
35
header: string
46
additionCount: number
@@ -15,6 +17,7 @@ declare module '@pierre/diffs' {
1517
name: string
1618
oldName?: string
1719
lang?: string
20+
type?: ChangeTypes
1821
hunks: FileDiffHunk[]
1922
}
2023

0 commit comments

Comments
 (0)