Skip to content

Commit 5ecf1b0

Browse files
committed
feat: implement commit range selection with Shift+click
1 parent 667db0d commit 5ecf1b0

File tree

1 file changed

+83
-6
lines changed

1 file changed

+83
-6
lines changed

web/main.ts

Lines changed: 83 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,31 @@ class GitGraphView {
839839
this.selectedCommits.clear();
840840
}
841841

842+
private selectCommitRange(fromHash: string, toHash: string) {
843+
const fromIndex = this.commitLookup[fromHash];
844+
const toIndex = this.commitLookup[toHash];
845+
846+
if (fromIndex === undefined || toIndex === undefined) return;
847+
848+
this.clearCommitSelection();
849+
850+
// Determine the range
851+
const startIndex = Math.min(fromIndex, toIndex);
852+
const endIndex = Math.max(fromIndex, toIndex);
853+
854+
// Select all commits in the range
855+
for (let i = startIndex; i <= endIndex; i++) {
856+
const commit = this.commits[i];
857+
if (commit) {
858+
this.selectedCommits.add(commit.hash);
859+
const commitElem = document.querySelector(`tr.commit[data-id="${i}"]`);
860+
if (commitElem) {
861+
commitElem.classList.add('commitSelected');
862+
}
863+
}
864+
}
865+
}
866+
842867
private getSelectedCommitsArray(): string[] {
843868
return Array.from(this.selectedCommits).sort((a, b) => {
844869
const indexA = this.commitLookup[a];
@@ -2526,22 +2551,74 @@ class GitGraphView {
25262551
const mouseEvent = <MouseEvent>e;
25272552

25282553
if (mouseEvent.shiftKey) {
2554+
if (this.selectedCommits.size > 0) {
2555+
// Shift-click: select range from first selected commit
2556+
const anchorCommit = Array.from(this.selectedCommits)[0];
2557+
this.selectCommitRange(anchorCommit, commit.hash);
2558+
2559+
// Check if exactly 2 commits are selected to show diff
2560+
if (this.selectedCommits.size === 2) {
2561+
// Get the two selected commits
2562+
const selectedHashes = Array.from(this.selectedCommits);
2563+
const commitElems = selectedHashes.map(hash => {
2564+
const index = this.commitLookup[hash];
2565+
return document.querySelector(`tr.commit[data-id="${index}"]`) as HTMLElement;
2566+
}).filter(elem => elem !== null);
2567+
2568+
if (commitElems.length === 2) {
2569+
// Load comparison between the two commits
2570+
const [firstIndex, secondIndex] = selectedHashes.map(hash => this.commitLookup[hash]);
2571+
if (firstIndex < secondIndex) {
2572+
this.loadCommitComparison(commitElems[1], commitElems[0]);
2573+
} else {
2574+
this.loadCommitComparison(commitElems[0], commitElems[1]);
2575+
}
2576+
}
2577+
} else if (this.selectedCommits.size > 2) {
2578+
// More than 2 commits selected, close any open details
2579+
this.closeCommitDetails(true);
2580+
}
2581+
} else {
2582+
// No commits selected, just select this one
2583+
this.toggleCommitSelection(commit.hash, eventElem);
2584+
}
2585+
} else if (mouseEvent.ctrlKey || mouseEvent.metaKey) {
2586+
// Ctrl/Cmd-click: toggle individual commit selection
25292587
this.toggleCommitSelection(commit.hash, eventElem);
2588+
2589+
// Check if exactly 2 commits are selected to show diff
2590+
if (this.selectedCommits.size === 2) {
2591+
// Get the two selected commits
2592+
const selectedHashes = Array.from(this.selectedCommits);
2593+
const commitElems = selectedHashes.map(hash => {
2594+
const index = this.commitLookup[hash];
2595+
return document.querySelector(`tr.commit[data-id="${index}"]`) as HTMLElement;
2596+
}).filter(elem => elem !== null);
2597+
2598+
if (commitElems.length === 2) {
2599+
// Load comparison between the two commits
2600+
const [firstIndex, secondIndex] = selectedHashes.map(hash => this.commitLookup[hash]);
2601+
if (firstIndex < secondIndex) {
2602+
this.loadCommitComparison(commitElems[1], commitElems[0]);
2603+
} else {
2604+
this.loadCommitComparison(commitElems[0], commitElems[1]);
2605+
}
2606+
}
2607+
} else if (this.selectedCommits.size > 2) {
2608+
// More than 2 commits selected, close any open details
2609+
this.closeCommitDetails(true);
2610+
}
25302611
} else if (this.expandedCommit !== null) {
25312612
if (this.expandedCommit.commitHash === commit.hash) {
25322613
this.closeCommitDetails(true);
2533-
} else if (mouseEvent.ctrlKey || mouseEvent.metaKey) {
2534-
if (this.expandedCommit.compareWithHash === commit.hash) {
2535-
this.closeCommitComparison(true);
2536-
} else if (this.expandedCommit.commitElem !== null) {
2537-
this.loadCommitComparison(this.expandedCommit.commitElem, eventElem);
2538-
}
25392614
} else {
25402615
this.clearCommitSelection();
25412616
this.loadCommitDetails(eventElem);
25422617
}
25432618
} else {
2619+
// Regular click: select only this commit and load details
25442620
this.clearCommitSelection();
2621+
this.toggleCommitSelection(commit.hash, eventElem);
25452622
this.loadCommitDetails(eventElem);
25462623
}
25472624
}

0 commit comments

Comments
 (0)