Skip to content

Commit c3be70b

Browse files
Copilotalexr00
andcommitted
Implement loading indicator for commit clicks in timeline
Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com>
1 parent 8248267 commit c3be70b

3 files changed

Lines changed: 25 additions & 9 deletions

File tree

src/github/views.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,10 @@ export interface Issue {
6363
continueOnGitHub: boolean;
6464
isDarkTheme: boolean;
6565
isEnterprise: boolean;
66-
canAssignCopilot: boolean;
67-
reactions: Reaction[];
68-
busy?: boolean;
66+
canAssignCopilot: boolean;
67+
reactions: Reaction[];
68+
busy?: boolean;
69+
loadingCommit?: string;
6970
}
7071

7172
export interface PullRequest extends Issue {

webviews/common/context.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +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) => this.postMessage({ command: 'pr.openCommitChanges', args: { commitSha } as OpenCommitChangesArgs });
296+
public openCommitChanges = async (commitSha: string) => {
297+
this.updatePR({ loadingCommit: commitSha });
298+
try {
299+
await this.postMessage({ command: 'pr.openCommitChanges', args: { commitSha } as OpenCommitChangesArgs });
300+
} finally {
301+
this.updatePR({ loadingCommit: undefined });
302+
}
303+
};
297304

298305
setPR = (pr: PullRequest | undefined) => {
299306
this.pr = pr;

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' | null>(null);
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(null);
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,17 +130,19 @@ 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="spinner">{loadingIcon}</span>}
132139
</div>
133140
</div>
134141
<div className="timeline-detail">
142+
{isLoading && clickedElement === 'sha' && <span className="spinner">{loadingIcon}</span>}
135143
<a
136144
className="sha"
137-
onClick={handleCommitClick}
145+
onClick={(e) => handleCommitClick(e, 'sha')}
138146
title={event.htmlUrl}
139147
>
140148
{event.sha.slice(0, 7)}

0 commit comments

Comments
 (0)