Skip to content

Commit c6fa091

Browse files
Copilotalexr00
andauthored
Show loading indicator when clicking on commits in timeline (#7465)
* Initial plan * Initial setup - Planning implementation of commit loading indicator Co-authored-by: alexr00 <[email protected]> * Implement loading indicator for commit clicks in timeline Co-authored-by: alexr00 <[email protected]> * 💄 * Fix loading indicator layout issues Co-authored-by: alexr00 <[email protected]> * Fix wrapping --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: alexr00 <[email protected]>
1 parent d71b3c3 commit c6fa091

File tree

5 files changed

+38
-8
lines changed

5 files changed

+38
-8
lines changed

src/github/pullRequestOverview.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,7 @@ export class PullRequestOverviewPanel extends IssueOverviewPanel<PullRequestMode
538538
try {
539539
const { commitSha } = message.args;
540540
await PullRequestModel.openCommitChanges(this._item.githubRepository, commitSha);
541+
this._replyMessage(message, {});
541542
} catch (error) {
542543
Logger.error(`Failed to open commit changes: ${formatError(error)}`, PullRequestOverviewPanel.ID);
543544
vscode.window.showErrorMessage(vscode.l10n.t('Failed to open commit changes: {0}', formatError(error)));

src/github/views.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ export interface PullRequest extends Issue {
105105
lastReviewType?: ReviewType;
106106
revertable?: boolean;
107107
busy?: boolean;
108+
loadingCommit?: string;
108109
}
109110

110111
export interface ProjectItemsReply {

webviews/common/common.css

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,21 @@ button.inlined-dropdown {
459459
margin-left: 5px;
460460
}
461461

462+
.commit-spinner-inline {
463+
margin-left: 8px;
464+
display: inline-flex;
465+
align-items: center;
466+
vertical-align: middle;
467+
grid-column: none;
468+
}
469+
470+
.commit-spinner-before {
471+
margin-right: 6px;
472+
display: inline-flex;
473+
align-items: center;
474+
vertical-align: middle;
475+
}
476+
462477
.loading {
463478
animation: spinner-rotate 1s linear infinite;
464479
}

webviews/common/context.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,14 @@ export class PRContext {
293293

294294
public openSessionLog = (link: SessionLinkInfo) => this.postMessage({ command: 'pr.open-session-log', args: { link } });
295295

296-
public openCommitChanges = (commitSha: string) => {
297-
const args: OpenCommitChangesArgs = { commitSha };
298-
return this.postMessage({ command: 'pr.openCommitChanges', args });
296+
public openCommitChanges = async (commitSha: string) => {
297+
this.updatePR({ loadingCommit: commitSha });
298+
try {
299+
const args: OpenCommitChangesArgs = { commitSha };
300+
await this.postMessage({ command: 'pr.openCommitChanges', args });
301+
} finally {
302+
this.updatePR({ loadingCommit: undefined });
303+
}
299304
};
300305

301306
setPR = (pr: PullRequest | undefined) => {

webviews/components/timeline.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { ReviewType } from '../../src/github/views';
2828
import PullRequestContext from '../common/context';
2929
import { CommentView } from './comment';
3030
import Diff from './diff';
31-
import { commitIcon, errorIcon, mergeIcon, plusIcon, tasklistIcon, threeBars } from './icon';
31+
import { commitIcon, errorIcon, loadingIcon, mergeIcon, plusIcon, tasklistIcon, threeBars } from './icon';
3232
import { nbsp } from './space';
3333
import { Timestamp } from './timestamp';
3434
import { AuthorLink, Avatar } from './user';
@@ -107,12 +107,18 @@ export default Timeline;
107107

108108
const CommitEventView = (event: CommitEvent) => {
109109
const context = useContext(PullRequestContext);
110+
const [clickedElement, setClickedElement] = useState<'title' | 'sha' | undefined>(undefined);
110111

111-
const handleCommitClick = (e: React.MouseEvent) => {
112+
const handleCommitClick = (e: React.MouseEvent, elementType: 'title' | 'sha') => {
112113
e.preventDefault();
113-
context.openCommitChanges(event.sha);
114+
setClickedElement(elementType);
115+
context.openCommitChanges(event.sha).finally(() => {
116+
setClickedElement(undefined);
117+
});
114118
};
115119

120+
const isLoading = context.pr?.loadingCommit === event.sha;
121+
116122
return (
117123
<div className="comment-container commit">
118124
<div className="commit-message">
@@ -124,19 +130,21 @@ const CommitEventView = (event: CommitEvent) => {
124130
<div className="message-container">
125131
<a
126132
className="message"
127-
onClick={handleCommitClick}
133+
onClick={(e) => handleCommitClick(e, 'title')}
128134
title={event.htmlUrl}
129135
>
130136
{event.message.substr(0, event.message.indexOf('\n') > -1 ? event.message.indexOf('\n') : event.message.length)}
131137
</a>
138+
{isLoading && clickedElement === 'title' && <span className="commit-spinner-inline">{loadingIcon}</span>}
132139
</div>
133140
</div>
134141
<div className="timeline-detail">
135142
<a
136143
className="sha"
137-
onClick={handleCommitClick}
144+
onClick={(e) => handleCommitClick(e, 'sha')}
138145
title={event.htmlUrl}
139146
>
147+
{isLoading && clickedElement === 'sha' && <span className="commit-spinner-before">{loadingIcon}</span>}
140148
{event.sha.slice(0, 7)}
141149
</a>
142150
<Timestamp date={event.committedDate} />

0 commit comments

Comments
 (0)