Skip to content

Commit e4cc3c6

Browse files
committed
Implement the ability to show a Git diff for files listed in the Stage Files Modal
1 parent c7fe3be commit e4cc3c6

8 files changed

Lines changed: 107 additions & 10 deletions

File tree

‎packages/ui/src/components/editor/panel/modals/StageFilesModal/StageFilesModal.module.scss‎

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,7 @@
2020
}
2121

2222
&--select-all {
23-
&:hover {
24-
background-color: transparent;
25-
}
26-
27-
strong:hover {
28-
text-decoration: underline;
29-
}
23+
font-weight: 500;
3024
}
3125

3226
&__details {

‎packages/ui/src/components/editor/panel/modals/StageFilesModal/StageFilesModal.stories.tsx‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,17 @@ export const Default = () => {
2929
alert(`Go to file: ${file}`)
3030
}
3131

32+
const handle_show_diff = (file: string) => {
33+
alert(`Show diff for file: ${file}`)
34+
}
35+
3236
return visible ? (
3337
<StageFilesModal
3438
files={mock_files}
3539
on_stage={handle_stage}
3640
on_cancel={handle_cancel}
3741
on_go_to_file={handle_go_to_file}
42+
on_show_diff={handle_show_diff}
3843
/>
3944
) : null
4045
}

‎packages/ui/src/components/editor/panel/modals/StageFilesModal/StageFilesModal.tsx‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ type Props = {
1111
on_stage: (files_to_stage: string[]) => void
1212
on_cancel: () => void
1313
on_go_to_file: (file: string) => void
14+
on_show_diff: (file: string) => void
1415
}
1516

1617
export const StageFilesModal: React.FC<Props> = (props) => {
@@ -56,9 +57,7 @@ export const StageFilesModal: React.FC<Props> = (props) => {
5657
checked={all_selected}
5758
on_change={handle_toggle_select_all}
5859
/>
59-
<div className={styles.files__item__details}>
60-
<strong>Select all</strong>
61-
</div>
60+
<div className={styles.files__item__details}>Select all</div>
6261
</label>
6362
{props.files.map((file) => {
6463
const last_slash_index = file.lastIndexOf('/')
@@ -84,6 +83,14 @@ export const StageFilesModal: React.FC<Props> = (props) => {
8483
)}
8584
</div>
8685
<div className={styles.files__item__actions}>
86+
<IconButton
87+
codicon_icon="diff-single"
88+
title="Show Diff"
89+
on_click={(e) => {
90+
e.stopPropagation()
91+
props.on_show_diff(file)
92+
}}
93+
/>
8794
<IconButton
8895
codicon_icon="go-to-file"
8996
title="Go To File"
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import * as vscode from 'vscode'
2+
import * as path from 'path'
3+
import { ShowDiffMessage } from '@/views/panel/types/messages'
4+
import { Logger } from '@shared/utils/logger'
5+
import { dictionary } from '@shared/constants/dictionary'
6+
7+
export const handle_show_diff = async (
8+
message: ShowDiffMessage
9+
): Promise<void> => {
10+
const { file_path } = message
11+
const workspace_folders = vscode.workspace.workspaceFolders
12+
if (!workspace_folders) {
13+
Logger.warn({
14+
function_name: 'handle_show_diff',
15+
message: 'No workspace folders open'
16+
})
17+
vscode.window.showWarningMessage(
18+
dictionary.error_message.NO_WORKSPACE_FOLDERS_FOUND
19+
)
20+
return
21+
}
22+
23+
let target_workspace: vscode.WorkspaceFolder | undefined
24+
25+
if (workspace_folders.length == 1) {
26+
target_workspace = workspace_folders[0]
27+
} else {
28+
for (const folder of workspace_folders) {
29+
const potential_uri = vscode.Uri.joinPath(folder.uri, file_path)
30+
try {
31+
await vscode.workspace.fs.stat(potential_uri)
32+
target_workspace = folder
33+
break
34+
} catch {}
35+
}
36+
}
37+
38+
if (!target_workspace) {
39+
const error_message =
40+
dictionary.error_message.WORKSPACE_NOT_FOUND_FOR_FILE(file_path)
41+
Logger.error({
42+
function_name: 'handle_show_diff',
43+
message: error_message,
44+
data: { file_path }
45+
})
46+
vscode.window.showErrorMessage(error_message)
47+
return
48+
}
49+
50+
const rightUri = vscode.Uri.joinPath(target_workspace.uri, file_path)
51+
52+
try {
53+
const leftUri = rightUri.with({
54+
scheme: 'git',
55+
query: JSON.stringify({ path: rightUri.fsPath, ref: 'HEAD' })
56+
})
57+
const file_name = path.basename(file_path)
58+
const title = `${file_name} (HEAD ↔ Working Tree)`
59+
60+
await vscode.commands.executeCommand(
61+
'vscode.diff',
62+
leftUri,
63+
rightUri,
64+
title
65+
)
66+
} catch (error) {
67+
const error_message = `Could not show diff for file: ${file_path}`
68+
Logger.error({
69+
function_name: 'handle_show_diff',
70+
message: error_message,
71+
data: { error, file_path }
72+
})
73+
vscode.window.showErrorMessage(`${error_message}. See logs for details.`)
74+
}
75+
}

‎packages/vscode/src/views/panel/backend/message-handlers/index.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,4 @@ export * from './handle-get-collapsed-states'
4747
export * from './handle-manage-configurations'
4848
export * from './handle-save-component-collapsed-state'
4949
export * from './handle-undo'
50+
export * from './handle-show-diff'

‎packages/vscode/src/views/panel/backend/panel-provider.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import {
4747
handle_save_donations_visibility,
4848
handle_focus_on_file_in_preview,
4949
handle_go_to_file,
50+
handle_show_diff,
5051
handle_toggle_file_in_preview,
5152
handle_intelligent_update_file_in_preview,
5253
handle_commit_changes,
@@ -513,6 +514,8 @@ export class PanelProvider implements vscode.WebviewViewProvider {
513514
await handle_save_donations_visibility(this, message)
514515
} else if (message.command == 'GO_TO_FILE') {
515516
handle_go_to_file(message)
517+
} else if (message.command == 'SHOW_DIFF') {
518+
await handle_show_diff(message)
516519
} else if (message.command == 'FOCUS_ON_FILE_IN_PREVIEW') {
517520
handle_focus_on_file_in_preview(message)
518521
} else if (message.command == 'TOGGLE_FILE_IN_REVIEW') {

‎packages/vscode/src/views/panel/frontend/Panel.tsx‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,12 @@ export const Panel = () => {
442442
file_path: file
443443
})
444444
}}
445+
on_show_diff={(file) => {
446+
post_message(vscode, {
447+
command: 'SHOW_DIFF',
448+
file_path: file
449+
})
450+
}}
445451
/>
446452
</div>
447453
)}

‎packages/vscode/src/views/panel/types/messages.ts‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,11 @@ export interface GoToFileMessage extends BaseMessage {
265265
workspace_name?: string
266266
}
267267

268+
export interface ShowDiffMessage extends BaseMessage {
269+
command: 'SHOW_DIFF'
270+
file_path: string
271+
}
272+
268273
export interface GetWorkspaceStateMessage extends BaseMessage {
269274
command: 'GET_WORKSPACE_STATE'
270275
}
@@ -387,6 +392,7 @@ export type FrontendMessage =
387392
| ToggleFileInReviewMessage
388393
| FocusOnFileInPreviewMessage
389394
| GoToFileMessage
395+
| ShowDiffMessage
390396
| GetWorkspaceStateMessage
391397
| RequestGitStateMessage
392398
| IntelligentUpdateFileInPreviewMessage

0 commit comments

Comments
 (0)