Skip to content

Commit 2c8523d

Browse files
committed
Use selectionMode="multi" in commit files list
1 parent 368408e commit 2c8523d

4 files changed

Lines changed: 90 additions & 31 deletions

File tree

app/src/ui/history/file-list.tsx

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import { CommittedFileItem } from './committed-file-item'
77

88
interface IFileListProps {
99
readonly files: ReadonlyArray<CommittedFileChange>
10-
readonly selectedFile: CommittedFileChange | null
11-
readonly onSelectedFileChanged: (file: CommittedFileChange) => void
10+
readonly selectedFiles: ReadonlyArray<CommittedFileChange>
11+
readonly onSelectionChanged: (
12+
files: ReadonlyArray<CommittedFileChange>
13+
) => void
1214
readonly onRowDoubleClick: (row: number, source: ClickSource) => void
1315
readonly availableWidth: number
1416
readonly onContextMenu?: (
@@ -33,9 +35,11 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
3335
}
3436
}
3537

36-
private onSelectedRowChanged = (row: number) => {
37-
const file = this.props.files[row]
38-
this.props.onSelectedFileChanged(file)
38+
private onSelectionChanged = (rows: ReadonlyArray<number>) => {
39+
const files = rows
40+
.map(r => this.props.files[r])
41+
.filter((f): f is CommittedFileChange => f !== undefined)
42+
this.props.onSelectionChanged(files)
3943
}
4044

4145
private renderFile = (row: number) => {
@@ -48,10 +52,11 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
4852
)
4953
}
5054

51-
private selectedRowsForFile(): ReadonlyArray<number> {
52-
const { selectedFile: file, files } = this.props
53-
const fileIndex = file ? files.findIndex(f => f.path === file.path) : -1
54-
return fileIndex >= 0 ? [fileIndex] : []
55+
private selectedRowsForFiles(): ReadonlyArray<number> {
56+
const { selectedFiles, files } = this.props
57+
return selectedFiles
58+
.map(sf => files.findIndex(f => f.path === sf.path))
59+
.filter(i => i >= 0)
5560
}
5661

5762
private onRowContextMenu = (
@@ -75,8 +80,9 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
7580
rowRenderer={this.renderFile}
7681
rowCount={this.props.files.length}
7782
rowHeight={29}
78-
selectedRows={this.selectedRowsForFile()}
79-
onSelectedRowChanged={this.onSelectedRowChanged}
83+
selectionMode="multi"
84+
selectedRows={this.selectedRowsForFiles()}
85+
onSelectionChanged={this.onSelectionChanged}
8086
onRowDoubleClick={this.props.onRowDoubleClick}
8187
onRowContextMenu={this.onRowContextMenu}
8288
onRowKeyboardFocus={this.onRowFocus}

app/src/ui/history/selected-commits.tsx

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,14 @@ import { openFile } from '../lib/open-file'
1414
import {
1515
isSafeFileExtension,
1616
CopyFilePathLabel,
17+
CopyRelativeFilePathLabel,
18+
CopySelectedPathsLabel,
19+
CopySelectedRelativePathsLabel,
1720
DefaultEditorLabel,
1821
RevealInFileManagerLabel,
1922
OpenWithDefaultProgramLabel,
20-
CopyRelativeFilePathLabel,
2123
} from '../lib/context-menu'
24+
import { EOL } from 'os'
2225
import { ThrottledScheduler } from '../lib/throttled-scheduler'
2326

2427
import { Dispatcher } from '../dispatcher'
@@ -97,6 +100,7 @@ interface ISelectedCommitsProps {
97100

98101
interface ISelectedCommitsState {
99102
readonly isExpanded: boolean
103+
readonly selectedFiles: ReadonlyArray<CommittedFileChange>
100104
}
101105

102106
/** The History component. Contains the commit list, commit summary, and diff. */
@@ -111,11 +115,17 @@ export class SelectedCommits extends React.Component<
111115

112116
this.state = {
113117
isExpanded: false,
118+
selectedFiles: [],
114119
}
115120
}
116121

117-
private onFileSelected = (file: CommittedFileChange) => {
118-
this.props.dispatcher.changeFileSelection(this.props.repository, file)
122+
private onFileSelectionChanged = (
123+
files: ReadonlyArray<CommittedFileChange>
124+
) => {
125+
this.setState({ selectedFiles: files })
126+
if (files.length === 1) {
127+
this.props.dispatcher.changeFileSelection(this.props.repository, files[0])
128+
}
119129
}
120130

121131
private onRowDoubleClick = (row: number) => {
@@ -131,9 +141,7 @@ export class SelectedCommits extends React.Component<
131141
const nextValue = nextProps.selectedCommits.map(c => c.sha).join('')
132142

133143
if (currentValue !== nextValue) {
134-
if (this.state.isExpanded) {
135-
this.setState({ isExpanded: false })
136-
}
144+
this.setState({ isExpanded: false, selectedFiles: [] })
137145
}
138146
}
139147

@@ -266,8 +274,8 @@ export class SelectedCommits extends React.Component<
266274
{this.renderFileHeader()}
267275
<FileList
268276
files={files}
269-
onSelectedFileChanged={this.onFileSelected}
270-
selectedFile={this.props.selectedFile}
277+
onSelectionChanged={this.onFileSelectionChanged}
278+
selectedFiles={this.state.selectedFiles}
271279
availableWidth={availableWidth}
272280
onContextMenu={this.onContextMenu}
273281
onRowDoubleClick={this.onRowDoubleClick}
@@ -404,6 +412,42 @@ export class SelectedCommits extends React.Component<
404412
? `Open in ${externalEditorLabel}`
405413
: DefaultEditorLabel
406414

415+
const { selectedFiles } = this.state
416+
const isMultiSelect =
417+
selectedFiles.length > 1 && selectedFiles.some(f => f.path === file.path)
418+
const filesToCopy = isMultiSelect ? selectedFiles : [file]
419+
420+
const copyPathItems: ReadonlyArray<IMenuItem> =
421+
filesToCopy.length === 1
422+
? [
423+
{
424+
label: CopyFilePathLabel,
425+
action: () => clipboard.writeText(fullPath),
426+
},
427+
{
428+
label: CopyRelativeFilePathLabel,
429+
action: () => clipboard.writeText(Path.normalize(file.path)),
430+
},
431+
]
432+
: [
433+
{
434+
label: CopySelectedPathsLabel,
435+
action: () =>
436+
clipboard.writeText(
437+
filesToCopy
438+
.map(f => Path.join(repository.path, f.path))
439+
.join(EOL)
440+
),
441+
},
442+
{
443+
label: CopySelectedRelativePathsLabel,
444+
action: () =>
445+
clipboard.writeText(
446+
filesToCopy.map(f => Path.normalize(f.path)).join(EOL)
447+
),
448+
},
449+
]
450+
407451
const items: IMenuItem[] = [
408452
{
409453
label: RevealInFileManagerLabel,
@@ -421,14 +465,7 @@ export class SelectedCommits extends React.Component<
421465
enabled: isSafeExtension && fileExistsOnDisk,
422466
},
423467
{ type: 'separator' },
424-
{
425-
label: CopyFilePathLabel,
426-
action: () => clipboard.writeText(fullPath),
427-
},
428-
{
429-
label: CopyRelativeFilePathLabel,
430-
action: () => clipboard.writeText(Path.normalize(file.path)),
431-
},
468+
...copyPathItems,
432469
{ type: 'separator' },
433470
]
434471

app/src/ui/open-pull-request/pull-request-files-changed.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,14 @@ export class PullRequestFilesChanged extends React.Component<
251251
)
252252
}
253253

254+
private onFileSelectionChanged = (
255+
files: ReadonlyArray<CommittedFileChange>
256+
) => {
257+
if (files.length > 0) {
258+
this.onFileSelected(files[0])
259+
}
260+
}
261+
254262
private onRowDoubleClick = (row: number) => {
255263
const files = this.props.files
256264
const file = files[row]
@@ -292,8 +300,8 @@ export class PullRequestFilesChanged extends React.Component<
292300
>
293301
<FileList
294302
files={files}
295-
onSelectedFileChanged={this.onFileSelected}
296-
selectedFile={selectedFile}
303+
onSelectionChanged={this.onFileSelectionChanged}
304+
selectedFiles={selectedFile ? [selectedFile] : []}
297305
availableWidth={clamp(fileListWidth)}
298306
onContextMenu={this.onFileContextMenu}
299307
onRowDoubleClick={this.onRowDoubleClick}

app/src/ui/stashing/stash-diff-viewer.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@ export class StashDiffViewer extends React.PureComponent<IStashDiffViewerProps>
7575
file
7676
)
7777

78+
private onFileSelectionChanged = (
79+
files: ReadonlyArray<CommittedFileChange>
80+
) => {
81+
if (files.length > 0) {
82+
this.onSelectedFileChanged(files[0])
83+
}
84+
}
85+
7886
private onRowDoubleClick = (row: number) => {
7987
const files = this.getFiles()
8088
const file = files[row]
@@ -150,8 +158,8 @@ export class StashDiffViewer extends React.PureComponent<IStashDiffViewerProps>
150158
>
151159
<FileList
152160
files={files}
153-
onSelectedFileChanged={this.onSelectedFileChanged}
154-
selectedFile={selectedStashedFile}
161+
onSelectionChanged={this.onFileSelectionChanged}
162+
selectedFiles={selectedStashedFile ? [selectedStashedFile] : []}
155163
availableWidth={availableWidth}
156164
onRowDoubleClick={this.onRowDoubleClick}
157165
/>

0 commit comments

Comments
 (0)