Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit 8bddb0d

Browse files
committed
Display most recent draft when diff opened.
1 parent 208710a commit 8bddb0d

File tree

8 files changed

+98
-13
lines changed

8 files changed

+98
-13
lines changed
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
namespace GitHub.App.Models.Drafts
1+
using GitHub.ViewModels;
2+
3+
namespace GitHub.Models.Drafts
24
{
5+
/// <summary>
6+
/// Stores a draft for a <see cref="CommentViewModel"/>
7+
/// </summary>
38
public class CommentDraft
49
{
10+
/// <summary>
11+
/// Gets or sets the draft comment body.
12+
/// </summary>
513
public string Body { get; set; }
614
}
715
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
using GitHub.ViewModels;
3+
4+
namespace GitHub.Models.Drafts
5+
{
6+
/// <summary>
7+
/// Stores a draft for a <see cref="PullRequestReviewCommentViewModel"/>
8+
/// </summary>
9+
public class PullRequestReviewCommentDraft : CommentDraft
10+
{
11+
/// <summary>
12+
/// Gets or sets the side of the diff that the draft comment was left on.
13+
/// </summary>
14+
public DiffSide Side { get; set; }
15+
16+
/// <summary>
17+
/// Gets or sets the time that the draft was last updated.
18+
/// </summary>
19+
public DateTimeOffset UpdatedAt { get; set; }
20+
}
21+
}

src/GitHub.App/Services/PullRequestEditorService.cs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
using System.Linq;
66
using System.Reactive.Linq;
77
using System.Threading.Tasks;
8+
using EnvDTE;
89
using GitHub.Commands;
910
using GitHub.Extensions;
1011
using GitHub.Models;
12+
using GitHub.Models.Drafts;
13+
using GitHub.ViewModels;
1114
using GitHub.VisualStudio;
1215
using Microsoft.VisualStudio;
1316
using Microsoft.VisualStudio.Editor;
@@ -18,7 +21,6 @@
1821
using Microsoft.VisualStudio.Text.Editor;
1922
using Microsoft.VisualStudio.Text.Projection;
2023
using Microsoft.VisualStudio.TextManager.Interop;
21-
using EnvDTE;
2224
using Task = System.Threading.Tasks.Task;
2325

2426
namespace GitHub.Services
@@ -39,6 +41,8 @@ public class PullRequestEditorService : IPullRequestEditorService
3941
readonly IStatusBarNotificationService statusBar;
4042
readonly IGoToSolutionOrPullRequestFileCommand goToSolutionOrPullRequestFileCommand;
4143
readonly IEditorOptionsFactoryService editorOptionsFactoryService;
44+
readonly IMessageDraftStore draftStore;
45+
readonly IInlineCommentPeekService peekService;
4246
readonly IUsageTracker usageTracker;
4347

4448
[ImportingConstructor]
@@ -49,6 +53,8 @@ public PullRequestEditorService(
4953
IStatusBarNotificationService statusBar,
5054
IGoToSolutionOrPullRequestFileCommand goToSolutionOrPullRequestFileCommand,
5155
IEditorOptionsFactoryService editorOptionsFactoryService,
56+
IMessageDraftStore draftStore,
57+
IInlineCommentPeekService peekService,
5258
IUsageTracker usageTracker)
5359
{
5460
Guard.ArgumentNotNull(serviceProvider, nameof(serviceProvider));
@@ -58,13 +64,17 @@ public PullRequestEditorService(
5864
Guard.ArgumentNotNull(goToSolutionOrPullRequestFileCommand, nameof(goToSolutionOrPullRequestFileCommand));
5965
Guard.ArgumentNotNull(goToSolutionOrPullRequestFileCommand, nameof(editorOptionsFactoryService));
6066
Guard.ArgumentNotNull(usageTracker, nameof(usageTracker));
67+
Guard.ArgumentNotNull(peekService, nameof(peekService));
68+
Guard.ArgumentNotNull(draftStore, nameof(draftStore));
6169

6270
this.serviceProvider = serviceProvider;
6371
this.pullRequestService = pullRequestService;
6472
this.vsEditorAdaptersFactory = vsEditorAdaptersFactory;
6573
this.statusBar = statusBar;
6674
this.goToSolutionOrPullRequestFileCommand = goToSolutionOrPullRequestFileCommand;
6775
this.editorOptionsFactoryService = editorOptionsFactoryService;
76+
this.draftStore = draftStore;
77+
this.peekService = peekService;
6878
this.usageTracker = usageTracker;
6979
}
7080

@@ -129,7 +139,7 @@ public async Task<ITextView> OpenFile(
129139
}
130140

131141
/// <inheritdoc/>
132-
public async Task<IDifferenceViewer> OpenDiff(IPullRequestSession session, string relativePath, string headSha, bool scrollToFirstDiff)
142+
public async Task<IDifferenceViewer> OpenDiff(IPullRequestSession session, string relativePath, string headSha, bool scrollToFirstDraftOrDiff)
133143
{
134144
Guard.ArgumentNotNull(session, nameof(session));
135145
Guard.ArgumentNotEmptyString(relativePath, nameof(relativePath));
@@ -168,12 +178,37 @@ await pullRequestService.ExtractToTempFile(
168178
var caption = $"Diff - {Path.GetFileName(file.RelativePath)}";
169179
var options = __VSDIFFSERVICEOPTIONS.VSDIFFOPT_DetectBinaryFiles |
170180
__VSDIFFSERVICEOPTIONS.VSDIFFOPT_LeftFileIsTemporary;
181+
var openThread = (line: -1, side: DiffSide.Left);
182+
var scrollToFirstDiff = false;
171183

172184
if (!workingDirectory)
173185
{
174186
options |= __VSDIFFSERVICEOPTIONS.VSDIFFOPT_RightFileIsTemporary;
175187
}
176188

189+
if (scrollToFirstDraftOrDiff)
190+
{
191+
var (key, _) = PullRequestReviewCommentThreadViewModel.GetDraftKeys(
192+
session.LocalRepository.CloneUrl.WithOwner(session.RepositoryOwner),
193+
session.PullRequest.Number,
194+
relativePath,
195+
0);
196+
var drafts = (await draftStore.GetDrafts<PullRequestReviewCommentDraft>(key)
197+
.ConfigureAwait(true))
198+
.OrderByDescending(x => x.data.UpdatedAt)
199+
.ToList();
200+
201+
if (drafts.Count > 0 && int.TryParse(drafts[0].secondaryKey, out var line))
202+
{
203+
openThread = (line, drafts[0].data.Side);
204+
scrollToFirstDiff = false;
205+
}
206+
else
207+
{
208+
scrollToFirstDiff = true;
209+
}
210+
}
211+
177212
IVsWindowFrame frame;
178213
using (OpenWithOption(DifferenceViewerOptions.ScrollToFirstDiffName, scrollToFirstDiff))
179214
using (OpenInProvisionalTab())
@@ -228,6 +263,18 @@ await pullRequestService.ExtractToTempFile(
228263
else
229264
await usageTracker.IncrementCounter(x => x.NumberOfPRDetailsViewChanges);
230265

266+
if (openThread.line != -1)
267+
{
268+
var view = diffViewer.ViewMode == DifferenceViewMode.Inline ?
269+
diffViewer.InlineView :
270+
openThread.side == DiffSide.Left ? diffViewer.LeftView : diffViewer.RightView;
271+
272+
// HACK: We need to wait here for the view to initialize or the peek session won't appear.
273+
// There must be a better way of doing this.
274+
await Task.Delay(1500).ConfigureAwait(true);
275+
peekService.Show(view, openThread.side, openThread.line);
276+
}
277+
231278
return diffViewer;
232279
}
233280
catch (Exception e)
@@ -247,7 +294,7 @@ public async Task<IDifferenceViewer> OpenDiff(
247294
Guard.ArgumentNotEmptyString(relativePath, nameof(relativePath));
248295
Guard.ArgumentNotNull(thread, nameof(thread));
249296

250-
var diffViewer = await OpenDiff(session, relativePath, thread.CommitSha, scrollToFirstDiff: false);
297+
var diffViewer = await OpenDiff(session, relativePath, thread.CommitSha, scrollToFirstDraftOrDiff: false);
251298

252299
var param = (object)new InlineCommentNavigationParams
253300
{

src/GitHub.App/ViewModels/CommentThreadViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
using System.Reactive.Linq;
66
using System.Reactive.Subjects;
77
using System.Threading.Tasks;
8-
using GitHub.App.Models.Drafts;
98
using GitHub.Extensions;
109
using GitHub.Models;
10+
using GitHub.Models.Drafts;
1111
using GitHub.Services;
1212
using ReactiveUI;
1313

src/GitHub.App/ViewModels/PullRequestReviewCommentThreadViewModel.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
using System.Globalization;
44
using System.Linq;
55
using System.Threading.Tasks;
6-
using GitHub.App.Models.Drafts;
76
using GitHub.Extensions;
87
using GitHub.Factories;
98
using GitHub.Models;
9+
using GitHub.Models.Drafts;
1010
using GitHub.Primitives;
1111
using GitHub.Services;
1212
using ReactiveUI;
@@ -133,9 +133,9 @@ public async Task InitializeNewAsync(
133133
Comments.Add(vm);
134134

135135
var (key, secondaryKey) = GetDraftKeys(vm);
136-
var draft = await DraftStore.GetDraft<CommentDraft>(key, secondaryKey).ConfigureAwait(true);
136+
var draft = await DraftStore.GetDraft<PullRequestReviewCommentDraft>(key, secondaryKey).ConfigureAwait(true);
137137

138-
if (draft != null)
138+
if (draft?.Side == side)
139139
{
140140
vm.Body = draft.Body;
141141
}
@@ -193,13 +193,19 @@ public static (string key, string secondaryKey) GetDraftKeys(
193193
string relativePath,
194194
int lineNumber)
195195
{
196+
relativePath = relativePath.Replace("\\", "/");
196197
var key = Invariant($"pr-review-comment|{cloneUri}|{pullRequestNumber}|{relativePath}");
197198
return (key, lineNumber.ToString(CultureInfo.InvariantCulture));
198199
}
199200

200201
protected override CommentDraft BuildDraft(ICommentViewModel comment)
201202
{
202-
return base.BuildDraft(comment);
203+
return new PullRequestReviewCommentDraft
204+
{
205+
Body = comment.Body,
206+
Side = Side,
207+
UpdatedAt = DateTimeOffset.UtcNow,
208+
};
203209
}
204210

205211
protected override (string key, string secondaryKey) GetDraftKeys(ICommentViewModel comment)

test/GitHub.App.UnitTests/Services/PullRequestEditorServiceTests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ static PullRequestEditorService CreateNavigationService()
5656
var statusBar = Substitute.For<IStatusBarNotificationService>();
5757
var openFileInSolutionCommand = Substitute.For<IGoToSolutionOrPullRequestFileCommand>();
5858
var editorOptionsFactoryService = Substitute.For<IEditorOptionsFactoryService>();
59+
var draftStore = Substitute.For<IMessageDraftStore>();
60+
var peekService = Substitute.For<IInlineCommentPeekService>();
5961
var usageTracker = Substitute.For<IUsageTracker>();
6062
return new PullRequestEditorService(
6163
sp,
@@ -64,6 +66,8 @@ static PullRequestEditorService CreateNavigationService()
6466
statusBar,
6567
openFileInSolutionCommand,
6668
editorOptionsFactoryService,
69+
draftStore,
70+
peekService,
6771
usageTracker);
6872
}
6973
}

test/GitHub.App.UnitTests/ViewModels/CommentThreadViewModelTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
using System;
22
using System.Reactive.Concurrency;
33
using System.Threading.Tasks;
4-
using GitHub.App.Models.Drafts;
54
using GitHub.Models;
5+
using GitHub.Models.Drafts;
66
using GitHub.Services;
77
using GitHub.ViewModels;
88
using NSubstitute;

test/GitHub.App.UnitTests/ViewModels/PullRequestReviewCommentThreadViewModelTests.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
using System;
2-
using System.Collections.Generic;
1+
using System.Collections.Generic;
32
using System.Linq;
43
using System.Reactive.Concurrency;
54
using System.Reactive.Linq;
65
using System.Threading.Tasks;
7-
using GitHub.App.Models.Drafts;
86
using GitHub.Factories;
97
using GitHub.Models;
8+
using GitHub.Models.Drafts;
109
using GitHub.Primitives;
1110
using GitHub.Services;
1211
using GitHub.ViewModels;

0 commit comments

Comments
 (0)